去哪儿 客户端 C++ 一面 面经
1. 自我介绍
面试官好,我是[姓名],[学校][专业][年级]。我的技术方向是客户端开发,有iOS和后端开发的实习经验。
技术栈方面,客户端熟悉Objective-C、Swift,了解UIKit、多线程(GCD、NSOperation)、网络编程等;后端熟悉Java、Spring Boot、MySQL、Redis等技术。
实习经历上,我在[公司]做过客户端开发实习,负责[具体模块],主要解决了[技术难点];也在[公司]做过后端实习,参与了[项目]的开发,积累了全栈视角。
我对旅游行业很感兴趣,去哪儿的产品我也经常使用,希望能将技术应用到实际业务中,提升用户的出行体验。
2. 详细说说你的客户端实习经历
在[公司]客户端实习期间,我主要负责[具体模块,如:用户中心模块]的开发和优化。
主要工作内容:
功能开发:
- 实现了[具体功能],使用MVC架构,通过代理模式实现模块间通信
- 集成了第三方SDK(如地图、支付),处理了回调和异常情况
- 使用AutoLayout和Masonry实现自适应布局
性能优化:
- 优化列表滚动性能,使用Cell复用和异步图片加载,帧率从40fps提升到58fps
- 减少启动时间,通过延迟加载和并行初始化,启动时间减少30%
- 内存优化,使用Instruments定位内存泄漏,修复了循环引用问题
网络层:
- 封装网络请求,使用AFNetworking,统一处理错误和超时
- 实现请求缓存策略,提升弱网环境下的用户体验
- 使用Protobuf优化数据传输,减少流量消耗
遇到的挑战:
- 多线程数据同步问题:使用GCD的串行队列和信号量解决
- 内存泄漏:Block循环引用,通过weak-strong dance解决
- 崩溃率高:集成Bugly收集崩溃日志,定位并修复了空指针和数组越界问题
收获:深入理解了iOS的运行机制、内存管理、多线程编程,也学会了如何分析和解决实际问题。
3. 说说你的后端实习经历
在[公司]后端实习期间,我参与了[项目名称]的开发,这是一个[项目类型]系统。
技术架构:
- 使用Spring Boot + MyBatis构建RESTful API
- MySQL作为主数据库,Redis做缓存
- 使用RabbitMQ处理异步任务
- 部署在Docker容器中
主要工作:
接口开发:
- 开发了[具体模块]的CRUD接口
- 使用MyBatis-Plus简化数据库操作
- 统一异常处理和参数校验
性能优化:
- 数据库查询优化:添加索引,优化慢查询,响应时间从500ms降到50ms
- Redis缓存:热点数据缓存,缓存命中率达到85%
- 接口合并:减少客户端请求次数
业务逻辑:
- 实现了[具体业务],涉及多表关联查询和事务处理
- 使用分布式锁解决并发问题
- 定时任务处理数据同步
遇到的问题:
- 高并发下的库存超卖:使用Redis分布式锁 + 数据库乐观锁解决
- 消息队列堆积:增加消费者实例,优化消费逻辑
- 数据一致性:使用事务和补偿机制
收获:理解了后端系统的架构设计、数据库优化、分布式系统的挑战,也让我在做客户端时更理解服务端的逻辑。
4. OC中如何开启三个子线程执行任务,在第三个任务完成后执行第四个任务?
有多种实现方式,我介绍几种常用的:
方法一:使用GCD的dispatch_group
dispatch_group_t group = dispatch_group_create();
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
// 任务1
dispatch_group_async(group, queue, ^{
NSLog(@"任务1开始");
sleep(2);
NSLog(@"任务1完成");
});
// 任务2
dispatch_group_async(group, queue, ^{
NSLog(@"任务2开始");
sleep(1);
NSLog(@"任务2完成");
});
// 任务3
dispatch_group_async(group, queue, ^{
NSLog(@"任务3开始");
sleep(3);
NSLog(@"任务3完成");
});
// 等待前三个任务完成后执行任务4
dispatch_group_notify(group, dispatch_get_main_queue(), ^{
NSLog(@"任务4开始执行");
// 任务4的逻辑
});
方法二:使用NSOperationQueue
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
NSBlockOperation *op1 = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"任务1");
sleep(2);
}];
NSBlockOperation *op2 = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"任务2");
sleep(1);
}];
NSBlockOperation *op3 = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"任务3");
sleep(3);
}];
NSBlockOperation *op4 = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"任务4");
}];
// 设置依赖关系:任务4依赖前三个任务
[op4 addDependency:op1];
[op4 addDependency:op2];
[op4 addDependency:op3];
[queue addOperations:@[op1, op2, op3, op4] waitUntilFinished:NO];
方法三:使用dispatch_semaphore
dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
__block int completedCount = 0;
dispatch_async(dispatch_get_global_queue(0, 0), ^{
NSLog(@"任务1");
sleep(2);
completedCount++;
if (completedCount == 3) dispatch_semaphore_signal(semaphore);
});
dispatch_async(dispatch_get_global_queue(0, 0), ^{
NSLog(@"任务2");
sleep(1);
completedCount++;
if (completedCount == 3) dispatch_semaphore_signal(semaphore);
});
dispatch_async(dispatch_get_global_queue(0, 0), ^{
NSLog(@"任务3");
sleep(3);
completedCount++;
if (completedCount == 3) dispatch_semaphore_signal(semaphore);
});
dispatch_async(dispatch_get_global_queue(0, 0), ^{
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
NSLog(@"任务4");
});
推荐使用dispatch_group,代码简洁且性能好。NSOperation适合需要取消、暂停等复杂操作的场景。
5. 说说你对HTTP协议的理解
HTTP是应用层协议,用于客户端和服务器之间的通信。
核心特点:
- 无状态:每次请求独立,通过Cookie/Session维持状态
- 请求-响应模型:客户端主动发起,服务器被动响应
- 基于TCP:可靠传输
- 文本协议:可读性好(HTTP/2是二进制)
工作流程:
- 客户端建立TCP连接
- 发送HTTP请求(请求行、请求头、请求体)
- 服务器处理请求
- 返回HTTP响应(状态行、响应头、响应体)
- 关闭或保持连接(Keep-Alive)
请求方法:
- GET:获取资源,幂等,参数在URL
- POST:提交数据,非幂等,参数在body
- PUT:更新资源
- DELETE:删除资源
- HEAD:只获取响应头
- OPTIONS:查询支持的方法
常见请求头:
- Host:目标主机
- User-Agent:客户端信息
- Content-Type:请求体类型
- Cookie:会话信息
- Authorization:认证信息
常见响应头:
- Content-Type:响应体类型
- Content-Length:响应体长度
- Set-Cookie:设置Cookie
- Cache-Control:缓存策略
- Location:重定向地址
6. HTTP 1.0、HTTP 1.1、HTTP 2.0有什么区别?为什么要有这么多版本?
HTTP协议不断演进是为了解决性能、安全、功能等方面的问题。
HTTP/1.0(1996年):
- 每次请求都要建立新的TCP连接,完成后立即断开
- 不支持持久连接
- 没有Host头,一个IP只能部署一个网站
- 性能差:频繁建立连接开销大
HTTP/1.1(1999年):
- 持久连接(Keep-Alive):默认开启,复用TCP连接
- 管道化(Pipelining):可以连续发送多个请求,但响应
剩余60%内容,订阅专栏后可继续查看/也可单篇购买
本专栏系统梳理C++技术面试核心考点,涵盖语言基础、面向对象、内存管理、STL容器、模板编程及经典算法。从引用指针、虚函数表、智能指针等底层原理,到继承多态、运算符重载等OOP特性从const、static、inline等关键字辨析,到动态规划、KMP算法、并查集等手写实现。每个知识点以面试答题形式呈现,注重原理阐述而非冗长代码,帮助你快速构建完整知识体系,从容应对面试官提问,顺利拿下offer。
