大四上,面试字节客户端的面试记录。
一面(视频面试)
自我介绍?
大概介绍了姓名、学校、专业后,介绍ACM经历,相关技能,最后介绍对安卓学习的短期规划。简历中提到的移动终端编程?
大概介绍了团队分工,以及自己的主要工作内容,因为是非常水的项目,所以没有深问。数据结构 - 讲讲链表和数组的区别?
从查询效率和增删效率回答。操作系统 - 进程和线程?
随便答了几个点。操作系统 - 线程产生一个子线程,那么它们之间是从属关系吗?
面试时不知道怎么回答,猜了个不是从属关系。
参考答案:进程是资源分配的基本单位,线程是cpu调度的基本单位。对于cpu来说,其实不存在主线程和子线程之分,都是一个线程。进程的资源是进程下面的线程所共享的,只要进程还在,线程就可以正常执行,也就是说线程是依赖于进程的,线程与线程之间并不存在依赖关系,一个线程的死亡理论上不会对其他线程造成影响。但是上面通过调用JVM提供的接口,例如setDaemon与join改变了主线程与子线程的关系,这些应该是JVM接口代码做了处理干扰了线程的生命周期。操作系统 - 死锁怎么产生的?
举了“哲学家吃饭”的具体例子,互斥、保持等待、不可剥夺、环路等待。操作系统 - 怎么避免死锁呢?
举了“银行家算法”的例子,已有资源不能满足进程结束,就不给资源,释放等待的进程占用的资源,杀死长时间等待的进程。网络原理 - TCP三次握手和四次挥手的过程?
估计这个问题答得很水(实际上我并不清楚具体细节,只能大概说说,被识破了),面试官也就没继续深问了。编程 - 合并两个有序链表
一开始写了指针版的链表,但是中途突然忘记怎么插入了,于是提出使用C++完成。大致思路就是实现merge函数,将传入的vector分别记录下标,$O(SIZE)$合并。
二面(视频面试)
自我介绍。
编程题:给定struct TreeNode信息,和vector
LargestNode(TreeNode *root){},求树每层最大值。
利用一个dfs带着树根root和深度dep跑就好了,相应的修改vector对应项的值。编程题拓展:int CountNode(TreeNode *root,int DEEP),改成求某一层结点数量?
在dfs的基础上稍作修改便可。该题有别的解题思路吗?
主要回答了注意深度过大导致栈溢出,栈模拟(深度优先),队列模拟(广度优先)。了解分段和分页吗?
零零散散说了内存碎片。
参考答案:
段式存储管理是一种符合用户视角的内存分配管理方案。在段式存储管理中,将程序的地址空间划分为若干段(segment),如代码段,数据段,堆栈段;这样每个进程有一个二维地址空间,相互独立,互不干扰。段式管理的优点是:没有内碎片(因为段大小可变,改变段大小来消除内碎片)。但段换入换出时,会产生外碎片(比如4k的段换5k的段,会产生1k的外碎片)
页式存储管理方案是一种用户视角内存与物理内存相分离的内存分配管理方案。在页式存储管理中,将程序的逻辑地址划分为固定大小的页(page),而物理内存划分为同样大小的帧,程序加载时,可以将任意一页放入内存中任意一个帧,这些帧不必连续,从而实现了离散分离。页式存储管理的优点是:没有外碎片(因为页的大小固定),但会产生内碎片(一个页可能填充不满)。
两者的不同点:
目的不同:分页是由于系统管理的需要而不是用户的需要,它是信息的物理单位;分段的目的是为了能更好地满足用户的需要,它是信息的逻辑单位,它含有一组其意义相对完整的信息;
大小不同:页的大小固定且由系统决定,而段的长度却不固定,由其所完成的功能决定;
地址空间不同: 段向用户提供二维地址空间;页向用户提供的是一维地址空间;
信息共享:段是信息的逻辑单位,便于存储保护和信息的共享,页的保护和共享受到限制;
内存碎片:页式存储管理的优点是没有外碎片(因为页的大小固定),但会产生内碎片(一个页可能填充不满);而段式管理的优点是没有内碎片(因为段大小可变,改变段大小来消除内碎片)。但段换入换出时,会产生外碎片(比如4k的段换5k的段,会产生1k的外碎片)。了解生产者-消费者模型吗?
忘得差不多了,不敢答。现在需要把一些包裹按顺序用自己的思路构建一个可靠的模型?
包裹上记录收件人、编号、身份验证、发送时间等?
补充:序号、发出时间、对方没有回复要重新发送,对方收到了两个要拆开检验等,其实把网络原理放到具体应用来就会清晰很多。(这是一个很好的建议,可惜本科老师上课真的很没有趣味……)了解数据库吗?如何存储?
答到了平衡树索引、散列表等,分析时间复杂度;手写字符串hash?
写了个KR-hash,介绍了冲突概率,并且说到双hash。如何实现hashtable呢?
讲到邻接表,又讲到邻接表可以用trie树替换,这样效率更高。hashtable索引如何避免冲突呢?
线性探测、二次探测等;
补充:在表快满的时候这种效率极其低下?
回答:当表中元素数量达到一个阈值的时候,扩大hashtable,然后重新散列。
补充:可以用邻接表?
回答:(我之前说了可以邻接表,但是匹配效率低,所以提到trie树,这是一个优化。)如何让hashtable支持多线程呢?
答不上来……(这个问题涉及到hashtable和多线程的关系,由于多线程不熟所以被告知,这其实在工程里经常见到,但如果你实现不了,实际应用就效率太低。)我们非常看重基础知识,操作系统、计算机网络原理等,这并不是让你把书上的内容背好,而是说培养一种分析实际问题的能力,提供一些参考和思路。
羞了,确实前面落下的基础知识。