提离职原因
一、 遇到的最难的技术点
============
遇到问题:adam本地启动时用jdk1.8可以启动,用jdk1.7时虽然启动成功,但是访问地址无反应,而且线上jdk版本也是1.7,错误信息启动几分钟后控制台才有打印,刚开始没看到错误信息,没有头绪,看到错误信息后,明白了原因。
报错提示:1.WarningService: Shutdown: TcpSocketLinkOutOfMemory
2.AlarmClock slow alarmAlarm
原因:本地使用默认jvm配置,堆内存、cms perm gen非堆内存不够使用,内存溢出
Perm Gen全称是Permanent Generation space,是指内存的永久保存区域,因而称之为永久代。这个内存区域用于存放Class和Meta的信息,Class在被 Load的时候被放入这个区域。因为Perm里存储的东西永远不会被JVM垃圾回收的,所以如果你的应用程序LOAD很多CLASS的话,就很可能出现PermGen space错误。默认大小为物理内存的1/64。
解决方案:启动时配置jvm参数:-Xms2867M-Xmx2867M -Xmn1075M -XX:PermSize=512M -XX:MaxPermSize=512M,调大非堆内存代销
思考:通过上述问题加深了对jvm参数的理解,后续需要看下jvm内存使用情况
问题:在进行金额运算时,发现结果与预计不符,使用了BigDecimal 做除法运算时使用的是默认舍入方式。
解决:除法运算时指定舍入方式,并设置保留位数(避免无线不循环小数情况)。
思考:获取所需数据时,为了避免查询库次数过多,先将数据按范围都查寻出来放入map中,通过map做映射管理,降低访问数据库次数,提升性能;
二、 需要学习
=======
三、 java基础
=========
1.字符串常量池
常用的设计模式有哪些?
2. int(M)长度的意义
3. java容器(集合)有哪些?
4. hashmap hashtable区别
5. 虚引用与弱引用区别
6. TCP udp区别?实时性要求高用哪个?
8. Io nio 区别
9. btree深度为什么不能设置太深
10. 使用数组实现队列
- 并发包
string为什么定义成final类型 好处
- switch支持的数据类型
i. https://www.cnblogs.com/HDK2016/p/6854671.html
ii. https://blog.csdn.net/qq_33811662/article/details/79069805
- 枚举类在switch...case语句中使用的问题
https://blog.csdn.net/qq_3523...
- HashMap和ConcurrentHashMap区别(必考)
- ConcurrentHashMap的数据结构(必考)
- 高并发HashMap的环是如何产生的
- Boolean占几个字节
- jdk1.8/jdk1.7都分别新增了哪些特性
- Exception和Error
四、 多线程
======
1. Java 线程状态、线程池状态
2. 核心线程池ThreadPoolExecutor的参数(必考)
3. 为什么当线程池的核心线程满了后,是先加入到阻塞队列,而不是先创建新的线程?
l 线程池创建线程需要获取mainlock这个全局锁,会影响并发效率,所以使用阻塞队列把第一步创建核心线程与第三步创建最大线程隔离开来,起一个缓冲的作用。
l 引入阻塞队列,是为了在执行execute()方法时,尽可能的避免获取全局锁。
4. 如何控制线程池线程的优先级
5. sleep、yield、wait、join的区别(阿里)
6. volatile作用(必考)
Java内存模型规定所有的变量都是存在主存当中(类似于前面说的物理内存),每个线程都有自己的工作内存(类似于前面的高速缓存)。线程对变量的所有操作都必须在工作内存中进行,而不能直接对主存进行操作。并且每个线程不能访问其他线程的工作内存。
7. java中为什么notify()可能会导致死锁,而notifyAll()则不会
8. CountDownLatch的两种常用场景
9. threadlocal原理
10. Atomic类如何保证原子性(CAS操作)(必考)
11. synchronized实现原理?锁升级过程?
https://www.cnblogs.com/wuqin...
12.
13. synchronized和Lock的区别(必考)
14. 不可不说的Java“锁”事
java锁介绍
15. 为什么要使用线程池(必考)
l 防止频繁的创建线程消耗服务器资源
l CPU资源有限的情况下,新建更多的线程不仅不能处理更多的任务,反而会因为线程间频繁的切换导致处理任务的效率降低
l 更方便对线程进行集中管理
l 不停的创建线程,会占用很大的内存空间
16. 线程之间如何通信
17. volatile 在双重检查的单例中起到的作用:
主要在于singleton = new Singleton()这句,这并非是一个原子操作,事实上在 JVM 中这句话大概做了下面 3 件事情。
1. 给 singleton 分配内存
2. 调用 Singleton 的构造函数来初始化成员变量,形成实例
3. 将singleton对象指向分配的内存空间(执行完这步 singleton才是非 null了)
在JVM的即时编译器中存在指令重排序的优化。
也就是说上面的第二步和第三步的顺序是不能保证的,最终的执行顺序可能是 1-2-3 也可能是 1-3-2。如果是后者,则在 3 执行完毕、2 未执行之前,被线程二抢占了,这时 instance 已经是非 null 了(但却没有初始化),所以线程二会直接返回 instance,然后使用,然后顺理成章地报错。
五、 分布式 并发
=========
- 分布式主键 保证唯一性
- 幂等性
- bitmap
- 秒杀 限流
- 限流算法
六、 Spring
=========
- spring boot启动过程
- spring bean生命周期
- 动态代理
- spring 有哪些注解
- Spring调用流程
- Spring的IOC/AOP的实现(必考)
- 动态代理的实现方式(必考)
- Spring如何解决循环依赖(三级缓存)(必考)
- Spring的后置处理器
- Spring的@Transactional如何实现的
- Spring的事务传播级别
BeanFactory和ApplicationContext的联系和区别
- Spring的Interceptor和Servlet的Filter区别
https://blog.csdn.net/qq_40272613/article/details/88215273
七、 Mysql
- 索引怎么优化 分析?
- sql 优化
分页查询优化 - binlog,redolog,undolog都是什么,起什么作用
- 分库分表 可重复读怎么保证
- mysql隔离级别 及实现原理
- Innodb 中 RR 隔离级别能否防止幻读?
MySQL InnoDB的可重复读并不保证避免幻读,需要应用使用加锁读来保证。而这个加锁度使用到的机制就是next-key locks。
Mysql官方给出的幻读解释是:只要在一个事务中,第二次select多出了row就算幻读。
a事务先select,b事务insert确实会加一个gap锁,但是如果b事务commit,这个gap锁就会释放(释放后a事务可以随意dml操作),a事务再select出来的结果在MVCC下还和第一次select一样,接着a事务不加条件地update,这个update会作用在所有行上(包括b事务新加的),a事务再次select就会出现b事务中的新行,并且这个新行已经被update修改了,实测在RR级别下确实如此。
如果这样理解的话,Mysql的RR级别确实防不住幻读
原因是前面的UPDATE语句执行之后,会将当前记录上存储的事务信息更新为当前的事务,而当前事务所做的任何更新,对本事务所有SELECT查询都变的可见,因此最后输出的结果是UPDATE执行后更新的所有记录。
多读出的一行,是因为 "MVCC快照读中,“自己的修改可见”。"还是update的锁把快照读变成了当前读。
- 快照读 当前读?
- mysql索引结构为什么不用hash
- mvcc
- 行级锁 怎么实现的
- mysql可重复读怎么实现的
- 主键索引 非主键索引 聚集索引 非聚集索引 区别
- MySQL大数据量表根据非索引字段检索优化
- mysql日志 模式
- 分布式事务 https://www.cnblogs.com/xifenglou/p/8440836.html
- 分库分表、聚合查询
- 分库分表:https://www.jianshu.com/p/32b3e91aa22c
- 事务的基本要素
- 事务隔离级别(必考)
- 如何解决事务的并发问题(脏读,幻读)(必考)
- MVCC多版本并发控制(必考)
- InnoDB的行锁/表锁
- myisam和innodb的区别,什么时候选择myisam
- 为什么选择B+树作为索引结构(必考)9.索引B+树的叶子节点都可以存哪些东西(必考)
- 查询在什么时候不走(预期中的)索引(必考)
- sql如何优化
- explain是如何解析sql的
- order by原理
- 深度分页
八、 Redis
========
- redis如何保证和数据库一致性
- Redis数据分片是怎么做的
- 一致性hash怎么实现的
- redis部署方式 集群 哨兵
Redis(二)冰叔带你了解Redis-哨兵模式和高可用集群解析
l RDB方式:定期备份快照,常用于灾难恢复。优点:通过fork出的进程进行备份,不影响主进程、RDB 在恢复大数据集时的速度比 AOF 的恢复速度要快。缺点:会丢数据。
l AOF方式:保存操作日志方式。优点:恢复时数据丢失少,缺点:文件大,回复慢。
l 也可以两者结合使用。
- Redis支持的数据类型(必考)
Redis支持五种数据类型:string(字符串),hash(哈希),list(列表),set(集合)及zset(sorted set:有序集合)。
- Redis的LRU过期策略的具体实现
https://blog.csdn.net/nakiri_arisu/article/details/79205660
- redis过期怎么实现的
- 如何解决Redis缓存雪崩,缓存穿透,缓存击穿
- Redis 分布式优缺点
- Redis的应用场景
- Redis的管道pipeline
- redis内部数据结构
- zset跳表的数据结构 实现原理(必考)
九、 消息队列
=======
- Kafka常见面试题
- 消息队列积压从原理分析怎么处理?
消息积压处理
- kafka 什么时候慢? kafka为什么快?
- kafka reblance 怎么实现的?
目前kafka提供了5个协议来处理与consumer group coordination相关的问题:
l Heartbeat请求:consumer需要定期给coordinator发送心跳来表明自己还活着
l LeaveGroup请求:主动告诉coordinator我要离开consumer group
l SyncGroup请求:group leader把分配方案告诉组内所有成员
l JoinGroup请求:成员请求加入组
l DescribeGroup请求:显示组的所有信息,包括成员信息,协议名称,分配方案,订阅信息等
- kafka 消费端 实现多线程消费
- 如何保证Kafka不丢失消息?
Consumer端
consumer端丢失消息的情形比较简单:如果在消息处理完成前就提交了offset,那么就有可能造成数据的丢失。由于Kafka consumer默认是自动提交位移的,所以在后台提交位移前一定要保证消息被正常处理了,因此不建议采用很重的处理逻辑,如果处理耗时很长,则建议把逻辑放到另一个线程中去做。为了避免数据丢失,现给出两点建议:
- enable.auto.commit=false 关闭自动提交位移
- 在消息被完整处理之后再手动提交位移
手动提交可能导致重复消费:比如你刚刚消费完消息之后,还没提交 offset,结果自己挂掉了,那么这个消息理论上就会被消费两次。
解决重复消费:1.建立去重表,保证处理幂等性
- 如何保证消息的顺序消费?
生产端:
如果需要进行消息具有消费顺序性,可以在生产端指定这一类消息的 key,这类消息都用相同的 key 进行消息发送,kafka 就会根据 key 哈希取模选取其中一个分区进行存储,由于一个分区只能由一个消费者进行监听消费,因此这时候消息就具有消息消费的顺序性了。
消费端:
十、 JVM
======
- oom异常场景
https://www.cnblogs.com/developer_chan/p/11184924.html
ArrayList addAll 方法 ,批量添加 频繁扩容 需要控件连续 oom;解决:初始化集合大小,本来是数据汇总再插入数据库,不需要汇总 可以每个里面都插入
- CPU过高排查
l 使用top命令查询服务cpu使用情况
l 使用top -Hp 31737查询31737进程中各个线程的资源使用率
l 使用printf "%xn" 5322把线程id转化为十六进制(14ca),因为打印线程栈的时候,本地线程标识nid是用十六进制表示的
l 使用jstack命令打印堆栈信息,jstack 31737 | grep -10 14ca
l 查找本地线程标识为14ca的线程堆栈信息
l 查看源码
- 频繁fullgc 怎么排查 解决?
- cms和g1 区别?分别什么场景下使用?
- 调优
- syschronize 1.7优化
- await sleep
- cpu比较高查找原因
- 内存溢出了怎么查找
- jvm命令
- 运行时数据区域(内存模型)(必考)
- 垃圾回收机制(必考)
- 垃圾回收算法(必考)
- Minor GC和Full GC触发条件
- GC中Stop the world(STW)
- 各垃圾回收器的特点及区别
- 双亲委派模型
- JDBC和双亲委派模型关系
- Java基础
十一、 ZooKeeper
=============
- CAP定理
- ZAB协议
- leader选举算法和流程
十二、 Dubbo
=========
- 调用流程
- Dubbo支持哪些序列化机制
十三、 linux
=========
- 查看端口占用命令
十四、 其他
======
- 高并发系统的限流如何实现
- 高并发秒杀系统的设计
- 负载均衡如何设计
补充
另外还会考一些计算机网络,操作系统啊之类的。像消息队列,RPC框架这种考的比较少。
计算机网络就是分层啊,tcp/udp啊,三次握手之类的。操作系统就是进程与线程啊,进程的数据结构以及如何通信之类的。数据结构的排序算法也比较常考,考的话一定会让你手写个快排。剩下的算法题就靠LeetCode的积累了。其实非算法岗考的算法题都蛮简单的,很多题完全就是考察你智力是否正常,稍微难点的涉及到一些算法思想的按照LeetCode题目类型的分类,每种题做一两道基本就能完全应付面试了。
面试感受及评价
除了外企,体验最好的就是阿里。绝对的脱颖而出,无论是面试官的专业程度还是面试官对参与面试人员的态度都完全突出于其他公司。非常的尊重人,以及会引导我去作出正确的回答,唯一就是阿里的HR是非常强势的,永远有一票否决权。而有些公司面试官会故意误导你,想方设法让你说出错误的答案,并且有些态度极其傲慢,让人感觉很不尊重人。这里点名批评面试体验最差的两家公司:美团和Boss直聘。
外企的话,体验都很好。微软是英文面的,亚马逊不是。这俩都是以算法为主,微软除了算法还聊了操作系统和计算机网络,亚马逊聊了较长时间的项目细节。
最后
最后说下自己的情况,17年在京东实习,19年7月离职。正式工作时间很短,就一年(算实习两年),而且19年有半年的时间准备考研所以有半年的空档期,这也是为什么我被很多HR挂了的原因。虽然Offer没拿几个,但是一半多都面到HR面了,所以对于两三年经验的感觉整理的问题还是比较有代表性的。
补
十五、 算法题
=======
1. 最长回文子串
2. 大数据文件 30m 怎么排序
- 矩阵
- 小顶堆大顶堆
100万个数据取前20大的数据
- 快速排序
- 单链表获取倒数第n个元素
- 合并两个有序链表,LeetCode21题。(猿辅导)
- 反转链表,LeetCode206题。(头条,搜狐)
- 两个单单链表相交
- 杨辉三角求数字位置,LeetCode118,119题相关。(滴滴)
- 循环有序数组的查找,LeetCode33题。(滴滴)
- 求二叉树的最近公共祖先,LeetCode236题。(滴滴)
- 求阶乘后的0,LeetCode172题。(蚂蚁金服笔试)
- 实现一个增删查功能的LinkedList,LeetCode707题。(Boss直聘笔试)
- 矩阵置0,LeetCode73题。(跟谁学笔试)
- 二又树的层序遍历,LeetCode102题。(搜狐)
- 中文转数字/数字转中文。(头条)
- 链表的两数相加,LeetCode2题类型题。(头条)
- 括号匹配,LeetCode20题。(拼多多)
- 队列实现栈,栈实现队列,LeetCode225,232题。(拼多多)
- 判断字符串(IP地址)是否在集合内。(微软)
- 中缀表达式的计算,LeetCode224题。(微软)
- 划分字母区间,LeetCode763题。(亚马逊)
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。