简答一(选4每题10分)
• 函数防抖、截流的概念和使用场景
1,防抖(debounce):触发高频事件后 n 秒内函数只会执行一次,如果 n 秒内高频事件再次被触发,则重新计算时间
举例:就好像在百度搜索时,每次输入之后都有联想词弹出,这个控制联想词的方法就不可能是输入框内容一改变就触发的,他一定是当你结束输入一段时间之后才会触发
2,节流(thorttle):高频事件触发,但在 n 秒内只会执行一次,所以节流会稀释函数的执行频率
举例:预定一个函数只有在大于等于执行周期时才执行,周期内调用不执行。就好像你在淘宝抢购某一件限量热卖商品时,你不断点刷新点购买,可是总有一段时间你点上是没有效果,这里就用到了节流,就是怕点的太快导致系统出现bug。
• js判断变量是否为数组,至少2种方案
Array.prototype.slice.call(),[].concat.apply([],arr)、Function.prototype.call.bind(Array.prototype.slice)、[].slice.call(arr)ES6类数组转化为数组 Array.from(arr)
• 什么是跨域?前端如何解决?
浏览器从一个域名的网页去请求另一个域名的资源时,域名、端口、协议任一不同,都是跨域
解决方法:
PHP端修改header
header(‘Access-Control-Allow-Origin:*’);//允许所有来源访问
header(‘Access-Control-Allow-Method:POST,GET’);//允许访问的方式
• 请写出以下http状态码的含义
○ 200 请求成功。一般用于GET与POST请求
○ 302 临时移动。与301类似。但资源只是临时被移动。客户端应继续使用原有URI
○ 401 请求要求用户的身份认证
○ 404 服务器无法根据客户端的请求找到资源(网页)。通过此代码,网站设计人员可设置"您所请求的资源无法找到"的个性页面
○ 500 服务器内部错误,无法完成请求
○ 502 作为网关或者代理工作的服务器尝试执行请求时,从远程服务器接收到了一个无效的响应
• 写出5个常用linux命令&含义
1,top(总)查看系统资源的使用情况
2.vmstat(主要看的是后边的CPU)
3.mpstat -p All 查看所有内核的CPU信息
4. 查看运行内存 :free -m
5.查看单个进程的使用内存的情况:pidstat -p 进程号 -r 采样间隔秒数
• css画三角形
<!DOCTYPE html>
<html>
<head>
<title></title>
<style type="text/css">
/* css3绘制三角形 */
.triangle{
0px; /*设置宽高为0,所以div的内容为空,从才能形成三角形尖角*/
height: 0px;
border-bottom: 200px solid #00a3af;
border-left: 200px solid transparent; /*transparent 表示透明*/
border-right: 200px solid transparent;
}
</style>
</head>
<body>
<div class="triangle"></div>
</body>
</html>
• css清除浮动方法
1、父级div定义 height 原理:父级div手动定义height,就解决了父级div无法自动获取到高度的问题. 缺点:只适合高度固定的布局,要给出精确的高度,
2、结尾处加空div标签 clear:both 原理:添加一个空div,利用css提高的clear:both清除浮动,让父级div能自动获取到高度 如果页面浮动布局多,就要增加很多空div,让人感觉很不好
3、父级div定义 伪类:after 和 zoom 原理:IE8以上和非IE浏览器才支持:after,原理和方法2有点类似,zoom(IE转有属性)可解决ie6,ie7浮动问题
4、父级div定义 overflow:hidden 原理:必须定义width或zoom:1,同时不能定义height,使用overflow:hidden时,浏览器会自动检查浮动区域的高度 建议:只推荐没有使用position或对overflow:hidden理解比较深的朋友使用
5、父级div定义 overflow:auto 原理:必须定义width或zoom:1,同时不能定义height,使用overflow:auto时,浏览器会自动检查浮动区域的高度 缺点:内部宽高超过父级div时,会出现滚动条
• vue兄弟组件间通信方法
1,props/$emit
2,$emit/$on
3,vuex
4,provide/inject
5,$parent / $children与 ref
• vue2生命周期
beforeCreate
在实例初始化之后,数据观测(data observer) 和 event/watcher 事件配置之前被调用。
created
实例已经创建完成之后被调用。在这一步,实例已完成以下的配置:数据观测(data observer),属性和方法的运算, watch/event 事件回调。然而,挂载阶段还没开始,$el 属性目前不可见。
beforeMount
在挂载开始之前被调用:相关的 render 函数首次被调用。
mounted
el 被新创建的 vm.$el 替换,并挂载到实例上去之后调用该钩子。
beforeUpdate
数据更新时调用,发生在虚拟 DOM 重新渲染和打补丁之前。 你可以在这个钩子中进一步地更改状态,这不会触发附加的重渲染过程。
updated
由于数据更改导致的虚拟 DOM 重新渲染和打补丁,在这之后会调用该钩子。
当这个钩子被调用时,组件 DOM 已经更新,所以你现在可以执行依赖于 DOM 的操作。然而在大多数情况下,你应该避免在此期间更改状态,因为这可能会导致更新无限循环。
该钩子在服务器端渲染期间不被调用。
beforeDestroy
实例销毁之前调用。在这一步,实例仍然完全可用。
destroyed
Vue 实例销毁后调用。调用后,Vue 实例指示的所有东西都会解绑定,所有的事件监听器会被移除,所有的子实例也会被销毁。 该钩子在服务器端渲染期间不被调用。
• React 组件的生命周期方法
组件的生命周期可分成三个状态:
Mounting(挂载):已插入真实 DOM
constructor(): 在 React 组件挂载之前,会调用它的构造函数。
getDerivedStateFromProps(): 在调用 render 方法之前调用,并且在初始挂载及后续更新时都会被调用。
render(): render() 方法是 class 组件中唯一必须实现的方法。
componentDidMount(): 在组件挂载后(插入 DOM 树中)立即调用。
Updating(更新):正在被重新渲染
getDerivedStateFromProps(): 在调用 render 方法之前调用,并且在初始挂载及后续更新时都会被调用。根据 shouldComponentUpdate() 的返回值,判断 React 组件的输出是否受当前 state 或 props 更改的影响。
shouldComponentUpdate():当 props 或 state 发生变化时,shouldComponentUpdate() 会在渲染执行之前被调用。
render(): render() 方法是 class 组件中唯一必须实现的方法。
getSnapshotBeforeUpdate(): 在最近一次渲染输出(提交到 DOM 节点)之前调用。
componentDidUpdate(): 在更新后会被立即调用。
Unmounting(卸载):已移出真实 DOM
componentWillUnmount(): 在组件卸载及销毁之前直接调用。
• 请说出React中高阶组件的定义和应用场景
React 中的 高阶组件 其实是一个非常简单的概念,但又非常实用。在实际的业务场景中合理的使用高阶组件,可以提高代码的复用性和灵活性。
最后的最后,再对高阶组件进行一个小小的总结:
高阶组件 不是组件,是 一个把某个组件转换成另一个组件的 函数
高阶组件的主要作用是 代码复用
高阶组件是 装饰器模式在 React 中的实现
• React中如何用useMemo实现useCallback
//useMemo使用
const onClick = useMemo(() => {
//这里返回的依然是函数
return () => {
console.log('click')
}
}, []);
工程实践 (选1题20分)
• git实例 场景:你是第一天来公司上班的,项目代码托管在GitLab,项目地址:git@lab.com:org/project.git,现在有一处代码需要你修改。请写出完成此项任务中,与git/gitlab相关的操作步骤
1,创建文件夹 打开cmd git init
2, git clone git@lab.com:org/project.git 代码就conle下来了 然后修改好指定代码
3,git pull ,git add . ,git commit -m “修改代码” , git push
• 你使用 my-dev分支完成了一个需求的开发后,从提交QA测试,QA发现了一个bug,你修复完成后,需要合并到主分支(master分支)打包上线。请描述一下在此任务中,你需要用到的git、npm相关操作步骤
1,git checkout -b my-dev
2,git checkout master
3,git pull origin master//如果是自己一个开发就没有必要了,为了保险期间还是pull
4,git merge my-dev 然后我们把dev分支的代码合并到master上
5,git status 然后查看状态及执行提交命令
• 前端性能优化方案
1. 减少 HTTP 请求
2. 使用 HTTP2
3. 使用服务端渲染
4. 静态资源使用 CDN
5. 将 CSS 放在文件头部,JavaScript 文件放在底部
6. 使用字体图标 iconfont 代替图片图标
7. 善用缓存,不重复加载相同的资源
8. 压缩文件 在 webpack 可以使用如下插件进行压缩:
JavaScript:UglifyPlugin
CSS :MiniCssExtractPlugin
HTML:HtmlWebpackPlugin
9. 图片优化
(1). 图片延迟加载 (2). 响应式图片
10. 通过 webpack 按需加载代码,提取第三库代码,减少 ES6 转为 ES5 的冗余代码
读代码写执行结果(选2每题10分)
• 写出以下代码执行结果,并简单解释
1. function showName() {
2. console.log('Toutiao');
3. }
4. showName();
5. function showName() {
6. console.log('OceanEngine');
7. }
8. showName();
二次 OceanEngine
9. // ----
10. var myname = "abc"
11. function showName2(){
12. console.log(myname);
13. var myname = "aabbcc"
14. console.log(myname);
15. }
16. showName2();
17. // ----
18. let myname3= 'toutiao'
19. {
20. console.log(myname3)
21. let myname3= 'oceanengine'
22. }
undefined
aabbcc
• 写出以下代码运行结果
1. if ([] == false) {console.log(1);};
2. if ({} == false) {console.log(2);};
3. if ([]) {console.log(3);};
4. if ([1] == [1]) {console.log(4);};
5. if (null == undefined) {console.log(5);};
6. if (null == false) {console.log(6);};
1,3,5
• 以下是一个页面的代码,请写出用户点击了<div id="i"/>后控制台的输出结果
1. <body>
2. <div id="i"/>
3. </body>
4.
5. <script>
6. document.body.addEventListener("mousedown", () => {
7. console.log("key1")
8. }, true)
9.
10. document.getElementById("i").addEventListener("mousedown", () => {
11. console.log("key2")
12. }, true)
13.
14. document.body.addEventListener("mousedown", () => {
15. console.log("key3")
16. }, false)
17.
18. document.getElementById("i").addEventListener("mousedown", () => {
19. console.log("key4")
20. }, false)
21. </script>
key1
key3
• 请写出以下代码的执行结果
1. setTimeout(function() {
2. console.log('setTimeout');
3. })
4. new Promise(function(resolve) {
5. console.log('promise');
6. for (let i = 0; i < 10000; i++) {
7. if(i === 10) {
8. console.log('for');
9. }
10. i == 9999 && resolve('resolve');
11. }
12. }).then(function(val) {
13. console.log(val);
14. })
15. console.log('console');
promise
for
console
resolve
setTimeout
代码实现 (选1题 20分)
• 原生js实现获取cookie指定key值
function getCookie(name){
var strcookie = document.cookie;//获取cookie字符串
var arrcookie = strcookie.split("; ");//分割
//遍历匹配
for ( var i = 0; i < arrcookie.length; i++) {
var arr = arrcookie[i].split("=");
if (arr[0] == name){
return arr[1];
}
}
return "";
}
• JS实现对货币格式化函数
var Number = {
/**
* 将数值四舍五入(保留2位小数)后格式化成金额形式
*
* @param num
* 数值(Number或者String)
* @return 金额格式的字符串,如'1,234,567.45'
* @type String
*/
formatCurrency2:function(num){
if(!num || isNaN(num)){
num ="0.00";
}
num = num.toString().replace(/\$|\,/g,'');
sign =(num ==(num =Math.abs(num)));
num =Math.floor(num*100+0.50000000001);
cents = num%100;
num = Math.floor(num/100).toString();if(cents<10)
cents ="0"+ cents;
for(var i =0; i <Math.floor((num.length-(1+i))/3); i++){
num = num.substring(0,num.length-(4*i+3))+','+ num.substring(num.length-(4*i+3));
}
return(((sign)?'':'-')+ num +'.'+ cents);
},
/**
* 将数值四舍五入(保留1位小数)后格式化成金额形式
*
* @param num
* 数值(Number或者String)
* @return 金额格式的字符串,如'1,234,567.4'
* @type String
*/
formatCurrency1:function(num){
if(!num || isNaN(num)){
num ="0.0";
}
num = num.toString().replace(/\$|\,/g,'');
sign =(num ==(num =Math.abs(num)));
num =Math.floor(num*10+0.50000000001);
cents = num%10;
num =Math.floor(num/10).toString();
for(var i =0; i <Math.floor((num.length-(1+i))/3); i++){
num = num.substring(0,num.length-(4*i+3))+','+ num.substring(num.length-(4*i+3));
}
return(((sign)?'':'-')+ num +'.'+ cents);
},
formatCurrency:function(num){
if(!num || isNaN(num)){
num ="0.00";
}
var t = num, i, r;debugger;
for( t = t.toString().replace(/^(\d*)$/,"$1."), t =(t +"00").replace(/(\d*\.\d\d)\d*/,"$1"), t = t.replace(".",","), i =/(\d)(\d{3},)/; i.test(t);){
t = t.replace(i,"$1,$2");
}
return t = t.replace(/,(\d\d)$/,".$1"), r = t.split("."), r[1]=="00"&&(t = r[0]), t
}
};
1. // 调用示例
2. formatMoney(1234567890); // 返回 1,234,567,890
• 返回数组里出现次数最多的数字
let a = [1,2,3,3,2,2,3]
let countArr = []; //定义个数组来储存每个数字出现的次数,数组下标是对应的数字
for(let j=0; j<a.length; j++){
// 判断是否第一次出现
if(j === a.indexOf(a[j])){
countArr[a[j]] = 1
}else{
countArr[a[j]] = countArr[a[j]] + 1
}
}
let maxNum = 0 //储存数字的最多次数
for(let i=0; i<countArr.length; i++){
if(countArr[i] !== undefined && countArr[i] > maxNum){
maxNum = countArr[i]
}
}
for(let j=0; j<countArr.length; j++){
if(maxNum === countArr[j]){
console.log('出现最多的数字为:',j);
}
}
1. // 调用示例
2. MostNumber([1, 2, 2, 1, 3, 1, 1]); // 返回 1
【附加开放题(20分)】
• 请回忆下印象较为深刻的一个BUG,简要描述bug表现及debug过程和问题原因?