noah的前端面试题(一)|掘金技术征文

这段时间面试了一些公司然后我也整理一些面试题目供给大家参考一下,一些基本的题目就不分享出来了,还有一些手写的题目,另加一些我附加链接防止我表达的不够清晰详细。 

下一篇 前端面试题(二)

1. 谈一下css盒模型 如何触发 他是解决什么样子的问题

这个是老生常谈的题目了

1)BFC就是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面的元素。反之也如此 2) 内部的Box会在垂直方向,一个接一个地放置 3)属于同一个BFC的两个相邻Box的 margin会发生重叠  4)BFC的区域不会与float box重叠 主要是这四个也没比较每个都说的很清晰 最主要的是第一个 

那些元素生成BFC

  1. 根元素
  2. float属性不为none
  3. position为absolute或fixed
  4. display为inline-block, table-cell, table-caption, flex, inline-flex
  5. overflow不为visible

主要的解决是一些图形文字环绕效果和避免子元素的浮动脱离文档流而造成的高度坍塌的问题


2. 说一下你了解的弹性FLEX布局

各种概念和属性能想到大家都可以说一下,也扯到了Grid布局,基本这个也没啥问题。

分享一篇flex布局很详细的 Flex 布局教程


3. css预处理器有哪些 你用了那个 可以详细说一下其中特性吗

平时我在开发中主要使用的是 Less,所以可能对 Sass 和 Stylus 的熟悉程度稍差一些

可以 基本语法 嵌套语法 变量 @import 混入 继承 函数 逻辑控制 这些来说说 同时我给大家分享一篇文章 再谈 CSS 预处理器


4. 谈一谈移动端适配的问题

之前的公司是用rem布局 同时我也谈到淘宝的flexible.js用来适配的,vh布局一些东西。被问到用rem布局有什么缺点时候 我想了想说 我觉得很完美


5. 谈谈你们用的ui库和一些css类库


6. js中call apply bind的用法和其中之间的区别

他们三个都是为了动态改变某个函数运行时的上下文(context)或者是为了改变函数体内部this的指向  

apply()与call()作用没有区别,用法与call()方法稍有区别,就是call()的第二个参数(调用函数使用的参数),是一个一个传入的

bind()的作用其实与call()以及apply()都是一样的,都是为了改变函数运行时的上下文,bind()与后面两者的区别是,call()和apply()在调用函数之后会立即执行,而bind()方法调用并改变函数运行时的上下文的之后,返回一个新的函数,在我们需要调用的地方去调用他。

如果大家能够理解这个题目那么这三个用法也会了解很清晰了 cat.call(dog, a, b) = cat.apply(dog, [a, b]) = (cat.bind(dog, a, b))() = dog.cat(a, b)


7. 谈一谈你对this的理解 箭头函数内部的this是指向哪里的

this的指向在函数定义的时候是确定不了的,只有函数执行的时候才能确定this到底指向谁,实际上this的最终指向的是那个调用它的对象,也就是说 this是和上下文有关系,谁调用了他,他就指向谁。

箭头函数内部的this是词法作用域应该继承的是父执行上下文里面的this,切忌是父执行上下文 这样就很多箭头函数中的指向不明确就迎刃而解了。注意:简单对象(非函数)是没有执行上下文的 还有箭头函数call apply等方法会失效 也不能使用 let that = this 的hack写法


8. es6一些新的语法 

大家可以看一看阮一峰老师的 ECMAScript 6 入门 随便抽几点来说


9. 如何用es6进行数组的复制

扩展运算符提供了复制数组的简便写法 

const a1 = [1, 2]; const a2 = [...a1]; const [...a2] = a1;


10. 如何用es6进行数组去重,然后用es5实现的几种方法 谈谈你的思路

es6 数组 set可以用来实现数组去重

es5 里面可以用对象key值唯一的方式来实现 和 数组indexof方式 


11.  es6 es7有哪些方法实现函数的异步操作 es6之前呢是如何实现的

promise, async await , generator。

es6之前通过回调函数来实现的


12. 手写原声ajax get请求代码 ,在里面设置同步异步是在那个方法里面 ,get 和 post 区别

function get(){  
    var req = createXMLHTTPRequest();  
    if(req){  
        req.open("GET", url , true);  
        req.onreadystatechange = function(){  
            if(req.readyState == 4){  
                if(req.status == 200){  
                    alert("success");  
                }else{  
                    alert("error");  
                }  
            }  
        }  
        req.send(null);  
    }  
}  复制代码


XMLHttpRequest.open(method, url, async);一个可选的布尔参数,默认为true,表示要不要异步执行操作。如果值为falsesend()方法直到收到答复前不会返回。如果true,已完成事务的通知可供事件监听器使用。如果multipart属性为true则这个必须为true,否则将引发异常。

HTTP POST GET 本质区别详解

13. HTTP请求报文和HTTP响应报文  

