logo

4/19 985毕业生:至今0 offer,深夜无眠

作者
Modified on
Reading time
11 分钟阅读:..评论:..

南京大学,作为国内顶尖的学府之一,其计算机科学与技术系近年来在人才培养和科研创新方面成绩斐然,无数优秀学子从这里走出,成为了科技界的中坚力量。而在这样一个充满竞争和挑战的环境中,学生们的求职之路并非一帆风顺。

就在不久前的一篇帖子中,一名南京大学的计算机类学生分享了他的求职焦虑——面试数月,依旧0offer。

他的经历让很多同路人感同身受:兵荒马乱的求职季,焦虑的夜晚,以及那份不断逼近的压力
然而,这位学生并未放弃,尽管面对压力,他依然坚持着,继续寻找下一个面试的机会。
而在最新的动态更新中,虽然他对自己在美团一面的表现并不满意,但出人意料地,他收到了二面的通知。这不仅是对他能力的肯定,也是对坚持的奖赏。现在,他带着更加轻松的心态,准备迎接下一次的面试挑战。 现在,让我们追随这位南京大学的学子,继续学习技术,准备面试,展现自己的技术实力和面对挑战的决心。

面试官: 欢迎来到美团的面试,谈谈你对进程与线程之间的区别的理解?

求职者: 进程是操作系统进行资源分配和调度的基本单位,而线程是进程的执行单元。进程之间相互独立,拥有独立的地址空间,而同一进程的多个线程共享进程的资源。线程之间的通信和切换成本要低于进程,这使得多线程程序在执行效率上有优势。

面试官: 那么,哪些资源是线程独有的呢?

求职者: 线程独有的资源包括线程ID、寄存器组的值、栈和线程的执行状态。而进程的代码段、数据段和打开的文件等资源,则是其内的线程所共享的。

面试官: 聊聊进程之间的通信方式

求职者: 进程间通信的方式主要有管道(Pipe)、信号(Signal)、消息队列、共享内存、信号量以及**套接字(Socket)**等。 面试官: 匿名管道和命名管道的区别是什么?

求职者: 匿名管道只能用于具有亲缘关系的进程间通信,如父子进程,因为它们是半双工的,且只存在于内存中。而命名管道可以在任意两个进程间进行通信,是全双工的,且通过文件系统的名字进行标识。

面试官: 谈谈共享内存不同进程如何互斥的访问

求职者: 对于共享内存的互斥访问,可以通过信号量或者互斥锁来实现。这些同步机制可以帮助确保任一时刻只有一个进程能访问共享内存。

面试官: 不同的进程之间地址空间独立,同一个锁对象如何在不同的地址空间传递

求职者: 在不同的进程之间传递锁对象,通常是通过使用信号量集或者共享内存中的锁标志实现的,而不是直接传递锁对象本身。这样可以确保在独立地址空间的进程间同步访问共享资源。

面试官: 操作系统如何虚拟地址映射成物理地址

求职者: 操作系统通过使用页表来将虚拟地址映射到物理地址。每个进程都有自己的页表,该页表包含了虚拟地址到物理地址的映射信息。当进程访问某个虚拟地址时,操作系统通过查找页表来找到对应的物理地址。

面试官: 操作系统有没有用到什么技术加快地址查询

求职者: 是的,为了加快地址查询,操作系统使用了**快表(TLB,Translation Lookaside Buffer)**技术。TLB是一种小型的、快速的缓存,用于存储最近访问的页表项。这可以大大减少访问页表时的时间开销。

面试官: 介绍一下什么是僵尸进程

求职者: 僵尸进程是指已经结束但是其父进程还没有调用wait()waitpid()来回收其资源的进程。这种进程已经释放了大部分资源,但是在进程表中仍然保留着一条记录,直到父进程读取了它的退出状态。 【未完待续】

面试官: 如果操作系统中有很多小文件,会有什么弊端

求职者: 如果系统中存在大量小文件,会造成文件系统的管理开销增加,因为每个文件都需要一个inode来存储元数据。此外,小文件过多还会导致磁盘空间的利用率低下,因为文件系统通常会为每个文件分配一个最小的数据块,而小文件可能无法完全使用这个数据块,造成空间浪费。还有,文件的创建和删除会频繁更新文件系统的元数据,影响系统性能。

面试官: 那么,能否介绍一下写时拷贝技术求职者: **写时拷贝(Copy-On-Write, COW)**技术是一种优化策略,用于处理进程或线程中的资源复制问题。当系统进行如fork操作时,它并不立即复制父进程的资源给子进程,而是让父子进程共享同一份资源。只有当其中一个进程尝试修改这些资源时,系统才会真正地复制资源,从而为修改操作提供一个私有的副本。这样可以减少不必要的数据复制,节省内存空间并提高效率。

面试官: select和epoll的区别是什么?

求职者: select是传统的I/O多路复用技术,它监视一组文件描述符的状态变化。但它有一些缺点,比如它支持的文件描述符数量有限,且每次调用时都需要重新传递文件描述符集合给内核,效率低下。epoll是Linux特有的I/O多路复用机制,它克服了select的缺点,支持更多的文件描述符,且文件描述符的状态变化会被内核记录下来,下次调用时无需重新传递全部文件描述符,这提高了效率。

面试官: TCP的可靠性通过什么保证

