Skip to content

面试技巧

一: 面试真相 提升面试通过率

  1. 基础个人信息
  2. 2~3个负责或者参与的工作项目
  3. 谈谈对当前这份工作岗位的理解和人岗匹配度

基础信息: 面试官您好, 我叫vine web, 目前工作第七年, 这七年来一直做的是前端方面的工作, 有web端, H5, 小程序, 混合app等开发经验, 有过电商, 政府项目(图表类, 台账类, 地图类, gis, 大屏, 适配等), 公司官网, 公司后台管理平台, 配置平台等大量工作经历

总结项目: 有过百万级用户的"村景拍拍"小程序, 住建部内的 房改系统 和 灾后重建系统建设, 也有后台管理, 后台配置平台, 前端是跟用户打交道最多的一类程序员, 深切能感知用户的使用和交互

人岗匹配: 通过前期的了解, 知道贵公司是很注重产品和用户体验, 和我的价值观很相似, 并且我相信我过去的经验和我的认知很匹配这个岗位的要求, 希望今天能和你有一个非常愉快的交流

  1. 自我介绍很重要
  2. 项目经验star法则 要尽量让面试官听懂
  3. 诚实
  4. 90%核心岗留给内推和猎头
  5. 面试是棋逢对手的较量 尽量与面试官沟通交流
  6. 谈薪勇于说出自己诉求
  7. 反问面试官是送命题 不同层级面试官可问对应的有深度思考的问题 // 思考自己的岗位 -- 公司岗位定位, --- 业务的规划
  8. 展示自己的兴趣爱好有好处 15-20

二: 如何通过非投递得到面试机会

  1. 找知乎、论坛里的大佬毛遂自荐,不过要准备自己的作品集和相应能展现自身能力的作品
  2. 曲线救国
  3. 人脉破圈

三: 简历

  1. 面试技巧 应该是解决了什么具体业务问题、技术问题

产生了什么业务价值 技术价值

四: 面试

  1. 假设你现在是面试官,要面试xx公司xx岗位,现在需要你根据以下岗位需求,从基本面、专业面、沟通协作和团队管理四个维度,预测面试中可能被问到的10个问题+招聘岗位需求
  2. 假设你现在是xx公司面试官,要面试xx岗位,现在你问了xx问题,请给出你最欣赏的候选人的回答思路。
  3. 假设你是面试者,要面试xx公司xx岗位,现在面试官问了xx问题,请你做出回答

五 chatgpt

  • 01 预测重合度, 考察ChatGPT模拟面试问出的问题, 有多少真实面试过程中, 面试官实际会问到?
  • 02 回答满意度, 考察ChatGPT针对某一问题的实际回答, 面试官实际满意度
  • 03 思路满意度, 考察ChatGPT针对某一问题提供的回答思路, 面试官实际满意度

六 常见问题

自我介绍 面试完你还有什么问题要问的吗? 你的期望薪资是多少? 未来三到五年的规划是怎样的? 你的项目中技术难点是什么?遇到了什么问题?你是怎么解决的? 说下⼯作中你做过的⼀些性能优化处理? 你最有成就感的⼀件事? 离职原因? 你对加班的怎么看?

七 设计模式

前端设计模式是解决常见问题的一套最佳实践和标准方法,通过应用这些模式,可以提高代码的可维护性、可重用性和可扩展性。以下是一些可以探讨的前端设计模式,以及相关的具体问题:

常见的前端设计模式

  1. 模块化模式(Module Pattern)
  2. 单例模式(Singleton Pattern)
  3. 观察者模式(Observer Pattern)
  4. 发布-订阅模式(Pub-Sub Pattern)
  5. 工厂模式(Factory Pattern)
  6. 策略模式(Strategy Pattern)
  7. 装饰者模式(Decorator Pattern)
  8. 适配器模式(Adapter Pattern)
  9. 代理模式(Proxy Pattern)
  10. 组合模式(Composite Pattern)
  11. 状态模式(State Pattern)
  12. 命令模式(Command Pattern)
  13. MVC模式(Model-View-Controller)
  14. MVVM模式(Model-View-ViewModel)

具体问题

模块化模式(Module Pattern)

  1. 如何使用模块化模式来组织和管理前端代码?
  2. 在ES6中,如何利用import和export来实现模块化?
  3. 使用模块化模式的优缺点是什么?

