面的不好,很多都知道自己看过,但临场手写就写不对了,手写真耗时间,写着写着,查查错,面试就快结束了,自己承认知识掌握不扎实,仍需努力夯实基础。再次梳理一遍,对自己还是有帮助的。已凉,不过也让我认识到了自己的不足。     自我介绍     怎么学习前端的     你用过vue,知道vue的key是用来做什么的吧     key是为Vue中虚拟DOM标记的唯一id,通过这个key,我们的父节点可以更准确、更快速定位子节点.     讲一讲vue和react的区别     vue双向数据绑定,react单向,需要setState实现medel-view的转换     拓展:            数据绑定:Vue实现了双向的数据绑定,react数据流动是单向的               数据渲染:大规模的数据渲染,react更快               使用场景:React配合Redux架构适合大规模多人协作复杂项目,Vue适合小快的项目               开发风格:react推荐做法jsx + inline style把html和css都写在js了,vue是采用webpack +vue-loader单文件组件格式,html, js, css同一个文件          Vue怎么实现双向绑定的     Vue2.X通过 Object.defineProperty() 来劫持各个属性的setter,getter,新版本通过Proxy劫持     要想深入讲解知识点:            Object.defineProperty() 来劫持各个属性的setter,getter,在数据变动时发布消息给订阅者,触发相应监听回调。当把一个普通 Javascript 对象传给 Vue 实例来作为它的 data 选项时,Vue 将遍历它的属性,用 Object.defineProperty() 将它们转为 getter/setter。用户看不到 getter/setter,但是在内部它们让 Vue追踪依赖,在属性被访问和修改时通知变化。               vue的数据双向绑定 将MVVM作为数据绑定的入口,整合Observer,Compile和Watcher三者,通过Observer来监听自己的model的数据变化,通过Compile来解析编译模板指令(vue中是用来解析 {{}}),最终利用watcher搭起observer和Compile之间的通信桥梁,达到数据变化 —>视图更新;视图交互变化(input)—>数据model变更双向绑定效果。          拓展:代码(没写,自己总结面经顺便复习)     defineProperty 版本        // 数据const data = { text: 'default'};const input  = document.getElementById('input');const span  = document.getElementById('span');// 数据劫持Object.defineProperty(data, 'text', { // 数据变化 --> 修改视图 set(newVal) {  input.value = newVal;  span.innerHTML = newVal; }});// 数据变化 --> 修改视图input.addEventLisener('keyup', function(e) { data.text = e.target.value;});      proxy 版本   // 数据const data = { text: 'default'};const input  = document.getElementById('input');const span  = document.getElementById('span');// 数据劫持const handler = { set(target, key, value) {  target[key] = value;  // 数据变化 --> 修改视图  input.value = newVal;  span.innerHTML = newVal;  return value; }};const proxy = new Proxy(data, handler);// 视图更改 --> 数据变化input.addEventLisener('keyup', function(e) { proxy.text = e.target.value;});   聊一聊原型链是什么    每个对象都有prototype(原型),当我们访问一个对象的属性时,在找不到的情况再会在其原型上查找是否有这个属性,再找不到会去自己 [__proto__] 关联的 prototype 对象上去找,顺着原型链知道undefined。语言组织太差,有种有货道不出的感觉。     好了,做一道题       Function.prototype.a = () => { console.log(1);}Object.prototype.b = () => { console.log(2);}function A() {}const obj = new A();obj.a() // Errorobj.b() // 2A.a() // 1A.b() // 2      解释了通过函数声明可以同时继承Function和Object原型上的方法,通过new继承只能继承Object的方法     面试官问第一个Error是什么Error,脑抽了说是引用Error(ReferenceError),实际上是TypeErro,打印的是这个结果   Uncaught TypeError: obj.a is not a function   说到继承,你写一下你知道的继承方式     这下充分暴露了自己的不足,知道的六种继承方式,并说了出来,要求手写才发现很多都写错了       function person() { this.kind="person";}person.prototype.eat = function (food) { console.log(this.name+" is eating "+food);}function student() {}      先写了一下继承后上述prototype和proto的关系       student.prototype.__proto__ === person.prototype      原型继承       student.prototype = new person();      缺点:原型是所有子类实例共享的,改变一个其他也会改变。     该打,我没写完全对     构造继承       function student() {    person.call(this);}      缺点:不能继承父类原型,函数在构造函数中,每个子类实例不能共享函数,浪费内存。     这个倒是完全写对了     组合继承       function student() {    person.call(this);}student.prototype = new Person();      缺点:person的构造函数会多执行了一次     哭了,又没有完全写对     原型式继承       student.prototype = Object.create(person.prototype);      又搞错了     写成了       student.prototype = Object.create(person());      不知道怎么想的,面试官小姐姐提示我知道Object.create怎么一回事,还口述了手写过程       Object.prototype.myCreate(proto) { function f() {}; f.prototype = proto; return new f();}      口述的方法倒是对的     口述之后我发现person()不对劲,又重写了       student.prototype = Object.create(person);      面试官小姐姐温柔地说,没关系,我可能太紧张了     之后是寄生组合继承       function student() {    person.call(this);}student.prototype = new person();// 或者student.prototype = Object.create(person.prototype);      我的错误跟上面的一样,     这种继承方法父类原型和子类原型是同一个对象,无法区分子类真正是由谁构造。     最后当然是最完美的寄生组合优化继承   function student() {    person.call(this);}student.prototype = new person();// 或者student.prototype = Object.create(person.prototype);student.prototype.constructor = student;   总之错误真多,觉得没脸见人了,手写和口述讲思路难度差距真大    面试官问我知不知道防抖和节流     我回答知道,防抖在定时器定时期间再次触发,关掉旧的定时器,开始新的定时器。将多次执行变为最后一次执行,典型应用,提交按钮的点击事件。     节流在一段时间,只执行一次事件。等到这段之后再根据这段时间内由出发执行,将多次执行变成每隔一段时间执行,典型应用,拖拽事件。 我们用 leading 代表首次是否执行,trailing 代表结束后是否再执行一次     让我手写防抖,第一次手写如下       function debounce(func, wait = 1000) { let timer = null; return function(...args) {  if (timer) {   timer = null;  }  timer = setTimeout(func(...args), wait); } }      问我为什么要看到定时器把定时器赋值为null,我说要清空定时器,有没有更好的办法,我想了想说,这是一个引用类型,原先的定时器仍在内存中,可能导致内存泄露(还说错了,说成了本专业学过的频谱泄露),所以应该关闭定时器       function debounce(func, wait = 1000) {    let timer = null;    return function(...args) {        if (timer) {            clearTimeout(timer);        }        timer = setTimeout(func(...args), wait);    }}      自己补充再重写一下手写节流吧       function throttle(func, wait = 1000) {    let last = 0;    return function(...args) {        let now = +new Date();        if ((now - last) > wait) {            last = now;            func(...args);        }    }}      了解不了解事件循环机制,给我出了这一题       const promise1 = new Promise((resolve, reject) => {    setTimeout(() => {        resolve("success");  console.log("timer1");    }, 1000);    console.log("promise1里的内容"); });const promise2 = promise1.then(() => { throw new Error("error!!!");});console.log("promise1", promise1);console.log("promise2", promise2);setTimeout(() => {    console.log("timer2");    console.log("promise1", promise1);    console.log("promise2", promise2); },2000);      手写输出的顺序   promise1里的内容promise1: Proimse{<pending>}promise2: Proimse{<pending>}timer1Error: error!!!timer2promise1: Proimse{<fulfilled>:'success'}promise2: Proimse{<rejected>:Error'error'}    写完之后讲了讲思路,讲了promise是微任务,setTimeout是宏任务,事件循环机制:执行一个宏任务,执行微任务列表,经过循环再执行宏任务,再执行微任务列表。并提出老版本node循环机制不同把当前时刻宏任务、微任务执行顺序有不同     JS有哪些宏任务、微任务     宏任务setTimeout、setInterval(漏了setImmediate)     补充优先级:主代码块 > setImmediate > MessageChannel > setTimeout / setInterval     微任务包括:优先级:process.nextTick > Promise > MutationObserver     微任务提到了async、await,await后面的看作是promise.then后面的     CSS     position有哪些:     只说出来absolute、relative、fixed,不常用的背过忘了,抄一遍菜鸟上的加强记忆                 值              描述                        absolute              生成绝对定位的元素,相对于 static 定位以外的第一个父元素进行定位。元素的位置通过 "left", "top", "right" 以及 "bottom" 属性进行规定。                    fixed              生成绝对定位的元素,相对于浏览器窗口进行定位。元素的位置通过 "left", "top", "right" 以及 "bottom" 属性进行规定。                    relative              生成相对定位的元素,相对于其正常位置进行定位。因此,"left:20" 会向元素的 LEFT 位置添加 20 像素。                    static              默认值。没有定位,元素出现在正常的流中(忽略 top, bottom, left, right 或者 z-index 声明)。                    inherit              规定应该从父元素继承 position 属性的值。             提了父相子绝,被问如果父元素没有设置position:relative,子节点设置position:absolute怎么办,我说会一个个找父节点直到找到设置position:relative的,错了,应该是找到position:static以外的第一个父元素。     反问  
点赞 5
评论 5
全部评论

