☰
搜狗2017校招C++笔试试卷深度解析:考点、陷阱与备考指南
2026/10/30 9:27:38 网站建设 项目流程

你如果准备过校招,大概率见过这套搜狗2017校招C++工程师笔试试卷。就算没做过原题,网上流传的考点整理也早被各路面经抄了一遍又一遍。有意思的是,这套题放在今天看依然很有参考价值——它没有堆砌偏题怪题,而是把C++工程师日常开发里真正要用的功底翻来覆去地考。字符串处理、内存管理、STL容器、基础算法,这些题目看着朴素,实际每一道都在筛“背过八股但写不出代码”的人。

这套卷适合谁?两类人。一类是正在准备校招或实习面试的在校生,你需要用它来检验自己的C++基础到底扎不扎实;另一类是已经工作一两年、想回头补基础的在职开发,很多题你当时可能囫囵吞枣过去了,现在再看会有完全不同的体会。

我这篇博文不打算把原题答案列一遍——网上能找到的东西没必要复述,我重点把题目背后真正想考察的知识点、常见的错误思路、以及我当年踩过的坑讲清楚。文末还会附上笔试时的环境准备、代码调试习惯和一套自查清单,照着准备,比刷十套题都有用。

1. 笔试全景与备考策略

1.1 试卷结构分析

搜狗这套试卷整体分三块:单选、多选和编程题。

单选题大概二十来道,分值占比不高,但覆盖极广,从C++语言基础到操作系统、网络、数据结构都有涉及,甚至有少量概率题和逻辑题。多选题是拉开差距的地方——漏选、错选都不得分,对知识点的精确度要求很高。编程题通常两道,一道偏字符串处理,一道偏算法设计,允许用C/C++作答,在线OJ方式提交,需要用标准输入输出。

从我当年考场上的感受来说,最阴险的不是编程题,而是选择题里的那些“概念辨析”。比如考察sizeof和strlen的区别、虚函数能否是构造函数、const成员函数里能不能修改成员变量。这些题单独拎出来都不难,但混在一起、加上多个选项组合时,很容易在“好像对”和“其实不对”之间栽跟头。

1.2 为什么一套老题还值得认真刷

很多同学觉得2017年的题太老了,C++17都出来这么多年了,还有必要看吗?

这个想法我特别理解,但实际是错的。校招笔试考的是基础功底,不是最新特性。搜狗这套题里考的vector扩容机制、智能指针引用计数、红黑树的插入旋转——这些在今天依然是笔试面试的高频考点,而且短期内不会变。恰恰因为题目老,网上有大量考点整理、题解、讨论帖,学习材料反而更齐全。

另外有一点容易被忽略:老题能帮你判断一个公司的出题风格。搜狗这套题明显偏重工程实践基础,对语言特性的考察明显多于对算法难度的考察。你拿它和字节、阿里那些动辄Hard级别算法题的卷子对比,就能看出不同公司对C++工程师的能力预期是不一样的。

1.3 从搜狗笔试反推C++工程师的能力要求

站在今天的视角回头看搜狗这套题,它真正想筛选的能力有三项:

第一是语言功底扎实。这不是说你能背出多少条语法规则,而是面对一个具体问题时能准确说出“C++会怎么处理”。比如传引用和传值的开销差异、深拷贝和浅拷贝的风险、vector扩容时迭代器为什么会失效——需要的是底层机制的清晰认知,不是玄学背诵。

第二是代码实现干净利落。搜狗编程题通常题干不长,但边界条件很隐蔽。字符串去重、数字反转、链表操作这类题目,大多数人都能写出来,但能在15分钟内写出无bug版本的人并不多。考场上的拼的不是谁思路多惊艳,而是谁更少犯错。

第三是调试能力在线。笔试环境不像IDE那么友好,没有断点调试,全靠打印日志和自己review。平时刷题习惯用cout输出中间结果的同学在笔试里反而占优势,因为他们已经形成了“预处理输入→分步验证→边界测试”的肌肉记忆。