单例模式(Singleton Pattern)

  1. 如何在JavaScript中实现单例模式?
  2. 单例模式在前端开发中有哪些典型的应用场景?
  3. 使用单例模式有哪些潜在的问题?

观察者模式(Observer Pattern)

  1. 如何在JavaScript中实现观察者模式?
  2. 观察者模式与发布-订阅模式的区别是什么?
  3. 观察者模式在前端开发中的应用有哪些?

发布-订阅模式(Pub-Sub Pattern)

  1. 如何使用发布-订阅模式来实现松耦合的组件通信?
  2. 常见的发布-订阅库有哪些?如何使用它们?
  3. 发布-订阅模式的优缺点是什么?

工厂模式(Factory Pattern)

  1. 如何在JavaScript中实现工厂模式?
  2. 工厂模式在创建复杂对象时有哪些优势?
  3. 使用工厂模式有哪些注意事项?

策略模式(Strategy Pattern)

  1. 如何在JavaScript中实现策略模式?
  2. 策略模式在前端开发中的应用场景有哪些?
  3. 策略模式与状态模式的区别是什么?

装饰者模式(Decorator Pattern)

  1. 如何在JavaScript中实现装饰者模式?
  2. 装饰者模式如何增强对象的功能?
  3. 使用装饰者模式有哪些优缺点?

适配器模式(Adapter Pattern)

  1. 如何在JavaScript中实现适配器模式?
  2. 适配器模式如何帮助解决接口不兼容的问题?
  3. 适配器模式的典型应用场景有哪些?

代理模式(Proxy Pattern)

  1. 如何在JavaScript中实现代理模式?
  2. 代理模式在前端开发中的应用有哪些?
  3. 代理模式与装饰者模式的区别是什么?

组合模式(Composite Pattern)

  1. 如何在JavaScript中实现组合模式?
  2. 组合模式如何处理树形结构的数据?
  3. 使用组合模式的优缺点是什么?

状态模式(State Pattern)

  1. 如何在JavaScript中实现状态模式?
  2. 状态模式如何简化状态转换的管理?
  3. 使用状态模式有哪些注意事项?

命令模式(Command Pattern)

  1. 如何在JavaScript中实现命令模式?
  2. 命令模式如何实现操作的撤销和重做?
  3. 命令模式的典型应用场景有哪些?

MVC模式(Model-View-Controller)

  1. MVC模式如何分离关注点,提升代码可维护性?
  2. MVC模式在现代前端框架中的实现有哪些?
  3. MVC模式的优缺点是什么?

MVVM模式(Model-View-ViewModel)

  1. MVVM模式如何通过双向数据绑定简化UI更新?
  2. MVVM模式在前端框架中的实现有哪些?
  3. MVVM模式与MVC模式的区别是什么?

深入探讨的问题

  1. 如何选择合适的设计模式来解决特定的问题?
  2. 在前端开发中,如何组合使用多种设计模式?
  3. 设计模式的使用如何影响代码的性能和可维护性?
  4. 有哪些常见的设计模式反例(anti-patterns)?如何避免它们?

具体应用

  1. 在React/Vue/Angular中,如何应用这些设计模式?
  2. 如何在大型前端项目中实施设计模式?
  3. 有哪些实际案例展示了设计模式的应用?

这些问题可以帮助深入理解和应用前端设计模式,提高前端开发的质量和效率。

八 具体的应用和实现

好的,下面我将为每个设计模式提供具体的应用场景和实现方式。

1. 模块化模式(Module Pattern)

应用场景

模块化模式用于组织和管理代码,避免全局变量污染,提供命名空间和代码复用。

实现方式

使用ES6的模块系统:

mathModule.js

javascript
// 定义模块
export function add(a, b) {
  return a + b;
}

export function subtract(a, b) {
  return a - b;
}

main.js

javascript
// 导入模块
import { add, subtract } from './mathModule.js';

console.log(add(2, 3));  // 5
console.log(subtract(5, 3));  // 2

2. 单例模式(Singleton Pattern)

应用场景

单例模式用于需要保证一个类只有一个实例的场景,如应用配置对象、日志管理器等。

实现方式

使用闭包和立即执行函数:

