面试

记在前面

记录在面试中遇到过得题目,以及面试他人时常问的题目。

java基础

集合

  1. 开发中Java用得比较多的数据结构(集合)有哪些?

  2. ArrayList 如何动态扩容的?Arraylist与LinkedList异同?

  3. ArrayList是线程安全的吗?

    不安全 原因是add方法 elementData[size++] = e;不是原子操作,当多线程添加的情况下,假如size=0时,添加第一个元素的线程添加成功,同时在size没有及时写到内存中时,这时另一个线程继续添加就覆盖了原来的值。要保证线程安全,可以如下使用: Collections.synchronizedList(new ArrayList<>()); 本质是给ArrayList的每个方法加synchronized关键字,本质是利用Object来上锁。

    ArrayList是线程安全的吗?

  4. 循环删除list中元素会如下写会发生什么?

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    // 会抛出 java.util.ConcurrentModificationException异常
    for (String str : list) {
    if ("a".equals(str)) {
    list.remove(str);
    }
    }
    // 正确移除元素
    Iterator<String> it = list.iterator();
    while(it.hasNext()) {
    String str = it.next();
    if ("a".equals(str)) {
    it.remove();
    }
    }
  5. 谈谈你对HashMap的理解,底层原理的基本实现,hashmap实现原理 put的过程?HashMap怎么解决碰撞问题的?

  6. HashMap的遍历有哪两种常用的方法?或者HashMap的操作中,直接使用keySet()遍历有什么问题?

    map.keySet()和map.entrySet()来进行遍历。keySet 先遍历iterator对象,后面再多一步操作hashmap.get(), 第二次遍历只是针对一个bucket的遍历,在hash碰撞不多的情况下性能并不会有大影响。

  7. 假如你回答HashMap是线程安全的,接着问有没有线程安全的map,接下来问conurren包?

线程池

  1. 平时线程池用的多么?看你项目中有用,讲讲线程池的实现原理。最好用笔简单画下。
  2. 线程池中的corePoolSize和maximumPoolSize有什么不同?
  3. 哪种场景下线程池用完后极速回收?

并发

  1. synchronized和锁的区别,什么情况下使用synchronized和ReentrantLock?

    https://blog.csdn.net/qq838642798/article/details/65441415

  2. java并发这块了解的怎么样?说说你对volatile关键字的理解?能保证原子性吗?

  3. 什么是Callable和Future?

    Callable接口类似于Runnable,从名字就可以看出来了,但是Runnable不会返回结果,并且无法抛出返回结果的异常,而Callable功能更强大一些,被线程执行后,可以返回值,这个返回值可以被Future拿到,也就是说,Future可以拿到异步执行任务的返回值。可以认为是带有回调的Runnable。

    Callable接口代表一段可以调用并返回结果的代码;Future接口表示异步任务,是还没有完成的任务给出的未来结果。所以说Callable用于产生结果,Future用于获取结果。

反射

  1. 反射讲一讲,主要是概念, 都在哪需要反射机制?

    对于任意一个类,都能够知道这个类的所有属性和方法(成员变量和函数);对于任意一个对象,都能够调用它的任意一个方法和属性。
    编译时刻加载类是静态加载类
    运行时刻加载类是动态加载类
    new 创建对象 是静态加载类,在编译时刻就需要加载 所有可能使用到的类动态加载类,在运行时加载功能性的类设计时 动态加载Class c = Class.forName(args[0]) ;反射的操作都是编译之后的操作,编译之后集合是去泛型化的。java中集合的泛型,是防止错误输入的,只在编译阶段有效,绕过编译就无效了。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    // Foo的实例对象如何表示
    Foo foo1 = new Foo();
    // Foo这个类 也是一个实例对象,Class类的实例对象,如何表示呢
    // 任何一个类都是Class的实例对象,这个实例对象有三种表示方式
    // 第一种表示方式--->实际在告诉我们任何一个类都有一个隐含的静态成员变量class
    Class c1 = Foo.class;
    // 第二中表达方式 已经知道该类的对象通过getClass方法
    Class c2 = foo1.getClass();
    /*官网 c1 ,c2 表示了Foo类的类类型(class type)
    * 万事万物皆对象,
    * 类也是对象,是Class类的实例对象
    * 这个对象我们称为该类的类类型
    */
    // 不管c1 or c2都代表了Foo类的类类型,一个类只可能是Class类的一个实例对象
    // 第三种表达方式
    Class c3 = Class.forName("com.imooc.reflect.Foo");
    // 我们完全可以通过类的类类型创建该类的对象实例---->通过c1 or c2 or c3创建Foo的实例对象
    // 需要有无参数的构造方法
    Foo foo = (Foo)c1.newInstance();
  2. 反射的性能,如何优化?

    • 由于JDK的安全检查耗时较多所以通过setAccessible(true)的方式关闭安全检查就可以达到提升反射速度的目的 性能有了20倍的提升;
    • 缓存大法 多次动态创建一个类的实例的时候,有缓存的写法会比没有缓存要快很多。

