ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

百度核心系统工程师笔试复盘:考点拆解与备战指南

百度核心系统工程师笔试复盘:考点拆解与备战指南 2019年校招季我投了百度核心系统工程师这个岗位拿到第一批笔试的时候说实话有点懵。这套卷子和市面上常见的后端开发笔试题完全不是一个画风没有框架八股没有微服务调优扑面而来的全是操作系统、网络协议、分布式一致性甚至还有不少Linux底层和性能分析的内容。今天这篇复盘我就给还在准备系统工程师、基础架构方向校招的学弟学妹们拆一拆这套题到底在考什么、每种题型的核心套路是什么以及我在实际做题过程中踩过的坑和总结出来的复习方法。先说明一下具体题目细节属于回忆整理我不会逐字复述原卷而是把这批题里最典型、最有区分度的考点拿出来做深度拆解。你只要照着这个方向准备即使后面题目形式变了核心得分点也不会跑偏。1. 试卷整体结构与命题思路拆解1.1 核心系统工程师岗位到底在招什么人百度“核心系统”这几个字对应的是底层基础设施方向包括大规模分布式存储、消息队列、统一调度、内核网络优化这些方向。笔试筛选的不是“会写CRUD的人”而是能吃透底层原理、能扛住极端场景的人。我当时理解到这一点之后整张卷子就越做越顺了。比如操作系统的题不会只问你“什么是死锁”而是给你一个多线程程序让你分析锁的持有顺序、条件变量使用的对错。网络题不会只让你背三次握手而是给出tcpdump抓包结果让你判断连接为什么卡在SYN_RECV。所以准备这批题第一要务是把“原理”和“现象”绑定起来不能停留在名词解释层面。岗位本身决定了题目范围。核心系统工程师平时打交道最多的是Linux服务器、内核参数、网络协议栈、分布式组件以及海量数据下的性能问题。所以操作系统、计算机网络、数据结构算法、分布式系统这四块基本占了整张卷子80%以上的分数。剩下的编程题也往往不是纯算法竞赛题而是带工程背景的题目比如多线程日志、海量数据去重、缓存淘汰。这意味着你光会刷LeetCode还不够还得有把算法放到真实场景里落地的能力。1.2 第一批笔试题型与考点分布从题型来看第一批笔试主要分三块客观题、简答题、编程题。客观题包含单选和多选覆盖面很广但每题分值不高简答题通常要求写方案或分析原因是拉开差距的地方编程题一般两道左右一道偏算法一道偏系统设计或并发处理。我根据自己的回忆和同期同学的反馈整理了一张考点分布表大家可以对照着查漏补缺知识模块典型考点出现形式难度操作系统进程线程、内存分页、页面置换、死锁、零拷贝、IO模型选择、简答中高计算机网络TCP/UDP、三次握手四次挥手、TIME_WAIT、滑动窗口、拥塞控制选择、简答中高数据结构算法链表、LRU、TopK、哈希、布隆过滤器、二叉树遍历选择、编程中分布式系统CAP、Raft/Paxos、分布式锁、一致性哈希、缓存穿透选择、简答高语言底层C内存、智能指针、Go goroutine、并发安全选择、编程中Linux/工具常用命令、软硬链接、进程通信、系统调用选择低中注意这个分布不是官方的而是我根据考生回忆拼出来的。但它大致反映了核心系统工程师岗位的考察逻辑宁可多考基础也不考花哨框架。另外这批题有一个很明显的特征客观题喜欢在“看似简单的结论”上做文章。比如问你TCP主动关闭连接的一方会进入什么状态答案可能不是CLOSE_WAIT而是TIME_WAIT。如果你只是背过“四次挥手”但没理解谁主动谁被动很容易被绕进去。我建议做这类题的时候尽量把连接状态图、内存管理图都亲手画一遍不要只靠脑子记。1.3 和普通后端开发笔试的最大区别我之前也刷过不少后端开发岗位的笔试题对比之下核心系统工程师的题目有两点明显不同。第一不考Web框架不考业务设计。普通后端笔试可能会问“如何设计一个秒杀系统”“JVM调优参数怎么设置”但这套卷子基本不碰这些。它更关注的是消息队列的可靠性、文件系统读写延迟、多线程并发下的性能瓶颈这类问题。因为核心系统工程师写的代码往往要跑在成千上万台服务器上一个锁粒度没控制好可能就是全集群的性能事故。第二对“量级”极度敏感。普通开发题可能让你设计一个日活百万的系统核心系统题动辄就是百亿级数据、千台机器。我记得有一道题涉及海量URL访问频次的统计如果没做过内存估算很容易写出一个直接OOM的方案。后面我会专门讲这种题的完整计算过程这是很多人复习时最容易忽略的部分。如果你已经决定走系统工程师方向建议把复习重心从“应用层解题”切换到“原理层理解”。在读源码、看面经、做笔试复盘的时候多问自己一句为什么底层要这样设计换一个场景会有什么问题这套卷子筛的就是这种思维方式。2. 高频考点深度拆解原理、公式与避坑2.1 操作系统页面置换、零拷贝与IO模型操作系统在整张卷子里出现频率极高而且考察方式非常具体。我先说页面置换算法因为这是选择题里的常客也是很多人容易算错的点。经典的引用串训练题是7 0 1 2 0 3 0 4 2 3 0 3 2 1 2 0 1 7 0 1物理块数3。分别用FIFO、LRU、OPT去算缺页次数FIFO会缺15次LRU缺12次OPT缺9次。这个结果本身不重要重要的是你要知道为什么LRU比FIFO更接近最优。FIFO只看进入内存的先后完全不考虑“近期是否被访问”LRU则假设“最近用过的数据未来大概率还会用”所以每次淘汰最久没被访问的页。实际系统里不可能精确记录所有页的访问时间所以才会出现Clock算法这种近似实现用访问位来模拟。笔试里如果给的是带访问位、修改位的Clock算法不要只数缺页还要注意置换指针的移动规则。我记得当时有同学就因为没搞清“第一轮只找访问位为0的页找不到才轮转”这个规则把整个算错了。另一个我印象很深的知识点是零拷贝。题目可能会问从一个文件读取数据再通过socket发送标准readwrite做了几次拷贝和几次系统调用答案是四次上下文切换、四次数据拷贝两次DMA两次CPU拷贝。然后会问mmap、sendfile分别减少了哪一次拷贝。这里我建议用一个类比来理解readwrite就像你要把一摞文件从A办公室送到B办公室中间必须自己先走到文件柜拿出来放到自己桌上再走到B办公室放下去。mmap相当于文件柜和你的办公桌共用一块玻璃板你不需要自己誊抄直接指给B看。sendfile更极端让专门跑腿的人DMA直接帮你搬你只需要下个指令。理解了数据流选择题基本不会错。IO模型也是必考项。阻塞IO、非阻塞IO、IO多路复用、信号驱动IO、异步IO这五种要能讲清楚区别尤其是同步和异步的分界线。epoll在笔试里的高频追问是水平触发LT和边缘触发ET有什么区别ET模式为什么效率高但容易漏事件我当时是这么记的LT模式下只要缓冲区还有数据epoll_wait就反复通知你ET模式下只有状态发生变化时才通知一次。所以ET模式要求你把数据一次性读完否则剩下的数据可能要等下次新事件到来才会再被通知。实际工程里ET模式更接近“有消息就来一次”的高效模型但处理复杂度更高。笔试问到的时候把“事件驱动、边缘触发、循环read直到EAGAIN”这几个关键词打出来基本就是标准答案。2.2 网络协议TCP状态机与握手细节网络部分的难度比校招平均水平高一截。这里不是说题目多偏而是细节抠得很深。三次握手、四次挥手这种基础题不多说我重点讲几个容易丢分的变体。一个很典型的题客户端主动关闭连接过程是客户端先发FIN服务端回ACK服务端再发FIN客户端回ACK。此时客户端进入TIME_WAIT状态要等待2MSL才能完全关闭。题目可能会问为什么TIME_WAIT要等2MSL标准答案有两个层面一是保证最后的ACK能到达服务端万一ACK丢了服务端会重发FIN客户端还能再回一次二是让旧连接产生的所有报文段在网络中自然消失防止污染新连接。另一个常见坑是SYN队列和Accept队列。服务端收到SYN后先放入半连接队列完成三次握手后移入全连接队列然后由accept()取出。如果半连接队列满了新连接会被丢弃或忽略表现为客户端一直处于SYN_SENT服务端看不到连接建立。题目如果给你一个线上故障大量连接处于SYN_RECVCPU不高但连接建不起来大概率是SYN队列被打满或者backlog设置太小。答这类题要抓住“队列长度、内核参数、攻击/并发”几个关键词。TCP相关还有一个必须会的计算题在已知带宽和RTT的情况下估算最大吞吐量。公式很简单吞吐量上限 ≈ 窗口大小 / RTT。比如窗口是64KBRTT是10ms那最大吞吐量就是 64KB / 10ms 6.4MB/s。如果题目再升级问你带宽100Mbps、RTT 20ms时窗口至少多大才能打满带宽那就要反过来算100Mbps × 0.02s 2Mbit 250KB。这个换算关系在TCP性能调优里经常出现笔试也很喜欢出因为能同时考察你对单位换算和TCP滑动窗口的理解。另外我看到不少人在TCP拥塞控制上只背了“慢启动、拥塞避免、快重传、快恢复”几个名字但遇到“什么时候进入拥塞避免、ssthresh怎么变”就懵了。建议把拥塞窗口随RTT变化的曲线画一遍把“慢启动阈值减半”“窗口置为1”这些操作对应到具体流程里。如果时间允许再看一下CUBIC和BBR的不同这已经属于加分的深度了。2.3 数据结构与算法TopK、LRU与布隆过滤器算法选择题难度不大但编程题往往和“海量数据”绑定。我先把三个最高频的考点讲透。第一个是TopK问题。给你100亿个查询串统计出现频次最高的100个。直接的排序肯定不行100亿个字符串本身就是几十TB的规模单机内存装不下。正确思路是分而治之先哈希取模分片到多台机器或多个文件每个分片内用哈希表统计频次再用大小为K的小顶堆找到该分片的前K个。最后把所有分片的K个候选聚合再做一次TopK。这里面有几个关键点哈希分片要保证同一个key一定进同一个分片所以用hash(key) % N每个分片只要保留前K个不用存全量小顶堆的堆顶是当前最小只有比堆顶大的元素才替换入堆。第二个是LRU缓存淘汰。这个属于“必背级”手写题。核心结构是哈希表加双向链表。哈希表负责O(1)查找双向链表负责O(1)删除和移动。每次get把节点移到链表头部每次put如果容量满了先删除链表尾部节点再插入新节点到头部。写代码的时候最容易犯的错是删除节点时忘记同步更新哈希表或者移动节点时指针指错。我建议在本地把这题练到五分钟内无脑默写出来不只因为它是笔试高频题更因为面试几乎必问。第三个是布隆过滤器。它用多个哈希函数把key映射到一个位图上。判断“不存在”是100%准确的但判断“存在”可能有误判。公式需要会算位数组长度m和哈希函数个数k在元素量n和目标误判率p下的关系是位数组长度m ≈ - n × ln(p) / (ln2)^2哈希函数个数k ≈ (m / n) × ln2假设你有1000万个key希望误判率控制在1%那m大约为95850583 bit也就是接近12MBk取7个左右。这个结果反直觉1000万个key只要12MB就能挡住绝大多数无效查询。笔试如果让你设计一个缓存穿透方案布隆过滤器是标准答案之一答的时候最好把误判率为什么存在、怎么权衡空间和准确率讲清楚。2.4 分布式系统CAP、Raft与分布式锁分布式系统模块是这套卷子里区分度最高的部分也是核心系统工程师日常工作中避不开的知识。先说CAP这里最大的坑是“C、A、P三选二”这种粗浅理解。CAP里的C是一致性A是可用性P是分区容错性。在网络分区发生时你只能在一致性和可用性之间取舍不允许既保证所有节点数据一致、又保证所有节点都能继续服务。分区不是可选项而是必然发生的情况所以设计系统时真正做的是“在P存在的前提下选择C还是A”。Raft算法也是高频考点。它比Paxos容易理解但笔试问到选举过程时依然有人答不全。核心流程所有节点初始是Follower如果超过选举超时时间没收到Leader心跳就变成Candidate给自己投票并请求其他节点投票。获得超过半数投票的节点成为Leader。之后Leader负责接收客户端请求、复制日志到Follower、在大多数节点写入成功后提交。这里要注意一个细节任期term是递增的投票只能在同一个任期里进行日志复制要求方向只能是Leader到Follower不能反过来。能把这些讲清楚Raft的基础题基本稳了。分布式锁也是必考题。它考察的不只是Redis的SET key value NX EX更关键的是锁的“安全性”。我会从三个方案递进分析Redis SETNX实现简单易用但要注意不能只SETNX不设过期时间否则持有锁的进程挂掉就死锁了。设过期时间后又要注意业务执行时间超过锁超时时间的问题可能有多个进程同时进入临界区。Redlock红锁向多个独立Redis实例申请锁超过半数成功才算拿到。它能降低单点风险但依然不是绝对安全的分布式锁因为GC停顿可能让锁过期。ZooKeeper临时顺序节点创建临时顺序节点只有序号最小的节点能拿到锁其他节点监听前一个节点。因为临时节点在会话断开时会自动删除所以能避免“持有者挂掉不释放”的问题。笔试如果让你比较分布式锁方案不要只说某个方案好。要把“可靠性、性能、实现复杂度、应用场景”都摆出来展示你是在做工程选型而不是在背书。2.5 语言底层C内存管理与Go调度模型核心系统工程师的主要开发语言基本是C和Go所以笔试也会考察语言底层能力。C部分最常看到的是内存管理和智能指针。malloc和new的区别必须能说清楚malloc只分配原始内存不调用构造函数new会分配内存并调用构造函数。free和delete对应也要匹配混用是未定义行为。然后就是shared_ptr、unique_ptr、weak_ptr的区别。记住一句话unique_ptr独占所有权移动语义shared_ptr引用计数可以有多个所有者weak_ptr不增加引用计数用来打破循环引用。选择题如果问循环引用怎么解决答案往往是weak_ptr。还有一个隐蔽考点是“内存泄漏”。笔试里可能会给一段代码让你找泄漏点。常见的套路是new了对象但没delete或者shared_ptr相互引用导致计数永远不为0或者异常路径上忘记释放资源。答这类题最好顺手写出用RAII解决的方式这样即使选择题错了简答也能拿分。Go部分主要考goroutine和channel。GPM模型是必讲内容G是goroutineP是逻辑处理器M是操作系统线程。goroutine不是线程而是运行在线程上的轻量级协程初始栈只有几KB可以通过grow stack动态扩容。笔试里如果问“十万个goroutine会不会把内存打爆”基于2KB初始栈十万个大概占几百MB如果是百万级就千万小心。实际更准确的说法是Go的groutine溢出栈和复用机制让它比线程轻量得多但也不是无限制创建。并发安全方面sync.Mutex、sync.RWMutex、atomic、channel要能区分使用场景。数据竞争检测也是常考概念Go的go run -race可以在运行时检测数据竞争笔试可能以填空或选择形式出现问你用什么工具检测。3. 典型大题实操思路从读题到答完3.1 编程题套路多线程并发日志收集第一批笔试里有一类编程题很贴近工程模拟多线程环境下多个worker产生日志由一个collector统一写入文件要求不能丢日志、不能乱序并且性能尽量高。看到这种题先别急着写代码拆解需求的时间一定要留够。主要考察三件事数据怎么从worker传到collector锁怎么加才能保证线程安全文件IO怎么优化才能减少磁盘写入次数。最简单的方案是每个worker持有一个锁写日志时直接互斥。这个方案正确但性能很差因为所有worker争一把锁高并发下锁竞争严重。更好的方案是每个worker用一个无锁队列collector统一从队列里取数据批量写入。如果考试时间紧张可以退一步写成“加锁批量缓冲”关键要体现出你意识到了锁粒度的性能问题。文件IO部分尽量不要每条日志都调用一次write而是攒一批再写。可以设置一个buffer比如4KB或8KBbuffer满了或者定时刷新才写入磁盘。选择小批量还是大批量又是个权衡批量太小系统调用频繁批量太大掉电丢数据的风险高。这种地方没有绝对正确的答案但要让阅卷人看到你在“性能”和“可靠性”之间做了取舍。我当时写这类题的固定套路是先写清数据结构再画关键流程最后补充互斥逻辑。如果时间不够代码可能写不完全但设计思路写出来也能拿一半分。3.2 海量数据TopK题目的完整计算过程海量数据题最怕的不是算法不熟而是数字算不过来。我给你完整演示一道典型题的计算过程这类题非常容易在第一批笔试中出现。题目场景大概是有100亿条URL访问记录每条URL平均长度64字节统计被访问次数最多的100个URL。你的机器内存只有4GB单机处理。第一步算原始数据量100亿 × 64字节 6400亿字节 640GB。单机内存4GB肯定存不下所以必须先分片。第二步设计分片数量。如果分成1000个小文件每个文件约640MB已经超过内存但还可以通过流式处理。如果分成2000个小文件每个约320MB可以分批读入。这里分片数量不是越大越好文件太多会带来大量随机IO文件太少又装不进内存。我建议宁多勿少因为小文件读进内存做哈希统计时哈希表本身也有额外内存开销一个URL key存80字节左右320MB文件里可能就有几百万条记录哈希表会膨胀到远超文件本身。第三步每个小文件用哈希表统计词频再用大小100的小顶堆保留该文件的Top100。这个阶段每个文件只需要输出100个候选所以最终候选只有 2000×100 20万个聚合排序完全没问题。最后一步把20万个候选再统计一次得到全局Top100。这道题答到这里已经把“哈希分片、小顶堆、内存估算、IO模型”全部串起来了比只写“用MapReduce”要实在得多。3.3 系统设计题的答题框架以短URL为例简答题里比较常见的是“给一个场景让你给出系统设计方案”。我当时遇到的是短URL方向但换成长链接、消息队列、Redis缓存也一样。你只要掌握一套固定的答题框架就能应对大部分设计题。我的框架是四步走需求分析、容量估算、方案选型、细节补充。需求分析要先搞清楚量级。假设每天新增1亿个短URL每个短URL平均被访问10次那3年累计数据量就是1000多亿条。存储上必须分库分表缓存层至少需要支撑每秒约10万次读请求。容量估算是很多人的薄弱点。1亿个短URL每个映射关系存原URL和一个7位短码大概按128字节算一天1.28GB3年约1.4TB。如果只用单机MySQL早就爆了所以要用分布式KV或分库分表。缓存方面如果每天访问量为10亿次缓存命中率做到95%那Redis集群每秒要扛大约5000次写和10万次读需要评估单个Redis实例的能力后设计集群规模。方案选型是拿分重点。生成短码可以采用发号器方案用数据库自增ID或雪花算法生成全局唯一ID再转成62进制短码。优点是无冲突、查询快缺点是发号器本身可能成为性能瓶颈。另一个方案是直接对原URL做哈希比如MD5取前7位优点是去中心化但存在哈希冲突需要碰撞检测和重试。最后在细节补充里答题把缓存穿透、永久重定向、恶意请求防护这些点提一遍会显得考虑更周全。如果笔试时间紧张至少把容量估算和方案选型写出来已经能打败很多人了。3.4 手写LRU Cache边界条件才是得分点LRU Cache是笔试编程题出现频率最高的一道没有之一。我不光说原理直接给一个能跑的参考实现然后讲边界条件。class Node: def __init__(self, key0, value0): self.key key self.value value self.prev None self.next None class LRUCache: def __init__(self, capacity: int): self.capacity capacity self.cache {} self.head Node() self.tail Node() self.head.next self.tail self.tail.prev self.head def _remove(self, node): node.prev.next node.next node.next.prev node.prev def _add_to_head(self, node): node.prev self.head node.next self.head.next self.head.next.prev node self.head.next node def get(self, key: int) - int: if key not in self.cache: return -1 node self.cache[key] self._remove(node) self._add_to_head(node) return node.value def put(self, key: int, value: int) - None: if key in self.cache: node self.cache[key] node.value value self._remove(node) self._add_to_head(node) return if len(self.cache) self.capacity: lru_node self.tail.prev self._remove(lru_node) del self.cache[lru_node.key] new_node Node(key, value) self.cache[key] new_node self._add_to_head(new_node)这段代码里最容易出细节分的地方有三个。第一个是get操作时如果key存在除了返回值还要把对应节点移到链表头部。这是LRU的核心语义最近被访问过就不能被优先淘汰。漏写这一步整个数据结构就退化成了普通缓存。第二个是put已存在的key时要先更新value再移动到头部。顺序不能反如果先移动再更新代码逻辑也能跑但读起来不清晰而且容易在复杂版本里引入bug。第三个是容量满时要先删除尾部节点再从哈希表里删除对应key然后插入新节点。删除链表节点和删除哈希表条目必须成对出现漏一个就会造成内存泄漏或哈希表脏数据。建议在本地多写几遍把链表操作的四个指针连接练到肌肉记忆。4. 时间分配、常见失误与备战建议4.1 三个小时笔试的时间分配策略这套卷子整体题量不小我记得做完时候大概还剩10分钟检查。时间分配我建议按下面的节奏来已经经过自己和多位同届同学的验证前40分钟处理选择题和判断题。这类题要不要纠结我的经验是超过2分钟还没思路的题先标记跳过后面如果有时间再回头。因为选择题单位时间得分效率不高不值得为一道题影响大局。接下来50分钟做简答题。简答题重点是框架清晰每个小问尽量写2到4个要点。如果一道简答10分钟内没写完果断收尾进下一题宁可少写细节也不能空题。然后60分钟做编程题。先花10分钟读题和设计数据结构再开始写代码。最好先写能跑通的基本版本再去优化边界和性能避免一上来追求完美导致最后连基础版都没写完。最后30分钟检查。重点看三个地方有没有漏题、编码格式对不对、有没有明显语法错误或数组越界。这套时间分配最大的价值在于它保证了你不会在某个难题上耗到最后一题空着。校招笔试的淘汰逻辑是“基础题不能错难题尽量拿部分分”不是“必须AC全部题目”。4.2 最容易丢分的几个低级错误先列一个我亲眼见过以及自己踩过的错误清单每一条都是用分数换来的。多选题漏选或错选。选择题是多选时不确定的选项宁少选不多选因为少选还可能得部分分错选直接0分。不写单位。凡涉及容量、带宽、内存的题目必须写KB、MB、Mbps、ms。漏掉单位哪怕计算过程全对也可能因为表达不严谨扣分。简答只有结论没有推导。比如问“为什么不能直接三选二”只写“CAP不可兼得”完全没用要把分区容错的前提和取舍逻辑写出来。编程题不处理输入边界。空链表、容量为0、key不存在、并发调用。这些边界就是笔试和面试都爱深挖的细节。没看清楚“手写全代码”还是“写伪代码”。如果要求手写全代码就不要用注释代替实现如果只是思路题也不要花大量时间抠代码细节输出结构完整的设计更重要。除此之外还有一个容易被忽略的坑代码题里使用了C的map、Go的map或Python的dict要留意线程安全性。如果题目要求多线程场景使用非并发安全的数据结构一定要自己加锁。这一点很容易让阅卷人觉得你缺乏工程经验。4.3 留给后来人的备战清单如果你想认真准备这类核心系统工程师笔试我建议按以下清单复习顺序也是优先级从高到低操作系统进程线程、调度、死锁、虚拟内存、页面置换、IO模型、零拷贝。做到能不看笔记画出整个数据流。计算机网络TCP状态流转图、握手挥手、TIME_WAIT、拥塞控制、epoll的LT和ET。这是笔试和面试双高频。数据结构与算法LRU手写、TopK、布隆过滤器、哈希表、链表操作。至少完成LeetCode上关于LRU、LFU、前缀树这些经典题。分布式系统CAP、BASE、Raft选举、分布式锁、一致性哈希。不用追求源码级理解但关键流程要能背能画。语言底层C的new/malloc、智能指针Go的goroutine调度、channel、sync包。选一个主语言深入另一个了解核心概念。Linux基础常用命令、awk/sed、性能排查工具top/vmstat/iostat。有些选择题会直接考命令输出含义。这些内容不算多但每个点都要能“讲给别人听”。我复习时有个笨但有效的方法每学完一个模块假装自己在给室友讲题用大白话把原理说清楚。如果讲到一半卡住说明理解还没到位回头再看。个人体会这批笔试给我的最大感受是它不像普通校招卷那样考“你刷过多少题”而是考“你有没有真的理解计算机系统”。很多题没有绝对标准答案比如分布式锁该选Redis还是ZooKeeper只要你能把权衡讲清楚就能拿分。所以准备过程中不要只记结论要多问“为什么”和“在什么场景下会出问题”。最后再分享一个小技巧刷题遇到不会的知识点不要马上看答案先凭已有知识写一个“我认为的答案”再对照资料修正。这个过程留下的印象比直接背答案深刻得多。祝备战校招的各位顺利拿到心仪的offer如果这篇复盘对你有帮助那就是它最大的价值了。
返回列表