config.js

javascript
const Config = (function() {
  let instance;

  function createInstance() {
    return {
      appName: 'MyApp',
      version: '1.0.0'
    };
  }

  return {
    getInstance() {
      if (!instance) {
        instance = createInstance();
      }
      return instance;
    }
  };
})();

export default Config;

main.js

javascript
import Config from './config.js';

const config1 = Config.getInstance();
const config2 = Config.getInstance();

console.log(config1 === config2);  // true

3. 观察者模式(Observer Pattern)

应用场景

观察者模式用于一个对象(发布者)状态变化时通知其他依赖对象(订阅者)的场景,如事件处理系统。

实现方式

使用类和回调函数:

Observable.js

javascript
class Observable {
  constructor() {
    this.subscribers = [];
  }

  subscribe(callback) {
    this.subscribers.push(callback);
  }

  unsubscribe(callback) {
    this.subscribers = this.subscribers.filter(subscriber => subscriber !== callback);
  }

  notify(data) {
    this.subscribers.forEach(subscriber => subscriber(data));
  }
}

export default Observable;

main.js

javascript
import Observable from './Observable.js';

const observable = new Observable();

function logger(data) {
  console.log(`Received data: ${data}`);
}

observable.subscribe(logger);
observable.notify('Hello World!');  // Received data: Hello World!

4. 发布-订阅模式(Pub-Sub Pattern)

应用场景

发布-订阅模式用于不同模块之间的松耦合通信,如事件总线。

实现方式

使用简单的事件总线:

EventBus.js

javascript
class EventBus {
  constructor() {
    this.events = {};
  }

  subscribe(event, callback) {
    if (!this.events[event]) {
      this.events[event] = [];
    }
    this.events[event].push(callback);
  }

  unsubscribe(event, callback) {
    if (!this.events[event]) return;

    this.events[event] = this.events[event].filter(cb => cb !== callback);
  }

  publish(event, data) {
    if (!this.events[event]) return;

    this.events[event].forEach(callback => callback(data));
  }
}

export default new EventBus();

main.js

javascript
import EventBus from './EventBus.js';

function logger(data) {
  console.log(`Received data: ${data}`);
}

EventBus.subscribe('dataReceived', logger);
EventBus.publish('dataReceived', 'Hello World!');  // Received data: Hello World!

5. 工厂模式(Factory Pattern)

应用场景

工厂模式用于对象创建逻辑复杂,且需要灵活选择创建对象类型的场景。

实现方式

使用类和静态方法:

CarFactory.js

javascript
class Car {
  constructor(model, price) {
    this.model = model;
    this.price = price;
  }
}

class CarFactory {
  static createCar(type) {
    switch (type) {
      case 'sedan':
        return new Car('Sedan', 20000);
      case 'suv':
        return new Car('SUV', 30000);
      default:
        throw new Error('Unknown car type');
    }
  }
}

export default CarFactory;

main.js

javascript
import CarFactory from './CarFactory.js';

const sedan = CarFactory.createCar('sedan');
const suv = CarFactory.createCar('suv');

console.log(sedan);  // Car { model: 'Sedan', price: 20000 }
console.log(suv);  // Car { model: 'SUV', price: 30000 }

6. 策略模式(Strategy Pattern)

应用场景

策略模式用于多种算法可以互换,且算法的选择对客户端透明的场景。

实现方式

使用类和策略对象:

Strategy.js

javascript
class Strategy {
  execute(data) {
    throw new Error('Strategy.execute() must be overridden');
  }
}

class ConcreteStrategyA extends Strategy {
  execute(data) {
    return data.toUpperCase();
  }
}

class ConcreteStrategyB extends Strategy {
  execute(data) {
    return data.toLowerCase();
  }
}

class Context {
  setStrategy(strategy) {
    this.strategy = strategy;
  }

  executeStrategy(data) {
    return this.strategy.execute(data);
  }
}

export { ConcreteStrategyA, ConcreteStrategyB, Context };

main.js

javascript
import { ConcreteStrategyA, ConcreteStrategyB, Context } from './Strategy.js';

const context = new Context();

context.setStrategy(new ConcreteStrategyA());
console.log(context.executeStrategy('Hello World'));  // HELLO WORLD

