免费获取学习方案
ARTICLE DETAIL

资讯详情

深耕编程基础知识与建站技术分享的一线实战洞察。

搜狗C++校招笔试题解析:考点梳理与实战模板

搜狗C++校招笔试题解析:考点梳理与实战模板 搜狗2017校招C工程师笔试试卷这个话题放到现在来看依然有一批人在讨论。原因其实很简单搜狗的笔试风格在当年的互联网公司里属于相当有代表性的一类——题量大、时间紧、C底层细节抠得深还夹杂着大量考察“工程直觉”的题。你光背《C Primer》不一定能过但如果你真的动手写过几个小项目、踩过内存问题的坑这套卷子会让你答得非常舒服。所以哪怕你已经不打算投搜狗拿这套题来检验自己的C水平也绝对值回票价。我结合近些年网上流传的回忆版题目和同类大厂笔试的常考方向把这套卷子拆解开从考点结构、高频错题、代码模板到应试策略完整梳理一遍。内容分成六块前两块讲卷子本身和选择题里的雷区中间几块重点讲手写代码和算法模板最后给出一个可以直接照着做的复习清单。无论你是准备秋招的应届生还是想查漏补缺的在职开发者都可以拿这篇文章当一个自测索引。1. 这套卷子的底牌卷面结构、题量与隐藏筛选逻辑1.1 卷面结构拆解与时间分配搜狗2017校招C笔试延续了当时的典型风格选择题 编程题的组合总时长在两个半小时左右。选择题覆盖C语法、数据结构、操作系统、网络基础四块大概有二十到三十道每道题的分值不高但胜在覆盖面极广。后面跟着两道到三道编程题要求在白板式的在线编辑器里手写完整代码不允许本地编译调试时间压力非常大。这个结构本身就在筛选人。选择题考察的是“你知不知道”编程题考察的是“你能不能写出来”。前者可以用排除法蒙后者完全靠硬功夫。很多同学死在时间分配上前面选择题纠结太久后面编程题只够写一题甚至一题都跑不通。我的建议是拿到卷子先花两分钟整体扫一遍题目分布心里对编程题的题量有个数选择题遇到卡壳超过两分钟的先标记跳过别恋战。从网上回忆版的反馈来看编程题基本都在LeetCode中等难度以内但有一个微妙的地方它要求你用纯C实现连STL的使用有时都会受限。比如有的题目明确要求“不能使用额外的容器”或“只能使用O(1)空间”这就是在考察你愿不愿意老老实实操作指针和下标而不是丢一个 map 过去糊弄。1.2 搜狗笔试的隐藏筛选逻辑搜狗的业务以搜索和输入法为主背后牵扯到字符串处理、索引构建、并发调度、内存复用这些高密度场景所以它的笔试题有一个隐藏偏好所有考点都会向“字符串”“并发”“底层内存”三个方向倾斜。你在备考时如果时间有限优先把这三大块吃透通过率会高很多。举个例子操作系统层面它很少直接问“进程和线程的区别”这种八股而是会问“一个多线程程序里两个线程同时对一个int变量做操作最终结果是否一定是2为什么”这种题。表面考并发实际上考你对CPU缓存、指令重排、原子性的理解深度。如果你只背了“多线程共享全局变量会有问题”这句话答不出本质分数就拿不全。所以备考这套试卷本质上是备考一场“C工程实践能力的摸底考试”。它不像ACM那样追求极限算法更看重你写出的代码是不是干净、健壮、能在生产环境里跑起来。有了这个认知后面的复习方向就有谱了。2. 选择题里的高频雷区C语法与内存布局2.1 C对象模型与虚函数考点选择题里几乎必考虚函数而且问法非常刁钻。常见的有这么几类含虚函数的类sizeof()是多少虚函数表在内存里的什么位置构造函数里调用虚函数会发生什么析构函数要不要声明为virtual为什么。先说sizeof的问题。很多新手以为“有虚函数就是4字节”因为有个虚表指针。但你得记住指针大小是平台相关的32位下是4字节64位下是8字节。而且类里如果还有别的成员变量还要考虑内存对齐。比如一个类有一个char和一个虚函数64位下sizeof不是9而是16因为char后面要填充7个字节让虚表指针对齐到8字节边界。再说构造函数里调用虚函数的问题。答案是不会触发多态。因为构造子类对象时基类构造函数先执行此时子类部分还没初始化虚表指针指向的是基类的虚表所以调用虚函数只会调用基类版本。这个考点在《Effective C》里有专门的条款但笔试时很多人凭直觉作答掉进陷阱。我在实际项目里被这个坑过一次。当时在基类构造函数里调了一个虚函数做日志初始化结果子类的初始化逻辑根本没执行排查了半天才发现是对象模型在作祟。从那以后我给自己定了个规矩构造函数和析构函数里绝不调用虚函数任何需要在构造阶段完成的逻辑一律改成显式的init()方法。2.2 STL容器选型与迭代器失效STL相关的选择题核心就两个字失效。vector、deque、list、map这些容器在插入、删除元素时哪些迭代器会失效哪些不会是高频考点。规则其实不复杂vector插入元素导致重新分配内存时所有迭代器和引用全部失效删除元素后被删除位置之后的迭代器全部失效。deque插入元素到首尾两端时其他迭代器不受影响插入到中间位置所有迭代器失效。list插入和删除都不会使其他迭代器失效只是被删除元素的迭代器指向的内容没了。map/set删除节点只影响被删除节点的迭代器其他迭代器不受影响。为什么搜狗爱考这个因为搜索引擎的底层要高频处理文档列表、倒排索引这些场景里几乎全是用vector加自建内存池来管理如果你在遍历时乱删元素导致迭代器失效线上就是崩溃。笔试里会问“下面这段代码有什么问题”for (auto it vec.begin(); it ! vec.end(); it) { if (*it % 2 0) { vec.erase(it); } }这题一眼就能看出问题erase之后it已经失效再执行it就是未定义行为。正确写法是for (auto it vec.begin(); it ! vec.end();) { if (*it % 2 0) { it vec.erase(it); } else { it; } }C11之后可以用erase返回下一个有效迭代器这个特性这个知识点虽然简单但在面试手写代码时特别容易因为紧张写错。建议备考时把vector的删除、去重、合并这几类操作各写一遍形成肌肉记忆。2.3 static、const、constexpr等概念辨析这一块属于经典八股但搜狗的题目往往会把它们混合在一起考察你对“声明”和“定义”、对“编译期”和“运行期”的理解。static放在不同位置含义完全不同修饰全局变量/函数限制为文件内部可见内部链接属性。修饰局部变量延长生命周期到程序结束且只在首次执行时初始化。修饰成员变量所有对象共享一份必须在类外单独定义C17之后inline static可以简化。修饰成员函数不依赖对象实例不能访问非static成员。constexpr则是C11引入的、C14/17逐步放宽的“编译期求值”能力。很多人的困惑是constexpr和const到底什么区别。最简单的理解const是“运行期只读”constexpr是“编译期常量”。一个const变量的值可以在运行时才确定而constexpr变量的值必须在编译期就能算出来。所以constexpr函数天然可以用于数组长度、模板参数等需要编译期常量的场景。搜狗的笔试题里常出现这类判断“以下哪种写法能通过编译”。你看多了就会发现它真正想考的不仅是语法而是你对C各个版本演进的理解。C11、C14、C17、C20每个版本都在修正上一版本的痛点如果你能说出constexpr在C14里放宽了“可以包含循环和局部变量”这个变化答这些题就很有底气。我在VSCode里配C开发环境时经常用C17标准编译。如果你也是这个环境记得在tasks.json里加上-stdc17不然默认的编译器标准可能比较老跑constexpr相关代码会报莫名其妙的错误。这个小坑我帮好几个同事解决过。3. 必背的编程题模板算法题解与手写代码3.1 字符串与数组循环右移、字符串转数组、最小公倍数搜狗的编程题字符串是绝对主力。因为搜索、输入法、推荐——这些业务全是字符串驱动的。下面这几个题目在回忆版里反复出现你最好能直接默写出来。字符串循环右移是常客。比如“abcde”循环右移2位变成“deabc”。最经典的解法是三次反转先把整体反转变成“edcba”再把前k个反转变成“decba”再把后n-k个反转变成“deabc”。时间复杂度O(n)空间O(1)代码极短void reverseStr(string s, int l, int r) { while (l r) swap(s[l], s[r--]); } void rightRotate(string s, int k) { int n s.size(); if (n 0) return; k % n; if (k 0) return; reverseStr(s, 0, n - 1); reverseStr(s, 0, k - 1); reverseStr(s, k, n - 1); }注意k要取模否则当k大于n时会越界或者逻辑错误。这个边界条件我在笔试时吃过亏第一次写没取模结果用例只过了一半。再比如字符串转数组。这里要分清楚是“每个字符转成int”还是“把整个数字字符串转成一个数”。如果是前者直接减0即可如果是后者就要考虑正负号、溢出、非法字符判断。笔试时我建议写一个防御性强的版本把所有异常情况都考虑进去否则在线评测的隐藏用例会把你打回原形。int strToInt(const string str) { if (str.empty()) return 0; long long res 0; int i 0, sign 1; while (str[i] ) i; if (str[i] || str[i] -) { sign (str[i] -) ? -1 : 1; i; } for (; i str.size(); i) { if (str[i] 0 || str[i] 9) break; res res * 10 (str[i] - 0); if (res * sign INT_MAX) return INT_MAX; if (res * sign INT_MIN) return INT_MIN; } return res * sign; }这类题还有一个变体求n个整数的最小公倍数。考的是你知不知道“先算最大公约数再两两合并”这条路。两个数的最大公约数用辗转相除法也就是欧几里得算法然后最小公倍数就是两数乘积除以最大公约数。int gcd(int a, int b) { return b 0 ? a : gcd(b, a % b); } int lcm(int a, int b) { return a / gcd(a, b) * b; } int lcmOfArray(const vectorint nums) { int res 1; for (int num : nums) { res lcm(res, num); } return res; }注意先除后乘避免a*b溢出。这个细节我在实际写代码时经常注意笔试考场上如果你能写出这一步评卷人会觉得你确实有工程经验。3.2 链表与指针单链表找环、链表反转的边界链表题是C笔试的另一座大山。原因很现实手写链表能给足你操作指针的空间同时极易出错考察“代码精准度”。搜狗常考的链表题无非那么几道反转链表、找中间节点、判断是否有环、找到环的入口、合并两个有序链表。判断单链表是否有环用快慢指针一个走一步一个走两步如果相遇说明有环。但要找到环的入口就需要一个数学推导从链表头到入口距离记为a入口到相遇点距离记为b相遇点再回到入口距离记为c。快指针走的距离是慢指针的两倍可以推出a c n圈。所以相遇后一个指针从头走一个指针从相遇点走再次相遇的位置就是环口。ListNode* detectCycle(ListNode* head) { ListNode* slow head; ListNode* fast head; while (fast ! nullptr fast-next ! nullptr) { slow slow-next; fast fast-next-next; if (slow fast) break; } if (fast nullptr || fast-next nullptr) return nullptr; slow head; while (slow ! fast) { slow slow-next; fast fast-next; } return slow; }这段代码很短但每一步都有讲究。第二段循环里如果链表无环fast会提前遇到空指针所以必须得在一开始就判断好。还有一个容易忽略的地方快指针走两步这种写法如果不判断next是不是空直接fast-next-next在链表末尾时会解引用空指针导致运行时错误。笔试平台不会给你看变量值只能靠你写代码时的谨慎来规避。这类问题在实际工程里也会遇到比如内存池的空闲链表管理链表结构虽然被封装起来了但指针边界问题始终是悬在头顶的一把刀。链表反转也是必背。我以前整理过一个通用写法用三个指针prev、cur、next每轮循环记录next再反转当前节点指向。写完之后一定要记得把原本头节点的next置空否则链会出现自环一旦跑起来就是死循环或者栈溢出。ListNode* reverseList(ListNode* head) { ListNode* prev nullptr; ListNode* cur head; while (cur ! nullptr) { ListNode* next cur-next; cur-next prev; prev cur; cur next; } return prev; }这道题还有一个高阶变体按k个一组反转链表。这意味着你需要同时实现“找第k个节点”“反转局部链表”“拼接前后部分”三个动作每一段都要极其小心笔试时如果要写建议先在草稿纸上画好指针变化图。我见过太多人在这题上翻车本来思路是对的就是指针边界没处理好连样例都没跑通。3.3 进阶算法快速幂、单调栈、多线程安全计数器再往下就是搜狗笔试题里用来拉开差距的进阶题目。快速幂是其中一个典型代表题面一般描述成“求x的n次方n可以很大要求O(log n)”。核心思路是把n拆成二进制举个例子求x的13次方13的二进制是1101所以x^13 x^8 * x^4 * x。每次对指数移位如果当前二进制位为1就乘上当前的base。代码实现简洁且适合背诵long long fastPow(long long x, long long n, long long mod) { long long res 1 % mod; x % mod; while (n 0) { if (n 1) res res * x % mod; x x * x % mod; n 1; } return res; }注意两点一是n很大时要用long long二是取模运算要尽早做否则中间过程可能溢出。快速幂的计算过程本身就是一个典型的位运算练习理解了它二进制枚举和状态压缩相关的题也会顺手很多。单调栈是很多同学容易忽略的考点但它在“求下一个更大元素”“求柱状图最大矩形面积”这类题里几乎是标配解法。它的思路很朴素维护一个栈让栈内元素保持单调递增或递减当新元素破坏了单调性就弹出栈顶元素同时栈顶元素的“答案”就是当前新元素。这个算法在事件驱动编程、广告投放的候选排序里也有点影子。笔试里如果遇到单调栈的题注意栈里存的是下标不是值。这一个小差别对应了“我要知道当前元素和栈顶元素之间的距离”的需求。你不存下标算面积或者距离就算不出来。这个细节新手很容易踩坑。多线程安全计数器是我要特意提的一道题它已经不属于纯算法的范畴而是考察并发能力。搜狗常出这类题要求写一个支持并发环境下线程安全的自增计数器。最简单的做法是加锁#include mutex class SafeCounter { public: int increment() { std::lock_guardstd::mutex lock(mtx_); return val_; } int get() { std::lock_guardstd::mutex lock(mtx_); return val_; } private: std::mutex mtx_; int val_ 0; };但如果你能更进一步用atomic实现无锁版本加分项会非常明显#include atomic class SafeCounter { public: int increment() { return val_.fetch_add(1) 1; } int get() { return val_.load(); } private: std::atomicint val_{0}; };为什么能这样改因为fetch_add和load都是原子操作不需要额外加锁。这个知识点涉及ABA问题、内存序、CAS操作如果你能顺带说清楚“atomic用的是CAS指令不是互斥锁”面试官会高看你一眼。我当年在项目里维护过一个全局计数器最开始用std::mutex压测发现并发上不去换atomic之后性能提升明显这个经验在笔试里直接变成了一道题的答案。4. 编程题实战三道高频题的完整推导4.1 题目实现一个字符串循环右移函数这是我在多个版本回忆帖里都看到过的题考法挺直白实现函数void rightRotate(std::string s, int k)把字符串循环右移k位。题面允许你使用额外空间但要求尽量O(1)空间。第一种思路利用std::string的substr拼接。缺点是使用了O(n)的额外空间而且如果题目要求原字符串翻转这种方式会被判超时或者内存超限。第二种思路就是我在前面写的三次反转法空间O(1)时间O(n)是这道题的满分答案。第三个容易犯的错误如果允许k是负数表示左移方向相反需要在代码开头额外判断。虽然大部分笔试用例不会卡这一点但作为一个追求稳健的工程师写防御性代码总没有坏处。我还会习惯性在函数开头加上对空串的检查。很多线上笔试用例会用空字符串来测试边界条件如果不处理s.size()为0时取模会直接出错。这个看起来很小的细节往往决定你是不是能一次通过全部用例。4.2 题目删除链表的倒数第N个节点这道题在LeetCode上也是经典中等题搜狗笔试出现频率同样不低。题面要求一次遍历删除倒数第N个节点。既然是倒数很多人下意识会想到先遍历一遍求出链表长度再删除正数第len-N个节点。但题目要求一次遍历所以需要用双指针第一个指针先走N步然后两个指针同步前进当第一个指针走到链表末尾时第二个指针正好指向要删除节点的前一个节点。这里有一个经典陷阱删除的是头节点。如果第一个指针走完N步后已经走到空指针说明倒数第N个节点就是头节点此时直接返回head-next就行。我写这道题的代码时习惯用一个哑节点dummy指向head这样统一处理删除头节点和删除中间节点逻辑简洁很多面试官看着也舒服。ListNode* removeNthFromEnd(ListNode* head, int n) { ListNode dummy(0); dummy.next head; ListNode* first dummy; ListNode* second dummy; for (int i 0; i n; i) { first first-next; } while (first-next ! nullptr) { first first-next; second second-next; } ListNode* toDelete second-next; second-next toDelete-next; delete toDelete; return dummy.next; }注意最后一个细节返回的是dummy.next而不是head。因为当删除的是头节点时head已经被delete掉了再返回它就是悬空指针。这个坑我当年在牛客网上刷题时踩过那之后凡是涉及链表头节点可能变动的题目我全部用哑节点方案。4.3 题目用生产者和消费者模型描述C多线程编程这题在搜狗笔试里出现得比较巧妙可能不出成编程题而是以一个问答题的形式出现请使用C11及以上标准实现一个多线程的生产者消费者队列并说明你的方案如何避免竞态条件。核心解法是互斥锁加条件变量。生产者往队列里push消费者从队列里pop当队列为空时消费者需要等待。C11提供了std::condition_variable配合std::unique_lock流程固定如下#include queue #include mutex #include condition_variable templatetypename T class BlockingQueue { public: void push(const T item) { { std::lock_guardstd::mutex lock(mtx_); queue_.push(item); } cv_.notify_one(); } T pop() { std::unique_lockstd::mutex lock(mtx_); cv_.wait(lock, [this] { return !queue_.empty(); }); T item queue_.front(); queue_.pop(); return item; } private: std::queueT queue_; std::mutex mtx_; std::condition_variable cv_; };有几个细节值得展开说。第一void push里我用了两个代码块来限制锁的粒度先把item压进队列就释放锁再通知消费者。如果你把notify放在加锁区域内消费者被唤醒后去抢锁还是要等生产者解锁等于白醒一次白白增加上下文切换。第二pop里用cv_.wait(lock, predicate)而不是裸wait(lock)是因为条件变量存在“虚假唤醒”的可能。你用predicate多检查一次队列是否真的非空这个严谨性写上去就是和普通写代码的分水岭。第三析构函数里需要唤醒所有等待线程否则程序退出时会有线程卡死。这个方案在搜狗常见场景里有直接对应输入法候选词的后台扩展、搜索日志的异步写入都依赖这种线程安全队列来解耦生产端和消费端。笔试能写出线程安全队列再往业务上扯一句应用场景本身就是对“校招”这个身份的加分项。5. 考试之外的硬功夫环境、调试与设计模式5.1 本地开发环境与编译选项虽然笔试是在线上环境里进行但你在本地准备的时候一定要把开发环境调得跟线上接近避免因为本地能编译、线上编译不了这种问题翻车。近几年的热搜词里VSCode配置C/C环境一直是高频话题说明现在还是有很多人在这一步卡壳。我用的是VSCode加MinGW-w64这套组合重点在于三处配置c_cpp_properties.json里设置编译器路径和C标准tasks.json里配置编译任务launch.json里配置调试器。编译命令建议显式写成g -stdc17 -O2 -Wall -Wextra main.cpp -o main-Wall和-Wextra会把潜在警告全列出来平时写题可能觉得吵但备考阶段开着比较安心。笔试时编译器可能没有任何警告提示本地养成习惯后代码质量会明显优于裸写。还有一个容易忽略的事如果你的Windows机器装的是Visual C Redistributable系列运行库那只是让编译后的exe能跑起来和实际编译环境是两码事。很多人误以为自己装了运行库就能用g编译这是环境准备期最大的误区。5.2 设计模式与回调函数搜狗笔试对设计模式的考察不算深但偶尔会出选择题。常考的是单例、工厂、观察者、策略这几种。我遇到过一个题目问的是“在多线程环境下实现单例需要考虑什么”答案牵扯到双检锁、静态局部变量初始化、原子指针。如果你能写出来静态局部变量版本的线程安全单例那就很稳class Singleton { public: static Singleton getInstance() { static Singleton instance; return instance; } Singleton(const Singleton) delete; Singleton operator(const Singleton) delete; private: Singleton() {} };C11标准规定函数内静态局部变量的初始化是线程安全的所以这个写法既简洁又正确比双检锁容易理解得多。我个人的建议是设计模式的备考关键词是“名字场景代码骨架”不需要过度背诵但至少看到题目能反应过来它考的是哪种模式。回调函数在笔试里也经常出现本质就是函数指针、std::function或者lambda表达式。搜狗可能会让你写一个简单的回调示例比如某个事件发生时调用一个外部传入的函数。这里要特别注意回调的生命周期问题如果回调里捕获了this指针或者引用一旦对象销毁后回调仍然被调用就会产生悬空引用。笔试不会让你跑起来看崩溃但面试官会在后续追问里深入这一点。5.3 内存泄漏与智能指针C工程笔试的另一个隐藏考点是内存管理尤其是你写完代码后面试官一定会追问“你的代码有没有内存泄漏”。所以在练习阶段凡是手动new出来的对象都要想一想delete在哪里。笔试的时候建议优先使用智能指针std::unique_ptr和std::shared_ptr在C11之后已经成为标配。如果你写一个函数返回动态分配的对象直接返回std::unique_ptr比裸指针更符合现代C风格。我见过一道回忆版的选择题问“下面哪段代码会自动释放内存”特意把裸指针、unique_ptr、shared_ptr混在一起。这个知识点本身不难但它背后代表的安全编程习惯才是真正的考察目的。你要是能主动说出“C的RAII机制让资源管理变得更安全”这类题目就完全没法难倒你。还有一点值得注意搜狗每年校招的进程里代码review和面试环节往往会围绕笔试代码展开。这意味着你写在试卷上的代码可能会被打印出来面试官看着你的代码问你“这里为什么不用智能指针”。如果你在笔试时就把代码写得现代、规范后面能省掉不少麻烦。6. 应试策略与复盘清单6.1 时间分配与做题顺序结合回忆版的题量和难度我给出一套亲测有效的时间分配策略总时长150分钟前60分钟解决全部选择题剩下90分钟留编程题。选择题遇到完全不会的直接蒙一个赶紧跳别回头改。很多时候第一直觉是对的越是反复纠结越容易改错。编程题的做题顺序也有讲究。先写自己最有把握、代码量最小的题目建立信心。第二写需要思考但思路清晰的题目最后再啃最难的。如果时间剩得不多哪怕只写出核心函数和关键逻辑也把代码框架摆在编辑器里别留空题。判卷系统给出的0分和部分分之间差的往往只是你有没有写下那几句核心代码。我考场上有一个习惯拿到编程题先花五分钟在纸上列出输入输出、边界条件、特殊用例然后再动键盘。这个过程能有效降低写代码时的返工率。实际执行下来代码一次跑通的概率比直接上手高很多。6.2 复盘清单与延伸追问考完试当天不要对答案但第二天一定要完整复盘。我的做法是自己建一个表格把每个错题归类到“语法”“算法”“系统设计”“并发”“网络”这几列里看看自己的薄弱环节到底在哪。如果你选择题错得最多的是网络相关那说明你复习的时候OS和网络的优先级可以提前如果你反复死在一些C语法细节上那就可以《C Primer》的对应章节再刷一遍。这里附上一个核心考点速查表基本覆盖搜狗2017校招笔试的全部主线内容知识领域高频考点备考建议C语言虚函数、对象内存布局、static、constexpr、移动语义认真读一遍C Primer对应章节配合在线小题练习STLvector扩容机制、迭代器失效、map底层红黑树手写一个简易vector加深理解数据结构链表反转、找环、栈、队列刷LeetCode链表和栈的经典题算法二分、快速幂、单调栈、双指针、字符串匹配每类总结一个模板反复默写操作系统进程线程、死锁、内存碎片、缓存一致性结合多线程编程实践来复习并发原子操作、互斥锁、条件变量、线程池手写一个线程安全队列网络TCP三次握手、HTTP状态码、DNS流程画流程图辅助理解配合抓包加深记忆设计模式单例、工厂、观察者、策略每个模式写一个可运行的最小示例工程能力内存泄漏、智能指针、RAII、回调生命周期定期写小项目保持代码手感6.3 推荐复习Roadmap四周冲刺方案如果你想系统性准备接下来十来天的校招笔试我给一个简单的四周方案。第一周专攻C语言基础和内存模型第二周刷数据结构和算法第三周集中解决操作系统和并发编程第四周练习整套模拟卷并复盘错题。把每天拆成三个小时一个小时看书补概念、一个半小时写代码、半个小时整理错题。我个人觉得最关键的一点是练代码必须动手敲不能只看。看一百道题的题解不如自己手写十道。笔试考场上你会紧张、会手抖只有形成条件反射的代码才可能稳定输出。我当年备考时用了很笨的办法把高频题目的代码模板反复默写直到不再需要思考就能准确写出来。这套搜索、输入法背景下的C笔试试卷放到今天依然值得研究。它不偏不怪考点全部落在真实的工程场景里答完你会对自己“到底会不会写C”有一个非常诚实的判断。备考之余多写几个小项目多踩几个内存和并发的坑比疯狂刷题更能带给你底气。最后分享一个我踩过几次坑之后养成的习惯在线笔试开始前无论平台提不提醒先看一眼编译环境默认的C标准。如果默认是C14或者C17就可以放心用lambda、auto、智能指针如果平台比较老只支持C11那就要避免使用C14之后才引入的语法特性。这个小细节可能直接决定你某道题能不能通过编译。祝你笔试顺利写出的代码一版通过。
返回列表