1.请求行
请求行由请求方法字段、URL字段和HTTP协议版本字段3个字段组成,它们用空格分隔。例如,GET /index.html HTTP/1.1。
HTTP协议的请求方法有GET、POST、HEAD、PUT、DELETE、OPTIONS、TRACE、CONNECT。
HEAD就像GET,只不过服务端接受到HEAD请求后只返回响应头,而不会发送响应内容。当我们只需要查看某个页面的状态的时候,使用HEAD是非常高效的,因为在传输的过程中省去了页面内容。
列子:
Request URL:https://www.baidu.com/
Request Method:GET
Status Code:200 OK
Remote Address:172.31.1.246:8080
2.请求头部
请求头部由关键字/值对组成,每行一对,关键字和值用英文冒号“:”分隔。请求头部通知服务器有关于客户端请求的信息,典型的请求头有:
User-Agent:产生请求的浏览器类型。
Accept:客户端可识别的内容类型列表。
Host:请求的主机名,允许多个域名同处一个IP地址,即虚拟主机。
列子:
Cache-Control:private, max-age=10
Connection:Keep-Alive
Content-Encoding:gzip
Content-Type:text/html; charset=utf-8
Date:Tue, 21 Feb 2017 03:05:37 GMT
Expires:Tue, 21 Feb 2017 03:05:47 GMT
Last-Modified:Tue, 21 Feb 2017 03:05:37 GMT
Proxy-Connection:Keep-Alive
Transfer-Encoding:chunked
Vary:Accept-Encoding
X-UA-Compatible:IE=10
3.空行
最后一个请求头之后是一个空行,发送回车符和换行符,通知服务器以下不再有请求头。
4.请求数据

请求数据不在GET方法中使用,而是在POST方法中使用。POST方法适用于需要客户填写表单的场合。与请求数据相关的最常使用的请求头是Content-Type和Content-Length。


HTTP响应也由三个部分组成,分别是:状态行、消息报头、响应正文 在响应中唯一真正的区别在于第一行中用状态信息代替了请求信息。状态行通过提供一个状态码来说明所请求的资源情况。


13. http状态码 说一下200和304的理解和区别

协商缓存和强制缓存的区别,流程,还有一些细节,提到了expires,Cache-Control,If-none-match,Etag,last-Modified的匹配和特征 还有同时有Etag,last-Modified同时出现的时候 etag(包括文件修改时间 文件大小 文件内容等信息)优先级高  浏览器缓存详解:expires,cache-control,last-modified,etag详细说明


14. websocket理解 websocket产生原因 了解http2嘛

在以前 HTTP 协议中所谓的 keep-alive connection 是指在一次 TCP 连接中完成多个 HTTP 请求,但是对每个请求仍然要单独发 header;所谓的 polling 是指从客户端(一般就是浏览器)不断主动的向服务器发 HTTP 请求查询是否有新数据。这两种模式有一个共同的缺点,就是除了真正的数据部分外,服务器和客户端还要大量交换 HTTP header,信息交换效率很低。它们建立的“长连接”都是伪.长连接,只不过好处是不需要对现有的 HTTP server 和浏览器架构做修改就能实现。

WebSocket 解决的第一个问题是,通过第一个 HTTP request 建立了 TCP 连接之后,之后的交换数据都不需要再发 HTTP request了,使得这个长连接变成了一个真.长连接。但是不需要发送 HTTP header就能交换数据显然和原有的 HTTP 协议是有区别的,所以它需要对服务器和客户端都进行升级才能实现。在此基础上 WebSocket 还是一个双通道的连接,在同一个 TCP 连接上既可以发也可以收信息。此外还有 multiplexing 功能,几个不同的 URI 可以复用同一个 WebSocket 连接。这些都是原来的 HTTP 不能做到的。

http2它常被提起的特性有: 

多路复用 : 多个HTTP请求可以放在同一个连接中进行。且自有数据流能并行传输 以后不必在使用雪碧图来

HEAD 压缩:HTTP1中每次HTTP请求,都是必须要带上HTTP头的.而HTTP/2则在建立连接后,把头字段作为键值对,在两边维护一份字典,相同的就不用再传了,如有新增或变更,则再在传输时带上。减少HTTP头的传输,交互密集时,其实能省不少流量 服务器推送

优先级请求:比如说你滚动条滑倒底部 底部图片的图片就会优先加载出来

服务器推送:就是服务端能主动推东西过去,以前只能是被动的。在我的印象中,很多年前“Comet"这门技术曾经在淘宝大放光彩过。

即当客户端发一个请求过来时,服务端能依据这个请求,推断出你后续还要什么,主动给推过去。大大减少了请求数,加快了反应时间.


15. 说一下为什么会有跨域问题 你平时怎么解决跨域的。以及后续JSONP的原理和实现以及cors怎么设置。

浏览器的同源策略 同源是指,域名,协议,端口相同,三者有一个不同,则为跨域

 node代理,具体自己起个node服务,在node中转发来自浏览器的请求,node服务和浏览器请求要同源,然后转发携带具体参数,cookie...,转发到后端的跨域接口,转发库可以用axios,支持在node,和浏览器都可以使用。

nginx配置代理

在react,vue中可以用webpack-dev-server配置代理

