面试技巧
一: 面试真相 提升面试通过率
- 基础个人信息
- 2~3个负责或者参与的工作项目
- 谈谈对当前这份工作岗位的理解和人岗匹配度
基础信息: 面试官您好, 我叫vine web, 目前工作第七年, 这七年来一直做的是前端方面的工作, 有web端, H5, 小程序, 混合app等开发经验, 有过电商, 政府项目(图表类, 台账类, 地图类, gis, 大屏, 适配等), 公司官网, 公司后台管理平台, 配置平台等大量工作经历
总结项目: 有过百万级用户的"村景拍拍"小程序, 住建部内的 房改系统 和 灾后重建系统建设, 也有后台管理, 后台配置平台, 前端是跟用户打交道最多的一类程序员, 深切能感知用户的使用和交互
人岗匹配: 通过前期的了解, 知道贵公司是很注重产品和用户体验, 和我的价值观很相似, 并且我相信我过去的经验和我的认知很匹配这个岗位的要求, 希望今天能和你有一个非常愉快的交流
- 自我介绍很重要
- 项目经验star法则 要尽量让面试官听懂
- 诚实
- 90%核心岗留给内推和猎头
- 面试是棋逢对手的较量 尽量与面试官沟通交流
- 谈薪勇于说出自己诉求
- 反问面试官是送命题 不同层级面试官可问对应的有深度思考的问题 // 思考自己的岗位 -- 公司岗位定位, --- 业务的规划
- 展示自己的兴趣爱好有好处 15-20
二: 如何通过非投递得到面试机会
- 找知乎、论坛里的大佬毛遂自荐,不过要准备自己的作品集和相应能展现自身能力的作品
- 曲线救国
- 人脉破圈
三: 简历
- 面试技巧 应该是解决了什么具体业务问题、技术问题
产生了什么业务价值 技术价值
四: 面试
- 假设你现在是面试官,要面试xx公司xx岗位,现在需要你根据以下岗位需求,从基本面、专业面、沟通协作和团队管理四个维度,预测面试中可能被问到的10个问题+招聘岗位需求
- 假设你现在是xx公司面试官,要面试xx岗位,现在你问了xx问题,请给出你最欣赏的候选人的回答思路。
- 假设你是面试者,要面试xx公司xx岗位,现在面试官问了xx问题,请你做出回答
五 chatgpt
- 01 预测重合度, 考察ChatGPT模拟面试问出的问题, 有多少真实面试过程中, 面试官实际会问到?
- 02 回答满意度, 考察ChatGPT针对某一问题的实际回答, 面试官实际满意度
- 03 思路满意度, 考察ChatGPT针对某一问题提供的回答思路, 面试官实际满意度
六 常见问题
自我介绍 面试完你还有什么问题要问的吗? 你的期望薪资是多少? 未来三到五年的规划是怎样的? 你的项目中技术难点是什么?遇到了什么问题?你是怎么解决的? 说下⼯作中你做过的⼀些性能优化处理? 你最有成就感的⼀件事? 离职原因? 你对加班的怎么看?
七 设计模式
前端设计模式是解决常见问题的一套最佳实践和标准方法,通过应用这些模式,可以提高代码的可维护性、可重用性和可扩展性。以下是一些可以探讨的前端设计模式,以及相关的具体问题:
常见的前端设计模式
- 模块化模式(Module Pattern)
- 单例模式(Singleton Pattern)
- 观察者模式(Observer Pattern)
- 发布-订阅模式(Pub-Sub Pattern)
- 工厂模式(Factory Pattern)
- 策略模式(Strategy Pattern)
- 装饰者模式(Decorator Pattern)
- 适配器模式(Adapter Pattern)
- 代理模式(Proxy Pattern)
- 组合模式(Composite Pattern)
- 状态模式(State Pattern)
- 命令模式(Command Pattern)
- MVC模式(Model-View-Controller)
- MVVM模式(Model-View-ViewModel)
具体问题
模块化模式(Module Pattern)
- 如何使用模块化模式来组织和管理前端代码?
- 在ES6中,如何利用import和export来实现模块化?
- 使用模块化模式的优缺点是什么?
单例模式(Singleton Pattern)
- 如何在JavaScript中实现单例模式?
- 单例模式在前端开发中有哪些典型的应用场景?
- 使用单例模式有哪些潜在的问题?
观察者模式(Observer Pattern)
- 如何在JavaScript中实现观察者模式?
- 观察者模式与发布-订阅模式的区别是什么?
- 观察者模式在前端开发中的应用有哪些?
发布-订阅模式(Pub-Sub Pattern)
- 如何使用发布-订阅模式来实现松耦合的组件通信?
- 常见的发布-订阅库有哪些?如何使用它们?
- 发布-订阅模式的优缺点是什么?
工厂模式(Factory Pattern)
- 如何在JavaScript中实现工厂模式?
- 工厂模式在创建复杂对象时有哪些优势?
- 使用工厂模式有哪些注意事项?
策略模式(Strategy Pattern)
- 如何在JavaScript中实现策略模式?
- 策略模式在前端开发中的应用场景有哪些?
- 策略模式与状态模式的区别是什么?
装饰者模式(Decorator Pattern)
- 如何在JavaScript中实现装饰者模式?
- 装饰者模式如何增强对象的功能?
- 使用装饰者模式有哪些优缺点?
适配器模式(Adapter Pattern)
- 如何在JavaScript中实现适配器模式?
- 适配器模式如何帮助解决接口不兼容的问题?
- 适配器模式的典型应用场景有哪些?
代理模式(Proxy Pattern)
- 如何在JavaScript中实现代理模式?
- 代理模式在前端开发中的应用有哪些?
- 代理模式与装饰者模式的区别是什么?
组合模式(Composite Pattern)
- 如何在JavaScript中实现组合模式?
- 组合模式如何处理树形结构的数据?
- 使用组合模式的优缺点是什么?
状态模式(State Pattern)
- 如何在JavaScript中实现状态模式?
- 状态模式如何简化状态转换的管理?
- 使用状态模式有哪些注意事项?
命令模式(Command Pattern)
- 如何在JavaScript中实现命令模式?
- 命令模式如何实现操作的撤销和重做?
- 命令模式的典型应用场景有哪些?
MVC模式(Model-View-Controller)
- MVC模式如何分离关注点,提升代码可维护性?
- MVC模式在现代前端框架中的实现有哪些?
- MVC模式的优缺点是什么?
MVVM模式(Model-View-ViewModel)
- MVVM模式如何通过双向数据绑定简化UI更新?
- MVVM模式在前端框架中的实现有哪些?
- MVVM模式与MVC模式的区别是什么?
深入探讨的问题
- 如何选择合适的设计模式来解决特定的问题?
- 在前端开发中,如何组合使用多种设计模式?
- 设计模式的使用如何影响代码的性能和可维护性?
- 有哪些常见的设计模式反例(anti-patterns)?如何避免它们?
具体应用
- 在React/Vue/Angular中,如何应用这些设计模式?
- 如何在大型前端项目中实施设计模式?
- 有哪些实际案例展示了设计模式的应用?
这些问题可以帮助深入理解和应用前端设计模式,提高前端开发的质量和效率。
八 具体的应用和实现
好的,下面我将为每个设计模式提供具体的应用场景和实现方式。
1. 模块化模式(Module Pattern)
应用场景
模块化模式用于组织和管理代码,避免全局变量污染,提供命名空间和代码复用。
实现方式
使用ES6的模块系统:
mathModule.js
// 定义模块
export function add(a, b) {
return a + b;
}
export function subtract(a, b) {
return a - b;
}
main.js
// 导入模块
import { add, subtract } from './mathModule.js';
console.log(add(2, 3)); // 5
console.log(subtract(5, 3)); // 2
2. 单例模式(Singleton Pattern)
应用场景
单例模式用于需要保证一个类只有一个实例的场景,如应用配置对象、日志管理器等。
实现方式
使用闭包和立即执行函数:
config.js
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
import Config from './config.js';
const config1 = Config.getInstance();
const config2 = Config.getInstance();
console.log(config1 === config2); // true
3. 观察者模式(Observer Pattern)
应用场景
观察者模式用于一个对象(发布者)状态变化时通知其他依赖对象(订阅者)的场景,如事件处理系统。
实现方式
使用类和回调函数:
Observable.js
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
class Model {
constructor() {
this.data = 'Hello MVC';
}
getData() {
return this.data;
}
setData(data) {
this.data = data;
}
}
export default Model;
View.js
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
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
import Controller from './Controller.js';
new Controller();
14. MVVM模式(Model-View-ViewModel)
应用场景
MVVM模式用于通过双向数据绑定简化UI更新的场景。
实现方式
使用Vue.js框架:
index.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
new Vue({
el: '#app',
data: {
message: 'Hello MVVM'
}
});
通过这些具体的应用和实现方式,可以更好地理解和运用前端设计模式来解决实际开发中的问题。