2025年2月凉面与热面(1)——杭州AI公司一二面

1,994 阅读9分钟

前言

这次面试算是我的首次战斗,在元宵过后开投 , 我觉得其重要性犹如南昌八一广场打响的第一枪 , 战争正式开始了 , 我拿着大二的“小卡拉米简历” 广泛撒网 ,经历了很多次“已读不回” ,也是约来一次面试 , 直接看面经

一面:

二面:

下面做简介 , 后期闭关将会深入些文章 ~ , 点赞关注不迷路 , 给你新鲜的面经!

无字动图.gif

一面要点


1. 原型链

深度解析:
原型链是 JavaScript 实现继承的核心机制。每个对象都有一个隐藏属性 [[Prototype]](可通过 __proto__Object.getPrototypeOf 访问),指向其原型对象。当访问一个对象的属性时,如果对象本身没有该属性,JavaScript 会沿着原型链向上查找,直到找到该属性或到达原型链的顶端(null)。

  • 原型链的终点:所有对象的原型链最终都会指向 Object.prototype,而 Object.prototype 的原型是 null
  • 构造函数与原型:每个构造函数都有一个 prototype 属性,指向其原型对象。实例对象的 __proto__ 指向构造函数的 prototype
  • 性能问题:原型链过长会导致属性查找效率降低,尤其是在深层嵌套的原型链中。

示例:

function Person(name) {
    this.name = name;
}
Person.prototype.sayName = function() {
    console.log(this.name);
};

const person = new Person('Alice');
person.sayName(); // 输出: Alice
console.log(person.__proto__ === Person.prototype); // true
console.log(Person.prototype.__proto__ === Object.prototype); // true
console.log(Object.prototype.__proto__ === null); // true

2. 实现继承

深度解析:
JavaScript 的继承方式有多种,每种方式都有其适用场景和优缺点。

  1. 原型链继承
function Parent() {
    this.name = 'Parent';
}
Parent.prototype.sayName = function() {
    console.log(this.name);
};

function Child() {}
Child.prototype = new Parent(); // 继承

const child = new Child();
child.sayName(); // 输出: Parent
- 优点:简单,易于实现。
- 缺点:所有实例共享原型属性,修改一个实例的原型属性会影响其他实例。

2. 构造函数继承

function Parent(name) {
    this.name = name;
}

function Child(name) {
    Parent.call(this, name); // 继承属性
}

const child = new Child('Alice');
console.log(child.name); // 输出: Alice
- 优点:可以传递参数,避免共享属性。
- 缺点:无法继承父类原型上的方法。

3. 组合继承

function Parent(name) {
    this.name = name;
}
Parent.prototype.sayName = function() {
    console.log(this.name);
};

function Child(name) {
    Parent.call(this, name); // 继承属性
}
Child.prototype = new Parent(); // 继承方法

const child = new Child('Alice');
child.sayName(); // 输出: Alice
- 结合原型链继承和构造函数继承的优点。
- 缺点:父类构造函数被调用两次,性能开销较大。

4. 寄生组合继承

function Parent(name) {
    this.name = name;
}
Parent.prototype.sayName = function() {
    console.log(this.name);
};

function Child(name) {
    Parent.call(this, name); // 继承属性
}
Child.prototype = Object.create(Parent.prototype); // 继承方法
Child.prototype.constructor = Child;

const child = new Child('Alice');
child.sayName(); // 输出: Alice
- 最优解决方案,避免了组合继承的缺点。
- 使用 `Object.create` 创建原型链,避免调用父类构造函数。

3. 虚拟 DOM

