去哪儿 客户端 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是二进制)

工作流程:

  1. 客户端建立TCP连接
  2. 发送HTTP请求(请求行、请求头、请求体)
  3. 服务器处理请求
  4. 返回HTTP响应(状态行、响应头、响应体)
  5. 关闭或保持连接(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++八股文全集 文章被收录于专栏

本专栏系统梳理C++技术面试核心考点,涵盖语言基础、面向对象、内存管理、STL容器、模板编程及经典算法。从引用指针、虚函数表、智能指针等底层原理,到继承多态、运算符重载等OOP特性从const、static、inline等关键字辨析,到动态规划、KMP算法、并查集等手写实现。每个知识点以面试答题形式呈现,注重原理阐述而非冗长代码,帮助你快速构建完整知识体系,从容应对面试官提问,顺利拿下offer。

全部评论

相关推荐

现在是2026.2.27,距离我2025.8.16在boss上投出第一份简历以来已经过去了半年多时间了。可能许多牛友对我并不陌生,在去年的89月份,深陷实习焦虑的我不停的在牛客上发帖求助,改过的简历不知道发了多少次。因为双非本的缘故,在实习这条路上可谓是处处碰壁。boss上四位数的沟通只换来两位数的回复,好不容易约到的面试很多还因为各种原因被挂。最终在9月底遇到了我实习过程中的第一个贵人:美团实习的ld。尽管那是个测开岗,但是没有关注我实际的技术栈,而是用专业的提问让我感受到了前所未有的面试体验,发掘了自己的技术闪光点。最终让我决定放弃了另一家中小厂的后端。他们非常尊重我对开发学习的热情,也给足了我自由发挥的空间,如果不是他们让我深度参与的用例生成项目,我或许连接到后面面试的机会都没有。尽管岗位不是开发,但这个过程中对大厂工作流程的深度参与以及对业务,项目,和技术的思维提升对我后续的开发面试一样提供了巨大的帮助。时代的洪流让我们每个人都被迫卷入其中,错过了互联网的红利时期,无论实习还是秋招都令不同背景的同学倍感压力,尽管如此我们依旧要相信:努力定有回报最后祝各位27的兄弟姐妹们,在暑期实习的面试路上一路披荆斩棘,策马扬鞭,用梦中情司的offer回应自己一直以来不愿放弃的拼搏timeline:2.6一面2.11 二面2.12 三面 当天转hr面2.26 hr面,面完云证+录用评估2.27 offer
点赞 评论 收藏
分享
评论
点赞
1
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务