查看原文
其他

【356期】辗转各大厂面试一遍,总结了这些面试问题

来源:zhihu.com/question/461650956/

answer/2032267124


硕二Java后端开发,最近准备换工作,各大厂基本面了个遍,收获了阿里,美团,京东,快手,头条的offer,总结了一下我面试各个大厂时候的面试题。

京东

一面:

  1. java中的锁都有哪些?乐观锁和悲观锁,独占锁和共享锁,重入锁和非可重入锁,公平锁和非公平锁, 轻量级锁和重量级锁。

  2. jvm对锁的优化?锁升级,锁粗话,锁消除的概念。偏向锁->轻量级锁->重量级锁的过程。

  3. 工作中volatile的使用,volatile的作用是?主要用于DCL单例模式中,volatile的作用是禁止指令重排以及保证线程之间的可见性,底层主要是通过cpu的lock指令,锁住一个对esp寄存器加0的空操作,实现了内存屏障。

  4. 线程的创建方式?继承Thread,实现Runnable和Callable,或者使用线程池。

  5. 线程池的核心参数以及工作机制?标准八股文

  6. 拒绝策略都有哪些?标准八股文

  7. NIO和BIO的区别?非阻塞IO主要是通过操作系统提供的api,创建socket的时候绑定NON_BLOCK属性,在执行read、accept等操作时,线程不阻塞,一直返回-1。一般可以结合多路复用器select,poll,epoll等使用。

  8. select,poll,epoll有什么区别吗?select主要将一堆文件描述符传到select的参数中,然后返回有时间就绪的文件描述符的个数,但是还是需要用户线程去主动轮训有哪些文件描述符有事件产生,缺点一是需要将文件描述符从用户态内核态之间拷贝,二是需要用户线程主动轮训文件描述符。epoll是基于事件的回调的,可以通知用户线程那个文件描述符有事件就绪, 用户线程就不需要遍历了。

  9. 看过操作系统对epoll的实现吗?没看过。

  10. 讲讲Netty。Netty怎么用的?项目中用到过netty,讲了讲。

  11. Netty中怎么解决粘包问题的?内置一堆handler,可以换行,可以根据分隔符,也可以根据传输的字节长度,http就是会传输一个content-length。

  12. Mysql用过吗?项目中没用过mysql,用的是hbase,了解过mysql。

  13. Mysql的索引是什么数据结构,为什么用这种结构?标准八股文。

  14. Redis用过吗?常见数据结构,SDS怎么实现的?SDS是一个结构体,里面包含了一个char数组,一个free字段,一个length字段,获取字符串长度是O(1)复杂度,C语言需要从头到尾遍历,复杂度高,另外还有二进制安全,惰性释放,避免缓冲区溢出等有点。

  15. Redis的部署模式?单机,集群,哨兵等

  16. Redis主从复制过程?当时不知道。

算法题

  • 链表按k个一组反转。

二面:

由于一面问的基础知识很多,二面主要问问项目。包括项目中的流量走向,微服务拆分,项目qps,考察对项目的了解程度。由于项目因人而异,不用说太多。

另外看我简历上有写大数据相关技术栈,考察了一个HQL的题。具体想不起来了。

算法题:

  • 冒泡排序。由于太长时间没写冒泡排序了,给写成了选择排序。。。

美团

一面:

上来说项目,把项目中的各种问题,各种难点讲了讲。也是比较关注对项目的整体了解,以及对项目中各项指标的了解等。对Java基础方面没怎么问。除了项目方面的问题,主要有以下几个问题:

  1. Redis主从同步的过程。由于之前在京东就被问过,当时不会回去看书了,这次就回答上了^ - ^。

  2. 为什么选用Hbase,Hbase和Mysql的区别是什么?怎样做技术选型?

  3. Hbase调用一次的耗时是多少?

  4. Hbase索引的原理。

  5. 介绍一下消息队列。Kafka怎样保证高性能IO的。顺序写磁盘,零拷贝,批量处理减少IO次数等。

算法题:

  • 记不清了,印象中不是很难。

二面:

  • 项目中遇到过什么问题?
  • 项目中用到了Netty,怎么用的,为什么用?
  • Netty的事件循环是怎么回事?
  • Netty的线程模型讲一下?Reactor模型。

