计科八股20260606——二叉树、PCA、图深度学习、进程上下文、C语言预编译、文件读写、单精度浮点数

要高考了,我也只剩一百天了。


Q:介绍数据结构二叉树?

第一反应:二叉树就是每个节点有且只有最多两个孩子的节点,分别记作左孩子和有孩子,所以这个node可以定义为指向父节点的指针、指向左、右节点的指针,还有自己的value值。然后完全二叉树的性质相对较多,比如树的节点个数向下取整log2+1就是深度,这些都可以用数学简单证明出来。

AI表示面试官希望听到二叉树的优势:"二叉树的每个节点度数 ≤ 2,这个结构决定了它可以用数组连续存储(完全二叉树),也可以用链式存储(指针)。更重要的是,任何多叉树都可以用'左孩子右兄弟'表示法转换成一棵二叉树,所以二叉树是树结构里通用性最强、实现最方便的一种形式。"

Q:二叉树的最大深度你知道吧(老师还解释了一下),你怎么求?

我的第一反应:链式存储的就用DFS,数组存储的可以直接找到最大的下标,然后取log2+1。

"求二叉树的最大深度,可以根据存储结构用不同的方法。

如果是链式存储的通用二叉树,我会用深度优先搜索(DFS)递归地去算。核心逻辑就是:树的深度 = max(左子树的深度, 右子树的深度) + 1。这个解法的时间复杂度是O(n)。

如果明确知道树是用数组存储的完全二叉树,并且节点是从下标1开始连续存放的,那就可以直接用公式计算:最大深度 = floor(log2(节点数)) + 1。这是一种利用完全二叉树性质的数学解法,可以直接算出来,不需要遍历。"

Q:你了解深度学习吧?有没有用过降维的什么算法?

这里帖主写的PCA,我也跟着复习一遍PCA。

PCA 是一种线性降维算法。核心是找到能让数据方差最大的投影方向,把数据投影到这些方向上去。

具体做法是:

  1. 对数据中心化
  2. 计算协方差矩阵
  3. 对协方差矩阵做特征分解,得到特征值和特征向量
  4. 按特征值从大到小排序,取前 k 个特征向量作为新坐标轴
  5. 把原始数据投影到这些轴上,得到降维结果

优点是算法简单、线性计算快,缺点是不擅长处理非线性数据。

Q:映射回去是怎么做的?

映射矩阵的转置

Q:说一下图神经网络层与层之间是如何相连的?

"图神经网络的层与层之间通过消息传递机制相连。每一层,每个节点根据邻接矩阵找到它的邻居(包括自己),把邻居的特征进行聚合(如求平均、加权和或注意力加权),然后通过一层线性变换和非线性激活,得到该层新的节点表示。多层堆叠后,节点就能逐步融合更大邻域的信息。"

Q:C语言预编译是什么?

一、预编译做什么?(4件事)

预处理指令 作用 例子
#include 文件包含:把头文件内容原封不动地插入到当前位置 #include <stdio.h>
#define 宏定义:把代码中的宏名替换成对应的值或表达式 #define PI 3.14159
#if / #ifdef / #endif 条件编译:根据条件决定保留还是删除某段代码 #ifdef DEBUG ... #endif
#pragma 编译器特殊指令 #pragma once
  1. 宏定义和函数的区别?

宏是文本替换,在预编译阶段完成,没有函数调用开销;但宏不检查类型,且参数会重复计算(如 SQUARE(x++) 有问题)。函数在编译阶段处理,有类型检查。

  1. #include <stdio.h> 和 #include "myheader.h" 的区别?

<> 只在系统默认路径里找(如 /usr/include)。"" 先在当前目录找,找不到再去系统路径找。

  1. #ifndef HEADER_H 这种写法是干什么用的?

防止头文件被重复包含。第一次包含时 HEADER_H 未定义,进入 #define;第二次包含时已经定义,跳过整个文件内容。

六、面试回答模板

"C语言的预编译是编译的第一个阶段,处理所有以 # 开头的预处理指令,包括文件包含(#include)、宏替换(#define)、条件编译(#if)等。这一步是纯文本层面的处理,不涉及任何C语言的语法检查。预编译完成后,输出一个没有预处理指令的 .i 文件,再交给编译器进行真正的编译。"

Q:好,那问你操作系统,你知道进程上下文是什么么?

