腾讯-微信支付C++ 二面 面经总结

1. 介绍一下你做过的最有挑战性的项目,遇到了什么技术难点,如何解决的?

回答框架:

  • 项目背景:简要说明项目目标和技术栈
  • 技术挑战:具体描述遇到的核心问题(性能瓶颈、并发问题、架构设计等)
  • 解决方案:详细说明采用的技术方案和实现细节
  • 效果量化:用数据说明优化效果(性能提升X%、响应时间降低等)
  • 反思总结:学到了什么,还有哪些改进空间

示例:"我做过一个高并发的订单处理系统。最大的挑战是在秒杀场景下,数据库成为瓶颈,出现大量超时。我采用了多级缓存架构:Redis缓存库存,本地缓存热点数据,使用Lua脚本保证原子性扣减库存。同时引入消息队列异步处理订单,削峰填谷。最终QPS从2000提升到15000,响应时间从500ms降到50ms以内。"

2. 你的项目中使用了哪些设计模式?为什么选择这些模式?

常用设计模式及应用场景:

  • 单例模式:数据库连接池、日志管理器、配置管理器。保证全局唯一实例,注意线程安全(双重检查锁、局部静态变量)
  • 工厂模式:创建不同类型的对象,解耦对象创建和使用。如根据配置创建不同的消息处理器
  • 策略模式:支付方式选择(微信、支付宝、银行卡),不同的加密算法。避免大量if-else
  • 观察者模式:事件通知系统,订单状态变化通知多个模块
  • 装饰器模式:给对象动态添加功能,如日志、性能监控、权限检查
  • 责任链模式:请求处理流程,如参数校验→权限验证→业务处理→日志记录

选择原则:根据实际需求,不要为了用设计模式而用。重点是代码的可维护性、可扩展性和可读性。

3. 你们的系统是如何保证高可用的?如果服务器宕机了怎么办?

高可用架构设计:

  1. 冗余部署:多机房部署,异地容灾负载均衡(Nginx、LVS)分发流量无状态服务,方便水平扩展
  2. 故障检测:健康检查(心跳机制)监控告警(Prometheus、Grafana)日志收集分析(ELK)
  3. 故障恢复:自动重启机制服务降级:关闭非核心功能熔断机制:防止雪崩效应限流:保护系统不被压垮
  4. 数据可靠性:数据库主从复制、读写分离Redis哨兵或集群模式定期备份,快速恢复
  5. 灰度发布:小流量验证快速回滚机制

目标:99.99%可用性(年停机时间<53分钟)。

4. 如何设计一个分布式锁?需要考虑哪些问题?

实现方案:

方案一:基于Redis的分布式锁

// 加锁:SET key value NX PX 30000
bool lock(string key, string requestId, int expireTime) {
    return redis.set(key, requestId, "NX", "PX", expireTime);
}

// 解锁:Lua脚本保证原子性
bool unlock(string key, string requestId) {
    string script = R"(
        if redis.call('get', KEYS[1]) == ARGV[1] then
            return redis.call('del', KEYS[1])
        else
            return 0
        end
    )";
    return redis.eval(script, {key}, {requestId});
}

方案二:基于Zookeeper

  • 创建临时顺序节点
  • 最小序号获得锁
  • 监听前一个节点,避免羊群效应

需要考虑的问题:

  1. 互斥性:同一时刻只有一个客户端持有锁
  2. 死锁:设置过期时间,防止客户端崩溃导致锁无法释放
  3. 锁误删:使用唯一标识(UUID),只能删除自己的锁
  4. 原子性:加锁和设置过期时间必须原子操作
  5. 可重入:同一线程可以多次获取锁(记录持有者和计数)
  6. 锁续期:业务执行时间超过过期时间,需要自动续期(看门狗机制)
  7. 高可用:Redis集群模式,Redlock算法(多个独立Redis实例)
  8. 性能:自旋等待 vs 阻塞等待

推荐使用成熟的库如Redisson,已经处理了这些细节问题。

5. 你们的日志系统是怎么设计的?如何处理海量日志?

日志系统设计要点:

  1. 日志级别:DEBUG、INFO、WARN、ERROR、FATAL生产环境通常只记录INFO及以上
  2. 日志格式:时间戳、日志级别、线程ID、文件位置、消息内容结构化日志(JSON格式),便于解析
  3. 日志输出:异步写入,避免阻塞业务线程双缓冲机制:前台缓冲收集,后台缓冲写入日志轮转:按大小或时间切割文件
  4. 性能优化:使用线程局部存储减少锁竞争批量写入,减少系统调用内存映射文件(mmap)提高IO性能
  5. 海量日志处理:分布式日志收集(Filebeat、Fluentd)集中存储(Elasticsearch)可视化分析(Kibana)日志采样:高频日志只记录部分
  6. 关键信息:请求ID(traceId):串联整个调用链用户ID、订单号等业务标识耗时统计