跨域资源共享cors,后端设置Access-Control-Allow-Origin:*

jsonp利用script标签支持跨域 并在其中加入回调函数 jsonp只支持get请求

iframe+script 等现实开发中,并不是很实用

16.如何设置cookie的跨域请求

Access-Control-Allow-Credentials设置为true

17. 从输入链接到前端渲染出页面经过什么步骤

从输入URL到页面加载的过程?如何由一道题完善自己的前端知识体系!内容有很多大家可以按到自己的理解说一下其实没必要那么详细

浏览器解析->查询缓存->dns查询->建立链接->服务器处理请求->服务器发送响应->客户端收到页面->解析HTML->构建渲染树->开始显示内容(白屏时间)->首屏内容加载完成(首屏时间)->用户可交互(DOMContentLoaded)->加载完成(load)

18. js继承可以说一下哪几种和其中的优缺点

我说了原型和构造函数相结合的组合继承方法 又谈了寄生组合继承

19. 谈一谈浅拷贝和深拷贝区别

object是JavaScript引用类型对象只会被克隆最外部的一层,至于更深层的对象,则依然是通过引用指向同一块堆内存.


我说了用JSON对象parse方法可以将JSON字符串反序列化成JS对象,stringify方法可以将JS对象序列化成JSON字符串,这两个方法结合起来就能产生一个便捷的深克隆.

还有Object.assign() 只是一级属性复制,比浅拷贝多深拷贝了一层而已。


20. 尾递归来实现斐波那契

function fibonacci(n, n1, n2) {
    if(n <= 1) {
        return n2
    }
    return fibonacci(n - 1, n2, n1 + n2)
}复制代码

21. 用proxy实现string repeat方法

22. vue数据双向绑定 

数据双向绑定是通过oject.defineProerty进行数据劫持和订阅者观察者模式相结合

1.实现一个监听器Observer,用来劫持并监听所有属性,如果有变动的,就通知订阅者。

2.实现一个订阅者Watcher,可以收到属性的变化通知并执行相应的函数,从而更新视图。

3.实现一个解析器Compile,可以扫描和解析每个节点的相关指令,并根据初始化模板数据以及初始化相应的订阅器

23. vue的生命周期 

beforecreated create  mounted updated destory等

有分别说了created和mounted区别 created 初始化完成时的事件写在这里,如在这结束loading事件,异步请求也适宜在这里调用

mounted 挂载元素,获取到DOM节点

destory可以做一些内存泄漏的东西

24. vue router模式和懒加载

vue-router 默认 hash 模式 使用 URL 的 hash 来模拟一个完整的 URL,于是当 URL 改变时,页面不会重新加载。
如果不想要很丑的 hash,我们可以用路由的 history 模式,这种模式充分利用 history.pushState API 来完成 URL 跳转而无须重新加载页面。
不过这种模式要玩好,还需要后台配置支持。因为我们的应用是个单页客户端应用,如果后台没有正确的配置,当用户在浏览器直接访问 oursite.com/user/id 就会返回 404,这就不好看了。
所以呢,你要在服务端增加一个覆盖所有情况的候选资源:如果 URL 匹配不到任何静态资源,则应该返回同一个 index.html 页面,这个页面就是你 app 依赖的页面

懒加载:当打包构建应用时,Javascript 包会变得非常大,影响页面加载。如果我们能把不同路由对应的组件分割成不同的代码块,然后当路由被访问的时候才加载对应组件,这样就更加高效了。

结合 Vue 的异步组件和 Webpack 的代码分割功能,轻松实现路由组件的懒加载。

25. 怎么管理vuex的state

用module

26. 服务端渲染的优点

1. 服务器端渲染固然耗CPU,但可以使用服务器端缓存的方式解决,并不是每个用户访问都需要重新渲染一遍。而且服务器端渲染甚至可以潜在地增加服务器效率(这点在参考资料第二个里有提到,不过是纯英文的,我有空会翻译下)。

2. 服务器端和客户端可以共享某些代码,避免重复定义。这样可以使结构更清晰,增加可维护性

3. 首次加载页面的速度加快。客户端渲染的一个缺点是,当用户第一次进入站点,此时浏览器中没有缓存,需要下载代码后在本地渲染,时间较长。而服务器渲染则是,用户在下载的已经是渲染好的页面了,打开速度比本地渲染快。

4. SEO。服务器端渲染可以让搜索引擎更容易读取页面的meta信息以及其他SEO相关信息,大大增加网站在搜索引擎中的可见度。

27. 如果有个图片特别大展示出来 如何优化;如果有大量图片想图库要展示如何处理

可以把图片转化base64的格式的非高清图片用来展示,等图片显示完了以后再通过js进行图片src替换;

先给每个图片src附上通用loading图片 通过滚轮触发事件把想要的图片替换loading图片

28.前端性能优化

https://www.jianshu.com/p/ead7dab72cd6


转载于:https://juejin.im/post/5ac5b3c9f265da2378408125

你可能感兴趣的:(网络,前端,javascript,ViewUI)