常见面试题-基础

91 阅读11分钟

聊一聊作用域/链?

作用域其实就是变量的查找机制(函数可以创建作用域),

作用域链首先在当前作用域查找变量,若未找到,将向其上一级查找,不断重复。

聊一聊函数柯里化?

柯里化其实就是把接收多个参数的函数改造成一个接收一个参数,但返回可接收余下参数的函数的技术。

柯里化的优点:

--1、参数复用

--2、将函数执行分段

--3、可延迟执行

柯里化的实际应用场景:.bind函数

聊一聊原型/链?

每一个构造函数都有一个prototype属性,

在构造函数构建对象时,会将新对象的__proto__属性指向构造函数的prototype对象,当查找新对象属性无果时,将会在__proto__里查找,不断重复。这就是原型链。

聊一聊this的指向问题?

this是一个对象,指向运行时所在的环境

This的绑定有四种情况

--1、默认绑定,例如,window作用域下的函数执行会被绑定到window对像

--2、隐式绑定,this指向调用函数所属的对象(且只有最后一层会影响调用位置)

--3、显示绑定,通过函数的call、apply、bind方法,改变函数体内部的this指向

--3、new绑定,

new的执行过程

---创建一个全新的对象

---给这个新对象添加一个__protp__属性,引用了构造函数的prototype

---这个构造函数中的this指向了这个新的对象

---如果构造函数没有返回其他对象,那么new表达式返回这个新对象,如果有,择返回构造函数返回的对象

var和let、const的区别?

—1、var声明的变量具有函数作用域,在整个函数内部可用;let、const声明的变量具有块级作用域,在代码快内可用,代码块可以是函数、循环或者条件语句等

—2、var声明的变量可以重新声明,let、const声明的变量不可以重新声明

—3、var存在声明提升,let、const则不存在,即在声明语句前访问var变量可访问到undefine,访问let、const变量则直接报错

—4、const在声明赋值之后便不可以修改其指向的信息了

聊一聊EventLoop事件循环?

EventLoop是指运行环境解决JS单线程运行时堵塞的一种机制,也是JS中异步执行的原理。

首先JS运行时包含了一个待处理函数的消息队列,每一个先进入的消息被处理后都会被移除队列,当这个队列被清空时,将会检查微任务队列是否有需要执行的任务,当全部执行完之后,再开始检查宏任务队列。

常见的微任务有Promise

常见的宏任务有setTimeout、setInterval、requestAnimationFrame等

聊一聊Promise与Async/Await的区别?

Async/Await是实现Promise的一种语法糖,它消除了Promise的.then的回调语法,更加的直观,但是Async/Await异常的捕获需要额外处理。

Async/Await的异常捕获:

async function fn() {

    try {

        const a = await run(); 

    } catch (e) {

        // ToDo

    }

}

聊一聊内存泄漏?

我认为内存泄漏主要分为两种

—1、一是内存的不正当使用

—2、二是随着时间或者操作的增加,占用的内存也不断增加,且不被清除

聊一聊Get和Post的区别?

—Get和Post最根本的区别是“约定和规范”

—1、方法名不同,我们约定GET是用来获取资源的,而POST是用来提交数据的。

—2、GET请求一般会被浏览器缓存,而POST不会。

—3、GET请求的参数是通过URL传递的,而URL的长度(一般2k)和类型(ASCII字符)是有限制的。而POST请求的参数是放在RequestBody里的,没有太多限制

—4、浏览器的回退和刷新不会对GET请求有任何影响,而POST会提示再次提交。

—5、GET请求的参数会被保存在历史记录中,并且GET请求的地址可被收藏在书签中。

—6、GET发送数据包时是直接把hearder和data一起发送出去,而POST会先发送header,服务器响应100,然后再发送data。(有些浏览器POST也只发一次)

这些约定和规范看似很多,但本质其实没有不同

聊一聊Post和Put的区别?

—1、方法名不同,POST通常用于创建新的数据,而PUT用于更新现有数据。

—2、PUT请求具有幂等性,执行多次PUT请求结果应当相同

聊一聊Http和Https的区别?

—1、HTTP是一种超文本明文传输协议,不提供任何加密机制。

—2、HTTPS是HTTP的安全版本,客户端与服务器之间传输是加密的。

聊一聊HTTPS的原理?

—1、首先由客户端发起请求。

—2、服务端收到客户端的请求后,将网站支持的证书信息和公钥发给客户端。

—3、客户端收到证书,验证证书的有效性,如果有效,客户端会生成一个随机值,并使用公钥对该随机值进行加密。

—4、客户端将加密后的随机值发送个服务器,服务器使用私钥获取客户端生成的随机值。

—5、服务端和客户端可以用该随机值对数据进行对称加密了。

聊一聊TCP?

—TCP是一种面向连接的传输控制协议,它使用三次握手来建立连接,并使用四次挥手来断开连接。

—为什么要进行三次握手和四次挥手:三次握手主要是为了确保双方都准备建立好了连接,四次挥手主要是为了每个方向都单独进行关闭。

形象化三次握手:

—1、客户端发送服务端:我要发送信息了,请求建立连接SYN。

—2、服务端收到客户端的请求,并返回:我同意建立连接SYN+ACK。

—3、客户端收到服务端的同意信息,向服务端发送ACK,表示确认收到ACK

形象化四次挥手:

—1、客户端没有更多数据发送的时候,向服务器发送一个FIN报文,请求断开连接。

—2、服务器收到FIN报文后,向客户端发送一个ACK报文,表示确认。

—3、服务器没有更多数据发送的时候,向客户端发送一个FIN报文,请求断开连接。