设计模式

  1. 能否手写个单例模式的?

  2. 装饰者模式

框架

spring

  1. spring ioc aop 说下原理,理解,aop jdk 和cglib区别,spring选择什么,spring ioc用了什么模式,带来了什么效果?

  2. spring有几种注入方式?

    三种注入方式,构造器、接口、set注入,我们常用的是set注入。

springboot

  1. 项目中有用springboot,为什么用用springboot?

    • 上手容易
    • 独立运行
    • 简化配置
    • 自动配置
    • 应用监控
  2. springboot 的配置文件有哪几种格式?它们有什么区别?

    .properties 和 .yml,它们的区别主要是书写格式不同。

  3. springboot 的核心注解是哪个?它主要由哪几个注解组成的?

    核心注解:@SpringBootApplication ,由三个注解组合而成

    • @SpringBootConfiguration:组合了 @Configuration 注解,实现配置文件的功能。
    • @EnableAutoConfiguration:打开自动配置的功能,也可以关闭某个自动配置的选项。
    • @ComponentScan:Spring组件扫描。
  4. springboot 自动配置原理是什么?

  5. springboot可以兼容老 Spring 项目吗,如何做?

    可以兼容,使用 @ImportResource 注解导入老 Spring 项目配置文件。

springmvc

  1. springmvc原理,流程?

mybatis

  1. #{}和${}的区别是什么?

    #{}是预编译处理,${}是字符串替换。Mybatis在处理#{}时,会将sql中的#{}替换为?号,调用PreparedStatement的set方法来赋值。Mybatis在处理${}时,就是把${}替换成变量的值。使用#{}可以有效的防止SQL注入,提高系统安全性。

  2. mybatis提供了哪些动态sql标签?

    mybatis提供了9种动态sql标签:trim | where | set | foreach | if | choose | when | otherwise | bind。