实现示例:

class Logger {
    void log(Level level, const string& msg) {
        if (level < minLevel_) return;
        
        LogEntry entry{time(), level, threadId(), msg};
        frontBuffer_.append(entry);
        
        if (frontBuffer_.full()) {
            swap(frontBuffer_, backBuffer_);
            notify_writer_thread();
        }
    }
};

6. 如果让你设计微信红包系统,你会怎么设计?

核心需求分析:

  • 发红包:指定金额和个数,生成红包
  • 抢红包:高并发场景,先到先得
  • 查看红包:已领取列表、剩余金额

技术挑战:

  • 高并发:春节期间QPS极高
  • 一致性:金额不能超发
  • 公平性:随机金额算法
  • 性能:毫秒级响应

设计方案:

  1. 红包生成:二倍均值法:保证随机且公平预先生成所有金额,存入Redis列表红包ID、总金额、剩余个数、领取记录
  2. 抢红包流程:Redis原子操作(LPOP)获取金额乐观锁检查剩余个数异步写入数据库(消息队列)返回结果
  3. 数据存储:Redis:红包信息、剩余金额列表(热数据)MySQL:红包记录、领取记录(持久化)最终一致性:先Redis后DB,失败重试
  4. 高并发优化:分片:按红包ID哈希分散到不同Redis实例限流:单个红包QPS限制降级:超时直接返回"手慢了"
  5. 防刷机制:同一用户只能领一次(Redis Set记录)IP限流风控系统
  6. 监控告警:实时监控抢红包成功率金额对账:Redis和DB定期核对

核心代码逻辑:

bool grabRedPacket(string packetId, string userId) {
    // 1. 检查是否已领取
    if (redis.sismember("grabbed:" + packetId, userId)) {
        return false; // 已领取
    }
    
    // 2. 原子获取金额
    string amount = redis.lpop("amounts:" + packetId);
    if (amount.empty()) {
        return false; // 已抢完
    }
    
    // 3. 记录领取
    redis.sadd("grabbed:" + packetId, userId);
    
    // 4. 异步写DB
    mq.send({packetId, userId, amount});
    
    return true;
}

7. 说说你对微服务架构的理解,以及遇到的问题和解决方案

微服务架构特点

剩余60%内容,订阅专栏后可继续查看/也可单篇购买

C++八股文全集 文章被收录于专栏

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

全部评论

相关推荐