context.setStrategy(new ConcreteStrategyB());
console.log(context.executeStrategy('Hello World'));  // hello world

7. 装饰者模式(Decorator Pattern)

应用场景

装饰者模式用于动态地给对象添加新的功能的场景。

实现方式

使用类和包装对象:

Decorator.js

javascript
class Coffee {
  cost() {
    return 5;
  }
}

class MilkDecorator {
  constructor(coffee) {
    this.coffee = coffee;
  }

  cost() {
    return this.coffee.cost() + 1;
  }
}

class SugarDecorator {
  constructor(coffee) {
    this.coffee = coffee;
  }

  cost() {
    return this.coffee.cost() + 0.5;
  }
}

export { Coffee, MilkDecorator, SugarDecorator };

main.js

javascript
import { Coffee, MilkDecorator, SugarDecorator } from './Decorator.js';

let coffee = new Coffee();
coffee = new MilkDecorator(coffee);
coffee = new SugarDecorator(coffee);

console.log(coffee.cost());  // 6.5

8. 适配器模式(Adapter Pattern)

应用场景

适配器模式用于接口不兼容,需要适配的场景。

实现方式

使用类和适配器对象:

Adapter.js

javascript
class OldAPI {
  oldRequest() {
    return 'Old API response';
  }
}

class NewAPI {
  newRequest() {
    return 'New API response';
  }
}

class Adapter {
  constructor(newAPI) {
    this.newAPI = newAPI;
  }

  oldRequest() {
    return this.newAPI.newRequest();
  }
}

export { OldAPI, NewAPI, Adapter };

main.js

javascript
import { OldAPI, NewAPI, Adapter } from './Adapter.js';

const oldAPI = new OldAPI();
console.log(oldAPI.oldRequest());  // Old API response

const newAPI = new NewAPI();
const adapter = new Adapter(newAPI);
console.log(adapter.oldRequest());  // New API response

9. 代理模式(Proxy Pattern)

应用场景

代理模式用于控制对象访问的场景,如懒加载、权限控制等。

实现方式

使用类和代理对象:

Proxy.js

javascript
class RealImage {
  constructor(filename) {
    this.filename = filename;
    this.loadFromDisk();
  }

  loadFromDisk() {
    console.log(`Loading ${this.filename}`);
  }

  display() {
    console.log(`Displaying ${this.filename}`);
  }
}

class ProxyImage {
  constructor(filename) {
    this.realImage = null;
    this.filename = filename;
  }

  display() {
    if (!this.realImage) {
      this.realImage = new RealImage(this.filename);
    }
    this.realImage.display();
  }
}

export { RealImage, ProxyImage };

main.js

javascript
import { RealImage, ProxyImage } from './Proxy.js';

const image = new ProxyImage('test.jpg');
image.display();  // Loading test.jpg  Displaying test.jpg
image.display();  // Displaying test.jpg

10. 组合模式(Composite Pattern)

应用场景

组合模式用于处理树形结构的对象组合,如文件系统、UI组件树等。

实现方式

使用类和组合对象:

Composite.js

javascript
class Component {
  add(component) {}
  remove(component) {}
  display() {}
}

class Leaf extends Component {
  constructor(name) {
    super();
    this.name =

 name;
  }

  display() {
    console.log(this.name);
  }
}

class Composite extends Component {
  constructor(name) {
    super();
    this.name = name;
    this.children = [];
  }

  add(component) {
    this.children.push(component);
  }

  remove(component) {
    this.children = this.children.filter(child => child !== component);
  }

  display() {
    console.log(this.name);
    this.children.forEach(child => child.display());
  }
}

export { Leaf, Composite };

main.js

javascript
import { Leaf, Composite } from './Composite.js';

const root = new Composite('root');
const branch1 = new Composite('branch1');
const branch2 = new Composite('branch2');

const leaf1 = new Leaf('leaf1');
const leaf2 = new Leaf('leaf2');
const leaf3 = new Leaf('leaf3');

root.add(branch1);
root.add(branch2);
branch1.add(leaf1);
branch1.add(leaf2);
branch2.add(leaf3);

root.display();
// Output:
// root
// branch1
// leaf1
// leaf2
// branch2
// leaf3

11. 状态模式(State Pattern)

应用场景

