跨度时间:3.12 ~ 4.27
补充:第一次找实习,从3.12开始投递的简历,从一开始的Boss直聘乱投,但是基本没啥回信后(感觉和我现在是大二有关),直接投大厂:知乎,小米,百度,腾讯,美团...
第一次面试是3.22,一个初创公司,技术栈挺新的,而且mt挺好的,打电话让我面试。俩面OC后我拒绝后,还打了好几个电话让我入职,感觉对自己能力有个评估,后面就没投小厂了
真的被大厂乱挂,简历直接被筛,做了一堆测评
3月底收到腾讯的一面邀约,特别开心,后面又通过群友内推投递了百度(之前简历晒直接被挂),摆烂了好多次,最后总共面了三个公司,运气很好,全部OC了
建议,投递简历可以提前一个星期开始,因为我第一个星期基本没有回信(后面发现投成暑期实习了怪不得)
格墨科技一面(3.22)
其中一个项目实现
js 的基础类型(8种)
- null
- undefined
- string
- bigint
- boolean
- object
- symbol
闭包
- 是一个函数及词法环境
- 隐藏私有变量
写一个闭包
var store = (function() {
let S = {}
return () => {
get(key) {
return S[key];
}
set(key, value) {
S[key] = value;
}
}
})()
数组求和
- 用了reduce,问我如果是异步请求相加,如何并行实现?
跨域问题
- 同源策略影响
跨域解决
- jsonp
- cors
- 代理服务器
- websocket
浏览器缓存
- 强缓存 > 协商协商
osi七层模型
udp和tcp区别
- udp无连接,tcp面向连接
tcp三次握手
- syn
- syn/ack半连接队列
- ack全连接队列
vue和react区别
- vue响应式双向绑定
- react单向数据流
vue双向绑定原理
- v-model,利用响应式原理监听用户输入事件
响应式原理(从源码角度出发)
- 数据劫持结合发布订阅
proxy为什么有性能问题
-
对整个对象进行代理
格墨科技二面(3.25)-> 第二天OC
补充:拿的第一个offer,还是比较开心的哈哈
react了解过没
- 我说跟着文档敲了一点东西,比较熟悉的还是vue
vue如何编译模板的
- 通过Complier生成ast语法树,然后通过vue-parse转化一下,生成渲染函数,并优化,生成虚拟vnode节点,最后再vm.patch通过虚拟dom算法利用vnode节点生成真实dom节点
看我项目用了Monorepo,问为什么用
- 一个仓库(packages)管理所有项目,有利于团队合作开发,代码复用
问我pnpm和npm区别
问我软链接和硬链接区别
vite和webpack区别
- 一个适用于轻量级的项目,是一种基于ES模块的构建工具开发,速度快,一个适用于大型项目,拥有丰富的插件等
vite为什么快
- vite是一种基于ES模块的构建工具,它利用浏览器原生的ES模块加载机制,将代码分割成更小的块,并在浏览器中按需加载。这种方式比传统的打包工具(如webpack)更快,因为它不需要在本地打包和压缩代码,而是直接在浏览器中编译和加载代码。此外,vite还支持热更新,可以在开发过程中实时更新代码,从而提高开发效率。
- vite的热更新与构建方式有关,它利用浏览器原生的模块加载机制,在开发过程中实时编译和加载代码。因此,热更新是vite的一个重要特性,可以提高开发效率。
浏览器输入URL发生了什么
- url是否合法,不合法交给搜索引擎
- 缓存判断,dns解析
- 获取MAC地址
- tcp三次握手
- 判断有无https,有则TLS四次握手
- 返回数据,浏览器进行页面渲染
- tcp四次挥手(还说了http1.1默认keep-alive,也就是持久化连接不关闭)
浏览器进行页面渲染有什么细节
- 解析html,生成dom树,解析css,生成cssom树(还说了下载不阻塞,解析阻塞),遇到js脚本,判断有无async和defer,都无则进行js脚本解析,阻塞Render树的构建,最后根据cssom树和dom树生成render树并渲染页面
实现keep-alive
- 可以通过ref获取到组件实例,然后将该实例放入sessionstorge本地缓存中
<div id="app" keep-alive ref="child">
<div v-if="sessionstorge.getItem(app)"></div>
<div v-else></div>
</div>
- 以组件uid为键值用Map缓存该组件,并使用自定义组件获取slot插槽
<template>
<div v-if="isCached">
<slot></slot>
</div>
<div v-else ref="RefDom"></div>
</template>
<script setup>
import { Cache } from './Cache.js'
import { getCurrentInstance, render, ref, nextTick, defineProps } from 'vue'
const props = defineProps({ // 缓存key值
_key: {
type: String,
required: true
}
})
const instance = getCurrentInstance()
const RefDom = ref(null)
const isCached = ref(false)
let vnode = Cache.get(props._key)
nextTick(() => {
if (!vnode) {
isCached.value = true
vnode = instance.slots.default()[0]
Cache.set(props._key, vnode)
console.log('初始未缓存')
}
render(vnode, RefDom.value)
})
</script>
// 使用
<template>
<div>
<CacheView _key="1">
<h1>app</h1>
</CacheView>
</div>
</template>
<script setup>
import CacheView from './CacheView.vue'
</script>
算法:生成dom节点
<div id="app"></div>
const dom = el('ul', {'class': 'a'}, [
el('li', {'id': 'b'}, ['item1']),
el('li', {'id': 'c'}, ['item2'])
])
const vm = dom.render();
app.appendChild(vm);
// 生成以下代码
<ul class="a">
<li id="b"></li>
<li id="c"></li>
</ul>
// 实现如下:
function el(element, attribute = {}, children = []){
return {
render(){
const el = document.createElement(element);
Object.keys(attribute).forEach(key => el.setAttribute(key, attribute[key]));
children.forEach(item => {
if(typeof item == 'string') el.innerText = item;
else el.appendChild(item.render());
})
return el;
}
}
}
LRU缓存
class LRUCache {
constructor(n) {
this.size = n // 初始化最大缓存数据条为n
this.cacheMap = new Map() // 初始化缓存空间map
}
put(domain, info) {
if(this.cacheMap.has(domain)) {
// 已存在需更新数据的位置
this.cacheMap.delete(domain); //移除数据
}
if(this.cacheMap.size >= this.size) {
// 删除最不常用数据(Map.keys()返回一个迭代器 function* )
const firstKey = this.cacheMap.keys().next().value; // 不必当心cacheMap为空,因为this.size一般不为空
this.cacheMap.delete(firstKey);
}
this.cacheMap.set(domain, info); // 在末尾重新插入数据
}
get(domain) {
if(!this.cacheMap.has(domain)) return false;
const info = this.cacheMap.get(domain); // 获取结果
this.cacheMap.delete(domain); // 移除数据
this.cacheMap.set(domain, info); // 在末尾重新插入数据
return info;
}
}
问我怎么学习 前端
- 自学
有了解业界发生的事情吗
- chatGPT
目前在学什么
- 说自己最近在学编译原理,ast语法树的解析,还有next.js,react等
职业规划
-
不考研,全栈,架构方面
腾讯一面(3.31)
OpenEuler开源项目负责的模块
第一次有人问我的这个项目
ts泛型
ts的class、type、interface区别
let const和 var
预检请求
非简单请求和简单请求
项目如何处理跨域
node中间层代理转发
cookie作用(存储信息+身份验证)
xhr、fetch区别
axios有看过源码吗?如何判断是服务器环境还是浏览器环境
- 服务端用http模块转发请求,浏览器端用xhr发送请求
window
?- typeof process !== 'undefined' && Object.prototype.toString.call(process) === '[object process]'
vuex和全局变量,能不能用全局变量替换vuex
腾讯二面(4.11)
补充
leader面,有点哈人
我简历写了首屏加载时间由4.7s优化到1.7s,其实是看之前群友的简历随便模仿的一个时间,这里给自己挖了一个坑,他一直问我,对于一个博客系统,首屏加载需要这么久吗?不应该啊?所以,简历问题大家应该好好看待,不用一味模仿,对于有数据的需要自己测试一下。
项目问题
get和post区别
- 是否缓存
- 参数由url亦或者body传递,可携带数据大小
- 幂等性
性能方面做了哪些优化
邮箱SMTP协议登录(token)
webpack
webpack中使用的插件有什么
webpack常用的loader有什么
死亡webpack连问
闭包的业务场景
-
在事件处理程序中使用闭包
-
使用闭包来隐藏私有变量
- 如防抖节流中timer外部不可访问
-
const myModule = (function() { const privateVar = 'I am private'; function privateFunction() { console.log(privateVar); } return { publicFunction: function() { privateFunction(); } }; })(); myModule.publicFunction(); // 输出 'I am private'
匿名函数作用
- 避免污染全局变量,隐藏私有变量
反问
全程因为时间比较短,20来分钟,而且没有问算法题,我很疑惑哈哈,以为是kpi,没想到给过了🤣
腾讯三面(4.12)-> 4.23OC
介绍一下自己
- 自己坚持每周的15km长跑
平时学习方面
说一下你认为最有挑战性的项目
项目中的难点,以及怎么解决
项目中体现你能力的地方
- 在项目中,学习网络安全,让信息安全的同学帮忙测试网站安全,并实时进行修复和改进
如果给你负责一个项目,你会如何进行开展
- 制定详细的计划,并与团队成员和利益相关者保持沟通。同时,需要定期监控项目进度,并及时采取措施来应对任何问题。
团队沟通?如果团队的成员和你合作沟通不来(因为他造成项目进展方面的问题),怎么解决
- 主动询问,帮忙推进进度,拉双方领导进群沟通
性格方面
百度一面(4.20)
软工学的课
- 编译原理、数据库、c语言、计网、计组、操作系统...
手写快排
- 天天刷,5分钟秒
function sortArray(arr, left = 0, right = arr.length - 1) {
if (left >= right) return arr;
var i = left, j = right, flag = i;
while(i < j) {
// i为最大数,j为最小,flag为中间
while(arr[j] >= arr[flag] && j > flag) j --;
if (i >= j) break;
while(arr[i] <= arr[flag] && i < j) i ++;
var temp = arr[flag];
arr[flag] = arr[j];
arr[j] = arr[i];
arr[i] = temp;
flag = i;
}
sortArray(arr, left, flag - 1);
sortArray(arr, flag + 1, right);
return arr;
}
手写深拷贝
// 浅拷贝
function _shallowClone(obj) {
if(typeof obj !== 'object' && obj === null) return obj;
if(/^(Object|Array)/.test(obj.constructor.name)) {
return obj instanceof Array ? [...obj] : {...obj};
}
return obj;
}
// 深拷贝
function _completeDeepClone(obj, visited = new WeakMap()) {
if (typeof obj !== "object" || obj === null) return obj;
// 防止循环引用
if (visited.has(obj)) {
return visited.get(obj);
}
// 获取对象的构造函数
const constructor = obj.constructor;
// 处理特殊对象类型~正则对象和时间对象、弱引用对象
if(/^(RegExp|Date|WeakMap|WeakSet)/.test(constructor.name)) {
const res = new constructor(obj);
visited.set(obj, res);
return res;
}
// Map
if (constructor === Map) {
const map = new Map();
visited.set(obj, map);
obj.forEach((value, key) => {
map.set(key, _completeDeepClone(value, visited));
});
return map;
}
// Set
if (constructor === Set) {
const set = new Set();
visited.set(obj, set);
obj.forEach((value) => {
set.add(_completeDeepClone(value, visited));
});
return set;
}
// 处理函数对象和箭头函数
if(constructor === Function) {
let res;
if(!obj.hasOwnProperty("prototype")) { // 箭头函数
// res = new Function(`return ${obj.toString()}`)()
res = eval(obj.toString());
visited.set(obj, res); // 避免循环引用
return res;
}
// 考虑到构造函数和普通对象
res = function(...args) {
return obj.call(this, ...args);
}
visited.set(obj, res); // 避免循环引用
// 普通对象的自身的属性,比如fn.a = 2这种静态属性
Object.keys(obj).forEach(key => res[key] = obj[key]);
// 原型继承,寄生组合继承,复制该函数的原型链
res.prototype = Object.create(obj.prototype);
res.prototype.constructor = res;
return res;
}
// 处理普通对象和数组
const result = Array.isArray(obj) ? [] : {};
visited.set(obj, result);
// 获取对象的所有属性名,包括不可枚举属性
const props = Object.getOwnPropertyNames(obj); // 不可枚举类型
const symbolProps = Object.getOwnPropertySymbols(obj); // Symbol类型
props.concat(symbolProps).forEach(key => {
const descriptor = Object.getOwnPropertyDescriptor(obj, key);
if(descriptor) {
const { value, writable, enumerable, configurable } = descriptor;
Object.defineProperty(result, key, {
value: _completeDeepClone(value, visited),
writable, enumerable, configurable
})
}
});
return result;
}
数据类型
Boolean\String\Number\BigInt\Int\undefined\null
继承,原型链
- 看我深拷贝中的函数拷贝说我继承学的很不错
tcp三次握手
- syn
- ack/syn
- ack
syn确认码是怎么+1
tcp4次挥手
- fin
- ack
- fin
- ack
为什么需要tcp4次挥手,3次不就行吗?
面试官和我说也有tcp3挥手,将fin和ack一起发送
OSI七层模型
网络死亡几连问,问麻了
http状态码
反问
百度二面(4.24)
实习多久
哈哈开始画饼,让我最好实习到毕业且可提供转正名额
项目
手写防抖节流
手写dfs和bfs
简单的算法
// 用 JavaScript 写一个函数,输入 int 型,返回整数逆序后的字符串。如:输入
// 整型 1234,返回字符串“4321”。要求必须使用递归函数调用,不能用全局变量,
// 输入函数必须只有一个参数传入,必须返回字符串
function getR(num) {
if(parseInt(num) !== num) {console.log("Invalid number");return;}
let res = '';
G(String(num));
return res;
function G(str) {
if(str.length === 0) return;
res += str[str.length - 1];
G(str.slice(0, -1));
}
}
console.log(getR(23.40))
// 优化
function reverseInt(num) {
if(parseInt(num) !== num) throw Error("Invalid number");
if (num < 10) return num.toString();
const lastDigit = num % 10;
const remainingDigits = Math.floor(num / 10);
const reversed = reverseInt(remainingDigits);
return lastDigit.toString() + reversed;
}
const reversed = reverseInt(12340);
console.log(reversed); // "4321"
轮播图实现
npm执行过程
项目中测试方面
- 用pnpm workplace
盒模型
css文字截断
.truncate {
display: -webkit-box;
-webkit-line-clamp: 2; /* number of lines to show */
-webkit-box-orient: vertical;
overflow: hidden;
text-overflow: ellipsis;
}
flex实现两边大小固定,中间自适应
<!DOCTYPE html>
<html lang="en">
<body>
<style>
div {
display: flex;
flex-direction: row;
}
div div {
height: 100px;
}
div div:nth-child(1) {
width: 100px;
background-color: aqua;
}
div div:nth-child(2) {
width: 100%;
background-color: rgb(255, 0, 0);
}
div div:nth-child(3) {
width: 100px;
background-color: rgb(0, 0, 0);
}
</style>
<div class="div">
<div></div>
<div></div>
<div></div>
</div>
</body>
</html>
也可以用grid和table布局实现
<style>
/* .container {
display: table;
width: 100%;
}
.left, .right {
background-color: antiquewhite;
display: table-cell;
width: 100px;
height: 100px;
}
.middle {
display: table-cell;
height: 100px;
} */
.container {
display: grid;
grid-template-columns: 100px auto 100px;
width: 100%;
}
.left, .right {
background-color: antiquewhite;
width: 100%;
height: 100px;
}
.middle {
background-color: rgb(0, 0, 0);
width: 100%;
height: 100px;
}
</style>
<div class="container">
<div class="left"></div>
<div class="middle"></div>
<div class="right"></div>
</div>
百度三面(4.27)-> 第二天OC
主管面,该说不说,人真的特别好,后面还来找我,说有变动直接找她
自我介绍,部门介绍
哪里人,有没有谈恋爱
不知道为什么问我有没有谈恋爱?很奇怪
学习情况,实习多久,入职时间
项目介绍
项目中遇到的难点或者难以解决的地方
项目启动需要制定风险以控制突发情况
聊天
哈哈说我普通话不太标准,问我是不是广东人,笑的,被发现了😂
面评
说对我很满意,会联系hr
写在结尾
还面了小米,不过一面后不想面了,这个时候已经接了offer啦!!!
PS:滴滴约面了,离谱!3月投的,现在约。。。
祝各位全部 OC!