目录1
(didi)
- 深拷贝
- weakSet weakMap
- 闭包
- 爬楼梯算法
- 时间复杂度,空间复杂度的理解
- 性能监控平台的架构实现
目录2
(白龙马)
前端框架类RN做APP迭代开发 与 混合开发react,vue。
- FFC flex布局
- 防抖和节流的实现(以及节流最后一次事件要执行怎么实现)
- call apply的实现
- ast
- 闭包
- 类型判断的几种方法
- instansof 的实现
- 装饰器模式
- for...of (不可遍历对象) 迭代器 next 与 for...in 答案:juejin.cn/post/692344…
目录3
(shen ce)
sdk 数据采集开发,原生js。也要一些测试用例
- 代码容错有哪些方式
- 稳定性实现方式
- 扩展性实现方式
- 不用框架都用原生js
- cookie localStoage
- iframe
- 代码库被引入到其他项目中不会导致其他项目出问题。无侵入无污染
- 面向对象OOP的特点 答案:封装、继承、多态
- try...catch的使用场景
目录4
(vant)
-
vue-router的两种方式,history模式为何刷新页面就404了 答: 因为history模式本身的缺陷导致。需要后端配置Nginx 其他路由全部指向Index.html即可
-
冒泡排序,快速排序
- 攻击方式跨域请求伪造csrf如何攻击,如何预防
-
bfc
-
url转码和解码
escape()除了 ASCII 字母、数字和特定的符号外,对传进来的字符串全部进行转义编码,因此如果想对URL编码,最好不要使用此方法。而encodeURI() 用于编码整个URI,因为URI中的合法字符都不会被编码转换。encodeURIComponent方法在编码单个URIComponent(指请求参数)应当是最常用的,它可以讲参数中的中文、特殊字符进行转义,而不会影响整个URL。
js对文字进行编码涉及3个函数:escape,encodeURI,encodeURIComponent,相应3个解码函数:unescape,decodeURI,decodeURIComponent
1、 传递参数时需要使用encodeURIComponent,这样组合的url才不会被#等特殊字符截断。
例如:');
2、 进行url跳转时可以整体使用encodeURI
例如:Location.href=encodeURI("cang.baidu.com/do/s?word=百…");
3、 js使用数据时可以使用escape
- splice,slice区别
答案:splice会改变原始数据,slice不会改变原始数据。
splice(开始位置,删除个数,增加的元素...)
slice(开始位置, 结束位置) // 截取的内容不包含结束索引的内容
-
TCP比UDP更可靠吗
-
https与http的区别, http是如何加密的
-
浏览器为什么有跨域限制?如何跨域?正向代理,反向代理的区别。
-
输出所有符合条件的ip地址 ,(IP地址是0到225之间,不能大于225)
/ 2、要求,输出所有符合条件的ip地址
// eg:
// 输入字符串: '22521511135'
// 输出结果: [ '225.215.11.135', '225.215.111.35' ]
const ipStr = "225 21 511 135";
function getIp(ipStr) {
}
- 解析 url 中的 queryString 【此处逻辑有问题代码没写完】
/**
* 输入:https://www.youzan.com?name=coder&age=20&callback=https%3A%2F%2Fyouzan.com%3Fname%3Dtest&list[]=a&list[]=b&json=%7B%22str%22%3A%22abc%22,%22num%22%3A123%7D&qws&www=null
*
* 输出:
* {
* name: 'coder',
* age: '20',
* callback: 'https://youzan.com?name=test',
* list: ['a', 'b'],
* json: {
* str: 'abc',
* num: 123
* },
* qws: '',
* www: '',
* }
*/
// list[]=a&list[]=b;
// json 转码
const testUrl = `https://www.youzan.com?name=coder&age=20&callback=https%3A%2F%2Fyouzan.com%3Fname%3Dtest&list[]=a&list[]=b&json=%7B%22str%22%3A%22abc%22,%22num%22%3A123%7D&qws&www=null`;
function parseQueryString(url) {
let searchUrlArr = url.split('?')[1].split('&');// ['age=20',...]
let len = searchUrlArr.length;
let res = {};
for (let i = 0; i < len; i++) {
let searchUrlArrItem = searchUrlArr[i];
let preI = i < 0 ? 0 : i - 1;
let preSearchUrlArrItem = searchUrlArr[preI];
let item = searchUrlArrItem.split('=');
let preItem = preSearchUrlArrItem.split('=');
// key 相同
if (item[0] === preItem[0]) {
// res[item[0]] = item[1];
} else {
res[item[0]] = item[1];
}
}
return res;
}
console.log('parseQueryString(testUrl)', parseQueryString(testUrl))
function parseQueryString(url) {
// [list[]=a, list[]=b, json=%7B%22str%22%3A%22abc%22,%22num%22%3A123%7D]
let searchUrlArr = url.split('?')[1].split('&'); // ['age=20',...]
let res = {};
let hasArrTag = (item) => {
return item.indexOf('[]') > 0
};
let result = searchUrlArr.reduce((pre, cur, arr) => {
let preItem = pre.split('=');
let curItem = cur.split('=');
let con = preItem[0] === curItem[0] && hasArrTag(preItem[0]) && hasArrTag(curItem[0]);
if (con) {
res.curItem[0] = [...preItem[0], ...curItem[0]];
} else {
res.curItem[0] = curItem[1];
}
}, []);
return res;
}
- 模块化commonjs与es6 module的区别?以及文件的循环引用如何解决?
答案:
CommonJs解决了变量污染,文件依赖等问题,上面我们也介绍了它的基本语法,它可以动态导入(代码发生在运行时),不可以重复导入。
Es Module也是解决了变量污染问题,依赖顺序问题,Es Module语法也是更加灵活,导出值也都是导出的引用,导出变量是可读状态,这加强了代码可读性。Es Module语句import只能声明在该文件的最顶部,不能动态加载语句,Es Module语句运行在代码编译时。
CommonJs
- CommonJs可以动态加载语句,代码发生在运行时
- CommonJs混合导出,还是一种语法,只不过不用声明前面对象而已,当我导出引用对象时之前的导出就被覆盖了
- CommonJs导出值是拷贝,可以修改导出的值,这在代码出错时,不好排查引起变量污染
Es Module
-
Es Module是静态的,不可以动态加载语句,只能声明在该文件的最顶部,代码发生在编译时
-
Es Module混合导出,单个导出,默认导出,完全互不影响
-
Es Module导出是引用值之前都存在映射关系,并且值都是可读的,不能修改
-
Node是 CommonJS 在服务器端一个具有代表性的实现; -
Browserify是 CommonJS 在浏览器中的一种实现; -
webpack打包工具对 CommonJS 的支持和转换;也就是前端应用也可以在编译之前,尽情使用 CommonJS 进行开发。
参考:
- 对象的循环引用如何解决?
- 0.1+0.2===0.3 吗?为什么? (浮点数计算分析与解决方法)
小数点在计算机中是以二进制表示,而有些小数用二进制表示是无穷,所以才会出现上面这种精确度的问题。 一些浮点数表示成二进制 caibaojian.com/float-point…
0.1+0.2===0.3 //false
0.1+0.2==0.3 //false
0.1 + 0.2===0.30000000000000004 // true
0.1+0.2!=0.3 // true
目录5
(bd gaojing ditu)
- 明道云 炎黄盈动 云程
一、深拷贝
答案只考虑数据和对象类型,函数,正则等数据类型不在处理范围内,以及循环引用没处理。
function deepCopy(obj){
let res = obj.constrantor === 'Array' ? [] : {};
for(let i in obj){
if(Object.prototype.toString.call(obj[i]) === '[object Object]'){
res[i] = deepCopy(obj[i]);
}else{
res[i] = obj[i];
}
}
return res;
}
var testObj ={
a:1,
b: {
c:2
}
};
deepCopy(testObj);
二、weakSet weakMap
三、闭包
四、爬楼梯算法
// 假设楼梯一共有N层台阶,一次可以走1层,或者2层,请问走到顶层有几种方法?
// 3层 是 1 1 1 ,1 2 , 2 1 , 共3方法
// 4层 是 1 1 1 1, 1 1 2 , 1 2 1, 2 2 ,2 1 1,共4种方法
// 输入 n 层数 输出 解决办法个数
// 代码实现共两种方法: 动态规划 与 递归
1) 递归实现
// 定义爬楼梯方法
const f = []; //用于存储不同楼层对应的解决办法个数
const climbStairs = function(n) {
// 处理边界条件
if(n==1) {
return 1
}
if(n==2) {
return 2
}
// 若 f(n) 不存在,则递归计算其值
if(f[n]===undefined) f[n] = climbStairs(n-1) + climbStairs(n-2)
// 若 f(n) 已经有值,则直接返回
return f[n]
};
2) 循环实现
const climbStairs = function(n) {
const f = [];// 初始化结果数组
f[1] = 1;
f[2] = 2;
// 动态更新每一层楼梯对应的结果
for(let i = 3;i <= n;i++){
f[i] = f[i-2] + f[i-1];
}
return f[n];
};