2025年高频计算机面试题库及答案.docxVIP

  • 0
  • 0
  • 约6.86千字
  • 约 14页
  • 2026-01-05 发布于四川
  • 举报

2025年高频计算机面试题库及答案

1.反转链表时,迭代法和递归法的实现步骤及时间空间复杂度差异?

迭代法实现步骤:初始化三个指针prev(初始为null)、curr(头节点)、next(临时保存curr下一个节点)。循环中,先保存curr.next到next,然后将curr.next指向prev,接着prev和curr分别后移(prev=curr,curr=next),直到curr为null时结束,prev即为新头节点。时间复杂度O(n),空间复杂度O(1)。

递归法实现步骤:递归终止条件是当前节点或下一个节点为null,返回当前节点(即尾节点作为新头)。递归调用处理子问题(反转当前节点之后的部分),然后将当前节点的下一个节点的next指向当前节点(即原后继节点的next指向自己),最后将当前节点的next设为null(断开原连接)。时间复杂度O(n),空间复杂度O(n)(递归栈深度)。差异核心在于递归隐含使用栈空间,迭代则是原地操作。

2.二叉树中如何找到两个节点的最近公共祖先(LCA)?

若树是二叉搜索树(BST),利用其性质:LCA的值介于两节点值之间(或等于其中一个)。从根节点开始,若当前节点值大于两节点值,递归左子树;若小于则递归右子树;否则当前节点即为LCA。

若是普通二叉树,采用后序遍历:递归左右子树,若左子树找到一个节点、右子树找到另一个节点,则当前节点是LCA;若仅左子树找到,返回左子树结果;仅右子树找到则返回右子树结果;都没找到返回null。特殊情况:若其中一个节点是另一个的祖先,直接返回该祖先节点。

示例代码(普通二叉树):

```java

publicTreeNodelowestCommonAncestor(TreeNoderoot,TreeNodep,TreeNodeq){

if(root==null||root==p||root==q)returnroot;

TreeNodeleft=lowestCommonAncestor(root.left,p,q);

TreeNoderight=lowestCommonAncestor(root.right,p,q);

if(left!=nullright!=null)returnroot;

returnleft!=null?left:right;

}

```

3.堆排序的核心步骤是什么?如何优化其稳定性?

核心步骤:①建堆(将数组调整为大顶堆或小顶堆,从最后一个非叶子节点开始向前遍历,执行下沉操作);②排序(将堆顶元素与末尾元素交换,缩小堆范围,重新调整堆,重复直到堆为空)。

堆排序不稳定的原因是交换堆顶与末尾元素时,可能破坏相同值元素的相对顺序。优化稳定性需额外记录元素原始位置,或在比较时优先按原始位置排序(如将元素封装为对象,包含值和索引,比较时若值相同则按索引排序),但这会增加空间复杂度(O(n)),实际应用中堆排序因不稳定性较少用于需要稳定排序的场景。

4.进程与线程的本质区别是什么?为什么多线程比多进程更高效?

本质区别:进程是资源分配的最小单位(拥有独立的内存空间、文件描述符等),线程是CPU调度的最小单位(共享进程资源,仅拥有独立的栈和寄存器)。

多线程更高效的原因:①线程创建/销毁开销小(无需分配新内存空间,只需分配栈空间);②线程间通信无需经过内核(共享内存直接通信,而进程间通信需通过管道、消息队列等内核机制);③上下文切换代价低(线程切换仅需保存/恢复寄存器和栈,进程切换需保存/恢复所有资源和页表)。但需注意,多线程受限于GIL(如Python)或CPU核心数,并非绝对高效。

5.虚拟内存的作用及实现机制?

作用:①扩展物理内存(将部分数据存于磁盘,程序无需等待物理内存足够即可运行);②隔离进程(每个进程拥有独立虚拟地址空间,避免地址冲突);③提高内存利用率(通过页面置换,按需加载必要数据)。

实现机制:基于页表(记录虚拟页到物理页的映射)和缺页中断。当程序访问的虚拟页未加载到物理内存时,触发缺页中断,操作系统从磁盘读取该页到内存(若内存不足则通过页面置换算法如LRU、FIFO淘汰部分页),更新页表后恢复程序执行。虚拟地址空间通常分为用户空间和内核空间(如Linux中32位系统用户空间3GB,内核空间1GB)。

6.死锁的四个必要条件是什么?如何预防和避免死锁?

四个必要条件:互斥(资源同一时间只能被一个进程使用)、占有且等待(进程持有资源并请求其他资源)、不可抢占(资源只能被持有者主动释放)、循环等待(进程间形成

您可能关注的文档

文档评论(0)

1亿VIP精品文档

相关文档