当前位置: 首页 > Web前端 > HTML5

我的前端面试日记(一)

时间:2023-04-05 16:30:49 HTML5

第一次写面试心得。虽然之前有过一些电话面试的经历,但是相对来说,我觉得这次经历对我来说还是比较有收获的。在这里我把面试经历留作日记吧!(采访时间:2018年6月12日下午2点10分;时长:50min;公司:*)1.谈谈React,为什么选择React(一),React的特点是高效,虚拟DOM,最小化与DOM的交互:当浏览器渲染一个网页,首先解析HTML文档并构建DOM树,然后用CSSOM树生成RenderObject树,最后渲染成页面。浏览器中的渲染引擎和JavaScript引擎是分离的,渲染引擎会提供一些接口供JavaScript调用。两者之间的通信是通过一个网桥,性能其实很差。过去,通常优化性能的方法是减少DOM操作次数。而React提出了一个新的思路就是虚拟DOM:组件的HTML结构不再直接生成DOM,而是映射生成一个虚拟的JavaScriptDOM结构,React通过diff算法将最小的变化写入DOM,从而减少DOM实际大小的倍数以提高性能。服务器端渲染React提供开箱即用的服务器端渲染。服务器端渲染消除了服务器对浏览器的依赖。它先渲染“视觉”部分,然后交给客户端渲染。组件编码React中的一切都是基于组件的。您可以定义一个组件,然后在其他组件中像引用HTML标记一样引用它。通俗地说,组件其实就是自定义标签;通过React构建组件使得代码更容易复用,可以很好的应用在大型项目的开发中。声明式设计React采用声明式范式和函数式编程,可以轻松描述应用程序。FlexibleReact与已知的库或框架配合得很好。JSXJSX是JavaScript语法的扩展。React开发不一定要使用JSX,但我们推荐使用它。单向响应数据流React实现了单向响应数据流。数据以一个方向从上到下流动,即从父组件到子组件。该原则使组件之间的关系简单且可预测;props作为对外接口,state作为内部状态。(2)为什么选择React与Vue、angular等其他双向数据绑定框架相比,我个人更喜欢这种更精简的单向数据流形式,因为它可以更好地预测数据变化;当然最重要的原因还是学校图书馆,React的书籍资料比较丰富(...说实话,尴尬)2、刚才你提到了虚拟DOM的Diff算法,说说你对它的理解。因为当时对这个算法没有多想,只是结合前面的知识点简单说了下;这里是具体的下评:React的Diff算法巧妙的使用了启发式的方法,将复杂度为O(n^3)的数差比较算法转化为一个O(n)复杂度的问题;该算法基于两个假设:同一类的两个组件将生成相似的树结构,而不同类的两个组件将生成不同的树结构;可以为元素提供唯一标识,保证元素在不同的渲染过程中保持不变。具体实现细节:(比较树结构)即先检查两个节点的区别。当节点类型不同时,React会把它们当作两棵不同的词树,导致前面的子树直接被移除,然后再创建和插入。前子树的优点:巧妙的避免了在树结构上进行大量的差异检测,然后关注同一部分,实现了快速准确的差异检测逻辑;缺陷:如果两棵子树结构相似,即顶层节点不同,但子节点结构相同。这时候只需要删除和插入不同的top节点,但是React会删除整个子树,然后重新构建和插入。3.你知道React的生命周期吗?(1)、加载过程当组件第一次被渲染时,依次调用的函数:constructiongetInitalStategetDefaultPropscomponentWillMountrendercomponentDidMount(2)、更新过程更新过程会依次调用以下生命周期函数,其中render函数与“加载”过程:-componentWillReceiveProps-shouldComponentUpdatecomponentWillUpdaterendercomponentDidUpdate不是所有更新过程执行所有功能。(3)React组件的卸载过程只涉及一个函数componentWillUnmount。具体可以参考React生命周期详解4.说到shouldComponentUpdate,你是怎么用的,怎么判断是否更新?在生命周期中,render函数决定了应该渲染什么,shouldComponentUpdate决定了一个组件什么时候不需要渲染;shouldComponentUpdate(nextProps,nextState)接收两个参数,即本次渲染的props和state对象,返回一个布尔值,默认返回true,表示已更新;返回false表示本次更新不需要到此为止;通过比较props和state是否与上次相同来判断是否需要更新,可以避免不必要的更新操作,提高性能;因为props和state都是对象,所以通常使用一般是浅层比较。如果我需要对两个对象进行深入全面的比较,我考虑使用JSON.stringify()5.如果我需要在React中获取DOM节点,应该在什么阶段获取,如何获取DOM节点,需要在componentDidMount或者componentDidUpdata中获取,因为只有在这个阶段才构建真正的DOM节点,使用ref属性获取DOM节点。6、如果我需要通过原生js获取这个节点的父节点,可能只能作为一个过渡,比较简单,直接使用DOM节点的parentNode属性来回答;但还有一点。nextSibling属性:返回目标节点的下一个兄弟节点。如果目标节点后面没有属于同一父节点的节点,则nextSibling将返回null;nextSibling属性是只读属性。previousSibling属性:返回目标节点的前一个兄弟节点。如果目标节点之前没有属于同一父节点的节点,则previousSibling将返回null;previousSibling属性是只读属性。parentNode属性:注意:parentNode属性返回的节点始终是元素节点,因为只有元素节点才可能有子节点。当然有一个例外:文档节点,它没有父节点。所以文档节点的parentNode属性会返回null;parentNode属性是只读属性。7.现在我需要通过类名获取DOM。我当时直接说的是:可以用document.getElementsByClassName(),document.querySelector(),document.querySelectorAll();两种方法的区别:getElementsByClassName()和querySelectorAll()返回一个DOM列表。虽然可以通过循环遍历,但是它们只是伪数组,不能使用数组方法;getElementsByClassName()只能通过类名获取,而querySelectorAll和querySelector是使用CSS选择器获取的。当时只说querySelector返回一个DOM节点,有点不对;querySelector返回文档中与指定CSS选择器匹配的第一个元素。9、刚才提到了伪数组,那么如何区分对象是数组呢?答:如果objinstanceofArray返回true或false;==Arrayistrueorfalse当时还加入了Array.isArray(obj)来判断传入的值是否为Array。如果对象是数组,则为真;否则,它是错误的。10.说到ES6,说说你对ES6的理解答:ES6主要是增加了一些新的特殊效果,比如:const定义了常量,但是const定义的常量只是不可变值,即基本数据类型是不可变的,而引用类型,因为它建立的是引用,所以即使使用了const定义的对象,其属性仍然是可变的;让定义变量。与var相比,它修复了一些问题,例如变量提升、重复定义等,而const和let的定义具有块级作用域;对于字符串扩展:字符串模板,以及一些方法(忘记了,赶紧跳过);有:剩余参数、函数默认参数、模块化、Promise、装饰器、Symbol、set、map等;刚知道,大概说了这些;我最近也在更新ES6笔记。我对ES6有深刻的理解。ES6没有深入的问题,从let和const的块级作用域直接导致闭包。11、刚才讲了块级作用域,说一下它和闭包的区别,即闭包一般在什么时候使用?答:闭包的作用主要是获取函数内部的变量,将变量保存起来,不被垃圾回收器回收,供应后使用;使用一般是对作用域进行封装,即替换全局变量,避免全局变量污染;因为使用闭包会保存变量,不会被回收器回收,所以应该尽量避免,以防止内存泄漏。在函数内部或在其他函数中访问参数在函数执行之前为要执行的函数提供具体参数在函数执行之前为函数提供具体参数只有在函数执行或引用时才能知道节点循环绑定点击事件,在事件函数中使用当前循环的值或节点而不是上一个循环的值或节点来暂停执行打包相关函数包,如何避免你说的内存泄漏?感觉自己给自己挖了一个坑。(回收机制和内存泄露我不懂~~)答:一个变量的可回收性一般需要根据浏览器的js引擎的recycler机制来判断。大概有两种方式(当时只提到一种);即引用计数:引用计数的意思是跟踪记录每个变量被引用的次数。当本期引用数为0时,表回收一般通过赋值为null来手动清空。科普:引用计数:当声明一个变量并为该变量赋一个引用类型的值时,这个值的引用次数为1,如果相同的值赋给另一个变量,则增加该值的引用次数减1。反之,如果包含引用这个值的变量获得另一个值,则这个值的引用计数减1。当这个值的引用次数为0时,表示没有办法访问它,所以可以清除它所占用的内存空间:当一个变量进入环境时,比如在a中声明了一个变量函数,变量被标记为“进入环境”。从逻辑上讲,进入环境的变量占用的内存永远不会被释放,因为只要执行流进入相应的环境,它们就可能被使用。当变量离开环境时,它被标记为“离开环境”。13.你懂HTML5吗?让我们谈谈HTML5。添加了一些语义标签和一些API,删除了一些元素。用于媒体播放的绘画画布的视频和音频元素存储在本地和离线。关闭浏览器后自动删除语义较好的内容元素,如article,footer,header,nav,sectionformcontrols,calendar,date,time,email,url,search新技术webworker,websocket,Geolocation删除的元素:纯表达元素:basefont,big,center,font,s,strike,tt,u对可用性有负面影响的元素:frame,frameset,noframes就不那么细说了,上面的评论14,说到localStorage,sessionStorage和cookies说说他们的区别?相同点:都可以作为浏览器存储,都不能跨域访问;区别:cookie会一直携带在同源http请求头中(即使不需要),sessionStorage和localStorage不会在浏览器和服务器之间来回传递,数据会自动发送到服务器并且只保存在本地;sessionStorage和localStorage的存储大小远大于cookies,可以达到5M甚至更大;localStorage存储持久化数据,除非主动删除数据,否则浏览器关闭后数据不会丢失;sessionStoragedata会在当前浏览器窗口关闭后自动删除;cookie设置的cookie在cookie过期时间之前有效,不管浏览器是否关闭。15.根据你的简历,你上过《计算机网络》?讲ISO的七层,依次讲应用层、表示层、会话层、传输层、网络层、数据链路层、物理层16、讲应用中的http和ftp协议在哪一层层(现在回头看,好像错了~~~~)科普:应用层:表示允许访问OSI环境(应用协议数据单元APDU)(HTTP、FTP、SMTP、DNS)表示层:翻译、加密和压缩数据(表示协议数据单元PPDU)会话层:建立、管理和终止会话(会话协议数据单元SPDU);传输层:提供端到端的可靠消息传递和错误恢复(segment段)(TCP和UDP);网络层:负责数据包从源到目的地的传输和互联网互连(PackeT)IP寻址;数据链路层:将比特组装成帧,点对点传输(帧Frame)物理层:通过介质传输比特,确定机械和电气规格(Bit)17.说说你对http的理解,我们来谈谈状态码,你常用的状态码及其含义HTTP超文本传输??协议,基于请求/响应模式。HTTP是无状态协议,FTP是有状态状态码:100:post请求中第一次发送header信息后服务器返回100,表示请求继续;200:表示请求正常,请求成功;301:永久重定向;302:临时重定向;304:用于协商缓存,表示浏览器缓存资源没有变化,仍然可用。400:请求语法或参数错误;401:认证失败,比如跨域失败;403:请求未被授权;404:Found没有找到对应资源的位置;500:服务器内部发生错误;502:Errorgateway18.听你讲浏览器缓存,说说你知道的缓存方式。缓存有两种,强缓存和协商缓存。协商缓存:向服务器发送请求,服务器会根据请求的请求头的一些参数判断是否命中协商缓存。如果命中,则返回304状态码,并带上新的响应头,通知浏览器从缓存中读取资源;更多浏览器缓存细节科普:深入浏览器缓存19、接着说CSS,两个div垂直布局,上设置margin—bottom:50px;下边距-顶部:100px;此时两个div之间的距离为100px,因为垂直方向的边距会重叠。详细了解可读的CSS格式化模型。20.如果我需要消除这种情况,如何处理就是消除两个兄弟div之间的边距重叠问题:两个兄弟div设置为float:left(或display:inline-block);宽度:100%;比较科普(parentandchild之间的marginOverlapelimination)外层元素padding替换内层元素transparentborderborder:1pxsolidtransparent;内部元素绝对定位position:absolute:外部元素overflow:hidden;内部元素添加float:left;或显示:内联块;内部元素内边距:1px;21、现在需要用flex布局实现两个div水平布局:父元素设置display;flex使用浮动布局(或显示:inline-block)//htmlfloat

