- 作者:老汪软件技巧
- 发表时间:2024-10-10 07:01
- 浏览量:
我是All in AI的前端老兵shunwuyu,带班攻战互联网大厂面试十年了。春招、秋招,都感觉与同学们一样热血沸腾。我以同学的口吻写了面试系列,希望对大厂入职大厂有所帮助。
如果您喜欢我的面试系列,欢迎点赞,收藏,也欢迎加我V(shunwuyu), 入群一起交流。
前言
能在小红书里找到美团面试,大家惊愕了吧。我这个面试来自美团一位实习生的文章,说他要去上课了,可以内推面他的坑位。没想一投,面试就安排到位了。 大二升大三的第一次大厂面试,不求黄袍加身,但求面试官温柔待我。反正远程实习干着,大厂都面面。
面试题截图
自我介绍
可以看
判断数组的方法
let arr = [1, 2, 3];
console.log(arr instanceof Array); // true
function isArrayLike(obj) {
return obj != null && typeof obj === 'object' && 'length' in obj;
}
let arr = [1, 2, 3];
console.log(isArrayLike(arr)); // true
小结: 普通考题,但能展现js基础能力,答题主要在于全面。
箭头函数和普通函数的区别js中的异步方法
JavaScript 是一种单线程语言,这意味着它在同一时间只能执行一个任务。然而,JavaScript 通过异步编程模型来处理耗时的操作,如网络请求、文件读写等,从而避免阻塞主线程。
JavaScript 的异步方法主要有三种:回调函数、Promise 和 Async/Await。
async/await原理概念:async/await 是基于 Promise 的语法糖,目的是简化异步代码的书写,避免回调地狱,提供一种更类似于同步代码的异步编程体验。async 函数:使用 async 关键字定义的函数总是返回一个 Promise 对象。即使函数内部没有明确返回 Promise,JavaScript 也会将返回值自动封装为 Promise.resolve()。await 表达式:await 用于暂停 async 函数的执行,等待一个 Promise 解析。await 后面必须是一个 Promise 对象或可转化为 Promise 的值。函数会在 Promise 解析完成后恢复执行,并返回 Promise 的结果。如果 Promise 被拒绝,await 会抛出异常,可以使用 try/catch 来捕获。事件循环:async/await 并不会阻塞主线程,而是将异步操作推入事件循环的微任务队列(microtask queue)。当同步代码执行完毕后,JavaScript 引擎会检查微任务队列并执行相应的回调,这就是为什么 await 不会阻塞整个程序。
总结:async/await 是基于 Promise 实现的语法糖,利用事件循环将异步任务放入微任务队列,使得异步代码看起来像同步代码,极大简化了代码的可读性。
事件冒泡机制
定义:事件冒泡是浏览器处理 DOM 事件的一种机制。当一个事件发生在一个元素上时,它首先会被该元素处理,然后事件会按照父子层级向上(从目标元素到根元素 document)依次触发父级元素的相同事件监听器,直到到达最顶层。
事件传播阶段:事件传播分为三个阶段:
默认行为:事件冒泡是浏览器的默认行为,但可以通过 event.stopPropagation() 来阻止事件进一步冒泡。
实际应用:
通个addEventListener的第三个参数,可以控制时间在哪个阶段触发。
addEventListener 的第三个参数可以是一个布尔值或一个对象,它的作用是指定事件监听器的选项,主要包括以下几种情况:
capture(布尔值):
options(对象): 第三个参数也可以是一个包含以下属性的对象,用于更精细地控制事件监听器的行为:
事件循环
可以查看
解构url
直接上
vue 生命周期
生命周期demo
请求数据应该放在哪个生命周期?为什么?
在 Vue 3 中,请求数据通常放在 onMounted 生命周期钩子中。原因是 onMounted 会在组件的 DOM 渲染完成后调用,这时可以安全地进行异步请求并更新组件的状态,而不会阻塞页面的初次渲染。
聊聊vue响应式数据的proxy
在 Vue 3 中,响应式系统采用了 Proxy 代替 Vue 2 中的 Object.defineProperty,以更灵活、强大的方式实现响应式数据。
let handler = { ownKeys(target) { console.log('Listing keys'); return Object.keys(target); } };
let handler = {
getOwnPropertyDescriptor(target, prop) {
console.log(`Getting descriptor for ${prop}`);
return Object.getOwnPropertyDescriptor(target, prop);
}
};
function lazyReactive(target) {
const handler = {
get(target, key, receiver) {
const value = Reflect.get(target, key, receiver);
if (typeof value === 'object' && value !== null) {
// 懒代理:只有在访问时才代理嵌套对象
return lazyReactive(value);
}
return value;
},
set(target, key, value, receiver) {
const oldValue = Reflect.get(target, key, receiver);
const result = Reflect.set(target, key, value, receiver);
if (oldValue !== value) {
// 触发视图更新
updateView();
}
return result;
}
};
return new Proxy(target, handler);
}
// 模拟视图更新
function updateView() {
console.log('View updated');
}
const state = lazyReactive({
count: 0,
nested: {
name: 'Vue 3',
details: {
version: '3.0.0'
}
},
array: [1, 2, 3]
});
console.log('Initial state:', state);
state.nested.name = 'Vue 3.1'; // 懒代理,只在访问 nested 时代理
console.log('Updated nested.name:', state.nested.name);
state.nested.details.version = '3.1.0'; // 懒代理,只在访问 nested.details 时代理
console.log('Updated nested.details.version:', state.nested.details.version);
console.log('Final state:', state);
function reactive(target) {
return new Proxy(target, {
get(target, key, receiver) {
return Reflect.get(target, key, receiver);
},
set(target, key, value, receiver) {
const result = Reflect.set(target, key, value, receiver);
console.log(`${key} changed to ${value}`);
return result; } }); }
const state = reactive({ count: 0 });
state.count = 1; // 输出: count changed to 1 console.log(state.count); // 1 // 新增属性 state.newProp = 'new value'; console.log(state.newProp); // 'new value' // 新增属性会触发响应式 state.newProp = 'updated value'; // 输出: newProp changed to updated value console.log(state.newProp); // 'updated value'
有一串只有"["、"]"、"{"、"}"、"("、")" 判断是否是合法
function isValid(s) {
// 用于存储左括号的栈
const stack = [];
// 括号对映射
const mapping = {
')': '(',
'}': '{',
']': '['
};
// 遍历字符串中的每个字符
for (const char of s) {
if (char in mapping) {
// 如果是右括号,检查栈顶是否有匹配的左括号 #只是一个占位符
const topElement = stack.length === 0 ? '#' : stack.pop();
if (mapping[char] !== topElement) {
return false;
}
} else {
// 如果是左括号,将其推入栈中
stack.push(char);
}
}
// 检查栈是否为空(所有的左括号都应该匹配)
return stack.length === 0;
}
// 示例用法
console.log(isValid("()")); // 输出 true
console.log(isValid("()[]{}")); // 输出 true
console.log(isValid("(]")); // 输出 false
console.log(isValid("([)]")); // 输出 false
console.log(isValid("{[]}")); // 输出 true
总结
最近我们挺多同学在小红书上找到一些面试线索的, 还有远程实习了, 大家也可以试试。