详情>
详情>
详情>
详情>
详情>
Content Security Policy>
详情>
详情>
function parseString(str, obj) { Object.keys(obj).forEach(key => { str = str.replace(new RegExp(`{{${key}}}`,'g'), obj[key]); }); return str; } const str = "我的name是{{name}},{{name}}很厉害,才{{age}}岁"; const obj = { name: "kangkang", age: "15" }; console.log(parseString(str, obj));
详情>
这个无害是相对于watch和methods,计算属性能减少性能的损耗
我们可以将同一函数定义为一个方法而不是一个计算属性。两种方式的最终结果确实是完全相同的。然而,不同的是计算属性是基于它们的依赖进行缓存的。计算属性只有在它的相关依赖发生改变时才会重新求值。这就意味着只要依赖的data还没有发生改变,多次访问计算属性会立即返回之前的计算结果,而不必再次执行函数。
而方法是每次都会执行, watch在依赖的data没有改变也会执行。
详情>
假设按照升序排序的数组在预先未知的某个点上进行了旋转。(例如,数组[0,1,2,4,5,6,7]可能变为[4,5,6,7,0,1,2])。搜索一个给定的目标值,如果数组中存在这个目标值,则返回它的索引,否则返回-1。你可以假设数组中不存在重复的元素。你的算法时间复杂度必须是O(logn)级别。
async function async1() { console.log('async1start') await async2() // 等所有的同步任务执行完才会执行异步任务 console.log('async1end') } async function async2() { console.log('async2') } console.log('scriptstart') setTimeout(function() { console.log('setTimeout') }, 0) async1() new Promise(function(resolve) { console.log('promise1') resolve() }) .then(function() { console.log('promise1then') return 'promise1end' }) .then(res => { console.log(res) }) .then(res => { console.log(res) }) console.log('scriptend') //打印如下: scriptstart async1start async2 //同步任务 promise1 scriptend async1end // await会等所有同步任务执行完后,才继续执行后面的任务 promise1then // promise1end undefined // 前面没有return 则默认返回undefined setTimeout // promise.then里面是微任务,promise.then.then还是微任务,宏任务会等所有微任务执行完再执行。
详情->
详情->
详情->
详情->
详情->
node.js react.js 数据大屏 前端埋点
个人技术栈,呆过哪些公司,简单介绍下做过什么项目。过往经历,最近工作,最近项目。
五洲行-机票旅游订票平台
应用魔方-低代码开发平台
数字清关平台-清关数据大屏-前端埋点系统
现有一个含有字符串的数组,形如:[“ab”,“c”,“ab”,“d”,“c”]要求将其中出现的重复字符串,依次添加上数字序号,如:[“ab1”,“c1”,“ab2”,“d”,“c2”]
要求:
1).未重复出现的字符串不处理;
2).仅对相同的一组字符串依次添加序号,而不是共用一组序号;
3).保持原数组顺序;
慢热,学习热情高
团队规模,目前团队技术栈,前端是全栈开发吗
function Person() {} let p = new Person() //{constructor: ƒ} console.log(p.__proto__) //{constructor: ƒ} console.log(Person.prototype) //{constructor: ƒ, __defineSetter__: ƒ, hasOwnProperty: ƒ...} console.log(p.__proto__.__proto__) //ƒ Object() { [native code] } console.log(p.__proto__.__proto__.constructor) //{constructor: ƒ, __defineSetter__: ƒ, hasOwnProperty: ƒ...} console.log(p.__proto__.__proto__.constructor.prototype) //ƒ Object() { [native code] } console.log(p.__proto__.__proto__.constructor.prototype.constructor) //ƒ Function() { [native code] } console.log(p.__proto__.__proto__.constructor.prototype.constructor.constructor) //ƒ Function() { [native code] } console.log(p.__proto__.__proto__.constructor.prototype.constructor.constructor.constructor)
.container { display: flex; width: 600px; height: 300px; } .a { width: 500px; flex-shrink: 1; } .b { width: 400px; flex-shrink: 2; }
很明显,a.width + b.width已经大于父元素的宽度, flex-shrink会让子元素进行压缩,以适应父元素的宽度,值越大压缩的越严重。
知识点>
setImmediate(() => { console.log(1); }); setTimeout(function(){ console.log(2); }); new Promise(function(resolve){ console.log(3); resolve(); console.log(4); }).then(function(){ console.log(5); }); console.log(6); process.nextTick(function(){ console.log(7); }); console.log(8); // 3 4 6 8 5 7 1 2
// 输入不仅仅只有Array function promiseAll (args) { return new Promise((resolve, reject) => { const promiseResults = []; let iteratorIndex = 0; // 已完成的数量,用于最终的返回,不能直接用完成数量作为iteratorIndex // 输出顺序和完成顺序是两码事 let fullCount = 0; // 用于迭代iterator数据 for (const item of args) { // for of 遍历顺序,用于返回正确顺序的结果 // 因iterator用forEach遍历后的key和value一样,所以必须存一份for of的 iteratorIndex let resultIndex = iteratorIndex; iteratorIndex += 1; // 包一层,以兼容非promise的情况 Promise.resolve(item).then(res => { promiseResults[resultIndex] = res; fullCount += 1; // Iterator 接口的数据无法单纯的用length和size判断长度,不能局限于Array和 Map类型中 if (fullCount === iteratorIndex) { resolve(promiseResults) } }).catch(err => { reject(err) }) } // 处理空 iterator 的情况 if(iteratorIndex===0){ resolve(promiseResults) } } ) } if (!Promise.all) Promise.all = promiseAll;
<div class='content'> <div class='son'> 内容区 </div> </div> // 方法1绝对定位 .content{ position: relative; //重点 background:black; width:100px; height:200px; .son{ position:absolute; left: 50%; top: 50%; transform: translate(-50%,-50%); background:red; } } // 方法2 flex .content{ width:100px; height:200px; display: flex; justify-content: center; align-items: center; background:black; .son{ background:red; } }
有看过核心源码,具体包括以下几个部分:
详情>
详情>
5-1. 详情>
5-2. 哪些情况用 vuex ?
5-3. 场景:登录,注册(需要根据登录用户信息来展示菜单和用户名)
5-4. 除了 vuex ,还有哪些组件间通信方式?详情>
5-5. 你是如何处理兄弟组件间通信的?
decorator相当于一个高阶函数,接收一个函数,返回一个被装饰后的函数。
详情>
没有
没有
没有
协议,域名,端口不同即跨域
详情>
http://ip:port
与指向该 ip:port 的域名是同域吗?一个ip可以对应多个域名
是同域名,在协议和端口相同的情况下,域名和对应的ip的同域的
为什么要做首屏优化:
首屏时间的快与慢,直接影响到了用户对网站的认知度。
所以首屏时间的长短对于用户的滞留时间的长短、用户转化率都尤为重要。
详情>
详情>
不知道
不知道
不知道
不知道
不知道
详情>
没用过
没用过
没用过
不会
详情>
项目层面,业务层面,代码优化,webpack优化,重点是从自己出发
详情>
详情>
发生在执行(import(‘xxModule’))的时候,它会单独打成一个包,采用动态加载的方式,具体过程:当用户触发其加载的动作时,会动态的在head
标签中创建一个script
标签,然后发送一个http
请求,加载模块,模块加载完成以后自动执行其中的代码,主要的工作有两个,更改缓存中模块的状态,另一个就是执行模块代码。
webpack的打包构建流程
详情>
详情>
为什么tree-shaking是最近几年流行起来了?而前端模块化概念已经有很多年历史了,其实tree-shaking的消除原理是依赖于ES6的模块特性。
ES6 module 特点:
ES6模块依赖关系
是确定的,和运行时
的状态
无关,可以进行可靠的静态分析
,这就是tree-shaking的基础。
所谓静态分析就是不执行代码
,从字面量
上对代码进行分析
,ES6之前的模块化,比如我们可以动态require一个模块,只有执行后
才知道引用的什么模块,这个就不能通过静态分析去做优化。
这是 ES6 modules 在设计时的一个重要考量,也是为什么没有直接采用 CommonJS,正是基于这个基础上,才使得 tree-shaking 成为可能,这也是为什么 rollup 和 webpack 2 都要用 ES6 module syntax 才能 tree-shaking。
在代码压缩优化工具uglify,压缩代码的时候进行的。
详情>
不会
详情>
用的是mongodb,前端大概要什么结构的字段,就设计什么结构,父子结构的通过id关联。
全栈工程师,资深工程师,当前在职场经验丰富和能力提成后也能做技术管理
能更好的理解项目,能在技能上得到更大的提升,提升工作效率,提升自身的价值。
做了哪些东西,亮点有什么。
不会
详情>
详情->
这个得想一下,太难的一般用插件也可以解决
add(1)(2)(3)(4) => 输出10
详情>
详情>
let / const、箭头函数、解构赋值、默认参数、扩展运算符、类、字符串模板、数组新增的高阶函数、Promise
Object Null Number Undefined String Boolean Symbol BigInt
详情>
强缓存和弱缓存详情>
详情>
详情>
可以在简历上体现
从体验,代码,打包,请求速度等多方面来谈
去除大量重复文件,提取可以复用文件,建立前端埋点日志,等等
详情>
详情>
详情>
详情>
详情>
详情>
var b = {name:1} b.hasOwnProperty('name') // true
原型链:
所有的JS对象都有一个__proto__属性,指向它的原型对象。当试图访问一个对象的属性时,如果没有在该对象上找到,它就会搜寻该对象的原型,以及该对象的原型的原型,层层向上查找,直到找到一个名字匹配的属性或到达原型链的末尾null,这样的一种查找关系,就称为原型链。
详情>
其它答案有讲
综合其它答案,讲一下自己项目中实际用到的
详情>
其它答案有讲
详情,基础知识>
详情,实践>
详情,实践>
其它答案有讲
详情>
详情>
详情>
一面 90min 感觉面试官很nice 少数聊的不错的面试官 问的相对比较深入
• Node server内存机制
• V8的垃圾回收机制
• 内存泄漏有哪些场景?如何查找?
• 项目得nuxt.js服务流量处理?100万用户如何处理?
• 项目nuxt.js的缓存是如何做的?
• 网页的多国语言处理
• 了解前端缓存吗?
• 浏览器缓存?以及优先级?
• HTTP2的特性?服务器推送了解吗?
• HTTP3了解吗?和HTTP2、HTTP1的区别
• TLS的握手过程?哪个环节用到了私钥
• 打包工具?webpack的原理?
• 热更新具体描述一些?
• webpack压缩如何做的?
• babel如何转es6的代码?
• 跨域方案?
• 项目的错误监控方案?如果sentry的 js文件加载不出来如何错误上报?
笔试
1、八股文
setTimeout(() => {
console.log(‘start’);
Promise.resolve().then(() => {
console.log(‘Promise 1’);
setTimeout(() => {
console.log(‘setTimeout 2’);
})
});
setTimeout(() => {
console.log(‘setTimeout 1’);
Promise.resolve().then(() => {
console.log(‘Promise 2’);
});
});
}, 0)
console.log(‘end’);
2、超级八股文
var s = 0;
var i = 1;
var funcs = [];
var n = 3;
function x(n) {
for (i = 0; i < 3; i++) {
funcs[i] = () => {
s = s + i * n;
console.log(s);
};
}
}
x(1);
funcs0;
funcs1;
funcs2;
3、编程题 实现一个循环检测的函数?
const a = {
b:{
c:{}
}
};
a.b.c.d = a;
console.log(isCycle(a));
4、斐波那契数列数列
/**
问题描述:
假设你正在爬楼梯。需要 n 阶你才能到达楼顶。
每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢?
注意:给定 n 是一个正整数。
实例:
输入: 3
输出: 3
解释: 有三种方法可以爬到楼顶。
1 阶 + 1 阶 + 1 阶
1 阶 + 2 阶
2 阶 + 1 阶
*/
字节飞书
一上来就手撕题,有一题撕不出来有点尴尬
• leetcode 31
• 手撕发布订阅模式 EventEmitter
问的大部分是项目延展问题
• 拿到一个需求功能,你的开发步骤
• SEO怎么做的
• 如果有一个用户白屏咋整?(讨论题)
• 印象深刻的故障解决流程
• 技术选型是怎么做的?解决了什么问题?
企业微信
太惨烈了都忘记问了什么,只记得几个问题 面了一个半小时
• 用过PWA吗?
• SSR的原理
• 同源两个标签页的通讯方式
• 做题
二维平面上有 N 个点,请找出两两之间斜率最大的两个点
interface Point {
x: number;
y: number;
}
function run(arr: Point[]): [Point, Point] {
// TODO
}
有一个 4x4 的矩阵,上面随机分布了 9 个点。你每次可以把一个点移动到其他格子,请移动最少的步数,另矩阵内有横、竖、斜三条线能连上 4 个点:
oooo
oooo
oxxx
xxxx
如上述例子中,“o” 为点,“x” 为空位,则最少移动两个点:
oooo
oxox
ooxx
oxxx
在第一行、第一列,正斜线都能连上4个点。
解题:
第一题网上有答案
第二题:
这道题,思路1:
首先,4 * 4的格子,放9个点,有C(16 , 9) = 11440种
暴力,把这11440种里面,符合要求的找出来
对于给定的矩阵,和符合要求的对比,看看哪一种移动次数最小
理论上,这就是O(1)的时间复杂度,因为时间复杂度是一个常数,和输入数据没有关系
思路2:
9个点,最好情况就是,不用移动就符合要求,
最差情况就是要移动其中7个点(因为16 - 9 = 7,只有7个空位了)
所以直接暴力,枚举要移动哪些点,到哪些目的地
时间复杂度也是O(1)的
项目中有什么亮点,哪一点让你印象深刻
参考的几个点:稳定,性能,团队上手,能否支持后续的迭代
公司项目:
个人项目,vue+node+express+mongodb
去除大量重复文件,提取可以复用文件
详情>
详情>
详情>
即webpack的优化
CDN的原理
flex布局?常用来干啥?常见的属性;grid布局?
浏览器刷新频率?60赫兹?requestAnimationFrame的题目——根本没用过啊喂
JS事件循环机制 + 八股文输入输出题(process.nextTick todo)
HTTPS为什么能保证安全
HTTPS一定是安全的吗?
说一下中间人攻击 ——todo没说出来
Vue的数据双向绑定原理
如何处理线上故障
题 leetcode 20题
将array 数组(仅包含整数的无序的数组)进行重新排列,
排序后数组符合特征 array[0] <= array[1] >= array[2] <= array[3]…。
示例:
输入: array = [2,7,2,1,6,3]
输出: [2,7,1,6,2,3] 或其他符合要求的答案
*/
function sort(array = []) {
if (!array || !array.length) return []
if (!array.length === 1) return []
array.sort((a, b) => a - b)// 快排
let i = 1
while (i < array.length) {
swap(array, i, i + 1)
i += 2
}
return array
}
function swap(arr, i, j) {
let temp = arr[i]
arr[i] = arr[j]
arr[j] = temp
}
const test = sort([1, 2, 3, 4, 5])
console.log(test) //[ 1, 3, 2, 5, 4 ]
• 前东家的情况巴拉巴拉
• 印象最深刻的项目?
• 回首过去,那些事情可以做得更好?
• 印象最深刻的bug?
• 项目优化的地方有哪些
• 职业规划已经期望薪酬
• 感觉都像闲聊的话题。。。
三面 HR面
HR很nice,没有什么坑
阿里文娱
项目详情和难度
ocpc和ocpm的区别
汇量科技
树结构设计和遍历
模块联邦实现
项目相关(ocpc和ocpm)
如何实现表单和表格模块化
如何做一个小游戏
(项目巨无细致的挖)
详情>