总结下2019年7月份面试的几家公司,职位后端开发工程师,个人感觉还是要多出去面面,多面面就会有感觉,都有一定的套路,涉及的基础和项目一定要自己提前准备下,可以通过脑图或者博客的方式自我总结下
主要面了:平安科技,OPPO,头条,Shopee, 微众,有赞,腾讯微视。其中平安科技和有赞就暂时不写了,腾讯可能因为岗位是go/c++语言的原因导致一面面试还不错的情况下没有后续了
OPPO
一面二面
- kafka分流如何保证数据不丢?
- kafka文件如何存储的,consumer消费的时候如何快速根据offset定位数据?
- kafka为何如此之快?kafka零拷贝技术知道吗?
- 如何按照比重实现负载均衡?
目前知道的两种思路:加权轮询,加权随机
加权轮询:假设三台机器权重比为:x:y:z,则开始的x请求给到机器1,再来y个请求给到机器2,再来z个请求给到机器3,之后继续这样轮询 。缺点:当x:y:z比值较大的时候可能负载均衡的效果就没有那么好了,比如91:90:189
加权随机:生成随机数[0,x+y+z), [0,x-1]请求给机器1,[x,x+y-1]请求给机器2,[x+y,x+y+z-1]给机器3,当然也可以归一化为[0,1)通过概率范围加权轮询
- redis热点key失效了,前端高并发请求,如何防止瞬间击穿mysql?代码层面能否写下
基本思路:加锁,可以参考https://time.geekbang.org/column/article/88909
先加读锁获取,没获取到再加写锁,加写锁之后在判断一次缓存中是否有,没有才去读数据库,可以保证单机条件下只会有一次去加载数据库
这个思路不一定对,可以自行google下
- redis缓存雪崩和击穿,如何解决?
- 缓存击穿:大量缓存中不存在的key请求到缓存,之后又查询mysql,造成后端数据库压力增大
解决方案:
1.发现数据库不能存在时缓存一个空值或者空对象
如果之后对应的key又有数据怎么整,首先缓存空值要设置一个过期时间,如果有数据更新,则更新对应的key的value即可
2.利用布隆过滤器先前置拦截掉大部分无效的key
- 缓存雪崩:大量key同时失效,导致大量请求瞬间打到mysql数据库
解决方案:
1.缓存key时设置随机的过期时间范围,避免同时失效
2.提前识别热点key,缓存时间尽量设置长一点或者干脆暂时不设置过期时间
3.引入资源隔离组件,比如hystrix, 限流
- 布隆过滤器了解吗?干什么用的,多次散列怎么操作?能否保证一定准确?
布隆过滤器只保证不存在的一定不存在,存在的不一定存在,因为存在hash冲突,为了减少hash冲突可以通过多次散列来实现
- 分布式CAP原理了解吗,实际中如何保证最终一致性,比如通过MQ,举个例子说明下
- 如何防止多次同时下单将账户余额更新成负数?
比如一开始账户有10块钱,然后一个用户通过两个手机买了分别买了一个6块钱和8块钱的东西,如何保证数据不会被减成负数?
思路:
1.通过对用户的账户加分布式锁,获取到锁之后,先查出余额,只有余额大于等于物品价格时才更新数据库并提示下单成功,否则提示下单失败
2.不加锁的实现1:更新操作多加一个where条件,条件为账户余额 > 商品价格时才扣除余额,否则不扣除并提示下单失败,可以通过update返回的int值判断是否成功
3.不加锁的实现2:数据库新增一个字段version,每次更新时通过判断当前version是否大于之前拿到的version,是则更新失败,否则更新成功且version+1,但是这个解决不了将余额减为负数
- 如何防止同一个订单重复下单,导致订单信息重复?
1.数据库层面,订单号建立唯一索引
2.采用cache.setnx命令,只有设置成功才往下插入,否则返回错误提示信息:重复下单
- hashmap为什么一定要扩容为两倍?
1.最主要的还是计算hash槽时,会用hash&(n-1),不是2的整数倍则搞不了,按位运算简单高效
2.rehash之后,通过扩容为原来的2倍的方式,之前某个hash槽的数据一分为2,要么和原来的位置一样,要么在原来的位置上+原来容量,如果不是2倍则需要完全重新分配,实现上和效率上都不高
- 生成交接码的具体代码细节?
1.先构造一个字符数组,字符就是构成交接码的字符
2.利用UUID.randomUUID得到一个字符串,然后将这个字符串分段,每一段对字符数组长度取模一位一位得到最后的交接码
- snowflake的具体细节?
- 线程数满了导致CPU飙升,如何排查问题?
top查出耗费CPU多的进程,然后jstack dump一下得到线程堆栈分析(待补充)
- 项目中缓存查询次数太多导致请求时间过长,如何优化?针对多个1-N的关系
之前说的是包件1-N的关系,redis中缓存包和件列表关系,件信息单独key存储,然后比如交接取件时更新队员的件信息即可,查询的时候根据任务查到包,在根据包查到件号列列表,再去查件的信息,这样当件很多时,缓存查询次数太多了
优化:包-件详情列表,实际中件详情列表可以放在扩展属性中,每次更新包的件时记得更新件详情列表可以了,先全部取出来,有删除的先删除,有更新的先更新,然后统一再设置到扩展属性中;实际也是这么做的,当时说不能这么做,更新属性不好更新,尴尬。。。
- 可重入锁如何实现?实现思路说一下
记录锁的持有者和一个计数器实现
业余时间可以多扩展下自己的技术,多用一些高级特性和掌握性能调优
三面
- 自我介绍,挑重点项目讲下
- 项目业务交互图,重点问了下上游系统实现有了解吗,根据自己的理解瞎扯了下类似Dijkstra最短路基算法,选择最优的快件配送路线
- 项目中的难点,自己解决过的最难的问题
- dubbo的请求调用过程
- dubbo的负载均衡
- dubbo的降级策略(可以参考hystrix)
- mycat的原理,优缺点,以及与其他数据库中间件的比较
三面感觉更偏重问项目和考察项目所用技术的深度等,没有问基础相关的东西
头条
平时可以多读些经典项目的源码,学习源码的设计思路
都是用牛客网的视频面试,可以比较方便的写代码
一面
- 自我介绍,做的主要项目
- kafka的架构(比较开放,挑自己擅长的重点讲解)
- redis集群如何水平扩容?
比较机智的扯到了一致性hash算法以及它的优点
- 循环队列的实现
开始队列头和队尾头都指向第一个元素,每push一个元素则tail++%n,每pop一个元素head++%n
- 计数实现某个用户的某个操作某个时间段的feed流次数,一般是超过多少次就会限制用户的操作。int count(user_id, operate_type, duration)
方式1:采用zset,key=user_id+operate_type, score存储,然后精确统计,缺点:占用空间太大
方式2:采用循环队列,队列存储duration的请求,值为时间,缺点:当请求多的时候,循环队列太大
方式3:在方式2的基础上,循环队列大小设置为每分钟一个槽,值为分钟数对应的次数,每次来一个请求在对应的槽上加1
...
- 自己实现BlockingQueue
无锁实现非阻塞的BlockingQueue?
- 乐观锁和悲观锁的理解
- mysql的四种事务隔离级别,幻读如何解决?
二面
项目介绍,总体业务流程图(某两个模块交互既画了通过kafka传递数据又通过RPC,为什么?自己画的坑,机智的说需要通过RPC请求来做容错操作,然后具体解释了下场景),总体架构图,项目中的难点
限制某个接口的并发数
Semaphore信号量限制并发数(类似计数器法,比计数器法好在可以将多出的请求放入等待队列中,防止瞬时的高并发导致服务不可用);滑动窗口统计单位时间内的请求量,超过某个数值的请求拒绝提供服务
网上写的是:计数器法:请求进来+1,处理完-1;令牌桶法:定期往桶中放令牌,一个请求会拿走一个令牌,没有令牌了则等待,达到一个限流的作用,缺点:请求数远大于令牌产生数时会阻塞很长的时间,当然也可以选择丢弃请求;漏桶法:???
- disconf实现热加载的原理
http://www.kailing.pub/article/index/arcid/63.html
disconf是基于zk的,disconf-client会去zk的某个数据节点监听,当disconf-web发生配置更新时会触发数据节点的变化,从而disconf-client调用对应的回调函数,更新对应的配置文件属性类信息
- 算法:给定一个数组,求缺失的最小正整数
三面
- 还是自我介绍,重点介绍下做过的项目,项目中遇到的难点和解决思路
- 实际生产环境中kafka数据有存在丢失的情况吗?
- kafka消费者是使用的多线程消费吗?是的。
- 那多个线程同时消费,offset怎么控制?
- 多线程了解吗?balabala, 说了下它的几个关键参数,以及它的核心思路就是生产者-消费者模式
- 那你自己手动实现一个固定大小的线程?开始用牛客网的ide界面写。。。
现场写还是有点挑战的,大概写出来了,不过提示了一两次完善了下
继续追问:你这样实现的线程池提交一个任务之后没有返回值,如何实现一个提交任务之后能拿到执行结果的线程池?这个没写出来,其实可以通过FutureTask包装提交的任务,然后利用FutureTask就可以得到执行的返回值了
Shopee
这个比较惨,只面了一面就给我挂了,面试的时候其实我感觉面试官有些也搞错了
一面
- 自我介绍,主要做过的项目
- 挑了一个项目,让画项目的架构图
- 项目中做了一个kafka容错相关的处理,被问及kafka不是保证数据不丢吗?为什么要做容错
我说可能是发送数据会失败,比如网络抖动或者kafka出问题了;面试官说kafka发送失败了会重试啊,我说重试也是可能失败的啊。说实话我觉得我说的没毛病,而且kafka只保证已经持久化的数据不丢,没有持久化的事不保证的,这里面试官内心一直觉得没必要做容错处理,哎。。。
项目中kafka发送数据之后立即返回还是等待什么ack之后才返回(有相关的参数可选,可以看下官方文档)
有了解过网络攻击吗?最近刚好看了下TCP三次握手,就说了下黑客频繁发起二次握手导致连接占满
如何解决恶意二次握手呢?可以通过tcp_syncookies解决,可以参考https://coolshell.cn/articles/11564.html
如果黑客二次握手后也不下线,通过tcp_syncookies发送请求时,也回应,怎么办?
随便扯了下,那上层可以通过https加密来保证安全性Https的核心是什么以及如何客户端与服务端如何交互的?
Cookie, Session的区别
Session的sessionId存储到浏览器之后,关闭浏览器再启动还能拿到该sessionId吗?
这个不是太了解,应该是可以的
https://www.cnblogs.com/tongxuping/p/6914065.html,百度了下这个要看保存sessionId的Cookie是否设置了过期时间,设置了则会持久化到客户端磁盘中则可以拿到,没有设置则关闭浏览器就拿不到了java基础:Object有哪些方法,说了下wait/notify/notfiyAll/toString/clone,面试官不满意,还有呢?一时记不起来了,不过个人感觉这个问题有点那啥。。。
sleep和wait的区别
wait为什么是Object的方法,sleep为什么是Thread的方法?说了下,wait是用于线程之间同步的,而同步一般是通过监视器对象,都是继承自Object而不是Thread
concurrentHashMap 1.7的源码?分段锁
concurrentHashMap 1.7这个最多支持多少的并发读?
心里想这是什么鬼问题?这是理解不了,再三确认,面试官各种解释,没明白,然后面试官说,读的时候相应的段会加锁,共有16段,所以并发读就是16
我说如果读会加锁的话就是16,但是一般来说读时不会加锁的,要加也是加读共享锁,最多也就是某个短暂时刻不一致,最终还是一致的,那可能ConcurrentHashMap读加了分段锁了吧
回去我查了下源码,读根本没有加锁,这面试官这是误导我呀!真是醉了union和union all的区别?这个忘了。。。
一道算法题:数组中只有0,1,2三种数字,将其排序
立刻想到计数排序,面试官说如果只允许空间复杂度O(1),时间复杂度O(n),且只能遍历一遍,怎么做?
想了下可能要三个指针,通过交换来完成排序,但是最后没想出来。。。
微众银行
一面
- 先自我介绍
- linux awk用过吗?
- linux如何批量杀掉符合某个条件的进程
linux确实有点弱:只知道通过ps -ef|grep "条件" 查出所有的进程,然后根据id一个一个kill
google下,可以通过简单的脚本实现,弱鸡啊。。。 - java基础,有点不记得问什么题了
- jvm了解吗,大概说下?自由发挥就可以了
- jvm内存模型哪些部分会发生OOM?
- mysql cpu高如何排查?
- 应用CPU高如何排查?
- mysql如何定位慢查询? druid监控+mysql慢查询日志
- mysql如何主从复制? binlog日志,可以扩展下两种的格式:rows和statement
之后就聊的比较随意了
二面
问了下Spring/mybatis使用的版本号,有关注不同版本的漏洞吗?
有关注java8, java9,....java11的新特性吗?主要关注了java8
java8有哪些新特性使用的比较多?
lambada表达式,面试官接着问lambada书写要注意什么?书写不当可能会产生什么问题?
try...resource语法糖
LocalDateTime数据源用的什么?druid
有关注不同版本的druid的bug吗?
不同微服务之间为什么既有RPC又有Rest/http呢?
开发为什么不都使用RPC?因为RPC请求类如果修改了字段会报错,导致模。。。补充mybatis的核心源码-设计思路?
mybatis # $的区别
项目中解决过的问题举个例子
更看重对jar不同版本的安全漏洞问题
三面
- 主要是讲项目的技术架构,以及项目中遇到的难点及解决思路
四面
- 还是讲项目,主要是讲了下项目的业务总体流程,项目中遇到的难点及解决思路
- 项目中的数据量和并发量
- 个人兴趣爱好,优缺点,未来的职业规划
一面二面技术面,三面四面项目和个人职业规划
蚂蚁金服(后续更新)
一面电话面
- 自我介绍,主要还是项目介绍,项目的主要交互流程
- 项目中遇到的难点
- kafka存储结构,说了下生产过程和消费过程涉及到的数据是如何存储和读取的
- kafka优化
- mysql优化慢查询,平时是如何去定位和优化的
- 设计模式,如何理解开闭原则,里氏替换原则等等,项目中是如何实践的
架构还是要理论+实际的场景多去总结,不断优化理论,不断实践,找到自己的架构思路
项目中涉及的架构,高可用,高并发等等是如何实践的,要有自己的思考
快手(后续更新)
一面
- 3选2算法题,难度一般
- 实现如下功能,三个线程,线程1打印A,线程2打印B,线程3打印C,让三个线程交替打印ABCABCABC..., 总共打印10次ABC
- 给定一个int有符号整数,将该有符号整数逆序,不能采用字符串和数组
比如123-->321, -123-->-321, 120-->21 - 给定一个数字数组,将奇数放在偶数前面,奇数之间不用保证顺序,偶数之间也不用保证顺序
比如[1,2,3,4,5,6]-->[1,3,5,2,4,6], [2,1,6,5,9,10,8]-->[1,5,9,2,6,8,10]
- 开始自我介绍,介绍项目
- 老套路,项目中遇到的难点
- kafka为何如此之快,零拷贝技术了解过吗?
- ConcurrentHashMap实现原理,扩容如何扩的?
- JVM CMS和G1垃圾回收器的了解
- JVM 对象头有哪些东西?
- synchronized锁降级怎么降级的?
- mysql优化,索引等等,谈下自己的理解
- 有什么问题想问的吗