相关推荐

不愿透露姓名的神秘牛友
06-21 11:33
昨天是学校最后一场招聘会,鼠鼠去参加了,全场只有一个招聘java的岗位,上来先做一份笔试题,做完后他拿张纸对答案,然后开始问简历上的问题,深圳小厂,6-8k(题目如下),后面还有两轮面试。然后我就在招聘现场逛呀逛,看到有公司招聘电商运营,给的比上年的小厂还多,鼠鼠就去了解了下,然后hr跟鼠鼠要了份简历,虽然我的简历上面全是求职Java开发相关的内容,但是hr还是鼓励我说没关系,她帮我把简历给老板看看,下周一会给我通知。招聘会结束后鼠鼠想了一段时间,也和朋友聊了聊,发现我可能是不太适合这个方向,然后就跟爸爸说回家了给我发条微信,我有些话想跟他说说。晚上爸爸到家了,跟我发了条微信,我立马跑出图书馆跟他打起了电话,这个通话长达一个小时,主要是跟爸爸坦白说我不想找这行了,是你的儿子太没用了,想试试其他行业。然后爸爸也跟我说了很多,说他从来没有希望我毕业后就赚大钱的想法,找不到就回家去,回家了再慢慢找,实在找不到就跟他干(帮别人装修房子,个体户),他也知道工作不好找,让我不要那么焦虑,然后就是聊一些家常琐事。对于后面的求职者呢我有点建议想提一下,就是如果招实习的时间或者秋招开始,而你的简历又很差的情况下,不要说等做好项目填充完简历之后再投,那样就太晚了,建议先把熟悉的项目写上简历,然后边投边面边完善,求职是一个人进步的过程,本来就比别人慢,等到一切都准备好后再投岂不是黄花菜都凉了。时间够的话还是建议敲一遍代码,因为那样能让你加深一下对项目的理解,上面那些说法只是针对时间不够的情况。当然,这些建议可能没啥用,因为我只是一个loser,这些全是建立在我理想的情况下,有没有用还需其他人现身说法。上篇帖子没想到学校被人认了出来,为了不丢脸只能匿名处理了。
KPLACE:找研发类或技术类,主要还是要1.多投 2.多做准备,很多方面都要做准备 3.要有心理准备,投累了就休息一两天,再继续,要相信自己能找到
投递58到家等公司10个岗位
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务