求职者: TCP通过几种机制来保证可靠性,包括序列号、确认应答、重传机制、流量控制和拥塞控制等。序列号确保数据包的顺序性,确认应答和重传机制确保信息被正确接收,流量控制和拥塞控制则保证网络不会被过量的数据包淹没。

面试官: 那TCP如何保证数据包不乱序

求职者: TCP通过在每个数据包中加入序列号来保证数据的顺序性。接收方会根据序列号对数据包进行重排序,并且发送确认应答。如果接收方收到乱序的数据包,它会根据序列号重排这些数据包,以恢复原始发送顺序。

面试官: 在数据传输过程中,TCP如何保证不出错呢?

求职者: TCP保证数据传输不出错主要依靠校验和机制。每个TCP数据包在头部都有一个校验和字段,发送方会计算数据包内容的校验和并将其包含在数据包中。接收方收到数据包后也会计算校验和,与发送方发来的校验和进行比对,如果不一致,说明数据在传输过程中被损坏,接收方不会发送ACK确认,而是等待发送方重传该数据包。

面试官: 那校验和是如何计算出来的求职者: 校验和的计算通常是将数据分成16位长的段,然后将这些段进行二进制求和,如果有进位则将进位加到最低位,最后将结果取反。这个计算过程可以有效检测出数据的变更,包括位的改变或丢失。

面试官: 如果TCP使用两次握手会有什么问题?

求职者: 如果TCP使用两次握手,那么它就不能可靠地保证通信双方都准备好进行数据传输。具体来说,如果一个旧的连接请求延迟到了服务端,而服务端误认为这是一个新的连接请求并建立连接,而客户端却不知道这个连接的存在,这就可能导致服务端一直等待客户端发送数据,浪费资源。

面试官: TCP的TIME_WAIT状态等待2MSL的原因是什么?

求职者: TCP的TIME_WAIT状态等待2MSL(Maximum Segment Lifetime,最大报文段生存时间)的原因是确保TCP连接被可靠地关闭,并且确保所有重复的数据包在网络中都消失。这样可以避免在新的连接中出现旧连接的数据包,保证TCP连接的可靠性和数据的完整性。

面试官: 谈谈TCP和UDP的区别

求职者: TCP是一种面向连接的、可靠的传输协议,提供数据的顺序传输和重传机制,适用于对数据完整性和顺序有要求的应用。UDP则是一种无连接的传输协议,不提供数据传输的可靠性保证,但其开销小,传输效率高,适用于对实时性要求高的应用,如视频会议和在线游戏。

面试官: UDP传输是点对点的吗

求职者: UDP传输本质上是点对点的,它在发送数据时不建立连接,数据包从一个端点发送到另一个指定的端点。但是,利用UDP可以实现广播和多播,从而实现一对多或多对多的通信。

面试官: 如何判断操作系统的大端和小端

求职者: 可以通过简单的C语言程序来判断操作系统的字节序是大端还是小端。例如,定义一个整型变量并赋值为1,然后通过指向该整型变量的字符指针来检查内存中的第一个字节。如果第一个字节为1,则为小端模式;如果第一个字节为0,则为大端模式。

面试官: new和malloc的区别是什么?

求职者: new是C++中的运算符,用于分配内存并调用对象的构造函数初始化对象。malloc是C语言中的库函数,只负责分配内存,不负责对象的初始化。另外,new分配的内存需要用delete释放,而malloc分配的内存需要用free释放。

面试官: 很好,现在我们来到手撕代码环节,请你写一个函数来合并两个有序链表

求职者: 当然,这是一个标准的编程题目。合并两个有序链表的基本思想是使用两个指针分别遍历两个链表,并比较当前指针指向的节点的值,选择较小的那个节点加入到新链表中,然后移动该节点所在链表的指针。下面是合并有序链表的代码实现:

struct ListNode { int val; ListNode *next; ListNode(int x) : val(x), next(nullptr) {} }; ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) { ListNode* dummyHead = new ListNode(-1); ListNode* current = dummyHead; while (l1 != nullptr && l2 != nullptr) { if (l1->val < l2->val) { current->next = l1; l1 = l1->next; } else { current->next = l2; l2 = l2->next; } current = current->next; } current->next = (l1 != nullptr) ? l1 : l2; return dummyHead->next; }

面试官: 最后是反问环节,你有什么问题想问的吗?

求职者: 我想更深入地了解分布式系统方面的知识。在准备面试的过程中,我应该重点关注分布式系统的哪些方面?另外,请问这个部门的base在哪里?

面试官: 对于分布式系统,你应该了解它的基本概念,包括分布式存储、一致性、分区容错性(CAP定理)、负载均衡、分布式事务处理等方面。此外,还有分布式计算框架,如MapReduce、Spark等。你还需要了解一些分布式系统常用的技术和工具,例如Zookeeper、Kubernetes等。对于这个部门,我们的基地位于北京,这里是我们技术团队的核心所在,拥有优秀的工程师和完善的研发环境。

求职者: 明白了,非常感谢您提供的信息。我会进一步研究这些关键领域,并准备相关的知识点。同时,了解部门基地所在地也对我未来的工作计划有很大帮助。

面试官: 没问题,我们很欣赏你的热情和准备工作。如果没有其他问题,那么今天的面试就到这里。我们会尽快回复你的面试结果。祝你好运,希望未来能与你成为同事。

求职者: 非常感谢这次面试机会,期待与您的进一步沟通。谢谢!