ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

思科校招笔试解析:网络协议、C语言与Linux底层基本功备考指南

思科校招笔试解析:网络协议、C语言与Linux底层基本功备考指南 “思科2018校园招聘笔试题软件类B卷”——如果你不是正在准备校招的求职者可能看不出这个标题的分量。思科是靠交换机和路由器起家的网络设备厂商它的软件类笔试和国内互联网公司完全是两套打法。互联网大厂喜欢考LeetCode原题、堆算法模板思科这类网络设备厂商却在卷子里塞满了网络协议、C语言内存、Linux编程这些硬骨头。不少第一次做这类卷子的同学共同体验是怎么越做越像计算机等级考试加网络工程的合体这篇文章写给谁写给准备投思科、以及其他网络设备厂商或通信大厂软件岗的人。真实带过校招笔试的人都明白真题原卷很难完整留存但笔试的筛选逻辑十年也没怎么变过——数据结构、操作系统、网络协议、C/C基本功该考的永远会考。所以我不逐题复述没意义的原卷而是把这类B卷最可能的出题结构、每类考点的底层逻辑、以及怎么准备才能稳稳过关一次讲透。1. 先摸清出题人的“性格”思科软件笔试到底在筛什么1.1 一份标题背后藏着的岗位画像看到“思科软件类”这五个字要先想清楚一件事思科的软件岗和微信、淘宝的软件岗根本不是一个物种。思科的核心产品是路由器、交换机、防火墙、无线控制器软件团队的日常工作是在资源受限的硬件上写网络操作系统、转发引擎、协议栈、管理平台。这意味着岗位对候选人的画像非常清晰——不需要你发明新架构但必须能吃透底层机制。对应到笔试题型思科软件类考察的重心自然落在三块C/C网络设备代码几乎都是C和C写的、计算机网络这是吃饭的本行、操作系统与Linux并发、内存、IO是躲不掉的。算法题也会考但权重和考察方式跟互联网公司完全不同。后面我会具体对比。1.2 B卷的通行结构与时间分配按校招笔试的通行做法来推测B卷和A卷的编排逻辑是一致的同一套知识点范围不同的具体题目难度横向对齐。整场笔试通常控制在120分钟到150分钟卷面结构大概率包含三类题客观题选择题、判断题、代码题手写函数实现或算法、问答设计题网络原理、系统设计、场景分析。对软件类B卷而言一个相对合理的时间分配策略是选择题和判断题控制在40分钟以内这些题考基础概念答得快就给后面的代码题留出充分时间代码题留60分钟左右一般有两道一道偏数据结构算法、一道偏C语言字符串或链表操作问答设计题留20到30分钟重点在于把思路写清楚哪怕代码不完整也要写出关键步骤。这套时间感觉不一定和当年的真实卷面严丝合缝但它覆盖了这类笔试最常见的题量和难度。提前按这个节奏练笔比临时拿到卷子再分配要稳得多。1.3 思科笔试和互联网大厂笔试的差异对比既然要做备考决策就必须知道差异在哪里。我用一张表把两种路线的真实区别拉出来你一看就明白为什么“无脑刷LeetCode”对付不了思科这张卷子。维度思科软件类笔试互联网大厂软件笔试语言倾向C/C为主偶尔出现Python/JavaJava/Go/Python/C都有算法题权重有但占比约30%-40%通常占70%以上核心是算法网络知识必考且考得很深很细偶尔考多为应用层常识Linux系统直接考命令、系统调用、并发模型面试阶段更关注笔试较少答题风格重原理解释、重边界处理、重工程实现细节重算法复杂度、重AC率典型错误代码写错指针、内存泄漏、忽略字节序超时、内存超限、思路正确但细节缺失看明白了吗思科这张卷子的核心是筛选“能写设备软件的人”不是筛选“竞赛型选手”。所以备考的第一个动作就是把重心从“刷题量”切换到“底层基础是否扎实”。2. 数据结构与算法B卷里最不“思科”但最能拉开分差的部分2.1 考点范围清单思科软件类笔试题的算法部分难度不低但不偏门。从历届出题风格看考察频率最高的知识点集中在栈和队列、单链表的反转与删除、二叉树的遍历、字符串匹配与处理、快速排序和归并排序、动态规划入门题背包、最长公共子序列、时间复杂度和空间复杂度的计算。有意思的是思科不怎么考“脑筋急转弯”式的题目。它更喜欢考那些写了几十年还是这些经典题的家伙——因为设备软件和底层库中的很多函数归根结底就是这些经典结构的变体。面试官要的不是你能现场发明算法而是你能把经典算法写正确、写严谨、写完整尤其是边界条件。2.2 经典样例题用两个栈实现一个队列这道题几乎是这类笔试的“钉子户”。很多同学第一次碰到时觉得绕其实原理很简单栈是先进后出队列是先进先出要想用栈实现队列就必须把栈底的数据“翻”到栈顶去。和这类笔试的题风一致代码考察的其实是你能不能把翻转时机写清楚。核心思路是维护两个栈in负责入队out负责出队。出队时如果out为空就把in的所有元素倾倒进out再pop即可。templatetypename T class MyQueue { private: std::stackT in; std::stackT out; public: void push(T x) { in.push(x); } T pop() { if (out.empty()) { while (!in.empty()) { out.push(in.top()); in.pop(); } } T front out.top(); out.pop(); return front; } T front() { if (out.empty()) { while (!in.empty()) { out.push(in.top()); in.pop(); } } return out.top(); } bool empty() const { return in.empty() out.empty(); } };边界条件很关键pop()和front()执行前如果两个栈都是空的一定要先处理异常或断言否则代码就是未定义行为。时间复杂度上push是严格的O(1)pop和front是均摊O(1)——因为每个元素最多只被从in搬进out一次。这行分析一定要写在答题纸或代码注释里面试官很看重。另外不要忽略一个细节题目如果明确要求“不能使用额外的数据结构”那stack本身算不算额外数据结构有些出题人会在题目里写“只能用标准库stack”说明该用就用如果没写建议自己写个Node结构或用数组模拟栈更稳妥。2.3 容易被忽略的工程化考察字符串与指针思科这种公司非常喜欢考C语言风格的字符串题。这类题看起来简单实际上一写就错。比如实现一个strstr函数在源字符串中查找子串首次出现位置暴力匹配的写法也就二十来行但考察点全在细节上入参是const char*不应该修改原字符串对空指针和空串的处理要提前判断当needle为空字符串时按C标准库的语义应该返回haystack这个约定很多人不知道内层循环匹配失败时指针的复位位置要算对否则会出现漏匹配。这类题是笔试里的“高杠杆题”——会的人三分钟写完不会的人写出来全是漏洞却不知道自己错在哪。备考时建议把C标准库里的strcpy、strcat、strcmp、strstr、memcpy都亲手实现一遍不是背代码而是把指针运算和边界条件练成肌肉记忆。如果题目允许用char*而非std::string还意味着你必须自己管理内存、字符数组长度和\0终止符。这在选择题里也经常变成陷阱sizeof(指针)和strlen(指针)完全不是一回事前者在64位平台永远是8后者才是实际字符串长度。3. 计算机网络思科笔试最硬的内核3.1 从一道“打开网页”的综合题看整套网络知识栈网络部分最经典的考法是一道“描述在浏览器里输入网址到页面显示中间发生了什么”的综合性题。这类题没有标准答案但答得好不好一眼就能看出你是背过面试题还是真的懂网络。思科笔试的喜好就偏向后者。完整链路大概是这样的浏览器解析URL得到域名和默认端口HTTP是80HTTPS是443请求本地DNS缓存如果没有则向本地DNS服务器发起递归查询最终拿到目标IP浏览器发起TCP连接经三次握手建立连接如果走HTTPS还会进行TLS握手协商加密套件、交换证书、生成会话密钥浏览器构造HTTP GET请求报文交给传输层TCP将请求分段并编号交给网络层网络层封装IP报文如果目标IP和自己不在同一网段需要查找路由表确定下一跳数据链路层用ARP获取下一跳设备的MAC地址封装成以太网帧途中经过一个个路由器每跳都会重新封装二层MAC地址但IP地址通常保持不变直到到达目标服务器服务器解析请求返回HTTP响应报文浏览器解析HTML、CSS、JavaScript渲染页面如果连接不再复用TCP进入四次挥手流程关闭连接。写出这条链路不难真正帮你拉分的是那些“中间的解释”为什么要用ARP为什么MAC地址每跳都变而IP不变什么时候走三次挥手而不是四次如果答案是“NAT”场景下IP也会变那就更显功力。备考时建议把这十几步写在一张纸上反复默写直到每个环节都能讲明白“这层为什么存在、这层主要解决什么问题”。3.2 三次握手与四次挥手不能只背状态名TCP的状态名和时序是必考的但思科笔试很少只问“列出三次握手的状态”。它更常这么问为什么握手是三次而不是两次为什么挥手要四次握手三次的本质是为了防止失效的连接请求突然又传到了服务端。经典场景是这样的客户端发送的第一个SYN因为网络拥塞迟迟没到客户端超时重传了新的SYN并成功建立了连接。可等这个连接关闭之后那个拥塞在路上的旧SYN才姗姗来迟。如果只有两次握手服务端收到这个旧SYN就会误以为又是一次新连接请求白白分配资源。而三次握手让服务端只发出SYN-ACK而不建立连接必须等客户端回最后一次ACK——旧SYN没有对应的ACK自然穿帮。挥手为什么需要四次因为TCP连接是双工的断开时每个方向都需要独立关闭。客户端发FIN表示“我不再发数据了”服务端收到后可能还有数据没发给完所以先回ACK等自己的数据发完再发FIN。方向不同两个FIN不能合并于是就有了四次交互。对应状态上要注意主动关闭方收到对方的FIN后会进入TIME_WAIT状态要等2MSL最大报文段生存时间才真正关闭目的是确保最后一个ACK能到达也为了让旧的报文段在网络中消失。这个知识如果能在问答里主动说出来会明显高于“背状态表”的同学。3.3 网络基础与其他知识点这是和互联网公司差异最大的板块这里说的“网络基础”指的不是HTTP和DNS而是更底层、更思科的内容。如果你想进思科的软件岗VLAN、STP、OSPF、BGP这些词一定会出现在备考范围里。不过要认清楚笔试考的是原理不是让你敲配置命令。比如VLAN核心是解决二层广播域太大的问题。没有VLAN时所有接在同一台交换机上的设备共享广播域一台主机发ARP广播整网都能收到既浪费资源又不安全。划分VLAN之后广播被限制在相同VLAN内部不同VLAN之间想要通信必须经过三层设备路由器或三层交换机。对应到笔试就是要能够说清“VLAN隔离了广播域但事实上有VLAN间路由的需求时怎么解决”。再比如STP生成树协议要知道它的名字和解决的问题——二层网络中的环路会导致广播风暴、MAC地址表震荡STP通过选举根桥、阻塞冗余端口把物理环路修剪成逻辑上的树消除环路。动态路由协议方面OSPF是链路状态协议通过洪泛LSA、运行SPF算法来计算最短路径BGP是路径矢量协议用在大型企业网或ISP之间基于路径属性做路由决策。这些知识点不用啃到思科认证那种细粒度但至少要做到给一个场景能判断出这是哪个层级的网络问题以及该用哪个协议解决。复习时用几个晚上的时间把《TCP/IP详解 卷一》的前面章节和一份网络基础教程过一遍重点理解“交换机是转发的、路由器是路由的”这种思维模型。4. C/C与操作系统底层工程师的基本功考核4.1 结构体对齐与内存布局在思科这类公司的笔试里C语言不是“会不会写”的问题而是“写出来是否经得起编译器折腾”的问题。结构体对齐就是最容易暴露基本功的一道题。看一个例子在64位Linux、默认对齐规则下struct Example { char a; int b; short c; double d; };sizeof(struct Example)是多少计算逻辑是a占偏移0b按4字节对齐放到偏移4占4到7c按2字节对齐放到偏移8占8到9d按8字节对齐必须放到16的偏移上占16到23整个结构体还要是最大对齐数这里是8的整数倍所以总大小是24字节。很多人一上来就以为是142815字节这就是踩了内存对齐的坑。CPU访问内存是按字读取的如果把一个int放到奇地址上需要访问两次内存才能拼出来性能损失巨大。所以编译器会在字段之间“打洞”填填充字节。如果笔试题目里看到#pragma pack(1)说明强制1字节对齐那上面的结果就会不一样——但笔试第一步永远是判断是否设置了pack。关于内存布局还必须知道进程的地址空间结构从低地址到高地址依次是代码段、已初始化数据段、未初始化数据段BSS、堆、共享库、栈。堆向上生长栈向下生长。选择题里常出现的“全局变量还是局部变量”“静态变量存哪里”“堆和栈的主要区别”本质上都在这张内存地图里。4.2 const与指针的组合高频易错点const加指针的四种组合是几乎每次笔试都会出现的选择题。判断技巧只有一句话看const修饰的是谁。int a 10; const int* p1 a; // p1可变*p1不可变 int* const p2 a; // p2不可变*p2可变 const int* const p3 a; // 两者都不可变 int const* p4 a; // 等价于 const int* p4也就是const出现在*左边修饰的是指向的对象指针本身可以改const出现在*右边修饰的是指针本身指向的对象可以改。重点记这一个规则考试时套用即可。再深入一点这个知识点会结合函数参数考察比如const char* str和char* const str在函数签名里的意义就完全不同。前者是保护字符串内容不被修改后者是这个指针变量本身不能再指向别处。写设备代码时函数参数几乎全用前者因为函数没有理由修改调用者传入的字符串内容。这类题考察的不只是语法更是写工程代码的素养。4.3 进程、线程与并发问题操作系统的基础题思科考起来比互联网公司要“严肃”得多。因为它真的需要你在并发环境下写代码。最常考的几个点进程和线程的区别进程是资源分配的基本单位线程是调度的基本单位同一进程内的线程共享地址空间但进程之间彼此隔离。死锁的四个必要条件互斥、持有并等待、不可剥夺、循环等待。只要打破其中一个死锁就能解除。笔试里可能让你举一个现实中的死锁例子比如两个线程分别持有一把锁后又去抢对方的锁这就是教科书级的死锁。锁的类型互斥锁、读写锁、自旋锁、信号量各自适应什么场景。读写锁适合读多写少自旋锁适合临界区极短、避免线程切换开销的场景。常见的并发Bug竞态条件、死锁、活锁、优先级反转。至少要能说清竞态条件是哪行代码没有加锁保护导致两个线程同时改一个共享变量。考这些题的目的是防止你把并发编程当成调库。笔试不会直接让你写一个线程池但会在问答设计题里给你一个多线程读写共享资源的场景让你指出问题、给出改进方案。这类题没有唯一正确答案只要逻辑自洽、提到锁和原子性思路就基本对了。5. Linux与网络编程从读题到动手写代码5.1 一个最小可用的TCP回声服务器看到“Linux与网络编程”这个组合名字你可能会打退堂鼓。但这类笔试最大的优势是——代码考得很基础不需要你会写高性能工业级服务器但要能写完一个能跑通的TCP程序。下面是这类题的标准骨架#include stdio.h #include stdlib.h #include string.h #include unistd.h #include sys/socket.h #include netinet/in.h #define PORT 8888 int main() { int listen_fd, conn_fd; struct sockaddr_in server_addr; char buf[1024]; ssize_t n; listen_fd socket(AF_INET, SOCK_STREAM, 0); if (listen_fd 0) { perror(socket); exit(EXIT_FAILURE); } memset(server_addr, 0, sizeof(server_addr)); server_addr.sin_family AF_INET; server_addr.sin_addr.s_addr htonl(INADDR_ANY); server_addr.sin_port htons(PORT); int on 1; setsockopt(listen_fd, SOL_SOCKET, SO_REUSEADDR, on, sizeof(on)); if (bind(listen_fd, (struct sockaddr *)server_addr, sizeof(server_addr)) 0) { perror(bind); exit(EXIT_FAILURE); } if (listen(listen_fd, 128) 0) { perror(listen); exit(EXIT_FAILURE); } while (1) { conn_fd accept(listen_fd, NULL, NULL); if (conn_fd 0) { perror(accept); continue; } while ((n read(conn_fd, buf, sizeof(buf) - 1)) 0) { buf[n] \0; write(conn_fd, buf, n); if (strcmp(buf, quit\n) 0) { break; } } close(conn_fd); } return 0; }这段代码里面藏着好几个面试官特别看重的点socket()、bind()、listen()、accept()、close()这套调用链是否熟悉htonl、htons说明你理解主机字节序和网络字节序的差别x86是小端而网络传输是大端SO_REUSEADDR设置了端口复用这个知识很多初学者压根不知道写上了就是加分项read()返回值的判断大于0表示读到数据等于0表示对端关闭小于0才是出错。很多人漏了等于0的分支导致对端断开后死循环。笔试现场不要求跑通代码但阅卷人会按这套逻辑给你打分。与其背一堆高级框架不如把这个骨架默写到滚瓜烂熟。5.2 高并发方案演进从fork到epoll在TCP服务器的代码题之后通常还会跟着一道设计题如果要支持成千上万个客户端同时连接你的服务器怎么改这道题考察的是对多路复用机制的理解。简单说经历了三个阶段多进程/多线程模型每次accept到一个连接就fork()一个子进程或创建一个线程。缺点是进程和线程都有数量上限成千上万个连接就意味着成千上万个上下文切换资源消耗大性能下降快select和poll把需要监听的fd集合传给内核内核帮忙检查哪些fd有事件。缺点也明显select的fd数量有上限每次调用都要把整个fd集合从用户空间拷贝到内核空间O(n)的遍历逃不掉epoll事件驱动注册要关注的fd和事件后内核维护一个事件表只在事件发生时通知你。不需要每次遍历全量fd支持大量并发连接是Linux高并发服务器的默认答案。这道题能不能写对核心在于理解epoll_wait返回的是一个“就绪事件列表”而不是“所有注册的fd”所以才能做到O(就绪数量)处理时间。如果可以再补充一句“边缘触发模式下每次epoll_wait返回后需要把数据全部读完否则会漏掉后续事件水平触发模式则不用担心只要缓冲区还有数据就会持续上报”那就属于典型的加分细节。5.3 网络编程题里最容易写错的细节笔试里的网络编程考的不是代码量是代码的“稳”。以下几个细节是我反复看到同学踩坑的地方没有检查每一个系统调用的返回值。真实网络编程中accept可能被信号中断返回-1write可能只写了一半。很多同学笔试时只写核心逻辑忽略了错误处理这正好是思科这类公司最关注的点因为它们的产品运行在7x24小时环境里字节序转换缺失。端口号和IP地址不转网络字节序就bind在x86上运行正常但部署到大端机器上就全部出错死锁式的read处理。客户端发送数据后等回显服务端也等客户端继续发数据双方阻塞在读操作上谁也读不到谁的响应。笔试问“为什么卡住”时答案往往是缓冲区读写顺序不对忽略了粘包和半包。TCP是字节流协议没有消息边界。笔试如果考一个“设计通信协议”你要能想到用长度字段或分隔符来界定消息而不是把TCP当成UDP来用。这些细节在真正的网络设备开发中天天遇到。笔试考它们不是为了刁难你而是为了提前筛掉那些“能写出hello world但写不了生产代码”的人。6. 备考路线与复盘当下求职者需要注意的“先后次序”6.1 三个月备考主线怎么排如果你现在还有三个月左右的时间建议按这个节奏推进不要乱第1-2周主攻计算机网络。用《TCP/IP详解 卷一》前10章配合应试资料建立数据包流转的完整链路图目标是能不看资料说清“从浏览器输入URL到页面显示”全过程外加TCP状态机、VLAN和STP原理第3-4周主攻C语言和Linux。每天手写2个基础函数字符串、链表、内存操作把gcc、gdb、grep、awk、strace、tcpdump这组常用命令练熟。网络编程的TCP骨架代码至少默写三遍第5-8周刷算法题。以LeetCode的“数据结构”分类为主核心是链表、栈、队列、二叉树、字符串按每日3-5题的节奏推进。贪心和简单DP也要过一遍第9-10周专项强化。把思科笔试最可能出现的问答设计题列个清单逐个写成文字答案。注意要写下来不是“想想就行了”第11-12周模拟与复盘。用完整的2小时做一到两套模拟题重点不是得分而是训练时间分配和心态稳定。如果你想同时投互联网公司和思科要提醒自己别用互联网公司那一套去替代思科的准备。算法刷题可以部分复用但网络协议和Linux网络编程这部分如果没花时间思科笔试大概率会栽。6.2 笔试之后被追问的往往是卷面上的细节很多同学以为笔试是终点其实思科这类公司面试时往往会把笔试卷子翻出来追问。问法通常是“你写的TCP服务器这里怎么处理read返回0的情况”“如果客户端不主动close连接服务器会发生什么”“你刚才讲结构体对齐如果代码里加了#pragma pack(2)大小变成多少”这意味着备考不能只背一个答案而要把每个知识点背后“为什么这么设计”“如果不这么做会怎样”想清楚。笔试后把自己写的代码拍照留档面试前重新看一遍看看当时写错的地方现在是真懂了还是一知半解这点很有用。还有一个被很多人忽略的加分动作笔试时可以在代码注释里写明思路和边界条件说明。阅卷不仅看代码能不能跑通更会看你的工程思维。注释里的那句话可能比你的代码本身更能体现水平和专业度。6.3 最后说点实实在在的话我知道刷题很卷备考很累但思科这类公司的笔试其实藏了一条清晰的路径把网络协议、C语言、操作系统这三块基础啃透算法维持中上水平就能超过绝大多数候选人。这些年我看过太多同学把精力全放在算法题上结果在计算机网络和系统编程上丢了一堆基本分实在太可惜了。说到底一份校园招聘笔试题尤其是“软件类B卷”这种命名方式本质上是在检验一个工程师的底层功底。我的切身体会就是当年准备校招时最先啃的是算法后期才发现真正花时间背网络原理、系统调用和内存布局的那些深夜才是最有价值的部分。希望这份拆解能帮你少走那段弯路把有限的备考时间花在最值得的地方。
返回列表