—4、客户端收到FIN报文后,向服务器发送一个ACK报文表示确认,至此,TCP完全断开连接。

聊一聊跨域问题的解决?

跨域是指浏览器为了安全起见,限制了脚本内发起的跨院HTTP请求。这种限制被称为同源策略。同源策略规定,只有当协议、域名和端口都相同时。两个页面才被认为是同源的。

解决跨域的方案:

—1、代理:这个常用的解决方案,通过服务端代理异源请求。

—2、JSONP:通过动态创建SCRIPT标签来实现跨域请求的方法。通过回调函数来处理获取到的数据,

—3、CORS:通过服务器标识允许除自己以外的HTTP请求。(Access-Control-Allow-Origin)

—4、postMessage:postMessage是HTML5中新增的一个API,它允许不同源之间的窗口通信。

聊一聊浏览器缓存

浏览器缓存是为了降低网络资源的加载速度和频率。

浏览器缓存策略通常分为两种:强缓存(Expires,Cache-COntrol)和协商缓存(Last-modified,Etag),并且缓存策略都是通过设置HTTP Header来实现的。

强缓存是指在缓存期间不需要请求,返回STATE CODE直接为200。通过Expires和C ache-Control来实现,Expires是控制缓存过期的时间,受限于本地时间。Cache-Control是控制缓存的有效期,它的Max-Age可以指定最大生命周期。

聊一聊常见的网络攻击?

—1、XSS跨站脚本攻击,攻击者通过向网站注入恶意脚本来执行的一种攻击,可以用于窃取用户信息。

防范XSS攻击的关键在于需要客户端以及服务端对输入/输出的信息进行严格的验证和适当的编码。

比如直接攻击者可能直接注入script标签,或者在img的onerror和onload等事件内进行攻击。

还有一个就是防范用户存于Cookie的关键信息被截取,HttpOnly是需要设置的。

—2、CSRF跨站请求伪造,攻击者通过恶意网站诱骗用户去一个已经认证的网站并运行一些非自愿的操作,比如修改密码、转账等操作。该攻击方式的重点是诱骗。

防范CSRF攻击的关键在于关键操作页面的来源是可靠的。

可通过在关键操作页对Referer字段进行检查,并提示用户风险。

还有就是添加CSRF令牌,其原理是在用户访问网站是生成一个用于验证的随机数,当进入关键操作页面时一并在地址中加入此随机数,在提交操作时验证该随机数。由于攻击者不能事先知道用户的随机数,也就无法使用CSRF攻击了。

—3、SQL注入,攻击者通过向输入字段注入SQL代码执行恶意SQL查询,从而攻击数据库中的数据。

防范SQL注入的关键在于如何处理用户输入的字段,

一是不能手动拼接SQL查询语句和参数值,一定要使用数据库驱动程序提供的参数化方法。(比如?占位符,命名占位符等)。

一是系统需要尽量隐藏数据库的信息。

—4、点击劫持,点击劫持是一种将透明的iframe放置在一个看似无害的页面上,并引导用户点击操作iframe的内容,触发用户不知情的操作的攻击方式。

防范点击劫持可以通过设置header的X-Frame-Option禁止在iframe中打开或者通过JS(window.top===window)检查页面是否在iframe中打开来采取措施。

—5、DNS攻击,DNS攻击是对域名系统的攻击,可能导致用户重定向到恶意的网站。

聊一聊性能优化?

一般我认为前端的性能优化主要从两个方面考虑,一个是网站的加载速度,一个是用户的使用体验(操作的响应时间)。

优化网站加载速度:

—1、减少HTTP的请求大小和次数,具体我们可以合并和压缩部分JS、CSS文件,以减少文件的大小和数量,注意,文件的大小和数量需要平衡(大了影响单个加载速度,浏览器一般可同时处理6个HTTP请求,多了容易影响整体速度),否则会影响整体的加载速度。

—2、优化图像,使用适当的图像格式,若无透明要求,应当使用jpg或者webp,可对不同大小的屏幕使用不同的图片尺寸,并对图像进行适当的压缩来减小大小。

—3、优化缓存,使用CDN来加速静态资源的分发,减少服务器的负载,对于静态的JS,CSS等文件,需要缓存在浏览器端,以减少请求。

—4、优化懒加载,只将首屏出现的内容实时加载,对于可延迟加载的图片、视频等大型资源,可以在用户滚动到它们的可视区域时再进行加载,以减少页面初始化时间。

优化用户使用体验:

—1、减少DOM的操作,减少复杂的DOM操作,和频繁修改样式导致页面重排。

—2、监控用户用户的操作数据和网站性能,及时发现和解决性能问题。

—3、CSS动画尽量使用GPU加速,以及需要避免重排,若使用会发生重排的元素,那么尽量使元素脱离文档流(绝对定位和固定定位)。

聊一聊如何实现自适应页面?

—1、使用响应式的Web设计,包括使用CSS媒体查询、弹性布局、栅格化布局这些能够根据设备动态调整页面的布局方式。

—2、使用viewport元标签设置视口宽度为设备的宽度,并且限制页面初始的缩放比例。

—3、根据不同的设备优化图片和媒体资源。

—4、使用多种设备进行调试和测试。

视口:网页可见区域的大小,移动端由于屏幕较小,一般会采取两种视口,一是布局视口,就是网页实际大小(经常会看到有一些缩小的PC网页完整显示在了移动设备上),二是视觉视口,就是可见区域大小。

聊一聊promise的原理

--promise原理主要就是确认3个状态,然后把.then .catch的方法不断push进callback里,然后异步触发执行完对应状态后,不断的将callback里的方法执行并out