腾讯元宝客户端实习一面面经
前言
相较于搜狗输入法那场面试的面试官,这次的面试官明显就对我感兴趣很多了,和面试官互动得很深入。
依旧是深度定制DIY面试,无八股盛宴
正文
手撕环节
无自我介绍,上来直接开始手撕代码
题目是二维矩阵最优寻找target数(240. 搜索二维矩阵 II)
虽然leetcode做过,但是测试程序依旧是不支持Kotlin,面试官说可以用Java,然鹅我Java都忘得差不多了😂
没办法,最后面试官让我用JavaScript写,不得不说,JavaScript和Kotlin在基础语法上真的就大差不差,直接救我老命😂
虽然基础语法上大差不差,但是细节上坑死我了,把console.print写成print,把数组长度的length写成size和size(),在那里测试半天,最后还是面试官提醒我该怎么写🥹
最后代码出来了,但是边界条件没做好,又卡半天,面试官又善良的提醒了我一下while的边界条件,才把题目A掉。(面试官太善良了🥹)
本来面试官打算出第二道题的,看时间有点不够了,便结束了手撕环节
项目盘点环节
先是让我介绍一下简历里的两个项目,挑重点讲。于是我便快速的过了一遍项目重点和难点。
然后问了下简历中写的项目优化是怎么优化的
接着问了下项目用户受众情况
询问了下项目缓存的实现逻辑以及缓存过期逻辑
询问了下如何处理宽屏分辨率问题(答得不是很好,因为这块代码是AI写的(doge))
Kotlin相关知识
Kotlin中的suspend是怎么挂起的,它是线程安全的吗?
这个前半段有点问道我盲点了,后面问了下Gemini,Gemini是这样说的:
Gemini回答
简单来说:suspend 的挂起是通过“状态机(State Machine)”和“续体传递风格(CPS 变换)”实现的;而 suspend 关键字本身绝对不是线程安全的。
一、 suspend 是怎么挂起的?(底层原理)
suspend 实际上是一个编译器魔法。当你在 Kotlin 中写下一个 suspend 函数时,编译器会在后台对代码进行大幅度的重写。它并不会真正去“阻塞”或“休眠”底层的操作系统线程,而是将函数切分成了多个片段。
具体来说,编译器做了以下三件事:
- CPS 变换 (Continuation-Passing Style)
编译器会在你的 suspend 函数签名中,默默追加一个隐藏的参数:Continuation(续体)。
Continuation 可以理解为“后续的代码”或“一个书签”,它保存了函数恢复执行时需要的所有上下文。
- 你的代码:
1 | suspend fun getUserInfo(id: String): User |
- 编译器眼里的代码(伪代码):
1 | Object getUserInfo(String id, Continuation<User> cont) |
(注:返回值变成了 Object,因为它可能返回真实结果,也可能返回一个特殊的挂起标志。)
- 生成状态机 (State Machine)
编译器会把你函数内部的代码,以其他的 suspend 函数调用为“分界点”,切分成多个状态(label)。
假设你有这样一段代码:
1 | suspend fun fetchData() { |
编译器会把它变成类似下面这样的状态机(伪代码):
1 | Object fetchData(Continuation cont) { |
- 挂起与恢复 (Suspend & Resume)
- 挂起(Suspend): 当代码执行到
requestToken()并真正需要等待(比如网络 IO)时,它会向上一层返回一个特殊的标志COROUTINE_SUSPENDED。这个标志会一路return到最外层,从而把当前的 CPU 线程释放出来,让线程可以去干别的事情(比如更新 UI 或处理其他协程)。 - 恢复(Resume): 当网络请求完成时,底层系统(比如回调机制)会调用
Continuation.resumeWith(result)。这会重新触发fetchData函数,由于sm.label已经变成了 1,代码会直接switch到case 1继续执行,并带入了网络请求的结果。
生活中的比喻:
就像你看书时遇到了一个不懂的词(挂起点),你夹入一个书签(保存 Continuation 状态),然后合上书去查字典。在这个期间,你的大脑(线程)可以去喝水、听歌(执行其他任务)。查到意思后,你翻开书签那一页(Resume 恢复),继续往下读。
后半段我有点没懂面试官意思,以为面试官是说协程本身是不是线程安全的。
这就让我有点懵,这就好比你问线程本身是不是线程安全的这种问题
后面我知道了面试官是问用协程去操作一个变量是不是线程安全的,那当然是非线程安全的啦,这和线程并发出现竞争是一个道理。不过感觉答得不是很好
然后就是问Kotlin中和UI实现状态的同步是怎么做的。
我的回答就是用Kotlin的StateFlow,Compose会collect ViewModel中的StateFlow,根据StateFlow传来的变化而变化之类的,感觉答的不是很好。
接着就是问是否有用过传统Android XML UI。答:有用过,不过后来转Kotlin+Compose了。
AI相关知识
根据我的项目提问,询问在使用AI编程的时候如何节省Token。
我回答是让AI编程工具生成AGENT.md,GEMINI.md等文件,提前读取项目整个架构,避免AI无意义的搜索整个项目,然后每次给出清晰的指令,避免给出模糊的指令,以及模块化编程,避免AI大范围搜索和改动。
然后面试官询问Skill和MCP哪个用的token较少。
这当然是Skill啦,Skill当初提出就是为了解决MCP占用上下文过多的问题
最后问我用过哪些Agent,Agent是什么。
我目前接触的Agent就Copilot、Codex里面这些自带的Plan、Build这些Agent,没自己做过Agent,所以后半段答得不是很好。
反问环节
依旧是询问团队是用Java用的比较多还是Kotlin比较多
回答不出意外,已有代码用Java,新代码用Kotlin(咳特灵还是太好用了,有效治疗Java带来的偏头痛,以至于我完全不想用Java(逃))
面试小插曲
因为实验室刚搬迁,网络设施还没弄好,于是只能用手机热点给电脑共享网络。结果面试到一半时突然网络卡顿,立马查了用腾讯会议自带的网络检查功能检查,发现网络有问题,看了下手机,结果是逆天中信(为什么逆天之后说)打来的电话,把我网络顶掉了(有电话时移动数据会被顶掉),想都没想直接挂掉😡
Use this card to join MyBlog and participate in a pleasant discussion together .
Welcome to GoodBoyboy 's Blog,wish you a nice day .
