美团笔试只做了1道打卡题,第二周 HR 电话问要不要试试大前端客户端。我想了想应该也面不过,美团也无限复活,遂接了当练手,开始冲刺准备。
结果真是八八又股股,八股自己还赌输了,准备计网没准备 OS,寄的很彻底。以下是面经整理:
- 实习公司为什么要从自研引擎转 Unity?——自研扩展难度较大,Unity 生态好开发快,功能更强
- 为什么不转虚幻引擎?——棋牌休闲类,Unity 足矣(提了下 JJ 斗地主,面试官没绷住笑了,说挺有名的,盲猜也玩过哈哈哈)
八股
MySQL
- 数据倾斜了解吗?——我人都傻了,怎么上来是个这?我不是面的前端吗?后端也不一定问啊我去,只能道歉 x 1。后面想起来短链接文档里面提到了,大致意思是存储或查询分步不均匀,导致数据集中在了某些分区,更容易达到读写瓶颈,分库分表分布式情况下更突出。解决方法短链接文档提的是让这种数据量大的用户一般是 VIP 专门建库/表存其数据;GPT 是优化索引设计和数据分布,分库分表的话选择更合适的分片键等。总之就是让数据存储更均匀,查询也均匀,就不倾斜了
- 两阶段加锁了解吗?——复习看到标题了,但是没深入看,感觉不常见就没看,赌输彻底,道歉 x 2。看了看笔记,就是挺简单的概念问题罢了:两阶段是事务执行两阶段,加锁阶段和解锁阶段。加锁阶段申请 S/X 锁,申请到了才能继续执行,否则等待;解锁阶段解一个锁之后就不能再获取锁,但仍可以操作数据,只能继续逐步解锁,事务结束时释放所有的锁。这样的规定确保了事务在获取锁和释放锁的过程中不会出现环路造成的死锁(但没解决逻辑上循环依赖的死锁),并使得事务具有较高的并发度,因为解锁不必发生在事务结尾
- 什么是幻读?——经典八股,但好久没吟诵磕磕绊绊的,复习了一遍思路顺多了。大体上就是同一事务多次读取相同条件同一范围数据,读取间隔中间有新数据插入该范围,导致第二次读取读到了第一次没读到的数据,即幻影读
- MySQL 怎么解决幻读?——经典八股。MySQL 通过 MVCC+临键锁解决幻读,普通 Select 用 MVCC 快照读,当前读是临键锁避免插入新数据
- 讲讲 MVCC 机制——经典八股。多版本并发控制,为每一行数据维护多个版本,事务开始时创建读视图,根据可见性规则决定读视图能看到的数据版本。优点在于并发性高,可以并发读而不用获取锁,减少了锁竞争;缺点是空间换时间,多版本数据占用空间更多,需要及时清理(利远大于弊)
Java
- 讲讲 Java 引用类型——经典八股。强软弱虚,背到虚忘了。虚引用主要是和引用队列一起使用,监控接收对象被回收的通知,然后可以选择执行一些操作如资源回收等
- 虚引用什么时候被释放?——虚引用都答不上来还追问这个,哎,道歉 x 3。虚引用存在目的是监控关联对象何时被回收,回收后虚引用放入引用队列,需要手动清理引用队列,不会自动释放。
- 何时覆写 Object 的
equals()
和 hashCode()
?——类需要逻辑相等的比较,或者要存储在集合容器中高效哈希查找时。
- 能不能自己新定义一个
equals2()
来实现上述功能?——答了可以,想了想用作自定义类的比较相等的话,暂时没想到啥问题,寄。下来查了下,如果存集合类的话,判断时会默认调 equals()
方法;其它框架之类的可以也是这样,所以还是遵从约定,不要自己乱搞;并且在开发角度来说完全没必要,反而混淆视听。
- 那
hashCode()
呢?——一时间甚至没想起来 hashCode()
是干嘛的怎么覆写了,寄,道歉 x 4。查了一下默认就是对象地址算出来的 hash 值,自己覆写 equals()
判断两对象相等的话,官方 API 文档要求覆写 hashCode()
结果也要相等;不相等时不强求不相等,但建议不相等,提高哈希表性能
- throw 和 throws 有什么区别?——几个月没写 Java 大脑短路了,道歉 x 5。throw 在方法体内抛出具体异常对象,中断程序流程;throws 在方法签名抛出可能出现的异常类型,需要调用者处理。
- Object 类的
wait()
方法有什么用?——只记得 wait()/notify()
是一对,生产者消费者模型学的,细节大脑瞬间空白了,哎,道歉 x 6。下来看了一下,记忆复苏,就是单词字面意义。线程间通信,wait 释放当前持有锁开始等待;notify 随机唤醒一个等待该锁的线程开始抢锁,notifyAll 全唤醒抢锁
CS
- 进程线程区别?——经典八股。进程是操作系统分配资源的最小单位,线程是进程内的执行单元, CPU 调度的基本单位。再展开可以从安全性、上下文切换消耗、通信方式、创建资源消耗等各方面对比
- 进程分配的资源都有哪些?——乱答一气:内存、CPU、磁盘、网络;汇总了下大概有计算、存储、网络、IO、同步、系统等各种资源
- 线程间通信有哪些方式?——脑子只记得有个进程间通信八股,但也忘光光了,道歉 x 7。看了下小林有原题,互斥锁、读写锁、条件变量、自旋锁和信号量,本质应该就是共享进程的内存,不过需要保证安全共享
- 那进程间通信方式呢?——痛打落水狗啊,好耳熟的经典八股,但没复习忘光光了,道歉 x 8。小林:管道、消息队列、共享内存、信号、信号量、socket 等
- 什么是死锁?死锁条件?——经典八股。多线程无限期等待无法分配到的资源;四个条件:资源互斥、占有并等待、不可剥夺、环路等待。解决死锁主要是预防,资源分配不要出现环路等待,以及应用银行家算法。出现死锁则回滚进程、释放资源
- 有哪些排序算法?顺便讲讲时间复杂度——脑子知道起码十个常见的,到嘴边就没剩几个了,再加上时间复杂度,哎。整理一下——冒泡、选择、插入 n²;归并、快排、堆 nlogn;希尔、桶、计数、基数……
- 讲讲堆排序——直接讲 PriorityQueue 怎么用的,底层算法不知道,面试官说你直接讲第二阶段建完堆了,还有个第一阶段先建堆,哎,道歉 x 9。查了下应该是数组先建成大(小)根堆,然后开始交换数据,反复构建剩下的大(小)根堆再交换,这样完成堆排序
20 min 结束八股,没问项目,没问实习,估计八股答太扯了直接下一个流程了
手撕
- Java 写懒汉单例——还行,就是美团手撕编辑器字好小,缩进也很奇怪, volatile 没语法提示拼半天没拼对,但也算是双重判定加锁什么的写出来了。舍友之后提示还可以用枚举,查了下确实,Java 可以用枚举天然单例,挺有意思
- LC 143. 重排链表——还行,感觉挺复杂,还好前些天练过,灵神讲的很清晰,回想了一下算是顺畅写下来了,讲了讲思路就结束了
总结
带最后反问业务和技术栈,接近 1 h,答得真是一坨。准备的实习和项目基本没问,八股准备了一天计网然后一句没问,赌一把把 OS 放掉了,赌输太彻底了。整体难倒是不难,还是自己基础不牢,太菜,同志仍需努力!
过了几天看了下泡池子泡回人才库了,第三次美团一面挂哩,呜
继续总结、复盘、反思,老萌新秋招刚起步,希望有点 offer 吧呜呜呜~
牛友们觉得有帮助的话点个赞支持一下呗!感谢!
#牛客创作赏金赛##美团求职进展汇总#
#美团#