深度解析:
虚拟 DOM 是 React 的核心技术之一,用于优化 UI 更新的性能。

  1. 工作原理
    • 虚拟 DOM 是一个轻量级的 JavaScript 对象树,表示真实 DOM 的结构。
    • 当状态发生变化时,React 会生成新的虚拟 DOM 树,并与旧的虚拟 DOM 树进行对比(Diff 算法)。
    • 通过对比,React 计算出最小的 DOM 操作,然后批量更新真实 DOM。
  2. Diff 算法
    • 层级对比:React 只会对比同一层级的节点,不会跨层级对比。
    • Key 的作用:通过 key 属性标识节点,帮助 React 识别哪些节点是新增、删除或移动的。
  3. 优点
    • 减少直接操作真实 DOM 的次数,提高性能。
    • 提供跨平台能力(如 React Native)。
  4. 缺点
    • 虚拟 DOM 的创建和对比需要额外的计算开销,对于简单页面可能不如直接操作 DOM 高效。

juejin.cn/post/684490…

4. 对 TS 的了解程度

深度解析:
TypeScript 是 JavaScript 的超集,添加了静态类型系统,适合大型项目开发。

  1. 核心特性
    • 类型注解:通过 : type 语法为变量、函数参数和返回值添加类型。
    • 接口:定义对象的结构,支持可选属性和只读属性。
    • 泛型:提高代码的复用性和类型安全性。
    • 装饰器:用于元编程,常用于 Angular 框架。
  2. 工具链
    • tsc:TypeScript 编译器,将 TS 代码编译为 JS。
    • tsconfig.json:配置文件,定义编译选项。
  3. 实际应用
    • 在 React 项目中,使用 TypeScript 可以显著提高代码的可维护性,减少运行时错误。

juejin.cn/post/687211…


5. React 和 Vue 你爱谁?

深度解析:
React 和 Vue 都是优秀的前端框架,但设计哲学和适用场景不同。

  1. React
    • 优点
      • 灵活,生态丰富(如 Redux、React Router)。
      • 函数式编程思想,适合大型项目。
    • 缺点
      • 学习曲线较陡峭。
      • JSX 语法需要适应。
  2. Vue
    • 优点
      • 模板语法直观,易于上手。
      • 官方工具链完善(如 Vuex、Vue Router)。
    • 缺点
      • 灵活性较低,生态相对较小。

个人倾向
我更倾向于 React,因为它的函数式编程思想和 JSX 语法让我感到更加自由和高效。

juejin.cn/post/707188…


6. 项目部署经验?Docker?

深度解析:

  1. 项目部署
    • 使用 CI/CD 工具(如 Jenkins、GitLab CI)实现自动化部署。
    • 通过 Nginx 配置反向代理和负载均衡。
  2. Docker
    • 使用 Dockerfile 定义镜像构建步骤。
    • 使用 Docker Compose 管理多容器应用。
    • 通过 Kubernetes 实现容器编排。

7. 状态管理?底层原理?

深度解析:

  1. 状态管理工具
    • Redux:基于单向数据流,通过 Action 触发 Reducer 更新 Store。
    • MobX:基于响应式编程,通过观察者模式自动更新状态。
    • Context API:React 内置的状态管理工具,适合小型项目。
  2. Redux 底层原理
    • Store:存储全局状态。
    • Action:描述状态变化的动作。
    • Reducer:纯函数,根据 Action 更新状态。
    • Middleware:扩展 Redux 功能(如异步操作)。

我对 redux 理解深一点

8. 观察者模式和发布订阅

深度解析:

  1. 观察者模式
    • Subject 维护一组 Observers,状态变化时通知 Observers。
    • 强耦合,Subject 需要知道 Observers 的存在。
  2. 发布订阅模式
    • 通过 Event Bus 解耦发布者和订阅者。
    • 发布者不需要知道订阅者的存在。

这篇不错 :

juejin.cn/post/697872…


9. IoC 和 DI

深度解析:

  1. IoC(控制反转)
    • 将对象的创建和依赖关系的管理交给外部容器。
    • 降低代码耦合度。
  2. DI(依赖注入)
    • 通过构造函数、属性或方法注入依赖对象。
    • 提高代码的可测试性和可维护性。

10. LangChain 框架解决了什么问题?

深度解析:
LangChain 是一个用于构建基于大语言模型(LLM)应用的框架,解决了以下问题:

  1. 外部数据集成:将 LLM 与外部数据源(如数据库、API)集成。
  2. 工具链支持:提供预定义的工具链(如搜索、计算)。
  3. 记忆管理:通过 Memory 模块管理对话历史。