状态模式用于对象在不同状态下行为不同,且状态切换复杂的场景。

实现方式

使用类和状态对象:

State.js

javascript
class State {
  handle(context) {
    throw new Error('State.handle() must be overridden');
  }
}

class ConcreteStateA extends State {
  handle(context) {
    console.log('State A: handling request.');
    context.setState(new ConcreteStateB());
  }
}

class ConcreteStateB extends State {
  handle(context) {
    console.log('State B: handling request.');
    context.setState(new ConcreteStateA());
  }
}

class Context {
  constructor() {
    this.state = new ConcreteStateA();
  }

  setState(state) {
    this.state = state;
  }

  request() {
    this.state.handle(this);
  }
}

export { Context, ConcreteStateA, ConcreteStateB };

main.js

javascript
import { Context } from './State.js';

const context = new Context();
context.request();  // State A: handling request.
context.request();  // State B: handling request.
context.request();  // State A: handling request.

12. 命令模式(Command Pattern)

应用场景

命令模式用于将请求封装成对象,方便参数化和撤销操作。

实现方式

使用类和命令对象:

Command.js

javascript
class Command {
  execute() {
    throw new Error('Command.execute() must be overridden');
  }
}

class Light {
  on() {
    console.log('Light is ON');
  }

  off() {
    console.log('Light is OFF');
  }
}

class LightOnCommand extends Command {
  constructor(light) {
    super();
    this.light = light;
  }

  execute() {
    this.light.on();
  }
}

class LightOffCommand extends Command {
  constructor(light) {
    super();
    this.light = light;
  }

  execute() {
    this.light.off();
  }
}

class RemoteControl {
  setCommand(command) {
    this.command = command;
  }

  pressButton() {
    this.command.execute();
  }
}

export { Light, LightOnCommand, LightOffCommand, RemoteControl };

main.js

javascript
import { Light, LightOnCommand, LightOffCommand, RemoteControl } from './Command.js';

const light = new Light();
const lightOn = new LightOnCommand(light);
const lightOff = new LightOffCommand(light);

const remote = new RemoteControl();
remote.setCommand(lightOn);
remote.pressButton();  // Light is ON

remote.setCommand(lightOff);
remote.pressButton();  // Light is OFF

13. MVC模式(Model-View-Controller)

应用场景

MVC模式用于分离应用逻辑、用户界面和控制流程的场景。

实现方式

使用类和分层架构:

Model.js

javascript
class Model {
  constructor() {
    this.data = 'Hello MVC';
  }

  getData() {
    return this.data;
  }

  setData(data) {
    this.data = data;
  }
}

export default Model;

View.js

javascript
class View {
  constructor(controller) {
    this.controller = controller;
    this.init();
  }

  init() {
    const button = document.createElement('button');
    button.textContent = 'Click me';
    button.addEventListener('click', () => this.controller.handleClick());
    document.body.appendChild(button);

    this.label = document.createElement('div');
    document.body.appendChild(this.label);
  }

  render(data) {
    this.label.textContent = data;
  }
}

export default View;

Controller.js

javascript
import Model from './Model.js';
import View from './View.js';

class Controller {
  constructor() {
    this.model = new Model();
    this.view = new View(this);
    this.updateView();
  }

  handleClick() {
    const newData = 'Hello MVC Updated';
    this.model.setData(newData);
    this.updateView();
  }

  updateView() {
    const data = this.model.getData();
    this.view.render(data);
  }
}

export default Controller;

main.js

javascript
import Controller from './Controller.js';

new Controller();

14. MVVM模式(Model-View-ViewModel)

应用场景

MVVM模式用于通过双向数据绑定简化UI更新的场景。

实现方式

使用Vue.js框架:

index.html

html
<!DOCTYPE html>
<html>
<head>
  <title>MVVM Example</title>
  <script src="https://cdn.jsdelivr.net/npm/vue@2"></script>
</head>
<body>
  <div id="app">
    <input v-model="message" />
    <p>{{ message }}</p>
  </div>

  <script src="main.js"></script>
</body>
</html>

main.js

javascript
new Vue({
  el: '#app',
  data: {
    message: 'Hello MVVM'
  }
});

通过这些具体的应用和实现方式,可以更好地理解和运用前端设计模式来解决实际开发中的问题。