算法题:

  • 将阿拉伯数字转为大写的汉语数字。注意处理零值,以及三千七百这种。

  • 写算法题的时候看我写的代码还问到了Switch和if的那个性能高一些?Switch有点像数组,if需要不断的从头往后遍历,但是if 有一些优化,如分支预测等。

三面:

前两面都通过了,三面就随便问了一下,基本没问技术的问题,最后出了个算法题。

  1. 你们做需求怎么做,需求评审怎么做?

  2. 目前几点上班几点下班?

  3. 平时团建怎么搞的?多久一次?

  4. 平时看书吗?最近看了什么书?

算法题:

  • 旋转有序数组中找到某个值?二分查找。

阿里

一面:

  1. 项目中的容错限流,降级,兜底等怎么做的?

  2. 如果服务端挂了怎么,怎么降级?多级缓存,客户端内部缓存,CDN缓存。

  3. 我们项目中是千人一面的兜底,那如何能做到千人千面?

  4. Mysql异地多活该怎么做?有什么思路?

  5. 消息队列使用。场景题。

  6. Netty介绍一下,项目中怎么用的。

  7. 项目中Rpc用的thrift?thrift用的什么序列化协议?为什么用这个协议?

  8. redis主从同步?全量同步和增量同步。

  9. 超大文件排序应该怎么排?

  10. 数据库异地多活解决方案?

二面:

全程讲项目,项目中的各种细节,扣的很细,没问任何八股文。

三面:

三面是个p10大佬,也是问了问项目,说我项目比较薄(在大佬眼里当然薄了),然后又问了问我offer的情况和其他家薪资情况,其余的没细问。

头条

一面:

讲项目,除了项目还有下面的问题:

  1. redis 单机能抗多少qps?

  2. redis怎么避免热点key的?

  3. redis中的常见的数据结构?介绍一下SDS?

  4. 介绍一下跳表数据结构。查询的复杂度?新插入一个节点的流程。

  5. 为什用Hbase不用Mysql,Hbase的优势在哪?

  6. HBase的索引以及Mysql的索引有什么区别?

  7. Java中的HashMap实现原理以及ConcurrentHashMap实现原理?

  8. CAS概念,有什么缺点怎么解决?

  9. 项目中有过哪些措施避免Hbase热点Key?

  10. 解决过什么线上问题?

算法题:

  • 给一个数组和一个数,找出数组中按照该数的全排列。

如数组[1,2,3,4,5],给定的数字是3,输出 [1,2,3],[1,2,4],[1,2,5],[2,3,4],[2,3,5],[3,4,5]

二面:

上来先讲项目,对项目中的问题扩展一下问一问。其余的问题如下:

  1. 微服务拆分的原则?为啥要拆分微服务?都放在一起有什么弊端?

  2. 讲讲项目中的流量走向?从DNS->LVS->Nginx->网关服务->聚合服务->基础服务

  3. 讲讲DNS的流程?DNS和CDN有什么联系?

  4. Mysql分库分表的场景?什么时候需要分库分表?

  5. Mysql设计题?项目中很少用到mysql,没回答上。

  6. Java中的多线程相关的东西。线程池?项目中的线程池用哪个?为什么不用JDK提供的静态方法中的线程池?

  7. 如果在主线程中创建了三个线程执行任务,想等三个任务都执行完了主线程继续执行,怎么实现?CountDownLatch。

  8. 手写DCL单例模式,为什么用volatile?

算法题:

  • 数组跳跃到最后需要的最少步。

三面:

讲讲项目,项目没问太细。其余的问题:

  1. java中的 == 和 equals的异同点,为什么经常需要同时实现equals方法和hashCode方法?

  2. java中方法调用时传值还是传引用?

  3. 常见的设计模式?项目中用到过的以及源码中看到过的。

智力题:

  • 四辆小车,每辆小车加满油可以走一公里,小车之间可以将油给其他的车辆,问如何能让其中的一台车走的最远?最远多少?

算法题:

  • 0-1背包问题。

快手

一面:

讲项目,对项目没问太细,只是大概聊了聊。

  1. 项目中有用到过的应对高并发的措施?消息队列,读写分离,冷热分离,缓存,避免热点key等。

  2. IO方面?同步阻塞,同步非阻塞,异步非阻塞的概念。

  3. 有没有异步阻塞IO?

  4. 讲讲Netty,Netty中怎么解决TCP粘包问题的?

  5. Redis中的线程模型?为什么说redis是单线程的。

  6. Redis的特点?怎样保证高可用的?

  7. Redis的持久化机制

  8. Redis的淘汰策略?

  9. 分布式锁怎么做的?为什么用到分布式锁?

  10. 消息队列如何保证消息不丢失?

  11. 消费消息的时候做没做幂等?怎样做的?

算法题:

  • 用数组实现队列。

二面:

先问项目,然后从项目中他比较感兴趣的一个点展开。

  1. 你们项目中服务注册发现用的什么?用的ZK。

  2. 为什么用ZK,ZK有什么特性?

  3. 服务发现的过程?

  4. Rpc调用的时候路由规则是什么?有权重的随机路由。

  5. 在服务升级的时候,需要下线掉原来的服务,但是会有时间处于新的服务和旧的服务之间,请求可能会调用到新的代码也可能会调用老的代码,这个你们怎么处理的?

算法题:

  • 实现一个阻塞队列。

由于我看过JDK 中Doug Lea写的源码?所以写的不怎么费劲,下面附上JDK中的给的例子。

注意里面的判断需要用While不能用if,有一个虚假唤醒的机制,用if可能会有错。其实就是因为如果用if的话,if里面的notFull.await()方法会释放掉锁,可能出现其他线程改了这个变量,导致条件不满足了,而用while的话会在继续判断这个条件。

class BoundedBuffer {
     final Lock lock = new ReentrantLock();
    final Condition notFull  = lock.newCondition(); 
    final Condition notEmpty = lock.newCondition(); 
 
    final Object[] items = new Object[100];
    int putptr, takeptr, count;
 
    public void put(Object x) throws InterruptedException {
      lock.lock();
      try {
        while (count == items.length)
          notFull.await();
        items[putptr] = x;
        if (++putptr == items.length) putptr = 0;
        ++count;
        notEmpty.signal();
      } finally {
        lock.unlock();
      }
    }
 
    public Object take() throws InterruptedException {
      lock.lock();
      try {
        while (count == 0)
          notEmpty.await();
        Object x = items[takeptr];
        if (++takeptr == items.length) takeptr = 0;
        --count;
        notFull.signal();
        return x;
        } finally {
        lock.unlock();
      }
    }
  }

三面:

三面依旧是上来就讲项目,然后问了问细节。后面主要问了一下下面的问题,从这个问题展开问了很多:

  1. 线上如果出现耗时长,怎么排查?有可能是什么原因?用Arthas来查,可以定位到具体某个方法调用的耗时。或者查日志,看每个日志的打印出来的时间,在去判断。一般耗时长可能都是有IO操作,可能访问数据库了。

  2. 怎么避免访问数据库带来的耗时严重呢?加缓存。

  3. 如果加了缓存还是耗时长可能什么原因呢?可能有缓存穿透的问题。

  4. 什么是缓存穿透?大量请求查缓存中的数据不存在,流量都直接打到了数据库上。

  5. 怎样解决缓存透?将请求数据库不存在的值在缓存中存储一个空值,下次请求同一个值的时候就直接访问缓存并且返回了,不会请求到数据库上。

算法题:

  • 对称树的判断。

总结

总体来说京东给我的面试体验最好,其次是阿里和美团,各个大厂的风格也比较不同,像阿里就完全问项目,几乎不问基础,考察你对项目的了解程度,细节扣的很深,算法也几乎不问,头条就算法题几乎必须做出来,不然基本不会过。

主流Java进阶技术(学习资料分享)

与其在网上拼命找题? 不如马上关注我们~

PS:因为公众号平台更改了推送规则,如果不想错过内容,记得读完点一下“在看”,加个“星标”,这样每次新文章推送才会第一时间出现在你的订阅列表里。点“在看”支持我们吧!

您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存