2. 核心考点深度复盘:这些题到底在考什么

2.1 面向对象三大特性与虚函数机制

搜狗的单选题里至少有三四道和面向对象有关,涵盖封装、继承、多态,其中virtual相关的内容是绝对重点。

虚函数这里有个高频考点:虚函数表是什么时候生成的?构造函数能不能是虚函数?析构函数为什么通常要声明为虚函数?第一问答案是编译期,虚函数表在编译阶段生成,运行期只是通过虚表指针去查表。第二问是否定的,因为虚函数调用依赖虚表指针,而虚表指针是在构造函数体执行之前初始化的,此时虚表还没准备好。第三问是要防止“通过基类指针delete派生类对象”时只调用基类析构函数、不调用派生类析构函数导致资源泄漏。

class Base { public: virtual ~Base() { std::cout << "Base destructor" << std::endl; } }; class Derived : public Base { public: ~Derived() override { std::cout << "Derived destructor" << std::endl; } }; Base* p = new Derived(); delete p; // 输出:Derived destructor 然后 Base destructor

如果把上面Base的析构函数去掉virtual,delete p就只会输出Base destructor,Derived的析构逻辑被完全跳过。这个例子我反复讲,因为它几乎是笔试和面试里百考不厌的知识点。

还有一个隐蔽的考点:纯虚函数可以有函数体。这个说法是不是听着很反直觉?但标准允许纯虚函数带定义体,只是派生类仍然必须override它才能实例化。这是很多选择题里用来混淆选项的经典设计。

2.2 从关键词看底层功力:const和static的多种用法

搜狗笔试对const和static的考察密度相当高,而且总爱把两种用法混在一起出题。

先说const。它至少有五种常见位置:修饰全局常量、修饰局部变量、修饰指针本身(int* const p)、修饰指针指向的内容(const int* p)、修饰成员函数(void func() const)。笔试里考察最多的是后两种的区别。

int a = 10, b = 20; const int* p1 = &a; // p1指向的值不可变,但p1本身可以变 int* const p2 = &a; // p2本身不可变,但p2指向的值可以变 // p1 = &b; // 合法 // *p1 = 30; // 非法 // *p2 = 30; // 合法 // p2 = &b; // 非法

记法很简单:const修饰谁,谁就不可变。const int* p中const修饰*p,所以指向的值不可变;int* const p中const修饰p,所以指针本身不可变。

static在类里面的考点又不一样。静态成员变量属于类而不属于对象,必须在类外单独定义;静态成员函数没有this指针,只能访问静态成员。笔试里经常给一段代码,问输出结果,很多同学搞混“局部静态变量的生命周期”和“程序执行顺序”,从而答错。局部静态变量的初始化发生在第一次执行到该声明时,但析构发生在程序结束时(main退出或调用exit)。

2.3 现代C++特性:constexpr与C++版本演进

这套题虽然出在2017年,但已经包含了对C++11新特性的考察,其中constexpr就是常客。它是在C++11引入的关键字,用来声明“可以在编译期求值”的函数或变量。C++14放宽了限制,允许在constexpr函数里使用循环和局部变量;C++17又把constexpr扩展到if和lambda;C++20甚至支持constexpr虚函数和constexpr的std::vector操作。

这个演进过程本身就值得记忆。面试官问“constexpr是哪个C++版本引入的”,不是单纯考察时间点,而是想看你是否理解编译期求值和运行期求值的边界。

constexpr int square(int x) { return x * x; } constexpr int result = square(5); // 编译期计算 static_assert(result == 25, "result must be 25");

static_assert是C++11的另一个重要特性,配合constexpr可以在编译期做校验。搜狗这类公司对C++标准的跟进速度通常是积极的,因为搜索引擎对性能敏感,能在编译期完成的计算绝不拖到运行期。

3. 内存管理与STL容器:笔试的必考重灾区

3.1 堆与栈:不是你new了才叫堆

