Java-八股文

  1. hashcode()、equals()
  2. 1.如果hashcode()不相同,两个对象一定不是同一个对象
    2.如果hashcode()相同,两个对象不一定上同一个对象,需要进一步判别equals
    3.如果equals相同,应当认为两个对象就是相同对象
    由于hashcode方法仅返回一个值,equals里面有若干逻辑,因此,部分集合类的判断中,会优先判断hashcode,如果相同再继续equals判断
    结论:如果改写了equals方法,则必须改写hashcode方法,以便于逻辑一致
    
  3. string、stringbuffer、stringbuilder
  4. string:常量,每次修改都会创建新的字符串常量
    stringbuffer:线程安全的字符串变量
    stringbuilder:不安全的字符串变量
    
  5. extends、super
  6. <? extends T>:?是T的子类
    <? super T>:?是T的基类
    
  7. == 、 equals
  8. ==:基本类型-看值;引用类型-看引用地址
    euqals:看各种类的重写逻辑[逻辑里面也有可能复用==]
    
  9. 重载、重写
  10. 重载:针对单一类中,相同方法名,不同方法签名
    重写:针对父子类,相同方法名,相同方法签名
    重写:返回值类型、抛出异常都必须小于等于父类;访问修饰符大于等于父类
    
  11. 深拷贝与浅拷贝
  12. 浅拷贝:基本数据类型拷贝了第二份,引用类型的变量全部都是拷贝了一份引用地址,指向了原来的地方。
    深拷贝:所有数据类型都拷贝了第二份,不仅仅拷贝引用地址。
    
  13. 字节码
  14. 定义:字节码文件是Java源码编译过后的一种格式,各个平台上相同的源码编译出的字节码是相同的,但是,字节码转化的机器码不相同,这个转化上JDK(JRE)做的,因此,Java上跨平台语言
    相当于编译过程所指的,中间代码[前有词法分析、语法分析、语义分析][后有代码优化、目标代码生成]
    优点:实现了语言的跨平台;编译过程可以做代码优化,提高执行效率
    
  15. Java异常体系
  16. graph TD; Throwable --> Exception Throwable --> Error Exception --> RuntimeException Exception --> 非RuntimeException

    error是非常严重的错误,程序已无法正常运行,没必要捕获
    运行时异常,一般是逻辑问题,应尽量避免
    非运行时异常,不处理无法正常运行,必须处理

  17. 什么时候抛异常?什么时候捕获异常?
  18. 抛:自身无法处理就往上抛,由上级处理
    捕获:自身能处理就捕获,捕获走既定处理流程
    
  19. 类加载器
  20. graph TD; bootstrapClassLoader负责加载JAVA_HOME下lib里面的jar包与类文件 --> ExtClassLoader负责加载JAVA_HOME下lib下ext里面的jar包与类文件 --> AppClassLoader负责加载classpath路径下的类文件
  21. 类加载器的双亲委派模型
  22. 由16可知,类加载器共三个,AppClassLoader有两个父类
    当AppClassLoader加载时,会优先调用父类的加载器,这种JVM机制叫做双亲委派模型
    AppClassLoader.loadClass(){
      ExtClassLoader.loadClass(){
        bootstrapClassLoader.loadClass();
      }
    }
    
  23. 什么是幂等性
  24. 定义:多次重复执行与单次执行产生的效果应当一致,例如,相同的请求,请求一次与请求多次,产生的效果应当是稳定一致的
    
  25. 如何实现接口幂等性
  26. 就请求类型而言,
    删除、查询
    1.通过请求里面带的ID,或者请求参数拼接计算出一个ID,将ID存入Redis等存储中间件,用ID来标识请求是否处理过
    修改、新增
    2.除了阻断请求到数据库处理以外,还可以通过在数据库处理的时候,加上乐观锁,保证如果有其他请求修改的话,就放弃修改
    3.通过数据库的唯一约束来使得相同的修改失败也可以
    
    4.可以在数据库之前加个监控层,监控服务器资源,线程池资源等等
    5.网关是个好东西,可以针对性封ip,限流,鉴权,完全没有必要每个接口考虑这种事情,投入产出比太低
    
    
    
  27. 布隆过滤器原理及优缺点
  28. 原理
    存
    1.每个key通过若干哈希算法,得到对应下标
    2.对应下标的位置全部置为1
    取
    3.给定key计算对应下标,如果都为1,可能在里面,有0,肯定不在里面
    
    优点:
    1.占用空间小
    2.速度快,耗时少,O(K),K为哈希算法数量
    
    缺点:
    1.仅能判断在或不在,拿不到原值
    2.存在假阳性误判情况
    
  29. finally一定会执行吗?
  30. 正常情况 finally一定会执行 
    因此 接下来仅考虑什么情况不执行
    
    1.进入try之前就报错 从而终止了
    2.执行finally之前有system.exit(0) 退出JVM了 也不会执行finally
    
  31. 为什么不能用浮点型表示金额
  32. 为什么GC的年轻代与老年代要以15来划分?能否改变?
  33. 因为年龄是存在对象头里面的,总共就划分了4个bit位,最大值就是15,默认为什么是这个值,应该是当初发布GC的时候有实验过的经验值
    能改变,但是,最大值就是15[只有4个bit位]
    
  34. 依赖版本冲突问题如何解决?
  35. 1.首先定位是哪个包出现了冲突?
    IDEA可以进行依赖分析;或者mvn dependency:tree
    2.判断为什么冲突?
    2.1 单纯的只是自己引用了两个版本
    移除其中一个;
    采用dependencyManage统一管理版本号
    2.2 由于子项目或者依赖,引入了其下的一个依赖 导致与自己引入的依赖冲突
    子项目利用optional 将依赖不再传递至上级模块;
    主项目采用exclusion 将子项目依赖或者依赖的依赖直接排除在外
    
  36. 什么时候需要用到序列化与反序列化?
  37. 1.将对象数据持久化到磁盘
    2.深拷贝
    3.网络传输只能用流
    
  38. 从发请求到收响应,什么阶段需要用到序列化与反序列化?
  39. 网络传输阶段需要用到序列化与反序列化
    1.前端发请求到后台
    2.后台返回响应给前端
    
    后台处理过程中,如果需要用到深拷贝,也可能用到序列化与反序列化
    后台处理过程中,如果需要持久化,也可能用到序列化
    
  40. 实现序列化与反序列化为什么要实现serilizable接口?
  41. 1.这个接口是个标记,当JVM发现了该类有实现这个接口的时候,底层就会自动实现序列化与反序列化
    2.有了这个标记,应当可以确保不会对不可序列化的对象进行序列化
    
  42. serilizable接口为什么要指定serialVersinUID?
  43. 如果不指定,则JVM会依据对象生成对应ID来进行序列化与反序列化
    如果类一旦修改,那么序列化与反序列化两阶段生层的ID就有可能不同,从而导致失败
    因此,显式指定ID,可避免序列化与反序列化生成的ID不同
    
  44. 为什么新版JDK要将string内部的char[]改为了byte[]?
  45. 原本string内部有一个表示所有字符的char[],且string内部用的是UTF-16,即每个字符有2字节,共16bit位
    因此,如果内容全部都是ASCII 字符,那么每个字符都仅需要1个字节就能表示,即一个byte的空间,
    因此,string增加了compact string的优化,能尽量减少空间成本(char[]--->byte[])
    
    但是,这个优化对开发者来说是透明的,不需要修改任何代码
    
  46. 如何优化提升接口性能?
  47. 接口:Java+SQL
    Java:
    1.减少重复计算,用空间换时间
    2.利用布隆过滤器等方式,能尽早判断的东西提前,以便于更快返回,减少逻辑执行
    3.能异步执行的操作尽量异步,不必同步一直等待
    
    SQL:
    1.热点数据采用缓存方式,减少数据库IO成本
    2.SQL本身的分析优化
    
  48. new string的时候创建了几个对象
  49. 完全初始状态下,
    字符串常量池,如果没有这个字符串,重新实例化一个常量对象,保存该常量
    堆-实例化一个string对象,指向常量池中对应常量对象
    
    常量池有对应常量对象
    仅堆中实例化一个对象指向常量池中常量对象
    
  50. 反射机制的优缺点
  51. 优点:
    1.可以在运行时,对类进行修改与操作
    2.可以在运行时,轻松获得类的属性与方法,通过反射来动态调用
    
    缺点:
    1.清晰:反射机制多了以后,代码可读性降低
    2.性能:反射调用类,比直接调用类,性能会降低
    3.违反规范:使用反射可以绕过一些限制访问的属性与方法,从而破坏了原有的抽象性
    
  52. cookies与session的区别
  53. 1.cookies是客户端存储机制
    2.session是服务端存储机制[又会引出分布式环境下的session不共享问题,要么抛弃状态,要么Redis,要么轮询就盯着一个,要么服务端就不要了存在客户端就好了每次验证就行]
    
    graph TD; 客户端首次请求 --> 服务端将状态信息保存到session,并返回给客户端sessionID --> 客户端保存到cookies --> 携带sessionID请求服务端
  54. Integer与int的区别 为什么需要包装类
  55. 定义:
    Integer:包装类
    int:基本数据类型
    
    存储:
    包装类一定上保存到堆上
    基本数据类型如果是成员对象,保存到堆上,如果是局部变量,保存到栈
    
    初始:
    包装类初始为null
    基本数据类型为0
    
    本身:
    包装类本身提供若干方法
    基本数据类型本身不带任何方法
    
    Java是面向对象的语言,因此,很多操作需要对象来处理,对开发人员用对象也更灵活
    例如,集合必须保存对象
    
  56. JDK动态代理为什么只能代理有接口的类?
  57. 原因:
    JDK动态代理的原理: 继承java.lang.reflect.Proxy类 然后实现对应的接口 生成一个动态代理类 $Proxy
    由于Java仅支持单继承 所以这里只能是实现对应接口
    
    为什么要这么设计?
    1.动态代理的应用场景应该是针对原始实现的一个拦截,做功能的增强或者扩展,
    2.且Java一直提倡的是面向接口开发
    综上所述,从应用场景上来说,应该是合理的
    
    如果有代理实现类的需要 可以选择cglib组件
    通过继承对应的类 子类重写对应的方法 可以对原方法进行拦截
    
  58. API设计要素
    1. 资源路径(URI)
    2. HTTP动词(METHOD)
    3. 过滤信息(queryString)
    4. 状态码
    5. 错误信息
    6. 返回值
  59. HTTP状态码
    1. 2XX:成功,操作被成功接收并处理
    2. 3XX:重定向,需要进一步的操作以完成请求
    3. 4XX:客户端错误,请求包含错误或无法完成请求
    4. 5XX:服务端错误,处理请求的过程中发生了错误

    举例:

    1. 202:请求已接受,但是未完成
    2. 201:成功请求并成功创建新资源
    3. 301:请求的资源已永久迁移至新的URI上
    4. 305:该资源必须通过代理访问
    5. 401:身份未认证
    6. 403:请求能理解,服务器拒绝执行访问,例如请求没有权限的资源
    7. 502:网关服务器收到无效请求
    8. 503:服务器暂时无法处理请求

    完整列表:https://zhuanlan.zhihu.com/p/608552648?utm_id=0

  60. restful规范
  61. restful风格规范的初衷就是减少沟通障碍,所提出的一种API设计规范,因此,该规范主要是针对API设计要素提出了若干约束
    
    1. URI只能包含名词,不能包含动词,API的版本可以放到URI里面管理
    2. HTTP动词,不同的动词搭配相同的URI表示不同的意思:
      • GET: 从服务器获取资源(一项或多项)(查)
      • POST: 在服务器新建一个资源(增)
      • PUT: 在服务器更新资源,服务器返回完整的属性(改)
      • DELETE: 从服务器删除资源(删)【假删,逻辑删除】
    3. 状态码复用HTTP状态码即可
    4. 返回值统一使用JSON格式数据
  62. 字符流与字节流的区别
  63. 1.处理类不同
    inputStream outputStream是为了处理字节流存在的
    reader writer 是为了处理字符流存在的
    
    2.处理单元不同
    Java里面用的UTF-16。因此 一个字符一般是用于处理两个字节的Unicode字符
    字节流里面处理单元为一个字节
    字符流里面处理单元为两个字节
    
    3.处理格式不同
    字节流可以处理所有格式数据
    字符流仅能处理文本文件
    
    4.缓冲区使用不同
    字节流不会用到缓冲区
    字符流在使用过程中会用到缓冲区
    
  64. JDK7与JDK8的区别
  65. 接口:
    接口可以添加默认方法
    新增函数式接口声明
    
    方法:
    新增lambda表达式支持
    新增流式处理API
    
    集合:
    hashmap新增红黑树结构
    
  66. Integer类的缓存机制
  67. 所谓的Integer的缓存机制,就是Integer与String类似,也有常量池的概念
    默认-128~127,这个范围内的整数值包装类,会取常量池里面的对象,从而保证其连地址都是一样的
    

参考:

  1. https://blog.csdn.net/liwenxiang629/article/details/109508530
  2. https://blog.csdn.net/weixin_43235210/article/details/90444710?spm=1001.2101.3001.6650.1&utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7ECTRLIST%7ERate-1-90444710-blog-109508530.235%5Ev38%5Epc_relevant_sort&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7ECTRLIST%7ERate-1-90444710-blog-109508530.235%5Ev38%5Epc_relevant_sort&utm_relevant_index=2
  3. https://blog.csdn.net/cst522445906/article/details/126723280
  4. https://www.bilibili.com/video/BV1MU4y1j7Kq/?spm_id_from=333.337.search-card.all.click&vd_source=5c5bc2d817741ded0db4f222d4a03a7c
  5. https://zhuanlan.zhihu.com/p/608552648?utm_id=0
posted @ 2023-07-07 20:40  356a  阅读(79)  评论(0编辑  收藏  举报