刚考完奇安信2020客户端开发工程师-Linux开发的线上笔试,趁热打铁把题目和思路捋一遍。先说结论:这份笔试题不偏不怪,考的全是Linux客户端开发天天要碰的底层基本功,C/C++基础、系统编程、网络编程占了大头,穿插Linux常用命令和调试手段,整体风格偏“底子检查”。如果你正在准备客户端或者Linux方向的校招笔试,这篇文章值得收藏起来,不光是真题回忆,后面还把我这两周备考踩坑换来的整理思路一并放上了。
先说下我的情况,供你对照参考:非科班,自学C/C++一年多,Linux环境用了大半年但基本都是“会用命令、没看源码”的水平。5月31日下午场的笔试,90分钟,题型是单选+多选+编程题+简答题。考完最大的感受是:题目本身不难,但考察面很宽,任何一个环节薄弱都会在考场上卡壳。
1. 奇安信这个岗位到底考什么:笔试之前的岗位拆解
我在投简历之前先干了件事——把“客户端开发工程师-Linux开发”这个岗位描述拆了一遍。别小看这一步,它直接决定我这段时间复习的方向。如果连岗位要干什么都不清楚,指望考前突击刷题,大概率是白费。
1.1 从JD反推技能树
“客户端开发”这四个字看着简单,但在Linux平台上,它跟Windows客户端的套路完全不一样。Windows那边有Visual Studio全家桶、MFC、Qt Creator拖控件,你有一半精力在处理UI和系统API;Linux客户端这边更贴近“服务端视角”,你写的程序通常跑在桌面环境或者嵌入式设备上,要自己处理内存、进程、网络、日志,甚至要用命令行工具去排查问题。
从奇安信这家公司的安全背景倒推,Linux客户端开发大概率涉及这几个方向:终端安全产品(比如EDR、杀软客户端)、日志采集与上报、网络流量分析组件、系统监控模块。所以C/C++基础、文件操作、进程管理、网络通信、多线程这些考点几乎必然会出现。我当时给自己定的复习重点就是:C/C++语言细节、Linux系统编程、TCP/UDP网络编程、常用命令与调试工具,顺序按优先级排。
1.2 笔试考察侧重点:为什么这么考
很多同学备考喜欢抱着leetcode猛刷,觉得算法题做多了就能过关。但奇安信这份笔试题给我的感觉是:算法题比重不大,更看重“系统底层理解”。选择题里频繁出现的文件权限、进程状态、内存布局、网络状态机,这些靠刷题是刷不出来的,必须在真实Linux环境里跑过、看过、踩过坑才有感觉。
我后来回看这份卷子,它想筛选的人大概长这样:能用C/C++写Linux服务或客户端,能读懂系统报错并排查问题,对网络协议和并发有基础认知,出了bug知道怎么用工具定位。换句话说,它考的不是“你会不会写代码”,而是“你能不能在这个岗位上直接干活”。
1.3 备考资料的取舍
我当时在网上搜了一堆“Linux面试题大全”“Linux命令大全”之类的资料,发现内容良莠不齐,有的纯粹是名词解释合集,背完等于没背。后来我调整了策略:以真题为圆心,把每道题对应的知识点在Linux里实机操作一遍。
比如看到“find命令按文件名查找”,我不会只记参数,而是真的去建几个目录、放几个文件,把 -name、-type、-mtime、-exec 全跑一遍。看到“chmod 755 是什么意思”,我会新建用户、切换权限、用 ls -l 观察权限位变化。这样记忆远比背表格牢固,面试时被追问也不慌。这份卷子能答得七七八八,跟这个“实机验证”习惯有直接关系。
2. 笔试现场实录与题型复盘
下面进入正题,说说我印象里比较深的题目类型和具体考点。题目顺序记不太清了,细节凭记忆还原,但考察的知识点我反复核对过,基本准确。
2.1 选择题:Linux基础占了大头
选择题大概是30道左右,单选多选混在一起,多选少选都没分,这个要格外注意。考到的点我列一下:
- 文件权限:给出
-rw-r--r--让你说出所有者、所属组、其他人的权限,以及chmod 755和chmod u+x有什么区别。这题属于送分题,但如果你没在终端里敲过ls -l,可能连第一列字段的顺序都说不清。 - 进程与线程:问进程和线程的区别、线程共享哪些资源不共享哪些资源。多选里有一道“线程不共享的是哪个”,选项有堆、栈、全局变量、文件描述符,答案是栈,这个容易错。
- 僵尸进程与孤儿进程:问子进程先退出、父进程没调用wait(),子进程会变成什么。这个考点几乎必考,后面第3章我详细拆。
- 内存布局:问C程序的内存分区,全局变量和局部静态变量分别存在哪,堆和栈的生长方向。
- TCP连接:三次握手、四次挥手,问TIME_WAIT出现在哪一端、为什么要出现。这个也是高频考点,客户端开发对接网络的时候尤其会碰到。
- Linux常用命令的冷门参数:比如
find按大小查找用什么参数、tar解压到指定目录用哪个选项、grep显示匹配行行号用哪个选项。这种题不难,但平时不用就真的会卡住。
2.2 编程题:手撕代码没含糊
编程题好像是两道还是三道,我印象深的有这么几道:
- 字符串反转并去重:给一个字符串,要求反转顺序同时去掉重复字符。看起来简单,但复杂度要求不能太高,不能开额外数组硬存去重结果,我当时用了一个
bool标记数组记录ASCII码是否出现过。 - 手写LRU缓存:要求实现 get 和 put 两个方法,容量固定,超出容量要淘汰最久未使用的。这道题我在牛客题霸上刷过,用的是“双向链表+哈希表”的组合。
- 多线程交替打印:两个线程交替打印奇数和偶数,打印到100。考察线程同步的经典题,可以用互斥锁加条件变量做,也可以用一个原子变量自旋做。
编程题的环境是普通在线编辑器,不是IDE,没有补全提示,所有代码纯手打。平时如果习惯了IDE的自动补全,这里会很不适应,所以考前务必在纯文本环境下手写过几道题。
2.3 简答题:考的是排查思路
简答题不是背概念,而是给你一个实际场景,让你说出排查步骤。我记得有两道:
- 一个Linux进程CPU占用率持续100%,怎么排查?这题考的是工具链:先用
top看进程PID,再top -H -p PID看线程,再用perf或gdb attach看调用栈,定位到具体函数。 - 一个服务端口起不来,报“Address already in use”,怎么处理?被问到这个的时候我背后一凉,因为之前部署服务真遇到过。排查思路是
netstat -tunlp | grep 端口号找到占用进程,确认是否真的需要杀掉,或者临时换端口。如果要杀掉,用kill,杀不掉再kill -9,但也提到kill -9有风险,要确认进程没有重要数据要落盘。
这两道题如果只是在书上看过命令,没有真刀真枪处理过,答出来会很虚。面试官很容易接着追问“你当时是怎么发现是哪个进程占用的”,完全拿实操经验说话。
3. Linux方向高频考点逐题拆解
笔试考完,我复盘了一下,发现考到的Linux知识点其实可以串成一条线,从命令、文件、进程、内存、网络,一层一层往上。这一章把我在考场上遇到的高频考点展开讲讲,顺便补充一些实机验证的方法。
3.1 Linux常用命令的底层逻辑:别再背命令了
“Linux常用命令大全”这种资料我见过太多了,但把它们全部背下来没有意义。面试官想考的其实是你在什么场景下用什么命令、用了之后怎么看输出结果。比如ps aux和ps -ef输出字段略有不同,但很多人只背参数不背输出含义,考到ps aux里第几列是CPU使用率、第几列是内存使用率就懵了。
一个比较实用的学命令方法:按“场景”而不是按“字母表”学。比如“我想看这台机器上哪个进程最吃CPU”对应top加排序;“我想找一遍日志里包含error的行并统计条数”对应grep error file | wc -l;“我想把本机文件传到远端服务器”对应scp local_file user@host:/path。命令本身只是个工具,真正值钱的是你面对问题时的思路。
3.2 文件权限与目录操作:笔试必考的细节
文件权限几乎是Linux笔试前几道选择题里必出现的,原因很简单:客户端程序跑在用户态,经常要读写配置文件、日志文件、临时文件,权限不对程序就会崩。考场上考的是chmod 755的含义,我把这个拆一下:
755是三个八进制数字,分别对应所有者、所属组、其他用户的权限。每个数字由读(4)、写(2)、执行(1)三种权限相加得到。7=4+2+1,表示读、写、执行都有;5=4+1,表示只有读和执行,没有写权限。所以chmod 755 file的效果是:文件所有者能读写执行,其他人只能读和执行。对应ls -l显示就是-rwxr-xr-x。
另一个高频考点是“删除目录”。rm file删文件没问题,删目录必须加-r,也就是rm -r dir,否则会报 “cannot remove ‘dir’: Is a directory”。如果要强制删除不询问,加-f,所以rm -rf dir是一个高危命令,手滑一次可能把整个家目录都清空。笔试不一定会直接考,但面试官聊项目的时候会问“你有没有误删过文件”,如果你说用过这个命令还能活着,反而能证明你平时工作确实在操作Linux。
新建用户这块也常考,比如useradd test和adduser test有什么区别。在Debian系系统上,adduser是交互式创建用户的脚本,会自动建家目录、设置密码;useradd是底层命令,默认不建家目录,需要手动加-m参数。很多从CentOS切过来的同学在这里容易搞混。这类题目没有太多技巧,就是在实机上建一遍用户,看这两个命令的差别,比背十遍笔记都快。
3.3 进程与内存:僵尸进程、孤儿进程、共享内存与消息队列
笔试选择题里关于进程的坑,我总结下来就三个高频点:僵尸进程、孤儿进程、进程间通信方式对比。
僵尸进程是“子进程先退出,父进程还没来得及调用 wait() / waitpid() 回收它的退出状态,子进程就变成了Zombie状态”。它在进程表里还占着一个位置,但已经不执行任何代码了。如果父进程一直不回收,僵尸进程会越积越多,把系统进程表塞满,导致新的进程无法创建。笔试可能只问你“僵尸进程是怎么产生的”“怎么避免”,但面试极有可能追问“如果你的程序成了僵尸进程的父进程,怎么处理”。处理思路是:要么在代码里正确调用 waitpid(),要么直接把父进程干掉,让僵尸进程变成孤儿进程,被 init/systemd 收养并回收。
孤儿进程则是父进程先退出,子进程被系统“过继”给1号进程继续运行,不会变成无人管的状态。这两个概念放一起记就行,“僵尸是死了但没人收尸,孤儿是没人要但系统接管了”。
进程间通信那一块,考得比较多的是共享内存和消息队列的区别。共享内存是效率最高的IPC方式,因为它直接把物理内存映射到进程地址空间,省去了内核缓冲区的拷贝;但缺点是要自己处理同步互斥。消息队列是内核维护的链表,按消息类型读写,避免了共享内存的同步问题,但每次收发都有内核态拷贝,性能比共享内存低。面试里如果再问“你项目里怎么选”,只要答“数据量大、对性能要求高用共享内存+信号量,数据量小、需要按类型分发用消息队列”基本就稳了。
3.4 网络编程:TCP状态机是绕不开的坎
客户端开发必然要碰网络,笔试里TCP的题几乎不会缺席。印象最深的是TIME_WAIT那题,很多同学只知道四次挥手有TIME_WAIT,却不知道为什么要等2MSL(Maximum Segment Lifetime,报文最大生存时间)。原因有两层:第一,保证最后一个ACK如果丢了,还能有足够时间重传;第二,防止旧连接中的延迟报文出现在新连接里。这也是为什么大量短连接服务端会出现很多TIME_WAIT状态连接的原因,客户端开发如果写长连接常驻,反而不会太在意这个。
还有一个高频选择是:TCP三次握手第三次握手失败会怎样。很多人记不清。第三次握手失败时,服务端会发送RST报文,并释放这个半连接,客户端收到RST后报错。这块如果光背状态名会非常痛苦,建议自己在Linux下写一个简单的socket程序,用strace或tcpdump抓一遍完整握手和挥手过程,印象就深了。
4. 编程题手撕实操:从零实现到能跑
笔试的编程题其实很能拉开差距:有的人在IDE里能写出来,换到无补全的网页编辑器就歇菜;有的人虽然代码不整但思路完整。这一章我挑三道高概率遇到的题,给出可运行的实现和我在考场上踩的坑。
4.1 字符串反转并去重:注意复杂度要求
题目:给定一个字符串,反转它,同时去除重复字符,要求不能用额外的哈希集合,且空间复杂度尽量低。
我当时想到的方案是“标记数组法”:因为字符集有限(假设是ASCII 256个字符),可以开一个bool seen[256],遍历字符串的每个字符,遇到没见过的就标记,同时放到新数组里;最后逆序输出。这样时间O(n)、空间O(256),在笔试场景下够用了。
#include <stdio.h> #include <string.h> void reverse_and_unique(char *s) { int len = strlen(s); bool seen[256] = {false}; char buf[256] = {0}; int idx = 0; for (int i = 0; i < len; i++) { unsigned char c = s[i]; if (!seen[c]) { seen[c] = true; buf[idx++] = c; } } for (int i = idx - 1; i >= 0; i--) { putchar(buf[i]); } putchar('\n'); } int main() { char s[] = "hello linux"; reverse_and_unique(s); return 0; }踩坑点:字符数组下标要用unsigned char转型,否则遇到中文或大于127的字符时,char类型的负值会导致数组越界。这个细节我实际调试时遇到过,笔试时也差点漏掉。
4.2 手写LRU缓存:双向链表+哈希表
LRU在面试里出现的频率不亚于反转链表,笔试考“纯手写”时特别容易在指针操作上卡壳。核心思路是:用一个哈希表存key对应的链表节点指针,用一个双向链表维护访问顺序,get/put命中时把节点移到链表头部,超出容量时淘汰链表尾部节点。
#include <unordered_map> using namespace std; class LRUCache { private: struct Node { int key, val; Node *prev, *next; Node(int k, int v) : key(k), val(v), prev(nullptr), next(nullptr) {} }; int cap; Node *head, *tail; unordered_map<int, Node*> mp; void removeNode(Node* node) { node->prev->next = node->next; node->next->prev = node->prev; } void addToHead(Node* node) { node->next = head->next; node->prev = head; head->next->prev = node; head->next = node; } public: LRUCache(int capacity) : cap(capacity) { head = new Node(-1, -1); tail = new Node(-1, -1); head->next = tail; tail->prev = head; } int get(int key) { if (!mp.count(key)) return -1; Node* node = mp[key]; removeNode(node); addToHead(node); return node->val; } void put(int key, int value) { if (mp.count(key)) { Node* node = mp[key]; node->val = value; removeNode(node); addToHead(node); } else { Node* node = new Node(key, value); mp[key] = node; addToHead(node); if ((int)mp.size() > cap) { Node* last = tail->prev; removeNode(last); mp.erase(last->key); delete last; } } } };笔试时我踩了一个坑:忘了考虑更新已有key时先删后插的顺序,导致链表里出现重复节点。建议动手写之前先画一遍链表结构图,把“头尾哨兵节点”这个技巧记住,代码会好写很多。
4.3 TCP回显服务器:socket编程完整流程
如果笔试最后一题是“实现一个简单的TCP客户端/服务端”,千万别慌。它考的是流程熟不熟,不是代码多优雅。我默写的标准流程如下:
- 服务端:socket() -> bind() -> listen() -> accept() -> recv()/send() -> close()
- 客户端:socket() -> connect() -> send()/recv() -> close()
一个完整的最小回显服务端代码:
#include <stdio.h> #include <string.h> #include <unistd.h> #include <arpa/inet.h> #include <sys/socket.h> int main() { int listen_fd = socket(AF_INET, SOCK_STREAM, 0); if (listen_fd < 0) { perror("socket"); return 1; } int opt = 1; setsockopt(listen_fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)); struct sockaddr_in addr; memset(&addr, 0, sizeof(addr)); addr.sin_family = AF_INET; addr.sin_addr.s_addr = htonl(INADDR_ANY); addr.sin_port = htons(8888); if (bind(listen_fd, (struct sockaddr *)&addr, sizeof(addr)) < 0) { perror("bind"); return 1; } if (listen(listen_fd, 10) < 0) { perror("listen"); return 1; } while (1) { struct sockaddr_in client; socklen_t len = sizeof(client); int conn_fd = accept(listen_fd, (struct sockaddr *)&client, &len); char buf[1024]; int n = recv(conn_fd, buf, sizeof(buf) - 1, 0); if (n > 0) { buf[n] = '\0'; send(conn_fd, buf, n, 0); } close(conn_fd); } close(listen_fd); return 0; }这里有个笔试也常考的坑:服务端重启时报Address already in use。原因就是端口处于TIME_WAIT状态,需要在bind()之前加setsockopt(listen_fd, SOL_SOCKET, SO_REUSEADDR, ...)。我上机实验时遇到这个问题后,就再没忘记过这个API。
5. 面试追问与细节补漏
笔试只是第一关,重点要预判面试官会从笔试卷里挖出哪些追问。这一章把我能想到的延伸问题整理出来,相当于给笔试内容做个“二次复习”。
5.1 面试官会追问什么
笔试考文件权限,面试就会问“你部署服务的时候,日志文件权限是怎么设的,会不会让别的用户也能看”。笔试考僵尸进程,面试就会问“你负责的客户端程序有没有出现过僵尸进程,怎么排查”。笔试考TCP三次握手,面试就会问“如果客户端connect一个不存在的端口,会报什么错,怎么排查”。这类追问的底层逻辑都是把知识迁移到真实工作场景。
比如“connect超时”这个点我认为值得重点准备。客户端在Linux环境下连接远端服务,如果服务端没监听,客户端connect通常会收到ECONNREFUSED;如果网络不通或防火墙丢包,客户端会一直等tcp_syn_retries重试,默认可能长达2分钟。实际开发中前端界面会卡住,所以要用非阻塞connect + select/poll设置超时时间。这个知识点笔试选择题偶尔会考,面试聊项目时更容易被勾起。
5.2 客户端开发场景下的Linux知识
笔试考的是通用基础,但入职后你的工作场景会更具体。奇安信这类做安全产品的公司,Linux客户端开发至少有这么几个现实场景:
- 日志采集:客户端要定期写日志、切割日志,你要懂
logrotate的配置逻辑,也要懂文件锁,防止多进程同时写一个日志文件。 - 崩溃分析:客户端程序崩溃后会产生core文件,你至少得会用
gdb core看调用栈,知道怎么查段错误、怎么定位空指针。 - 开机自启:Linux桌面客户端常常要配置Systemd服务或者桌面自启动项,笔试不考,但工作会碰到。
- 与桌面环境交互:如果做的是带界面的客户端,会接触GTK或Qt,还得处理输入法框架、字体库、桌面通知等琐碎问题。笔试不会直接考,但面试问“你在Linux上开发GUI遇到最麻烦的事是什么”,如果你能说出输入法在Qt程序里失效这类具体问题,会非常加分。
- 系统兼容性:Linux发行版太多了,不同的libc版本、不同的桌面环境、有没有systemd,都会影响部署。面试官很乐意听到你说“我在Ubuntu 18.04/20.04和CentOS 7上都跑过”。
这些场景如果考前没有概念,哪怕笔试过了,面试大概率也会露馅。所以备考时除了刷题,我建议花点时间把Linux环境真正用起来,哪怕只是安装虚拟机、配好开发环境、跑几个服务,积累的“体感”是很难被速成的。
5.3 复盘前先承认:我踩了哪些坑
我自己这次笔试有两大失分点,写出来给大家避雷。
第一个是多选题的“少选也错”规则。几道关于进程和网络的多选题,我只选了绝对确定的选项,漏选了也可以确定的选项,直接0分。多选没有“部分给分”一说,犹豫不定时宁可少选,但不能盲目去蒙。
第二个是代码题没在文本编辑器里演练过。平时用VS Code写代码,括号补全和格式化都是自动的,到了在线笔试的纯文本框里,连{}都要手动对齐,浪费了不少时间。考完痛定思痛,我在终端里用vim练了一周写C++程序,再遇到在线编辑器就从容多了。
另外还有一个教训是时间分配。我习惯先做编程题,结果在LRU那道题上耗了太多时间,后面简答题只能快速作答。回来复盘发现,简答题其实只要写出关键命令和排查步骤就能拿分,性价比远比手撕LRU高。以后遇到类似笔试,我会先花两分钟扫一遍全卷,把容易拿分的题目先做掉。
6. 从笔试到Offer:Linux客户端开发学习路线整理
聊完真题,最后这部分是给还处于准备期的人看的。如果你打算走Linux客户端开发这条路,或者正在准备相关方向的笔试面试,下面这套路线是我自己验证过、也认为比较高效的,可以按顺序走。
6.1 基础必学清单:一步步来
按优先级排序,先掌握红色部分,再扩展黄色部分:
| 优先级 | 模块 | 具体内容 | 推荐验证方式 |
|---|---|---|---|
| 高 | C/C++语言基础 | 指针、内存管理、static/const、构造析构、STL常用容器 | 手写代码并编译运行 |
| 高 | Linux系统编程 | 文件I/O、进程fork、线程pthread、信号、IPC、socket | 写小型demo程序 |
| 高 | 网络基础 | TCP状态图、三次握手/四次挥手、select/poll/epoll区别 | tcpdump抓包验证 |
| 中 | 调试与排查 | gdb、strace、top、netstat、ss、perf | 用gdb调试一个段错误程序 |
| 中 | 构建与部署 | GCC编译参数、Makefile/CMake、动态库静态库、systemd | 从源码编译安装一个开源项目 |
| 低 | 桌面/GUI | Qt/GTK基础、信号槽、事件循环 | 写一个带按钮的简单窗口 |
| 低 | 脚本与自动化 | Shell脚本、Python基础 | 写一个批量重命名脚本 |
这个顺序不是随便排的。前三个模块是笔试直接考、面试直接问的核心区;中间两个模块是入职后天天用的生存技能;后面两个模块是加分项,如果时间紧张可以放一放。我当时就是按这个顺序推进的,基本上笔试出题范围被覆盖了八成。
6.2 实操环境搭建:没有Linux环境,一切复习都是纸上谈兵
如果你手头没有Linux机器,别犹豫,先搭一个。我最推荐的是通过虚拟机安装Linux发行版,选Ubuntu LTS或者Debian,镜像官网下载就行,装好之后建议把系统语言保持英文,不然路径和报错信息容易误导你。
装好系统后,优先做这几件事:配置SSH服务方便远程登录、安装vim和gcc/g++/gdb、安装Docker、用Docker拉几个常用镜像(比如Ubuntu、CentOS)方便测试不同系统行为。如果你用的是Windows机器,还可以在虚拟机里跑一个最小Linux系统用来练习命令行,占资源少,随开随用。这套环境搭好之后,前面说的所有命令、编程题、网络抓包实验都可以在里面完成。
如果不想装虚拟机,路由器上刷个Linux系统、云服务器按量付费开一台最低配,也都是可行方案。核心是“真的用起来”,不是“装完拍个照就关掉”。我自己就是在虚拟机里把一个TCP服务端、一个客户端跑通后,才真正理解socket那套抽象概念。
6.3 推荐资源与书单:少而精
书不用贪多,我真心看完了的只有几本,每一本都值得反复翻:
- 《UNIX环境高级编程》(APUE):系统编程入门经典,文件、进程、信号、线程、IPC都有,建议配合实验逐个消化。
- 《TCP/IP详解 卷1》:网络协议的权威文献,重点看TCP状态机和超时重传,配合抓包工具学。
- 《C++ Primer》:C++底子不牢的话,先把这本书的核心章节过一遍,重点看内存模型、拷贝控制、STL容器。
- 《Linux命令行大全》:不太适合系统学习,更适合当字典查。我建议把它当目录看,遇到不懂的命令去搜具体用法,不要从头背到尾。
除了书,学习过程中要多用在线刷题平台练手。不要只刷算法题,还要专门找“Linux命令题”和“系统编程题”来做。另外一个小技巧:把你在书上看到的每个系统调用(比如fork、pipe、mmap)都写一个最小示例,然后观察输出,这一步能帮你避开大量笔试选择题的坑。
6.4 面试前一周的冲刺策略
考前一周不要再看新东西,重点做三件事:
第一,把高频选择题考点过一遍,尤其是文件权限、进程状态、TCP状态,直接用题测自己。第二,手写代码保持手感,每天至少写一道链表/字符串/多线程题,编辑器就用纯文本框。第三,准备一段“项目或实验经历”的口述稿,内容不用高大上,哪怕只是“我用虚拟机搭了一个Linux服务器,部署了一个Python Flask应用,配置了systemd服务让他开机自启”,也比完全没有经历强。
这个阶段还有一个实用技巧:把常用的Linux命令整理成本地笔记,按场景分类,比如“查看端口占用”“查找大文件”“查看进程”“压缩解压”。不是让你背,而是让你在面试前最后看一遍,形成条件反射。我自己的笔记里记录了大量这类命令,包括但不限于find按时间查找、scp递归传输、du -sh *查目录大小、df -h查磁盘空间,这些基本就是Linux环境下开发同学的日常词汇表。
最后再分享一个我自己的小习惯:每次笔试或面试结束,不管结果怎么样,都花30分钟写一份复盘文档,把不会的题、被追问卡住的点、时间分配的问题都记下来。一次两次不觉得有什么,坚持几场之后你会发现自己对知识点的掌握会有一个非常明显的跳跃。这次奇安信笔试虽然有些题答得不够完美,但复盘完这份笔记之后,我对Linux客户端开发这个岗位需要什么能力,心里反而比考前清晰得多。希望这篇记录也能帮你少走一点弯路。