面试基本信息
- 公司: 顽岩资产(金融科技公司)
- 职位: Golang后端开发实习生
- 面试轮次: 一面(技术面)
- 面试形式: 在线语音面试
- 面试时长: 约47分钟
- 面试官: 技术面试官(负责机器学习平台开发)
面试问题与回答
问题1:自我介绍
面试官问题:
“先自我介绍一下”
我的回答:
“你好,我是王宇哲,现在是华东师范大学软件工程学院的研究生,主要研究方向是密码学方向。我之前本科期间获得过国家奖学金以及蓝桥杯国赛二等奖这类奖项。然后我现在主要技术栈在于Go语言。Go的话主要做了两个项目。第一个项目是叫抖音商城,它是一个分布式微服务,基于Go加gRPC的微服务架构的一个框架,一个商城系统。然后结合了一些可观测性之类的,还有消息队列redis之类的技术栈。还有一个的话是叫ANX,是我自己学习阶段的时候,自己做了一个叫AI多代理,就是分布式AI多代理架构的一个相当于让AI来进行微服务调用的一个框架。然后我之前实习的话是在业内名企实习的,主要的实习期间工作就是参与CMS系统的开发,以及一些日常维护工作。”
标准/建议回答:
其实可以这样组织会更好:
"您好,我是王宇哲,华东师范大学软件工程学院研究生,专业方向是密码学。在技术方面,我主要专注于Go语言后端开发,有两个比较重要的项目经历:
第一个是抖音商城项目,这是一个基于Go+gRPC的分布式微服务架构,我在其中负责了API网关设计、权限管理、黑名单功能等核心模块,还接入了消息队列、可观测性等技术。
第二个是ANX项目,这是一个创新性的AI多代理分布式架构,通过分层AI设计让AI能够精准调用微服务,我在其中解决了流式AI函数调用拼接等技术难点。
实习方面,我在某公司参与了CMS系统开发,使用PHP技术栈,主要负责官网重构和模板渲染优化。
在学术方面,我的研究方向是可搜索加密,主要关注模糊搜索相关的数据库技术。"
总结反思:
- 回答涵盖了基本信息,但可以更有逻辑性
- 面试官比较关注技术项目,后续主要围绕项目展开
问题2:实习项目的技术选型
面试官问题:
“实习的时候用的不是Go吧?现在还有系统在用PHP,他们是一个比较古早的系统吗?”
我的回答:
“他也不是很古早,但是当时就是因为他们官网,因为一开始它是纯静态页面的,后面的话就是加我进去,因为他们官网的话维护成本越来越高,因为它随着新闻就越来越多,因为他们公司主要业务也不是在IT上面,所以IT上面没有花很多功夫。然后我就是负责他们官网,当时是让我去写静态页面,然后我就想着既然都要写静态页面,要不把整个系统重构一下,给他直接就是让他们可以后台管理,这样的话不是省了开发的大量的时间吗?然后我们也就让我去组织这个,但是他给我要求就是要尽快完成。所以说为了快的话,我就选择了暂时先用PHP去实现它。”
标准/建议回答:
其实可以这样解释技术选型的考虑:
"确实用的是PHP,主要是基于业务需求和时间成本考虑的。当时公司官网是纯静态页面,随着内容增多维护成本很高,我提出了重构方案,将其改造为可后台管理的CMS系统。
选择PHP主要有几个原因:首先是时间要求紧迫,需要快速交付;其次PHP在Web开发方面生态成熟,特别是模板渲染这块有很多现成的轮子可以用;最后考虑到团队维护成本,PHP相对来说学习成本较低。
不过在具体实现上,我还是做了一些技术优化,比如设计了模板缓存机制,通过哈希值管理静态页面缓存,避免每次请求都重新渲染。"
总结反思:
- 回答解释了背景,但技术选型的逻辑可以更清晰
- 面试官关注技术选型的合理性
问题3:抖音商城项目架构设计
面试官问题:
“介绍一下抖音商城这个项目”
我的回答:
“抖音商城这个项目它是一个包含基本业务的一个商城系统。技术栈设计的话是使用了Go加gRPC,我专门设计了一个类似于API网关的一个东西,就是叫frontend微服务。它只直接与前端进行交互的,相当于它是进行请求转发的,然后以及去调用后台的各种gRPC服务。除此之外,它还负责把前端的token转化直接转化为user ID,以方便后面的gRPC微服务去调用。因为gRPC它基本上一般来说是部署在内网的安全的环境的。所以说不需要每个微服务它都要去解析一下token。因为这样会带来很大的开销。所以说我直接让frontend去解析完以后,丢给后台后面的几个微服务。”
标准/建议回答:
可以这样更系统地介绍架构设计:
"抖音商城是一个完整的电商系统,采用Go+gRPC的微服务架构。整体架构分为几个层次:
首先是API网关层,我设计了一个frontend微服务作为统一入口,负责几个关键功能:一是请求路由和转发,二是token解析和用户身份转换,三是统一的权限控制和黑名单管理。
这样设计的好处是,后端的gRPC微服务可以专注于业务逻辑,不需要重复处理认证授权,提高了开发效率和系统性能。
在权限管理上,我集成了casbin,并且实现了正则匹配功能,这样可以批量管理路由权限,比如/user/*下的所有子路径可以用一个规则统一管理。
黑名单功能采用了Redis+MySQL的设计,短期封禁放Redis,长期封禁存MySQL,这样既保证了查询性能,又控制了内存使用。
目前正在优化的是商品搜索功能,通过监听MySQL的binlog,实时同步数据到Elasticsearch,保证搜索数据的强一致性。"
总结反思:
- 介绍了核心架构,但可以更突出设计亮点
- 面试官对binlog监听比较感兴趣,进行了深入追问
问题4:MySQL binlog监听的替代方案
面试官问题:
“为什么要用到MySQL的binlog?在互联网公司里,可能这个binlog的权限不对研发开放。所以有没有其他的替代形式呢?”
我的回答:
“其他替代形式的话就是在代码里面嵌入一些。就比如说你直接去,每次插入的时候都给它放ES也插入一下。或者说用消息队列传递给后台专门维护ES的那个微服务,然后让他去同步一下,这是一个方案。但是这种方案的话,它最大的问题其实就是在于代码嵌入太大了,可能会对开发造成很大的开发层面上来说会有很多的工作量。”
标准/建议回答:
这个问题问得很好,确实在实际工作中binlog权限是个问题。替代方案有几种:
第一种是代码层面的双写,就是在业务代码中同时写MySQL和ES。优点是实现简单,缺点是代码侵入性强,而且存在一致性问题。
第二种是通过消息队列解耦,业务代码写完MySQL后发送消息,由专门的消费者负责同步ES。这样降低了代码侵入性,但增加了系统复杂度。
第三种是使用数据库的触发器或者存储过程,在数据变更时自动发送同步信号。
第四种是采用CDC(Change Data Capture)工具,比如Debezium,它可以监听数据库变更并推送到消息队列。
在生产环境中,我觉得消息队列方案是比较好的平衡,既保证了代码的清洁,又有较好的可靠性。至于选择哪种方案,主要看公司的技术栈和权限管理策略。
总结反思:
- 回答了替代方案,但没有深入分析各种方案的优缺点
- 面试官的问题很实际,体现了工程经验
问题5:AI多代理项目的架构设计
面试官问题:
“AIGC的那个项目,你里面写的主要都是跟gRPC和微服务架构有关的,介绍一下总体思路”
我的回答:
“他这个整体的目的就是用户输入一个指令,然后通过AI他会去解析这个指令,然后去调用相关的微服务。但是当时设计架构之初的时候,考虑到其实每一个AI的上下文是有限的。所以说他可能没有办法,如果他要管理的那个函数列表太多的话,他可能精准度就会相应的下来。所以说就调用的精准度会下来。所以说我就想到用一个分层的一种架构来实现。就比如说他有个主AI,主AI他不知道每个微服务中它具体有哪些函数,但是他知道有哪些微服务。然后他去判断用户的这个请求要交给哪些微服务去执行。然后他会把这个请求转发给对应的微服务,每个对应的微服务前面它都会有一个自己的AI,这个AI他只管理这个微服务中所有的函数列表。这样的话他就可以根据主AI的要求以及用户的要求去决定去调用哪个函数,然后去填充哪些参数,最后把整个结果返回回来。”
标准/建议回答:
这个项目的核心创新点在于分层AI架构设计,我来详细说明一下:
首先,问题背景是AI的上下文窗口有限,如果让一个AI管理所有微服务的函数列表,会导致调用精准度下降。
我的解决方案是设计了两层AI架构:
第一层是主AI(路由层),它只知道系统中有哪些微服务以及每个微服务的职责,负责根据用户请求进行分发。
第二层是专门的服务AI(执行层),每个微服务前置一个专门的AI,只管理该微服务的函数列表,负责具体的函数调用和参数填充。
技术实现上,我通过解析gRPC的proto文件,自动生成各层AI的函数清单。这样既保证了信息的准确性,又实现了自动化管理。
最大的技术难点是流式AI的函数调用拼接。因为AI是流式返回的,需要在合适的时机触发函数调用,并且正确拼接多个函数调用结果。
这种设计的优势是提高了调用精准度,缺点是增加了系统复杂度和响应时延。
总结反思:
- 说明了设计思路,但技术实现细节可以更具体
- 面试官对流式处理的技术难点比较感兴趣
问题6:系统设计开放题 - 数据版本管理
面试官问题:
“如果说我的数据集就是很大,那你现在要设计这个东西,你会怎么想的?就比如说我现在设计的这个模型仓库,一个模型可能几十兆几百兆,但是一个数据集可能是几十G或者几T的规模。他每次会有一些新增,但我有的时候还是要用上个版本的,你怎么去做管理呢?”
我的回答:
“我的想法就是能不能从索引上去思考这个问题。就比如说我们不做文件的管理,我们去做索引的管理。版本化的话,我们第一个版本它会有一个索引文件,第二个版本它会有另一个索引文件。然后我们要每次去加载数据集的时候,我们走这个索引,而不是去直接找所有的文件。然后文件的话全都堆在那一块就行了。”
标准/建议回答:
这是一个很好的大数据版本管理问题。我认为可以从几个角度来设计:
首先,索引化管理的思路是对的。我们可以设计一个类似Git的版本管理机制:
-
文件去重:使用内容哈希(如SHA256)作为文件唯一标识,相同内容的文件只存储一份。
-
增量存储:每个版本只存储相对于父版本的变更,包括新增、删除、修改的文件列表。
-
索引结构:每个版本维护一个索引文件,记录该版本包含的所有文件及其哈希值。索引文件本身也可以采用分层结构,支持快速查找。
-
存储优化:
- 热数据放SSD,冷数据放普通磁盘
- 对于大文件,可以考虑分块存储
- 使用压缩技术减少存储空间
-
版本树管理:支持分支和合并,就像Git那样。
具体实现上,可以用一个元数据数据库(如MySQL)管理版本关系和文件索引,用对象存储(如MinIO)管理实际文件内容。
这样既保证了存储效率,又支持灵活的版本管理。
总结反思:
- 回答了基本思路,但实现细节不够深入
- 这是一个很好的开放性系统设计题,考察架构思维
问题7:研究方向相关
面试官问题:
“你是学密码学的,没有去做一些跟密码学有关的项目或者实习吗?”
我的回答:
“密码学相关的项目没有。因为密码学的话其实好像没有很多对口的专对口的岗位,除了区块链。”
标准/建议回答:
确实密码学相关的岗位相对较少,但我的研究方向是可搜索加密,主要关注模糊搜索方面。虽然没有直接的密码学项目,但我觉得这个研究背景对后端开发还是有帮助的:
第一,密码学的严谨性训练了我的逻辑思维能力,这在系统设计和算法优化上很有用。
第二,可搜索加密涉及大量的数据库和索引技术,这与后端开发中的数据存储和检索优化是相通的。
第三,我平时会阅读很多数据库相关的论文,对前沿技术保持敏感度。
目前我还是希望专注于后端开发方向,因为我更享受解决工程问题的过程,而且Go语言的简洁性很符合我的编程风格。
当然,如果将来有机会,我也很愿意将密码学知识应用到数据安全、隐私保护等相关领域。
总结反思:
- 回答过于简单,没有体现研究背景的价值
- 可以将学术背景与工程实践联系起来
面试整体感受
- 难度评价: 适中,主要考察项目经验和架构思维
- 面试官风格: 专业友善,会根据回答深入追问技术细节
- 题目类型: 项目讲解(60%) + 系统设计(30%) + 背景了解(10%)
- 准备建议: 重点准备项目架构和技术选型的逻辑,要能说清楚为什么这样设计
面试结果
- 当场反馈: 面试官介绍了公司业务方向,询问了个人规划
- 后续流程: 面试官表示会考虑,后续HR会联系
- 个人感受: 整体交流比较顺畅,面试官对AI项目比较感兴趣
经验总结
做得好的地方
- 项目介绍比较完整,覆盖了技术栈和业务场景
- 对系统设计有自己的思考
- 回答问题比较诚实,不懂的地方不胡编乱造
需要改进的地方
- 技术细节表达不够准确,有些地方逻辑不够清晰
- 对开放性问题的思考深度不够
- 学术背景与工程实践的结合可以更好
准备建议
- 项目经验要深入:不仅要说做了什么,还要说为什么这样做,遇到了什么问题,如何解决的
- 系统设计要练习:多做一些开放性的架构设计题,培养全局思维
- 技术表达要准确:专业术语要用准确,技术方案要有逻辑
- 背景经历要串联:将学术背景、项目经验、个人规划串成一条主线
知识点复习
- Go语言GMP模型和并发机制
- 微服务架构设计原则
- 分布式系统数据一致性方案
- MySQL binlog原理和CDC技术
- 系统设计中的数据存储和版本管理
- AI工程化和流式处理技术
总的来说,这是一次很好的技术面试体验,面试官专业水平很高,问题有深度也很实际。对于准备后端开发岗位的同学,建议多关注系统设计和工程实践,不仅要会写代码,还要能设计系统。