一面&nbsp;情况:通过面经:百度后台开发实习一面&nbsp;-&nbsp;大概40min1.&nbsp;自我介绍2.&nbsp;大二实习的话时间能兼顾吗3.&nbsp;常见数据结构了解过吗&nbsp;说一下栈和队列的区别4.&nbsp;用Golang手撕一个二分查找在数组中找到目标值(第一次手撕遇到这个内心暗暗自喜觉得面试官不为难我太好了)5.&nbsp;Go语言学了多久6.&nbsp;HTTP和HTTPS的区别7.&nbsp;你说你项目里面用到了gRPC&nbsp;说一下RPC和HTTP的区别8.&nbsp;从浏览器输入一个网址到渲染页面出来的全过程背后是怎么样的9.&nbsp;接口请求是怎么打到一个后端服务的(我重点答了打到服务器之后会根据端口去区分)10.&nbsp;MySQL的索引是什么11.&nbsp;实际开发过程中用过什么索引&nbsp;讲一下12.&nbsp;项目中是怎么用Redis的&nbsp;用了哪些数据类型&nbsp;说一下13.&nbsp;MySQL聚簇索引和非聚簇索引的区别14.&nbsp;进程&nbsp;线程&nbsp;协程有什么区别15.&nbsp;你对项目部署了解多少&nbsp;Docker这些有用过吗16.&nbsp;平时开发用的是windows系统还是linux17.&nbsp;熟悉linux基本命令吗&nbsp;比如查看一个文件的最后几行内容用什么命令知道吗18.&nbsp;写完二分查找之后又问了我一个微信红包的场景题&nbsp;怎么保证微信红包的金额尽可能随机然后每个人抢到的概率随机&nbsp;怎么去设计(这个场景题我没怎么接触过&nbsp;答的不是很好)19.&nbsp;常见设计模式了解过吗二面情况:通过面经:百度后台开发实习二面&nbsp;-&nbsp;大概35min1.&nbsp;自我介绍2.&nbsp;你项目中用到的SingleFlight合并请求解决缓存穿透是怎么用的&nbsp;说一下3.&nbsp;有没有看过SingleFlight的底层实现原理?说一下4.&nbsp;如果让你用Go来实现这个&nbsp;你会怎么做&nbsp;说一下思路5.&nbsp;你提到了channel&nbsp;你知道channel的底层实现原理吗&nbsp;有缓冲的channel和无缓冲的channel有什么区别?6.&nbsp;项目中有没有遇到什么难点?7.&nbsp;说一下你的MySQL和ES的一致性是怎么做的?8.&nbsp;你说到用到了Kafka去消费消息&nbsp;那你怎么保证最终同步过去后MySQL和ES同步成功(我一直在答Kafka消费失败的重试机制&nbsp;死信队列那些&nbsp;然后面试官说他想问的是怎么确定MySQL和ES同步成功了&nbsp;我说可以考虑设计一个后台脚本来定期读取MySQL和ES&nbsp;然后判断是否一致)9.&nbsp;手撕题目:给你一个字符串表达式&nbsp;s&nbsp;,请你实现一个基本计算器来计算并返回它的值。注意:不允许使用任何将字符串作为数学表达式计算的内置函数,比如&nbsp;eval()&nbsp;。示例&nbsp;1:输入:s&nbsp;=&nbsp;&quot;1&nbsp;+&nbsp;1&quot;输出:2示例&nbsp;2:输入:s&nbsp;=&nbsp;&quot;&nbsp;2-1&nbsp;+&nbsp;2&nbsp;&quot;输出:3示例&nbsp;3:输入:s&nbsp;=&nbsp;&quot;(1+(4+5+2)-3)+(6+8)&quot;输出:23提示:1&nbsp;&lt;=&nbsp;s.length&nbsp;&lt;=&nbsp;3&nbsp;*&nbsp;105s&nbsp;由数字、'+'、'-'、'('、')'、和&nbsp;'&nbsp;'&nbsp;组成s&nbsp;表示一个有效的表达式'+'&nbsp;不能用作一元运算(例如,&nbsp;&quot;+1&quot;&nbsp;和&nbsp;&quot;+(2&nbsp;+&nbsp;3)&quot;&nbsp;无效)'-'&nbsp;可以用作一元运算(即&nbsp;&quot;-1&quot;&nbsp;和&nbsp;&quot;-(2&nbsp;+&nbsp;3)&quot;&nbsp;是有效的)输入中不存在两个连续的操作符每个数字和运行的计算将适合于一个有符号的&nbsp;32位&nbsp;整数后来才知道原来这个是Hot150题库上的一道&nbsp;Hard&nbsp;224.&nbsp;基本计算器&nbsp;之前没刷过&nbsp;还是自己准备不足(我一开始一直想用双栈法去做&nbsp;一个栈存数字一个栈存运算符&nbsp;但是当时可能是看到这道题是Hot100之外的&nbsp;并且面试官一直看着我有点紧张所以就有一些细节一直没写对&nbsp;最后面试官告诉我想复杂了&nbsp;可以更简单一点)10.&nbsp;最近在学习什么后端的方向11.&nbsp;有用过Linux吗&nbsp;平时开发用的是Windows还是linux觉得自己二面表现得很差&nbsp;应该是要挂掉我了&nbsp;没想到隔天HR打电话告诉我一二面都过了&nbsp;但是因为只剩下一个hc了&nbsp;想要更充分了解候选人所以再约一个三面&nbsp;然后这个时候官网进度那里面试环节已经是打勾了三面情况:三面后刷新官网已挂三面没有问任何技术相关的&nbsp;15分钟就结束了(面试官说一二面已经问过技术了我就不问了&nbsp;心里瞬间就放松了&nbsp;而且三面那天还发烧了)&nbsp;单纯聊天&nbsp;问我一些职业规划&nbsp;还有一些个人情况什么的&nbsp;然后面试官还问我为什么大二就出来实习&nbsp;身边大二出来实习的多不多&nbsp;未来规划是什么&nbsp;我说我对技术很热爱&nbsp;想学到企业开发的技术锻炼更多实战经验&nbsp;然后他还问我你们学校是不是就在旁边&nbsp;我说我骑个车三四分钟就到了哈哈哈(其实我经常去百度大厦下面吃麦当劳)&nbsp;还问了我一些职场中的问题比如给你十个任务&nbsp;每个任务优先级不一样&nbsp;Deadline也不一样&nbsp;如果是你的话你要怎么去在有限的时间内完成这些任务&nbsp;&nbsp;感觉是HR面不是技术面&nbsp;最后还问了我多大&nbsp;聊天还挺愉快的最后自己觉得应该是被横向评估挂掉了&nbsp;不过还是很感谢百度给了我人生中第一次面试的机会&nbsp;遇到的面试官都都挺不错的&nbsp;虽然面到了三面后把我挂了还是有点浇冷水的失落感&nbsp;甚至三面之前官网进度那里面试那个选项就已经是打勾了的&nbsp;然后三面完突然变成灰色了&nbsp;诶&nbsp;继续沉淀吧
Andrew1219:
点赞 评论 收藏
分享
评论
1
收藏
分享

创作者周榜

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