JVM

  1. 参数设置

    • -Xms 堆的最小值
    • -Xmx 堆的最大值
    • -Xmn 新生代容量
    • -Xss 设置栈容量
    • -XX:PermSize -XXMaxPermSize 限制方法区的大小
    • -XX:MaxTenuringThreshold 动态对象年龄判断
    • -XX:SurviorRatio Eden与Survivor区的比例
    • -XX:PretenureSizeThreshold 晋升老年代对象年龄
  2. 垃圾收集算法有哪些?

    • 标记-清除算法:最基础的收集算法,分为两个阶段 标记和清除 ( 缺点 效率不高,标记和清除两个过程效率都不高; 空间问题 内存产生大量不连续的内存碎片,导致大对象无法找到足够连续的内存而不得不出发另一次垃圾收集)
    • 复制算法:解决效率问题 将内存划分为大小相等的两块,每次只使用其中的一块,当这一块的内存用完了,就将还存活的对象复制到另一块上面,然后将已使用过的内存空间一次清理掉。 代价是将内存缩小了一倍。新生代98%是朝生夕死的,内存分为一块较大的Eden 空间和两块较小的Survivor空间,每次使用Eden和其中一块Survivor,回收时,将Eden和Survivor中还存活的对象一次复制到另一块Survivor空间上,最后清理掉Eden和刚用过的Survivor空间。Hotspot默认Eden和Survivor的大小比例是8:1
    • 标记-整理算法:复制算法在对象存活率较高时就要进行复制操作,效率将会遍低。更关键的是不想浪费空间就需要额外空间进行担保,以应对内存中所有对象都100%存活的极端情况。根据老年代的特定标记过程一样,后续操作是让所有存活的对象都向一边移动,然后直接清理掉端边界以外的内存。
  3. 对象的内存布局 由几部分构成?

    对象在内存中存储的布局可以分为3块区域:对象头(Header)、实例数据(Instance Data)和对齐填充(Padding)。

  4. 对象已死吗?如何判断? GC Roots 有哪些?

    用到了什么 可达性分析算法 (Reachability Analysiss)

    • 虚拟机栈(栈帧中的本地变量表)中引用的对象
    • 方法区中类静态属性引用的对象
    • 方法区中常量引用的对象
    • 本地方法栈中JNI(Native方法)引用的对象
  5. JVM中,如果把堆内存参数配置的超过了本地内存,会怎么样?

    应用运行不了。

    • windows下:

      1
      2
      Error occurred during initialization of VM 
      Could not reserve enough space for object heap
    • linux下:

      1
      2
      error='Cannot allocate memory'
      hs_err_pid1288.log
  6. 类加载器

    双亲委派模型的工作过程是:如果一个类加载器收到了类加载的请求,它首先不会自己去尝试加载这个类,而是把这个请求委派给父类加载器去完成,每一个层次的类加载器都是如此,因此所有的加载请求最终都应该传送到顶层的启动类加载器中,只有当父加载器反馈自己无法完成这个加载请求(它的搜索范围中没有找到所需的类)时,子加载器才会尝试自己去加载。

    好处:就是Java类随着它的类加载器一起具备了一种带有优先级的层次关系 。Object类在程序的各种类加载器环境中都是同一个类。反之,不使用,Java类型体系中最基础的行为也就无法保证,应用程序也将会变得一片混乱

  7. 什么时候触发minor GC 什么时候触发full GC?

    从年轻代空间(包括 Eden 和 Survivor 区域)回收内存被称为 Minor GC;

    对老年代GC称为Major GC;

    而Full GC是对整个堆来说的;

    Minor GC触发条件:当Eden区满时,触发Minor GC。

    Full GC触发条件:

    • System.gc()方法的调用
    • 老年代空间不足
    • 方法区空间不足
    • 通过Minor GC后进入老年代的平均大小大于老年代的可用内存
    • 由Eden区、From Space区向To Space区复制时,对象大小大于To Space可用内存,则把该对象转存到老年代,且老年代的可用内存小于该对象大小

    redis

    1. 看项目中用过redis。redis有什么数据类型?

      主要由五种:String、Hash、List、Set和Sorted Set

    2. 看项目中用过redis,用作缓存,哪种场景下适合用缓存?缓存击穿?

    3. 知道redis的持久化吗?都有什么缺点和有点?具体底层实现呢?

      RDB快照和AOF日志

      • RDB:Redis借助了fork命令的copy on write机制 在生成快照时,将当前进程fork出一个子进程,然后在子进程中循环所有的数据,将数据写成为RDB文件缺点:rdb有他的不足,就是一旦数据库出现问题,那么我们的RDB文件中保存的数据并不是全新的,从上次RDB文件生成到Redis停机这段时间的数据全部丢掉了。
      • AOF:AOF日志的全称是append only file,它是一个追加写入的日志文件 对于那些无法忍数据丢失的应用,建议使用AOF日志。
    4. redis过期策略都有哪些?LRU?写一个java版本的代码吧?

      惰性删除 + 定期删除

      被动删除:当读/写一个已经过期的key时,会触发惰性删除策略,直接删除掉这个过期key

      主动删除:由于惰性删除策略无法保证冷数据被及时删掉,所以Redis会定期主动淘汰一批已过期的key。当前已用内存超过maxmemory限定时,触发主动清理策略。

      当Redis内存使用达到maxmemory时,需要选择设置好的maxmemory-policy进行对老数据的置换

      • noeviction: 不进行置换,表示即使内存达到上限也不进行置换,所有能引起内存增加的命令都会返回error

      • allkeys-lru: 优先删除掉最近最不经常使用的key,用以保存新数据

      • volatile-lru: 只从设置失效(expire set)的key中选择最近最不经常使用的key进行删除,用以保存新数据

      • allkeys-random: 随机从all-keys中选择一些key进行删除,用以保存新数据

      • volatile-random: 只从设置失效(expire set)的key中,选择一些key进行删除,用以保存新数据

      • volatile-ttl: 只从设置失效(expire set)的key中,选出存活时间(TTL)最短的key进行删除,用以保存新数据

        1
        2
        3
        4
        5
        6
        7
        8
        public LRULinkedHashMap(int maxCapacity) { 
        super(maxCapacity, DEFAULT_LOAD_FACTOR, true);
        this.maxCapacity = maxCapacity;
        }
        @Override
        protected boolean removeEldestEntry(java.util.Map.Entry<K, V> eldest) {
        return size() > maxCapacity;
        }
    5. 使用redis如何设计分布式锁?使用zk可以吗?如何实现?这两种哪个效率高?

      redis锁定的原理是利用setnx命令,即只有在某个key不存在情况才能set成功该key。这样就达到了多个进程并发去set同一个key,只有一个进程能set成功。

    6. zookeeper实现了类似paxos协议,是一个拥有多个节点分布式协调服务?

      zookeeper实现锁的方式是客户端一起竞争写某条数据,比如/path/lock,只有第一个客户端能写入成功,其他的客户端都会写入失败。写入成功的客户端就获得了锁,写入失败的客户端,注册watch事件,等待锁的释放,从而继续竞争该锁。

