校招 未知部门 / 客户端开发 / 一面
[面试日期] 2026-05-04 [面试时长] 未知
[学校背景] 兰州大学 | 985 [学历背景] 未知
[发布人] 面试之星官方收录
<h2>腾讯客户端开发一面面经</h2>
<p><strong>腾讯客户端开发一面面经</strong></p>
<ol>
<li>
<p>关于招聘岗位有没有不清楚的地方?</p>
</li>
<li>
<p>请先做一个自我介绍。</p>
</li>
<li>
<p>C++中的多态你是如何理解的?多态是如何实现的,细节有哪些?</p>
</li>
<li>
<p>如果类有派生关系,父类和子类的构造函数和析构函数调用顺序是怎样的?</p>
</li>
<li>
<p>设计模式你有用过吗?了解哪些设计模式?</p>
</li>
<li>
<p>能简单讲一下单例模式和观察者模式是什么吗?分别在什么场景下使用?</p>
</li>
<li>
<p><code>const</code> 有什么作用?</p>
<p><strong>简要回答:</strong>
<code>const</code> 用于声明变量为只读,即其值不能被修改。在成员函数后加 <code>const</code> 表示该函数不会修改类的成员变量(非静态)。还可以用于函数参数、返回值等,提高代码安全性和可读性。</p>
<p><strong>详细回答:</strong>
<code>const</code> 是 C++ 中的类型限定符,主要作用如下:</p>
<ul>
<li><strong>修饰变量</strong>:定义常量,初始化后不可修改。例如 <code>const int a = 10;</code>。</li>
<li><strong>修饰指针</strong>:可分为指向常量的指针(<code>const int *p</code>,指针指向的值不可变)、常量指针(<code>int * const p</code>,指针本身不可变)以及指向常量的常量指针。</li>
<li><strong>修饰函数参数</strong>:表明函数不会修改传入的参数,常用于引用或指针参数,如 <code>void func(const string& s)</code>。</li>
<li><strong>修饰成员函数</strong>:放在函数声明末尾(如 <code>int getValue() const;</code>),表示该成员函数不会修改对象的任何非静态成员变量(除非成员被声明为 <code>mutable</code>)。这样的函数可以供常量对象调用。</li>
<li><strong>修饰函数返回值</strong>:防止返回值被修改,如 <code>const int& getRef()</code>。</li>
<li><strong>编译时优化</strong>:有助于编译器进行优化,并提高代码的可维护性和安全性。</li>
</ul>
</li>
<li>
<p>如果一个类的成员函数后面写 <code>const</code>,表示什么含义?</p>
</li>
<li>
<p>类中的静态变量是在什么时候初始化的?</p>
</li>
<li>
<p>函数内部的 <code>static</code> 变量是在什么时候初始化的?</p>
</li>
<li>
<p>操作系统的堆区和栈区有什么区别?</p>
</li>
<li>
<p><code>new</code> 和 <code>malloc</code> 有什么区别?</p>
</li>
<li>
<p>如果用了一段内存没有 <code>delete</code>,会有什么问题?</p>
</li>
<li>
<p>程序内存泄漏会有什么后果?</p>
</li>
<li>
<p>如果程序出现内存泄漏,你有什么办法去定位和解决?</p>
<p><strong>简要回答:</strong>
可以使用工具如 Valgrind、Dr. Memory、Visual Studio 的诊断工具、mtrace 等。也可以手动重载 <code>new</code>/<code>delete</code> 记录内存分配与释放的调用栈,在程序结束时输出未释放的内存块。还可以通过系统自带的内存分析器(如 Windows 的 CRT Debug Heap)来定位。</p>
<p><strong>详细回答:</strong>
内存泄漏是指动态分配的内存没有被正确释放,导致程序内存占用持续增长。定位方法包括:</p>
<ol>
<li><strong>静态代码检查</strong>:使用工具如 <code>clang-tidy</code>、<code>Cppcheck</code> 分析代码逻辑。</li>
<li><strong>动态分析工具</strong>:
<ul>
<li><strong>Valgrind (Linux)</strong>:运行程序并报告所有未释放的内存块及其调用栈。</li>
<li><strong>Dr. Memory (Windows/Linux)</strong>:类似 Valgrind。</li>
<li><strong>Visual Studio 诊断工具</strong> (Windows):使用 CRT Debug Heap,在 Debug 模式下通过 <code>_CrtDumpMemoryLeaks()</code> 输出泄漏信息。</li>
<li><strong>mtrace (glibc)</strong>:通过 <code>mtrace()</code> 和 <code>muntrace()</code> 记录 malloc/free 调用。</li>
</ul>
</li>
<li><strong>重载 operator new/delete</strong>:自定义内存管理,记录分配点(文件名、行号、调用栈),在程序结束时输出未释放记录的列表。</li>
<li><strong>使用智能指针</strong>:从源头避免内存泄漏,如 <code>unique_ptr</code>、<code>shared_ptr</code>。</li>
<li><strong>内存检测库</strong>:如 Google Performance Tools 的 tcmalloc 和 heap checker。</li>
<li><strong>系统级监控</strong>:如 Windows 的 Performance Monitor 观察进程内存增长趋势。</li>
</ol>
<p>在实际业务中,对于大型服务,可以定期拉取进程内存快照,对比堆内存变化,结合日志分析可疑模块。</p>
</li>
<li>
<p>除了看日志,有没有更高效的方法?假如让你写一个定位内存泄漏的工具,说说你的思路(以腾讯会议为例)。</p>
<blockquote>
<p>设计思路:通过重载 <code>operator new</code> 和 <code>operator delete</code>,记录每次内存分配的地址、大小、调用栈(文件、行号、函数符号),存储在一个全局哈希表中。释放时从表中删除条目。定期或在程序退出时,遍历哈希表中剩余未释放的记录,输出分配信息到日志,作为内存泄漏的疑似点。为降低性能开销,可加入采样或线程局部缓冲区,并使用红黑树/哈希表加锁或无锁结构。</p>
</blockquote>
</li>
<li>
<p>操作系统的进程和线程有何区别?</p>
</li>
<li>
<p>进程间通信的方式有哪些?能展开讲一下管道、socket的特点和适用场景吗?</p>
</li>
<li>
<p>线程同步都有哪些方式?</p>
</li>
<li>
<p>在Windows端实现窗口通信时,<code>send message</code> 和 <code>post message</code> 有什么区别?</p>
</li>
<li>
<p>什么是缓冲区溢出?造成缓冲区溢出有什么危害?</p>
</li>
<li>
<p>什么是死锁?怎么解决死锁问题?</p>
</li>
<li>
<p>路由器和交换机有什么区别?</p>
<p><strong>简要回答:</strong>
路由器工作在网络层(第三层),基于 IP 地址转发数据包,连接不同网络,提供路由和 NAT 等功能。交换机工作在数据链路层(第二层),基于 MAC 地址转发帧,用于同一网络内多个设备的互联。</p>
<p><strong>详细回答:</strong></p>
<table>
<thead>
<tr>
<th>特性</th>
<th>路由器</th>
<th>交换机</th>
</tr>
</thead>
<tbody>
<tr>
<td>工作层级</td>
<td>网络层(OSI 第三层)</td>
<td>数据链路层(OSI 第二层)</td>
</tr>
<tr>
<td>转发依据</td>
<td>IP 地址(路由表)</td>
<td>MAC 地址(MAC 地址表)</td>
</tr>
<tr>
<td>主要功能</td>
<td>连接不同网络(如局域网与广域网),路由选择,网络地址转换(NAT),防火墙</td>
<td>在同一网络内扩展端口,减少冲突域,根据 MAC 地址转发</td>
</tr>
<tr>
<td>广播隔离</td>
<td>隔离广播域(广播不会跨越路由器)</td>
<td>不隔离广播域(默认在一个广播域内,但 VLAN 可隔离)</td>
</tr>
<tr>
<td>应用场景</td>
<td>连接家庭网络到 ISP,企业网络间互联</td>
<td>连接同一子网内的电脑、打印机、服务器</td>
</tr>
<tr>
<td>处理方式</td>
<td>解包到 IP 层,重新封装,可能修改 IP 头(TTL 等)</td>
<td>只查看 MAC 头,不修改数据内容</td>
</tr>
</tbody>
</table>
<p>简单记忆:<strong>路由器在网络间转移数据,交换机在网络内转移数据</strong>。</p>
</li>
<li>
<p>DNS协议是干什么的?具体是怎么工作的?</p>
</li>
<li>
<p>TCP协议是怎么保证可靠传输的?有哪些机制?</p>
</li>
<li>
<p>HTTP和HTTPS有什么区别?加密过程能展开讲一下吗?</p>
<p><strong>简要回答:</strong>
HTTP 是明文传输协议,数据不加密;HTTPS 是在 HTTP 基础上加入 SSL/TLS 加密层,通过数字证书验证服务器身份,保证数据传输的机密性、完整性和身份认证。默认端口:HTTP 80,HTTPS 443。</p>
<p><strong>详细回答:</strong></p>
<ul>
<li><strong>HTTP (HyperText Transfer Protocol)</strong>:
<ul>
<li>无状态、明文传输,易被窃听和篡改。</li>
<li>默认端口 80。</li>
<li>性能略高(无需加密解密)。</li>
</ul>
</li>
<li><strong>HTTPS (HTTP Secure)</strong>:
<ul>
<li>即 HTTP + TLS/SSL 加密。</li>
<li>默认端口 443。</li>
<li>加密过程:客户端与服务器协商 TLS 版本和密码套件 → 服务器发送数字证书(含公钥)→ 客户端验证证书(通过 CA 信任链)→ 客户端生成临时对称密钥,用服务器公钥加密发送 → 服务器使用私钥解密得到对称密钥 → 后续通信使用对称加密(如 AES)保证效率。</li>
<li>安全性:防止中间人攻击、数据泄露、篡改。</li>
<li>性能:由于加密握手和加解密开销,略慢于 HTTP,但现代硬件影响很小。</li>
</ul>
</li>
<li><strong>其他区别</strong>:
<ul>
<li>HTTPS 需要 CA 证书(收费或免费如 Let's Encrypt)。</li>
<li>搜索引擎优先收录 HTTPS 网站。</li>
</ul>
</li>
</ul>
</li>
<li>
<p>为什么有了IP地址还要有MAC地址?它俩有什么区别?</p>
<p><strong>简要回答:</strong>
IP 地址负责网络层的全球寻址和路由(跨网络),而 MAC 地址负责数据链路层的本地设备唯一标识(同一网段内)。两者分工不同:IP 像邮政地址(城市+街道),MAC 像身份证号。路由器根据 IP 将数据包送到目标网络,到达本地网络后,再通过 MAC 地址找到具体设备。</p>
<p><strong>详细回答:</strong></p>
<ul>
<li><strong>IP 地址(逻辑地址)</strong>:
<ul>
<li>工作在网络层,用于跨网络的路由。</li>
<li>具有层次结构(网络号+主机号),由网络管理员或 DHCP 动态分配,可以变化。</li>
<li>解决的是“如何将数据包从源主机送到目标主机所在网络”。</li>
</ul>
</li>
<li><strong>MAC 地址(物理地址)</strong>:
<ul>
<li>工作在数据链路层,用于同一广播域内的设备通信。</li>
<li>由网卡制造商分配,全球唯一,固化在硬件中,通常不可改变。</li>
<li>解决的是“在同一个网络内,如何将数据帧从一台设备送到另一台设备”。</li>
</ul>
</li>
<li><strong>为什么两者都必要?</strong>
<ul>
<li>假设只用 IP:在本地网络内,IP 地址是动态的(如 DHCP),且 ARP 协议本身就是将 IP 映射到 MAC 来通信,底层仍然需要物理地址来封装以太网帧。</li>
<li>假设只用 MAC:跨网络时,路由器不知道全球所有 MAC 地址,因为 MAC 地址是平面结构,没有路由信息,无法高效转发。IP 提供了层次化路由,极大缩小了路由表。</li>
<li><strong>协作方式</strong>:当主机 A 向不同网络的主机 B 发送数据时,A 将数据包发往默认网关(路由器)的 IP,路由器根据 IP 路由表选择下一跳,最终到达目标网络;在目标网络内,通过 ARP 获取目标 IP 对应的 MAC 地址,将帧发往该设备。</li>
</ul>
</li>
<li><strong>类比</strong>:IP 像邮政编码+街道名(定位到城市和街区),MAC 像身份证号(精确到个人)。快递员先根据邮政编码送到对应城市(IP 路由),再到该城市的分拣站,根据地址找到具体街道和房间(再次 IP),最后送到收件人手中——但在网络场景中,最后一跳仍需要身份证(MAC)验证身份。</li>
</ul>
</li>
<li>
<p>关于你的实习经历,你觉得哪里比较有亮点?能不能展开讲一下遇到的技术难点以及是如何攻克的?</p>
</li>
<li>
<p>你有什么需要问我的吗?</p>
</li>
</ol>
<p>答得一坨,面完秒挂</p><a>#发面经攒人品#</a>
AI 推荐面试题
