服务端2月18日 10:35
TensorFlow 张量怎么创建和操作?constant 和 Variable 有什么区别?张量就是 TensorFlow 里的多维数组——0 维是标量(一个数),1 维是向量,2 维是矩阵,3 维及以上就是高阶张量。它和 NumPy 的 ndarray 很像,但有两个关键区别:**张量可以放在 GPU 上加速计算**,**张量是计算图中的节点,可以被自动求导**。
## 两种张量:constant 和 Variable
`tf.constant` 创建不可变张量,值一旦设定不能改。`tf.Variable` 创建可变张量,可以通过 `.assign()`、`.assign_add()` 修改。**模型权重用 Variable,输入数据用 constant**——这是最核心...服务端2月18日 11:31
NLP 模型评估指标怎么选?分类、生成、翻译指标详解NLP 评估的核心原则:**指标必须和业务目标对齐**。垃圾邮件检测最怕漏判(看召回率),医疗文本分类最怕误判(看精确率),机器翻译要看流畅度也要看忠实度——同一个 F1 分数在不同场景下含义完全不同。
按任务类型选择指标的速查表:
| 任务 | 核心指标 | 辅助指标 |
|------|----------|----------|
| 文本分类 | F1(不平衡时)、Accuracy(平衡时) | 混淆矩阵、AUC-ROC |
| 命名实体识别 | 实体级 F1(严格匹配) | 宽松匹配 F1、按实体类型分别看 |
| 机器翻译 | BLEU | COMET、人工评估 |
| 文...服务端2月18日 11:33
NLP 词向量有哪些方法?Word2Vec、GloVe 到 BERT 演进详解词向量就是把词映射成一段连续的实数向量(通常 50-300 维),让语义相近的词在向量空间中距离也近。计算机不认识"苹果"和"橘子",但它们对应的向量夹角很小——"苹果"和"汽车"的向量夹角大。这个"距离近=语义近"的性质,是一切下游 NLP 任务的基础。
词向量方法经历了三代演进:**静态词向量**(每个词固定一个向量)→ **上下文词向量**(同一个词在不同语境中有不同向量)→ **大模型嵌入**(深层语义表示)。
## 静态词向量:Word2Vec / GloVe / FastText
**Word2Vec**(2013)的核心思想:上下文相似的词,语义也相似。两种训练方式—...服务端2月18日 11:34
NLP 数据不平衡怎么处理?重采样、Focal Loss 和评估指标详解数据不平衡的核心问题:模型倾向于预测多数类,因为这样做在训练集上损失最低。比如 95% 正面 + 5% 负面的情感数据,模型全猜正面也有 95% 准确率——但负面的召回率是 0。
解决思路分三层:**数据层**(调整样本分布)、**算法层**(调整学习过程)、**评估层**(选对指标)。
## 数据层:重采样
**过采样**:复制少数类样本。最简单的是随机复制,但容易过拟合——模型反复看到同样的样本。NLP 里更好的做法是**回译**(中文翻英文再翻回来,得到语义相同但表达不同的新样本)和**同义词替换**,这比 SMOTE 在文本上更自然。
**欠采样**:随机丢弃多数类样本。...服务端2月18日 11:35
RNN、LSTM 和 GRU 有什么区别?怎么选?RNN 是处理序列数据的基础架构:每一步把当前输入和上一步的隐藏状态拼在一起做变换,输出新的隐藏状态。问题是反向传播时梯度要乘很多次权重矩阵,序列一长梯度就指数级衰减(梯度消失)或爆炸——这就是 RNN 记不住远距离依赖的根本原因。
**LSTM** 通过引入细胞状态和三个门来解决这个问题:遗忘门决定忘掉什么,输入门决定存什么,输出门决定输出什么。关键在于细胞状态的更新是加法而非乘法:`C_t = f_t ⊙ C_{t-1} + i_t ⊙ C̃_t`,加法让梯度可以无损地回传,不会逐层衰减。
**GRU** 是 LSTM 的简化版,把遗忘门和输入门合成一个更新门 `z_t`,还省掉了...服务端2月18日 11:36
NLP 模型微调实战:LoRA、QLoRA 和 PEFT 方法详解NLP 模型微调的核心思路:拿一个在大量数据上训练好的预训练模型,用你的目标任务数据继续训练它,让它从"什么都懂一点"变成"在你的领域特别擅长"。关键问题是:**调多少参数、用什么策略调、怎么避免把预训练知识调没了**。
## 全参数微调 vs 参数高效微调(PEFT)
全参数微调解冻所有权重,效果好但显存要求高——7B 模型全参微调至少需要 28GB 显存(Adam 优化器要存两份状态)。PEFT 冻住原始权重,只训练少量新增参数,显存降到原来的 1/3 甚至更低,效果通常能到全参的 90-95%。
**LoRA** 是目前最主流的 PEFT 方法:在权重矩阵旁加一个低秩分解 `...服务端2月18日 17:06
C语言 typedef 和 #define 有什么区别?指针声明陷阱详解typedef 是编译器层面的类型别名,#define 是预处理器层面的文本替换——一个在编译时做类型检查,一个在编译前做字符串替换,这是最根本的区别。
最经典的面试陷阱:**连续声明指针时结果不同**。`typedef char* PCHAR; PCHAR a, b;` 中 a 和 b 都是指针;而 `#define PCHAR char*; PCHAR a, b;` 展开后变成 `char* a, b;`,只有 a 是指针,b 是普通 char——这个 bug 编译器不会报错,能让你查半天。
另一个容易踩的坑:**宏函数的副作用**。`#define SQUARE(x) ((x)...服务端2月18日 17:07
C语言 const 关键字怎么用?指针组合和实战场景详解const 告诉编译器"这个值不许改"——但只限于编译期检查,运行时通过指针强转照样能绕过,所以 const 更像是"程序员之间的约定"而非硬件级的不可变。
最核心的考点是 **const 和指针的组合**,读法从右往左:`const int *p` → p is a pointer to int const(指向的值不能改);`int *const p` → p is a const pointer to int(指针本身不能改)。一个快速判断法:const 在 `*` 左边修饰数据,在 `*` 右边修饰指针。
实际项目中最有价值的用法是**函数参数加 const**:`void ...服务端2月18日 17:15
C语言递归函数怎么优化?尾递归和记忆化实战详解递归就是函数调用自身,每次调用在栈上压入新的栈帧(保存局部变量、返回地址),直到命中终止条件再逐层返回。三要素:终止条件、递归调用、向终止条件逼近——缺一个都会出问题。
递归最大的性能杀手是**重复计算**。经典的斐波那契 `fib(n-1) + fib(n-2)` 时间复杂度 O(2ⁿ),因为同一值被反复算。两个主流解法:**记忆化**(用数组缓存已算过的值,降到 O(n))和**尾递归**(把中间结果通过参数传递,编译器可复用当前栈帧而不压新帧)。
```c
// 尾递归:累加器参数携带中间结果
int fib_tail(int n, int a, int b) {
if...服务端2月18日 17:15
C语言联合体 union 怎么用?内存布局和实战场景详解联合体(union)的所有成员共享同一块内存,大小等于最大成员的大小(再按最严格对齐要求补齐)。和 struct 每个成员各占各的不同,union 同一时刻只有最后写入的成员是有效的——读其他成员是未定义行为(C99 附录 J 明确标注)。
三个核心使用场景:**类型双关**(不经过指针强转,用 union 做浮点数的二进制级操作)、**变体类型**(配合 enum 标记当前存的是哪种数据,俗称 tagged union)、**协议解析**(同一段内存既能当原始字节流读,也能按字段结构体读)。
```c
// 最常见的实用写法:tagged union
enum Tag { TAG_...