A:"进程上下文是操作系统为了支持多任务、实现进程切换而保存的一组'状态快照'。

它主要包含三个部分:一是寄存器的值,特别是程序计数器;二是内存管理信息,主要是页表地址;三是内核中与该进程相关的数据结构。

当操作系统决定切换到另一个进程时,它做的就是'保存当前进程的上下文' -> '恢复下一个进程的上下文'这个动作。这个'上下文切换'的过程是理解操作系统调度和性能开销的关键。"

Q:文件读写r和w的区别

模式 全称 文件必须存在 原有内容 读写位置
r read(读) ✅ 必须存在 保留 文件开头
w write(写) ❌ 不存在则创建 清空 文件开头

关键区别

  • r 是只读,不能写;w 是只写,不能读

  • w清空文件原有内容 (如果文件存在),r 不会

常见组合

  • r+:读写,文件必须存在,不清空

  • w+:读写,文件不存在则创建,存在则清空

  • a:追加写,文件不存在则创建,不清空,写入位置在末尾

Q:fopen返回什么

返回 FILE*类型的指针(文件指针),指向一个 FILE 结构体。

这个结构体里包含了:

  • 文件描述符
  • 当前读写位置
  • 缓冲区指针
  • 错误标志、文件结束标志等

返回值判断

  • ✅ 成功:返回有效的 FILE* 指针
  • ❌ 失败:返回 NULL(例如用 r 打开一个不存在的文件)

典型用法

cpp 复制代码
FILE *fp = fopen("test.txt", "r");
if (fp == NULL) {
    perror("打开文件失败");
    return -1;
}

Q:既然有了整数和双精度浮点数,为什么还要存在单精度浮点数?

一句话回答用更少的内存和更快的速度,换取较低的精度------在不需要高精度的场景下更高效。

三种浮点数对比

类型 字节数 有效十进制位数 取值范围
float(单精度) 4 字节 6-7 位 ±1.18e-38 ~ ±3.4e38
double(双精度) 8 字节 15-16 位 ±2.23e-308 ~ ±1.80e308
long double 16 字节 18-21 位 更大

为什么需要 float?

原因 解释
节省内存 4GB 内存存 1 亿个 double 要 800MB,float 只要 400MB
内存带宽 读 4 字节比 8 字节快,数据密集型任务(如图像处理)吞吐量翻倍
SIMD 向量化 AVX 指令集一次可处理 8 个 float 但只能处理 4 个 double
GPU 友好 GPU 对 float 的计算单元远超 double(如游戏显卡双精度只有单精度的 1/32)
深度学习 模型参数量大,用 float16 或 bfloat16 甚至 int8 来加速(NVIDIA Tensor Core)

"单精度浮点数存在的主要原因是:用一半的内存和更高的速度换取足够用的精度。

在图像处理、3D 图形、深度学习等大规模并行计算的场景下,内存带宽和计算速度往往是瓶颈。使用 float 可以让数据传输量减半、向量化指令一次处理更多数据,GPU 上 float 的计算单元也远多于 double。

double 适用于需要高精度的科学计算,但对于绝大多数视觉和 AI 任务,float 的 6-7 位有效数字已经足够。"

相关推荐
你怎么知道我是队长1 小时前
CRC校验介绍
c语言
scx_link1 小时前
逻辑回归的总结
算法·机器学习·逻辑回归
沐籽李1 小时前
Proteina-Complexa:NVIDIA 如何把蛋白 Binder 设计推进到全原子生成时代?
大数据·人工智能·算法·英伟达·蛋白质生成
落羽的落羽1 小时前
【项目】JsonRpc框架——开发实现2(业务层)
linux·数据结构·c++·人工智能·算法·json·动态规划
h_a_o777oah1 小时前
2026 蓝桥杯软件 C++B组 国赛比赛经历及备赛建议
c++·经验分享·算法·蓝桥杯
SHARK_pssm2 小时前
【数据结构——单链表】
数据结构·经验分享·笔记
lightqjx2 小时前
【算法】数据结构_并查集
数据结构·算法·并查集
小雨下雨的雨2 小时前
鸿蒙PC Electron框架实现流体气泡模拟器
前端·人工智能·算法·华为·electron·鸿蒙
txzrxz2 小时前
广度优先搜索详解(BFS)
算法·宽度优先