乐趣区

JAVA面试题43

    本文首发于 cartoon 的博客
     转载请注明出处:https://cartoonyu.github.io/c…

java

  1. 对 synchronized 的了解

    1. java 的一个关键字,用于重量级锁的设定
    2. 利用 synchronized 关键字,可以实现对互斥资源的访问
    3. 作用范围

      1. 普通方法,锁的粒度为当前对象
      2. 静态方法,锁的粒度为当前类的 class 对象
      3. 代码块,锁的粒度为括号内使用的对象
  2. 多线程的同步机制

    1. 使用同步代码块 synchronized
    2. 通过标志位轮询访问临界资源
    3. 通过 Condition 以及 lock 对资源的锁定以及释放
    4. 通过阻塞队列 BlockQueue(生产者 / 消费者)
  3. threadLocal 的概念以及使用场景

    1. 每个线程都能拥有该变量的独立副本
    2. 内部通过 ThreadLocalMap 进行值的存储以及读取

      1. 初始容量为 16

        1. 负载因子为 2 /3
        2. 通过再 hash 法解决 hash 冲突
  4. final,finally,finalize 的区别

    1. final 为不可变修饰词,用于声明属性,方法或类不可变
    2. finally 为异常捕获机制一部分,总是会被执行。若 try 或 catch 有 return 语句,finally 早于此 return 语句执行
    3. finalize 为 Object 方法,调用此方法可以实现资源的回收,但是回收时间由 JVM 决定
  5. java 注解的作用

    1. 生成文档
    2. 完成特定的标识(@Service 等)
    3. 在编译时进行格式检查(@Override)
  6. java 集合间的区别

    1. set 与 list 都只含单个元素,而 Map 含有 key-value 对
    2. Map 将 entry 数组置为 null,就是 set,所以 set 内元素是无序的,list 元素是有序的
  7. BIO NIO AIO 的区别

    1. BIO

      1. 同步阻塞

        1. 线程阻塞进行运算后返回结果
    2. NIO

      1. 同步非阻塞

        1. 请求共用一个线程进行处理
        2. 线程会直接返回结果到请求
    3. AIO

      1. 异步非阻塞

        1. 线程处理后会通过回调返回结果
  8. java 反射机制的理解

    1. 作用

      1. 在程序运行中,动态获取对象所属类,属性以及方法等信息
      2. 在程序运行时,动态改变对象属性
    2. 动态代理以及静态代理

jvm

  1. 怎么判断对象是否可回收?

    1. 引用计数法
    2. 可达性分析算法(GC ROOT)
  2. java 内存区域划分

    1. 运行时数据区域
    2. 线程共享

      1. 方法区
    3. 线程隔离区

      1. 虚拟机栈
      2. 本地方法栈
      3. 程序计数器

数据库

  1. MyBatis 分页方式以及区别

    1. 逻辑分页

      1. 数组分页
      2. RowBounds 分页
    2. 物理分页

      1. sql 分页
      2. 拦截器分页
  2. 数据库事务特性以及隔离级别

    1. 特性

      1. 原子性(Atomicity)

        1. 事务执行结果是一致的,成功或者回滚
      2. 一致性(Consistency)

        1. 事务执行前后数据库状态不受影响
      3. 隔离性(Isolation)

        1. 事务间操作相互独立
      4. 持久性

        1. 事务执行产生的结果是永久存储下来的
    2. 隔离级别

      1. read uncommitted

        1. 读取事务未提交的数据
      2. read commited

        1. 多次查询某一数据结果不一致
      3. repeatable

        1. 同时修改同一元素造成事务提交结果发生偏差
      4. serializable

        1. 事务的顺序执行
  3. redis 的数据类型以及底层数据结构

    1. string

      1. 通过 DDS(简单的动态字符串)实现
      2. DDS 的实现通过双端链表实现
    2. hash

      1. 压缩列表(数据量较小)

        1. key-value 对少于 512 个且所有键对大小都要小于 64 字节
      2. 散列表

        1. 链地址法解决冲突
    3. set

      1. 有序数组

        1. 数据都是整数
        2. 元素个数不超过 512 个
      2. 散列表
    4. list

      1. 压缩列表
      2. 双循环链表

        1. 所有数据大小小于 64 字节
        2. 数据个数小于 128 个
    5. 有序集合

      1. 压缩列表

        1. 类似于数组,存储空间是连续的,但是元素所占空间不唯一
      2. 双循环链表
  4. 缓存穿透的概念,解决方法

    1. 缓存穿透是指请求访问不存在的 key,请求穿透到 DB,流量大会造成 DB 崩溃
    2. 解决方法

      1. 采用布隆过滤器或者 BitMap 对请求进行过滤
  5. 缓存雪崩的概念,解决方法

    1. 大量 key 设置统一过期时间,造成瞬间 DB 访问量过大
    2. 解决方法

      1. key 的过期时间用随机数进行设置
  6. 缓存击穿的概念,解决方法

    1. 存在 key 在缓存失效的瞬间被大量请求访问,造成 DB 请求量大
    2. 解决方法

      1. 设置短期 key 替代原始 key
      2. key 再生成后删除短期 key