11. 什么是 RAG?

深度解析:
RAG(Retrieval-Augmented Generation)是一种结合检索和生成的模型架构:

  1. 检索阶段:从外部知识库中检索相关信息。
  2. 生成阶段:将检索到的信息与输入一起输入生成模型,生成更准确的输出。

12. 向量嵌入

深度解析:
向量嵌入是将高维数据映射到低维向量空间的技术:

  1. 应用场景:文本分类、语义搜索、推荐系统。
  2. 常用算法:Word2Vec、GloVe、BERT。

13. 相似性检索的原理

深度解析:

  1. 计算相似度:通过余弦相似度、欧氏距离等度量向量之间的距离。
  2. 算法:KNN(精确检索)、ANN(近似检索)。

14. AI 流式输出的底层原理

深度解析:

  1. 逐步生成:模型逐步生成输出序列,每一步都依赖于前一步的输出。
  2. 输出缓冲:通过缓冲区逐步返回部分结果。

juejin.cn/post/743566…


15. 大模型是如何推理的?


我浅浅的说了下

  • 自注意机制
  • 和基于概率的涌现性智能观点

专业的看下:

zhuanlan.zhihu.com/p/628511161


16. 各类模型的对比

主要讲了下哪些模型擅长什么

  • deepseek v3 deepseek r1
  • gpt
  • claude
  • ....

zhuanlan.zhihu.com/p/167261751…


17. 是否发布模型?

没有 , 回答了一些 coze 智能体的发布和 魔搭社区的应用


18. 如何实现 LangChain Memory

可以看看我的专栏 :juejin.cn/post/746337…

二面要点

大文件上传:juejin.cn/post/746723…

算法在项目中的应用

  • 贪心算法
    • 任务调度:在生产调度、工作流管理场景中,存在多个需按序执行且耗费时间和资源的任务。例如,一台机器一天内要完成多个工作量不同的任务,使用贪心算法,每次选择工作量最小的任务先做,能在有限时间内完成尽可能多的任务,提高生产效率。实际应用中还会结合任务优先级、资源限制、任务依赖关系等因素灵活调整 。
    • 背包问题(部分情况):在简单的背包问题里,已知背包容量固定,有多种物品,每个物品有各自的重量和价值,贪心算法可依据价值重量比(或其他策略),优先选择能使背包价值增加最多的物品放入,直到背包装满 。
    • 最短路径(部分算法):像 Dijkstra 算法,用于求单源最短路径,是贪心算法的典型应用。每次选择距离源点最近且未确定最短路径的顶点,更新其邻接顶点的距离,逐步确定所有顶点的最短路径 。
    • 股票交易:在交易次数无限制,且任何时候最多持有一股股票的情况下,只要股票价格上涨就进行交易获取利润,通过统计所有上涨带来的利润,得到最大收益 。
  • 动态规划
    • 资源分配:当项目资源有限,需分配给多个子项目或任务时,动态规划可通过分析不同分配方案下的收益情况,考虑资源约束和各子项的依赖关系等,找到使总收益最大的资源分配策略。比如,将有限的研发资金分配到不同产品的研发中 。
    • 最优路径规划:在地图导航等场景中,要考虑路况、距离、时间等多个因素找到从起点到终点的最优路径。动态规划可将路径问题分解为多个子问题,通过求解子问题并记录结果,避免重复计算,从而高效找到最优解 。
    • 最长公共子序列:在文本处理、版本控制等领域,比较两个序列(如文本段落、代码版本)的相似性时,可利用动态规划找出它们的最长公共子序列,从而确定修改、添加或删除的部分 。
    • 生产库存管理:考虑生产成本、库存成本、市场需求的不确定性等因素,动态规划能帮助制定最优的生产和库存策略,以最小化总成本 。

总结

首站大捷 , 然长路漫漫 , 大二财哥已然薪水 550 / 天, 实现我团首富 , 我当脚踏实地 , 仰望星空 ~ , 争取可以看到他的后背🤡 ~