overflow:hidden
//CSS.item1{float:left;//display:inline-block}.item2{overflow:hidden;//display:inline-block}22、现在我改一下要求,左边固定宽度,右边固定宽度左边自适应宽度:200px;设置浮动:左;右侧溢出:隐藏(或margin-left:左侧宽度);父元素显示:flex;left固定宽度width:200px;;右侧设置项拉伸属性flex-grow:1;父元素位置:相对;左边固定宽度width:200px;位置:绝对;rightmargin-left:左边宽度;父元素显示:table;left固定宽度width:200px;右侧宽度:100%;显示:表格单元格;23、现在我需要两个div分两列布局,要求高度可变(父元素也是)。我需要两个div实时具有相同的高度。即当左侧div的高度被其内部子元素拉高时,右侧div的高度与左侧父元素display:table同步;左侧固定宽度:200px;显示:表格单元格;右侧宽度:100%。父元素显示:flex;对齐项目:拉伸;左侧固定宽度:200px;;设置右边的itemstretch属性flex-grow:1;flex布局:父元素显示:flex;左边固定宽度width:200px;右侧固定宽度width:200px;中间flex-grow:1;使用浮动布局:父元素溢出:隐藏;左边固定宽度width:200px;float:left;固定右边宽度:200px;浮动:对;中间边距:0200px;这里有一个坑,就是HTML结构一定要变换,也就是中心和右边的位置一定要调换(当时没想到,一直被问你确定吗是这样的可以吗?shortcircuitshortcircuit~)想一想因为居中的div在正常的文档流中占据了全屏宽度,自然之后的浮动元素会放在下一行//Html结构left
rightcenter//CSS样式layout.left{width:200px;背景:素瓷;向左飘浮;}.center{背景:红色;边距:0200px;}.right{背景:rgba(22,220,22,0.5);浮动:对;宽度:200px;}带绝对定位的布局:绝对定位方式的原理是左右两边都使用绝对定位,因为绝对定位让它脱离了文档流,下面的c回车自然会流向他们,然后使用margin属性留出左右元素的宽度,可以让中间元素自适应屏幕宽度(这样)//CSS样式布局。左{宽度:200px;背景:素瓷;位置:绝对;}.center{背景:红色;边距:0200px;}.right{背景:rgba(22,220,22,0.5);位置:绝对;右:0;宽度:200px;}圣杯布局(不太了解)圣杯布局的原理是margin负值法。要使用圣杯布局,首先需要在中心元素之外包含一个div。包含一个div,需要设置float属性组成一个BFC,并设置宽度,这个宽度必须匹配左块外边距的负值://htmlstructure中心右//CSSstyle.left{width:200px;背景:素瓷;向左飘浮;margin-left:-100%;}.wrap{float:left;宽度:100%;}.center{背景:红色;保证金:0200px;}.right{背景:rgba(22,220,22,0.5);向左飘浮;左边距:-200px;width:200px;}整个过程耗时1小时左右,感觉还行。怎么说呢,不管你考不考,至少你知道自己还有哪些不足,可以有针对性的深入学习。最后附上本次面试涉及的一些知识点:React知识小册子;浏览器缓存详解;ES6知识总结;最后,JavaScript前端面试题正在跟进中。喜欢的话可以点个赞哦~~