spring

  1. AOP,IOC 的概念

    1. AOP

      1. AOP 面向切面编程,它将原本纵向的程序看作成一个个切面的组合,是 OOP 的补充
      2. 动态插入执行逻辑到原有执行流程中
      3. 通知(Advice): 具体实现逻辑
      4. 连接点(JoinPoint): 使用通知的位置
      5. 切入点(PointCut): 指定使用通知的连接点位置
      6. 切面(Aspect): 通知与切入点集合
      7. 引入(introduction): 添加新方法属性到现有类中
      8. 目标(target): 被通知的对象
      9. 代理(proxy)
      10. 静态代理
      11. 动态代理
      12. 织入(weaving): 将切面引用到目标对象生成代理对象的过程
    2. IOC

      1. 我把 IOC 称作为控制反转或者依赖注入,IOC 是 Spring 的核心思想,它使调用者不用管理对象的生存周期以及具体实现,能够更加注重于业务逻辑的实现。
      2. 在平时实际开发中,我通常使用向上转型的对象完成业务逻辑,这样我觉得能使对象中的耦合度降低,而且在代码重构的时候能够轻易切换实现类。
  2. Spring bean 的作用域

    1. singleton
    2. prototype
    3. session
    4. request
    5. global session
  3. Spring bean 是线程安全吗?

    1. prototype,request 每次被调用都会创建新对象,不存在线程问题
    2. singleton,session,globalSession 会造成线程间竞争,无状态 bean 是线程安全的,有状态 beanSpring 通过 ThreadLocal 进行解决
  4. spring mvc 的执行流程

    1. 请求通过 http 到达后端,由 DispatcherServlet 进行分发
    2. DispatchServlet 通过 HandlerMapping 查找处理的 Controller,中间或者会有过滤器等进行处理
    3. 如果在查找过程中发生错误,HandlerExceptionResolver 会返回一个 HandlerExecutionChain 对象到 DispathchServlet
    4. 请求正确分发到 Controller,Controller 调用 Service 以及 Repository 等进行处理,调用 RequestAndViewNameResolver 处理后返回 ModelAndView 对象到 DispatchServlet
    5. DispatchServlet 根据返回的 ModelAndView 对象,将对象交给 ViewResolver 组件进行视图的渲染,如果在语言上有特殊要求,渲染会调用 LocaleResolver 以及 ThemeResolver 进行国际化的适配

网络

  1. Session 与 cookie 的区别

    1. cookie 存储在客户端,session 存储在服务器
    2. cookie 只能存储字符串,session 可以存储任意对象
    3. cookie 的存储大小受客户端影响,大小为 4KB,session 存储大小不受影响
    4. 后端获取 cookie 通过 http 报文中的 cookie 字段获取,session 则通过 cookie 中的 sessionId 标识寻找
  2. session 的工作原理

    1. session 是存储在服务器端的一种标识客户端的数据结构
    2. 用户请求到达后台,后台检测是否有 sessionId 字段的存在

      1. 有的话,校验字段是否合法
      2. 没有的话,创建新 session 并返回对应 sessionId 到客户端
  3. TCP 与 UDP 区别

    1. TCP 面向连接,UDP 不面向连接
    2. TCP 有拥塞控制,UDP 没有拥塞控制
    3. TCP 资源开销大,UDP 资源开销小
    4. TCP 只支持一对一,UDP 支持一对多
    5. TCP 提供可靠传输,UDP 尽可能交付
    6. TCP 面向字节流,UDP 面向报文
  4. tcp 粘包的原因以及解决办法

    1. 原因

      1. 不同数据包在到达接收方时首尾部粘在一起
      2. 解决方法

        1. 在每个 tcp 报文首部添加报文长度
        2. 在报文的首部或者尾部设置特殊的符号位标识
  5. tcp 的三次握手与四次挥手

    1. 三次握手(连接过程)

      1. 一次握手(客户端发起)

        1. 创建 TCB
        2. 发送 SYN=1,seq=x
        3. 进入 SYN-SENT
      2. 二次握手(服务器发起)

        1. 发送 ACK=1,syn=1,ack=y+1,seq=x+1
        2. 进入 SYN-RCVD
      3. 三次握手(客户端发起)

        1. 发送 ACK=1,seq=x+1,ack=x+1
        2. 进入 ESTABLISHED
    2. 四次挥手(结束连接过程)

      1. 一次挥手

        1. 客户端发送 FIN=1,seq= u 为内容的请求报文
        2. 客户端进入 FIN-SENT- 1 状态
      2. 二次挥手

        1. 服务器端发送 ACK=1,seq=v,ack=u+ 1 为内容的确认报文
        2. 服务器端进入 CLOSE_WAIT
        3. 客户端进入 FIN-SENT- 2 状态
      3. 三次挥手

        1. 服务器端发送 FIN=1,seq=w,ACK=1,ack=u+ 1 为内容的释放报文
        2. 服务器端进入 LAST_ACK 状态
      4. 四次挥手

        1. 客户端发送 ACK=1,ack=w+1,seq=u+ 1 为内容的确认报文
        2. 客户端进入 TIME_WAIT 状态,等待 2MSL 后关闭连接
        3. 服务器端接受报文后关闭连接

设计模式

  1. 抽象工厂与简单工厂的区别

    1. 抽象工厂定义创建产品的大概流程,子工厂通过继承抽象工厂负责具体产品的创建,产品种类的增加不需要改变抽象工厂的代码逻辑
    2. 简单工厂负责具体产品的创建,产品种类的增加需要改变创建的逻辑

算法

  1. 快速排序实现

    1. 主要采用分治的思想
    2. 定义左右指针遍历元素(左右指针的初始值为边界)
    3. 循环遍历数组(左指针小于右指针)

      1. 循环遍历左指针直到元素大于右指针指向的元素
      2. 交换左右指针的元素值
      3. 循环遍历右指针直到元素小于小指针指向的元素
      4. 交换左右指针的元素值
    4. 返回左指针的值作为中线
    5. 分别递归中线左右,依据 2,3 的步骤进行处理
退出移动版