搜狗笔试对内存管理的考查很有代表性——不会直接问“堆和栈的区别”,而是给一段代码,让你分析变量存放在哪里、生命周期如何、是否会造成内存泄漏。

栈上的变量由编译器自动分配和释放,速度极快但空间有限。堆上的变量通过new或malloc分配,需要手动释放,生命周期完全由程序员控制。这里有个经典误解:很多同学以为只有显式new出来的对象才在堆上,实际上std::vector内部的数据存储就在堆上,哪怕你在栈上声明这个vector对象本身。

内存泄漏的考察集中在三种场景:

第一种是忘记delete。这个最直观,但笔试里很少直接考,因为太简单。

第二种是异常安全导致的泄漏。函数中new了一个对象,后续代码抛出异常,如果没有RAII机制保护,delete语句永远不会执行。

void func() { int* p = new int[100]; // 这里抛出异常的话,p永远不会被释放 doSomethingThatMayThrow(); delete[] p; }

第三种是基类析构函数不是虚函数导致的“半释放”。前面2.1节已经说过了,这种泄漏比较隐蔽,很多同学笔试时看不出来。

3.2 智能指针:从裸指针到RAII

搜狗这套题对智能指针的考察不算特别深,但已经出现了shared_ptr的引用计数问题。近几年面试对智能指针的考察明显加深,我不能不提。

shared_ptr通过引用计数管理对象生命周期,当最后一个持有它的shared_ptr被销毁时,对象被释放。这里有两个高频考点。

第一个是循环引用。两个对象互相持有对方的shared_ptr,引用计数永远无法归零,导致内存泄漏。解决办法是把其中一个改成weak_ptr。

struct Node { std::shared_ptr<Node> next; std::weak_ptr<Node> prev; // 打破循环引用 };

第二个是auto_ptr的黑历史。C++11之前用auto_ptr,它的拷贝操作会转移所有权,导致原指针变成空指针,这是非常反直觉的设计。C++11标准引入了unique_ptr替代它,后者禁止拷贝、只允许移动。搜狗这套题如果出到智能指针的选择题,很大概率会考察“哪种智能指针可以用于STL容器”这种问题——答案是shared_ptr和unique_ptr,不是auto_ptr。

我当时的做法是记一个简单结论:默认用unique_ptr,共享所有权用shared_ptr,需要打破循环或临时观察用weak_ptr,绝对不用裸指针管理动态内存。

3.3 STL容器面试必问:vector扩容与map底层实现

STL容器在搜狗笔试里占据的篇幅比智能指针大得多,vector和map是绝对重点。

vector的扩容机制可以说是STL面试第一题,几乎到了必考的地步。vector底层是连续内存的动态数组,当size要超过capacity时,会执行以下步骤:

  1. 分配新内存块,容量通常是原来的1.5倍或2倍(不同编译器实现不同,gcc是2倍,Visual C++也是约1.5到2倍之间)。
  2. 将旧元素拷贝或移动到新内存。
  3. 释放旧内存。

这里有两个相关考点。第一个是“迭代器失效”:扩容后所有迭代器、指针、引用都会失效,因为原内存被释放了。第二个是“频繁扩容的性能问题”:如果预先知道需要多少元素,应该用reserve提前分配足够容量,避免多次扩容。

std::vector<int> v; v.reserve(1000); // 提前分配容量,避免多次扩容 for (int i = 0; i < 1000; i++) { v.push_back(i); }

map的底层是红黑树,增删查改的时间复杂度都是O(log n)。与之形成对比的是unordered_map,底层是哈希表,平均时间复杂度O(1),但最坏情况O(n)。笔试常考的问题包括:为什么map的迭代器不会在插入元素后失效?因为红黑树节点在内存中独立存在,插入只改变指针指向,不移动已有节点。为什么unordered_map迭代器可能在rehash后失效?因为rehash会重新分配所有桶。

如果你不想背这些结论,可以换个角度理解:真正常用的容器就几个,知道它们“为什么要这么设计”,比背住“时间复杂度是多少”有价值得多。

3.4 迭代器失效:笔试里的经典陷阱

迭代器失效是STL容器笔试里最容易失分的点,也是搜狗风格的选择题最喜欢出的方向。

vector在执行insert或erase后,被操作位置之后的迭代器全部失效。map和set则比较皮实,插入操作不影响任何迭代器,erase也只让被删除元素的迭代器失效。list同样只有被删除元素本身的迭代器失效。

这几个结论背起来不难,但实际写代码时经常会犯“在遍历中删除元素”的错误:

// 错误示范:在遍历vector时erase元素 std::vector<int> v = {1, 2, 3, 4, 5}; for (auto it = v.begin(); it != v.end(); ++it) { if (*it % 2 == 0) { v.erase(it); // it已经失效,++it是未定义行为 } }

正确写法是:

for (auto it = v.begin(); it != v.end(); ) { if (*it % 2 == 0) { it = v.erase(it); // erase返回下一个有效迭代器 } else { ++it; } }

erase返回被删除元素的下一个迭代器,这是C++11之后的标准行为,也是解决“边遍历边删除”问题的标准姿势。笔试里如果遇到相关代码填空,十有八九考察的是这个细节。

4. 从选择题到编程题:算法与代码题实战

4.1 字符串处理:校招编程题的半壁江山

搜狗编程题几乎离不开字符串。这不是搜狗独有的偏好,整个校招市场都是如此——字符串处理不需要复杂的数据结构,却能充分考察代码的严谨性和边界条件处理能力。

高频题目类型包括:字符串去重、反转、判断回文、大小写转换、子串查找、字符串转整数或浮点数。每题都能玩出花来,但底层能力是相通的:字符指针的移动、越界判断、'\0'结尾的处理。

以“字符串转整数”为例,这道题在LeetCode上是中等难度,但笔试正确率并不高。考察点很清晰:

  • 空字符串处理
  • 前导空白字符跳过
  • 正负号处理
  • 数字字符的合法性
  • 溢出判断
  • 非法输入时该如何返回
int myAtoi(const std::string& s) { int i = 0; int sign = 1; long result = 0; while (i < s.size() && s[i] == ' ') i++; if (i < s.size() && (s[i] == '+' || s[i] == '-')) { sign = (s[i] == '-') ? -1 : 1; i++; } while (i < s.size() && isdigit(s[i])) { result = result * 10 + (s[i] - '0'); if (result * sign > INT_MAX) return INT_MAX; if (result * sign < INT_MIN) return INT_MIN; i++; } return result * sign; }

核心经验:笔试写字符串题,先把所有边界条件列出来,再动手写代码。不要上来就写主逻辑,写完再补边界,很容易漏。

4.2 排序算法底层:冒泡排序与选择排序的考点

排序算法是校招笔试的常青树,搜狗这套题也涉及到了。不过它考的往往不是“让你手写快排”,而是给出“某排序算法经过两轮后的数组状态”,让你判断这是哪种排序算法。

这里我建议把冒泡排序和选择排序的实现细节彻底弄清楚,因为它们代码短、容易考,而且经常作为对比选项出现。

冒泡排序的核心思想是“相邻元素两两比较,大元素逐步冒泡到末尾”,一趟排序后最大值一定被放到最后。选择排序的核心思想是“每趟从未排序区间选出最小值,放到区间最前面”,一趟排序后最小值一定在开头。

void bubbleSort(int arr[], int n) { for (int i = 0; i < n - 1; i++) { bool swapped = false; for (int j = 0; j < n - 1 - i; j++) { if (arr[j] > arr[j + 1]) { std::swap(arr[j], arr[j + 1]); swapped = true; } } if (!swapped) break; // 优化:本趟无交换说明已有序 } } void selectionSort(int arr[], int n) { for (int i = 0; i < n - 1; i++) { int minIdx = i; for (int j = i + 1; j < n; j++) { if (arr[j] < arr[minIdx]) minIdx = j; } if (minIdx != i) std::swap(arr[i], arr[minIdx]); } }

注意冒泡排序这个swapped标志的优化,很多教材不讲,但面试官问“怎么优化冒泡排序”时,答出这个会加分。它利用“某一趟没有任何交换说明数组已经完全有序”的性质,提前终止排序。

4.3 不容忽视的模板算法:快速幂和单调栈

搜狗这类以工程实践为主的公司,编程题通常不会考太冷门的算法模板,但快速幂和单调栈是例外——它们代码量不大、思路巧妙、出场率极高,值得反复练习。

快速幂解决的问题是高效计算倍率次幂,比如计算a^b mod m。朴素做法是循环相乘,时间复杂度O(b),当b很大时效率极低。快速幂的核心思想是把指数按二进制拆解:

long long fastPow(long long base, long long exp, long long mod) { long long result = 1; while (exp > 0) { if (exp & 1) { result = result * base % mod; } base = base * base % mod; exp >>= 1; } return result; }

时间复杂度降为O(log b),代价只是多记一个“base每次自乘、exp每次右移”的规则。笔试里求大数幂取模的题,基本都是这个模板。

单调栈常用于解决“下一个更大元素”“每日温度”等经典问题,核心维护一个栈内元素单调的栈结构。代码量不大,但要理解“什么时候入栈、什么时候出栈、出栈时做什么计算”非常关键。

std::vector<int> nextGreaterElement(const std::vector<int>& nums) { std::vector<int> res(nums.size(), -1); std::stack<int> st; // 栈中存下标 for (int i = 0; i < nums.size(); i++) { while (!st.empty() && nums[st.top()] < nums[i]) { res[st.top()] = nums[i]; st.pop(); } st.push(i); } return res; }

用单调栈维护一个“从栈底到栈顶单调递减”的结构,每当遇到比栈顶元素更大的值,就说明找到了栈顶元素的下一个更大元素,此时出栈并记录结果。

4.4 并发编程考点:再看ABA问题

搜狗这套题出得早,2017年的试卷对并发编程的考察还比较浅,但结合近几年面试趋势,ABA问题几乎已经成了C++并发领域的必问考点,我必须专门讲一下。

ABA问题发生在无锁数据结构中。简单说,线程1读取共享变量为A,线程2把变量从A改成B再改回A,线程1再次比较时发现值还是A,就认为没有其他线程修改过,继续执行。但实际上变量已经被改过两次了,这个“值没变”的判断是不可靠的。

一个经典例子是栈顶指针的CAS操作。线程1读取栈顶为节点A,准备把新节点N的next指向A;此时线程2弹出了A,随后另一个线程又压入了A(内存地址相同),线程1执行CAS时发现栈顶还是A,就以为栈没变,实际栈的结构已经完全变了。

解决方案有两种:一种是用带版本号的原子变量同时比较值和版本号;另一种是使用hazard pointer管理节点回收,确保节点不会在CAS前被复用。

// 版本号方法示例 std::atomic<uint64_t> abaGuard; // 比较时同时比较值和版本号 uint64_t oldVal = abaGuard.load(); uint64_t newVal = (oldVal & 0xFFFFFFFF) | ((oldVal >> 32) + 1) << 32; abaGuard.compare_exchange_strong(oldVal, newVal);

笔试考到ABA问题时,只要你能说清楚“为什么值相同不代表数据没有被修改过”以及“版本号能解决这个问题的原理”,基本就能拿全分。

5. 笔试环境准备与实战演练

5.1 VSCode配置C/C++开发环境

笔试虽然通常在线OJ完成,但平时的练习环境直接影响刷题效率。我用VSCode写C++已经好几年了,这里分享一套简洁稳定的配置方案。

第一步,安装C/C++扩展。这是微软官方扩展,提供代码提示、跳转定义、调试支持,直接搜索“C/C++”安装即可。

第二步,配置编译器。Windows用户建议安装MinGW-w64,macOS用户直接安装Xcode Command Line Tools,Linux用户用包管理器安装g++。

第三步,配置构建任务。在.vscode目录下创建tasks.json,指定编译命令:

{ "version": "2.0.0", "tasks": [ { "label": "build", "type": "shell", "command": "g++", "args": [ "-g", "-std=c++17", "${file}", "-o", "${fileDirname}/${fileBasenameNoExtension}.exe" ], "group": { "kind": "build", "isDefault": true } } ] }

这里我特意加了-std=c++17。校招笔试环境通常支持C++14或C++17,但部分同学本地默认编译器标准可能是C++98或者gnu++03,写auto、nullptr、基于范围的for循环时语法检查不通过,误以为是自己代码写错了,实际上只是标准版本太低。

5.2 编译器版本与C++标准对照

笔试中最尴尬的事情不是题不会做,而是代码在本地编译通过、提交到OJ上却编译失败。最常见的原因就是C++标准版本不匹配。

先明确一点:C++11和C++14是校招笔试的默认标准,C++17正在被更多公司支持,但老平台上可能仍然生效C++14。

标准版本发布时间代表性特性是否建议在笔试中使用
C++981998模板、STL、异常不建议,特性太老
C++112011auto、智能指针、lambda、移动语义必用,兼容性最好
C++142014泛型lambda、返回值推导推荐,增加不多但更灵活
C++172017if constexpr、结构化绑定、std::optional看OJ支持情况
C++202020概念、协程、范围for不建议,OJ支持率不稳定

我建议笔试中默认使用C++11或C++14风格的代码,避免使用C++17独有的特性。不是说你不能用std::optional,而是万一OJ平台不支持,你连改写的时间都没有。

提一个细节:有些同学喜欢用bits/stdc++.h这个万能头文件,本地可以,但部分OJ可能不支持,建议笔试前先确认平台是否允许。如果是在不支持的环境,还是老老实实逐个包含需要的标准头文件。

5.3 模拟笔试:用一套固定流程训练肌肉记忆

刷真题和自己模拟笔试是完全不同的体验。校招笔试通常限时90到120分钟,编程题2到3道,时间分配必须提前规划。

我当年的方法是:每周固定抽一个晚上,模拟一次完整笔试。环境就用VSCode加终端,不开IDE自动补全,不开语法提示,完全模拟在线OJ的裸写状态。计时90分钟,选择题和编程题一起做,时间到了立即停笔。

做完之后一定要复盘。重点不是对答案,而是问自己三个问题:哪些选择题是蒙的?哪些编程题花了太久时间?如果在考场上时间不够,该优先放弃哪道题?

我的建议是:编程题第一题如果15分钟没有完整思路,立刻跳过做第二题,不要在一道题上死磕。校招笔试是“做对足够多的题”,不是“完美解决一道题”。

5.4 常见编译错误与排查技巧

笔试紧张状态下,编译错误比算法错误更容易导致翻车。我总结了一下最常出现的问题和排查顺序,整理成了一张自查表。

问题现象可能原因排查方式
编译报错:undefined reference to 'main'文件名命名有误,或入口函数签名写错检查int main()是否存在,拼写是否准确
编译报错:could not convert '...' from '...'类型不匹配,比如把std::string传给const char*参数查看报错行,确认函数参数类型
运行超时死循环或算法复杂度过高检查while条件是否可能永不满足;确认算法是否O(n^2)以上复杂度
运行时崩溃(Segmentation fault)数组越界、空指针解引用、栈溢出检查循环边界条件;确认指针是否初始化;大数组是否放到局部变量中导致栈溢出
输出结果与预期不符边界条件未处理、多组输入未循环读取用极端用例测试:空输入、最大输入、单元素输入

我印象最深的是有一次模拟笔试,代码逻辑完全正确,但输出一直多一个空格。原来是循环体内每个结果后面都加了空格,没有处理“最后一个结果后面不需要空格”的细节。这种问题在本地能发现,但在OJ上只显示Wrong Answer,非常浪费时间排查。所以平时练习时,一定养成“输出格式严格匹配题目要求”的习惯,多一个空格、少一个换行都可能判错。

6. 面试官视角与备考建议

6.1 搜狗这类公司看重什么

我后来和技术圈的朋友复盘搜狗的面试风格,大家的共识是:搜狗对C++工程师的要求是“扎实落地”,不是追求最前沿的语言特性花活。

笔试题目设计也体现了这一点。它不会问你std::apply的变参模板展开怎么写,但一定会问你vector在扩容时迭代器为什么失效、shared_ptr循环引用有什么危害、map底层为什么用红黑树而不是AVL树。这些都是搜索引擎后端开发每天要面对的基础问题——你的代码要跑在千万级请求的线上环境,任何一个资源泄漏或迭代器悬垂都可能酿成事故。

所以在准备时,不要沉迷于冷门特性。把C++ Primer的重点章节吃透,配合Effective C++的实践建议,再加上LeetCode前200题的中等难度题目练习,这个组合拳打下来,应对搜狗这套笔试试卷绰绰有余。

6.2 一套实用的冲刺备考计划

如果你离笔试还有两到三周,可以参考我这套安排:

第一周主打基础回顾。每天抽2小时过C++核心语法,包括类与对象、继承与多态、运算符重载、模板基础、STL容器。配合完成50道与数据结构和字符串相关的LeetCode简单或中等题。

第二周主打真题模拟。找10套不同公司的C++校招笔试题,每天一套限时模拟,重点分析错题分布,找出自己的薄弱板块——是内存管理失分多,还是算法题超时严重,有针对性地专项突破。

最后三天只做三件事:复习错题笔记、整理各容器的时间复杂度表、练习标准输入输出处理。

这里推荐一个我实践过的小技巧:建立一个自己的“编码模板”文档,包含常用的头文件组合、快读快写模板、快速幂模板、并查集模板、单调栈模板等。笔试时先花2分钟把模板敲出来备用,能节省不少时间。

6.3 笔试时的时间分配与心态管理

最后聊聊考试现场的经验。

笔试刚开始的5分钟不要急着做题。先把整张卷子扫一遍,看清楚编程题有几道、难度如何、选择题总量多少,心里有个时间预算。我通常的分配是:选择题控制在40到50分钟,每道题不超过2分钟;编程题每道留20到30分钟,其中前5分钟只读题和想思路,不写代码。

编程题如果完全没有思路,先不要硬写,在草稿纸上画一画示例数据的处理过程。很多时候思路是在模拟样例时蹦出来的,而不是干想出来的。

还有一条特别重要的建议:如果一个知识点你有印象但不确定,先标记出来跳过,不要卡在一道选择题上。校招笔试的分值优势往往来自“会的题全部做对”,而不是“不会的题蒙对”。

7. 一点个人体悟

搜狗这套2017年的C++笔试试卷,我前前后后刷过三遍。第一遍是在校招季准备阶段,很多题做得云里雾里;第二遍是工作第一年,再看时发现很多考点和实际工作内容不经意间对上了;第三遍是写这篇文章前,我把所有考点重新复习了一遍,发现十年过去了,C++的标准从C++11走到了C++20,但这套题考察的核心能力——对底层机制的理解、对内存的敬畏、对边界的敏感——丝毫没有过时。

如果你正在准备校招,我想说:刷题有用,但别只刷题。每一道选择题背后都有一个“为什么”,把这个为什么弄清楚,比多做十道同类题更有价值。搜狗这套题里那些关于虚函数、智能指针、迭代器失效的考点,本质上都是在逼你想清楚“C++这门语言为什么这样设计”。

把这些问题想透了,将来无论面对哪家公司的笔试题,你都会发现万变不离其宗。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询