数据库

  1. 数据库索引问题,就是最左前缀问题 联合索引 (A.B),查询时where B = 会走索引吗,where A = 会走吗?

    最左前缀匹配问题。

  2. 创建复合索引时应该将最常用作限制条件的列放在最左边,依次递减。不要过度索引

  3. sql优化有哪些思路?

    应尽量避免全表扫描,首先应考虑在 where 及 order by ,group by 涉及的列上建立索引。最左前缀匹配原则,非常重要的原则,mysql会一直向右匹配直到遇到范围查询(>、<、between、like)就停止匹配

  4. 设计高并发系统数据库层面该怎么设计?数据库锁有哪些类型?如何实现?

    • 数据库服务器采用集群方式部署。

    • 数据库层面,主要就是用到垂直分库,水平分库, 读写分离,热备份等技术,提高数据库的读写能力

  5. 数据库锁?

    悲观锁 for update

    乐观锁 版本号 CAS

  6. 数据库事务有哪些?

    事务应该具有4个属性:原子性、一致性、隔离性、持久性。这四个属性通常称为ACID特性

    • 原子性(Atomicity):事务作为一个整体被执行,包含在其中的对数据库的操作要么全部被执行,要么都不执行。
    • 一致性(Consistency):事务应确保数据库的状态从一个一致状态转变为另一个一致状态。一致状态的含义是数据库中的数据应满足完整性约束。
    • 隔离性(Isolation):一个事务的执行不能被其他事务干扰。
    • 持久性(Durability):一个事务一旦提交,他对数据库的修改应该永久保存在数据库中
  7. 为什么要分库分表?

    性能问题,索引问题等

  8. 分库分表方案应该尽量避免的两个问题?

    数据迁移 热点

  9. 如何设计可以动态扩容缩容的分库分表方案?

网络

  1. cookie与session区别 ?

  2. post与get区别 ?

  3. 一个网址url从浏览器中输入后发生了什么?

客观

  1. 客观印象最深的bug是什么?如何解决的?如何防止?
  2. 如何学习一个新技术,团队需要有人来学习,有没有自己的方法论?