打开全栈工匠技能包-1小时轻松掌握SSR
两小时精通jq+bs插件开发
生产环境下如歌部署Node.js
开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】
网易内部VUE自定义插件库NPM集成
谁说前端不用懂安全,XSS跨站脚本的危害
webpack的loader到底是什么样的?两小时带你写一个自己loader
// 5s 后清理
mySetInterval.clear()
}, 5000)
第 4题:webpack 打包 vue 速度太慢怎么办?
============================
说说我的处理方式吧,纯经验之谈
1.使用webpack-bundle-analyzer
对项目进行模块分析生成report,查看report后看看哪些模块体积过大,然后针对性优化,比如我项目中引用了常用的UI库element-ui和v-charts等
2.配置webpack的externals
,官方文档的解释:防止将某些import
的包(package)打包到 bundle 中,而是在运行时(runtime)再去从外部获取这些扩展依赖。
所以,可以将体积大的库分离出来:
// …
externals: {
‘element-ui’: ‘Element’,
‘v-charts’: ‘VCharts’
}
3.然后在main.js
中移除相关库的import
4.在index.html
模板文件中,添加相关库的cdn
引用,如:
经过以上的处理,再尝试编译打包,会发现速度快了一些。
第 5 题:为什么for循环嵌套顺序会影响性能?
========================
var t1 = new Date().getTime()
for (let i = 0; i < 100; i++) {
for (let j = 0; j < 1000; j++) {
for (let k = 0; k < 10000; k++) {
}
}
}
var t2 = new Date().getTime()
console.log(‘first time’, t2 - t1)
for (let i = 0; i < 10000; i++) {
for (let j = 0; j < 1000; j++) {
for (let k = 0; k < 100; k++) {
}
}
}
var t3 = new Date().getTime()
console.log(‘two time’, t3 - t2)
解析:
两个循环的次数的是一样的,但是 j 与 k 的初始化次数是不一样的
-
第一个循环的 j 的初始化次数是 100 次,k 的初始化次数是 10w 次
-
第二个循环的 j 的初始化次数是 1w 次, k 的初始化次数是 1000w 次
所以相同循环次数,外层越大,越影响性能
第六题:统计 1 ~ n 整数中出现 1 的次数
========================
解析:
应该是说1-n的时候中间出现1的次数,比如1到11的时候 1、10、11这种 其实就算4次了,因为11中有两个1
function findOne(n){
let count = 0;
for(let i=0;i<=n;i++){
count+=String(i).split(‘’).filter(item=>item===‘1’).length
}
return count;
}
第 七 题:Vue 的响应式原理中 Object.defineProperty 有什么缺陷?为什么在 Vue3.0 采用了 Proxy,抛弃了 Object.defineProperty?
==============================================================================================
解析:
-
Object.defineProperty无法监控到数组下标的变化,导致通过数组下标添加元素,不能实时响应;
-
Object.defineProperty只能劫持对象的属性,从而需要对每个对象,每个属性进行遍历,如果,属性值是对象,还需要深度遍历。Proxy可以劫持整个对象,并返回一个新的对象。
-
Proxy不仅可以代理对象,还可以代理数组。还可以代理动态增加的属性。
第 8题:在输入框中如何判断输入的是一个正确的网址。
function isUrl(url) {
try {
new URL(url);
return true;
}catch(err){
return false;
}}
第 9 题:不用加减乘除运算符,求整数的7倍
======================
虽然这样做没什么技术含量,但至少符合题意吧哈哈
function(x){
let arr = Array(x)
let resultArr = […arr,…arr,…arr,…arr,…arr,…arr,…arr]
return resultArr.length
}
思考
当需要进行避免使用加减乘除的数学运算的时候,通常的方法有:位运算、Eval/Function 传参 hack、进制转换配合字符串转换操作等等,我们参考题目来源中提到的几种方式以及其他大佬们提供的解法来看下这道题。
位运算加法 - 连续7次相加
从上面的表可以看出一种实现简单的多位二进制整数加法的算法如下:
m 和 n 是两个二进制整数,求 m + n:
-
用与运算求 m 和 n 共同为 “1” 的位:m’ = m & n
-
用异或运算求 m 和 n 其中一个为 “1” 的位:n’ = m ^ n
-
如果 m’ 不为 0,那么将 m’ 左移一位(进位),记 m = m’ << 1,记 n = n’,跳回到步骤 1
-
如果 m’ 为 0,那么 n’ 就是我们要求的结果。
function bitAdd(m, n){
while(m){
[m, n] = [(m & n) << 1, m ^ n];
}
return n;
}
bitAdd(45, 55); //100
既然实现了加法,我们就可以很容易地将“乘7”这个操作通过循环加法实现出来:
function multiply7(num){
let sum = 0;
for(var i = 0; i < 7; i++){
sum = bitAdd(sum, num);
}
return sum;
}
multiply7(7); //49
这里变量 i 自增的时候用了加号,我们用数组将它代替掉:
function multiply7(num){
let sum = 0;
let counter = new Array(7); // 得到 [empty × 7]
while(counter.length){
sum = bitAdd(sum, num);
counter.shift();
}
return sum;
}
multiply7(7); //49
位运算加法 8+(-1)
既然有加法,我们也可以用 “目标数的8倍减去目标数的1倍” 来实现 “乘7” 的目的。首先贴出位运算加法常见的做法(此段完全引用自原文):
let multiply7 = (num) => bitAdd(num << 3, -num);
multiply7(7); //49
避免使用负号(减号),我们用补码来代替 ( num * -1) 的操作:
let multiply7 = (num) => bitAdd(num << 3, bitAdd(~num, 1));
multiply7(7); //49
黑科技 hack 手段
在 JavaScript 语言里,还有很多黑科技手段,比如我们可以使用字节码的形式来代替 “ * ” 乘号。
let multiply7_1 = (num) =>
new Function([“return “,num,String.fromCharCode(42),“7”].join(””))();
let multiply7_2 = (num) =>
eval([num,String.fromCharCode(42),“7”].join(“”));
setTimeout([“window.multiply7_3=(num)=>(7”,String.fromCharCode(42),“num)”].join(“”))
multiply7_1(7);// 49
multiply7_2(7);// 49
multiply7_3(7);// 49
进制转换
参考位运算我们进行一下思考:二进制整数向左位移一位、末尾补0,可以得到其2倍值;十进制整数向左位移一位、末尾补0,可以得到其10倍值;那么我们也可以依此法来进行七进制整数进位补0,来得到7倍值!
let multiply7_4 =
(num)=>parseInt([num.toString(7),‘0’].join(‘’),7);
multiply7_4(7);// 49
感悟
题目本身并没有进行非常强的要求,但是我们可以通过一个题目延展成若干个知识点:
最后
编程基础的初级开发者,计算机科学专业的学生,以及平时没怎么利用过数据结构与算法的开发人员希望复习这些概念为下次技术面试做准备。或者想学习一些计算机科学的基本概念,以优化代码,提高编程技能。这份笔记都是可以作为参考的。
开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】