深圳地区近期面试100多道题汇总(含超详细答案),2024年最新阿里巴巴二面注意事项

先自我介绍一下,小编浙江大学毕业,去过华为、字节跳动等大厂,目前阿里P7

深知大多数程序员,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年最新Web前端全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友。
img
img
img
img
img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上前端开发知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

如果你需要这些资料,可以添加V获取:vip1024c (备注前端)
img

正文

「先用sort排序,然后用一个指针从第0位开始,配合while循环去重」

function unique (arr) {

arr = arr.sort(); // 排序之后的数组

let pointer = 0;

while (arr[pointer]) {

if (arr[pointer] != arr[pointer + 1]) { // 若这一项和下一项不相等则指针往下移

pointer++;

} else { // 否则删除下一项

arr.splice(pointer + 1, 1);

}

}

return arr;

}

var arr = [1,1,2,5,6,3,5,5,6,8,9,8];

console.log(unique(arr))

深圳某云产品公司


4月23日上午

(从这家公司开始面试稍微有些难度了,面试官小哥哥人也很好,刚开始是一个高冷男神,但是在呆呆的猛烈回答下终于还是对我露出了微笑???,还说他也是掘友,有看过我的文章…掘友真是无处不在啊,感动???)

1. 描述一下Promise

这道题我会先大概介绍一下Promise

Promise 是一个对象,它代表了一个异步操作的最终完成或者失败。由于它的then方法和catch、finally方法会返回一个新的Promise所以可以允许我们链式调用,解决了传统的回调地狱问题。

再说一下then以及catch方法:

(此处我是直接拿我之前的一篇文章《45道Promise题》那里的总结)

  1. Promise的状态一经改变就不能再改变。(见3.1)

  2. .then.catch都会返回一个新的Promise。(上面的???1.4证明了)

  3. catch不管被连接到哪里,都能捕获上层未捕捉过的错误。(见3.2)

  4. Promise中,返回任意一个非 promise 的值都会被包裹成 promise 对象,例如return 2会被包装为return Promise.resolve(2)

  5. Promise 的 .then 或者 .catch 可以被调用多次, 但如果Promise内部的状态一经改变,并且有了一个值,那么后续每次调用.then或者.catch的时候都会直接拿到该值。(见3.5)

  6. .then 或者 .catch 中 return 一个 error 对象并不会抛出错误,所以不会被后续的 .catch 捕获。(见3.6)

  7. .then 或 .catch 返回的值不能是 promise 本身,否则会造成死循环。(见3.7)

  8. .then 或者 .catch 的参数期望是函数,传入非函数则会发生值透传。(见3.8)

  9. .then方法是能接收两个参数的,第一个是处理成功的函数,第二个是处理失败的函数,再某些时候你可以认为catch.then第二个参数的简便写法。(见3.9)

  10. .finally方法也是返回一个Promise,他在Promise结束的时候,无论结果为resolved还是rejected,都会执行里面的回调函数。

另外也可以说一下finally方法:

  1. .finally()方法不管Promise对象最后的状态如何都会执行

  2. .finally()方法的回调函数不接受任何的参数,也就是说你在.finally()函数中是没法知道Promise最终的状态是resolved还是rejected

  3. 它最终返回的默认会是一个**「上一次的Promise对象值」**,不过如果抛出的是一个异常则返回异常的Promise对象。

最后可以说一下all以及race方法:

  • Promise.all()的作用是接收一组异步任务,然后并行执行异步任务,并且在所有异步操作执行完后才执行回调。

  • .race()的作用也是接收一组异步任务,然后并行执行异步任务,只保留取第一个执行完成的异步操作的结果,其他的方法仍在执行,不过执行结果会被抛弃。

  • Promise.all().then()结果中数组的顺序和Promise.all()接收到的数组顺序一致。

  • all和race传入的数组中如果有会抛出异常的异步任务,那么只有最先抛出的错误会被捕获,并且是被then的第二个参数或者后面的catch捕获;但并不会影响数组中其它的异步任务的执行。

2. Promise.all中如果有一个抛出异常了会如何处理

这个,在上一题已经说到了:

all和race传入的数组中如果有会抛出异常的异步任务,那么只有最先抛出的错误会被捕获,并且是被then的第二个参数或者后面的catch捕获;但并不会影响数组中其它的异步任务的执行。

3. Promise为什么能链式调用

由于它的then方法和catch、finally方法会返回一个新的Promise所以可以允许我们链式调用

4. 描述一下EventLoop的执行过程

  • 一开始整个脚本作为一个宏任务执行

  • 执行过程中同步代码直接执行,宏任务进入宏任务队列,微任务进入微任务队列

  • 当前宏任务执行完出队,检查微任务列表,有则依次执行,直到全部执行完

  • 执行浏览器UI线程的渲染工作

  • 检查是否有Web Worker任务,有则执行

  • 执行完本轮的宏任务,回到2,依此循环,直到宏任务和微任务队列都为空

(具体可以看这里:https://juejin.im/post/5e58c618e51d4526ed66b5cf#heading-1)

5. docoment,window,html,body的层级关系

「层级关系」

window > document > html > body

  • windowBOM的核心对象,它一方面用来获取或设置浏览器的属性和行为,另一方面作为一个全局对象。

  • document对象是一个跟文档相关的对象,拥有一些操作文档内容的功能。但是地位没有window高。

  • html元素对象和document元素对象是属于html文档的DOM对象,可以认为就是html源代码中那些标签所化成的对象。他们跟div、select什么对象没有根本区别。

(我是这样记的,整个浏览器中最大的肯定就是窗口window了,那么进来的我不管你是啥,就算你是document也得给我盘着)

6. addEventListener函数的第三个参数

第三个参数涉及到冒泡和捕获,是true时为捕获,是false则为冒泡

7. 有写过原生的自定义事件吗

  • 使用Event

  • 使用customEvent (可以传参数)

  • 使用document.createEvent('CustomEvent')和initCustomEvent()

「创建自定义事件」

原生自定义事件有三种写法:

  1. 使用Event

let myEvent = new Event(‘event_name’);

  1. 使用customEvent (可以传参数)

let myEvent = new CustomEvent(‘event_name’, {

detail: {

// 将需要传递的参数放到这里

// 可以在监听的回调函数中获取到:event.detail

}

})

  1. 使用document.createEvent('CustomEvent')和initCustomEvent()

let myEvent = document.createEvent(‘CustomEvent’);// 注意这里是为’CustomEvent’

myEvent.initEvent(

// 1. event_name: 事件名称

// 2. canBubble: 是否冒泡

// 3. cancelable: 是否可以取消默认行为

)

  • createEvent:创建一个事件

  • initEvent:初始化一个事件

可以看到,initEvent可以指定3个参数。

(有些文章中会说还有第四个参数detail,但是我查看了W3C上并没有这个参数,而且实践了一下也没有效果)

「事件的监听」

自定义事件的监听其实和普通事件的一样,使用addEventListener来监听:

button.addEventListener(‘event_name’, function (e) {})

「事件的触发」

触发自定义事件使用dispatchEvent(myEvent)

注意⚠️,这里的参数是要自定义事件的对象(也就是myEvent),而不是自定义事件的名称('myEvent')

「案例」

来看个案例吧:

// 1.

// let myEvent = new Event(‘myEvent’);

// 2.

// let myEvent = new CustomEvent(‘myEvent’, {

//   detail: {

//     name: ‘lindaidai’

//   }

// })

// 3.

let myEvent = document.createEvent(‘CustomEvent’);

myEvent.initEvent(‘myEvent’, true, true)

let btn = document.getElementsByTagName(‘button’)[0]

btn.addEventListener(‘myEvent’, function (e) {

console.log(e)

console.log(e.detail)

})

setTimeout(() => {

btn.dispatchEvent(myEvent)

}, 2000)

8. 冒泡和捕获的具体过程

冒泡指的是:当给某个目标元素绑定了事件之后,这个事件会依次在它的父级元素中被触发(当然前提是这个父级元素也有这个同名称的事件,比如子元素和父元素都绑定了click事件就触发父元素的click)。

捕获则是从上层向下层传递,与冒泡相反。

(非常好记,你就想想水底有一个泡泡从下面往上传的,所以是冒泡)

来看看这个例子:

    • 点击

      冒泡结果:button > li > ul > document > window

      捕获结果:window > document > ul > li > button

      9. 所有的事件都有冒泡吗?

      并不是所有的事件都有冒泡的,例如以下事件就没有:

      • onblur

      • onfocus

      • onmouseenter

      • onmouseleave

      11. 描述下原型链

      12. 手写new

      function myNew (fn, …args) {

      let instance = Object.create(fn.prototype);

      let result = fn.call(instance, …args)

      return typeof result === ‘object’ ? result : instance;

      }

      13. typeof和instanceof的区别

      typeof表示是对某个变量类型的检测,基本数据类型除了null都能正常的显示为对应的类型,引用类型除了函数会显示为'function',其它都显示为object

      instanceof它主要是**「用于检测某个构造函数的原型对象在不在某个对象的原型链上」**。

      14. typeof为什么对null错误的显示

      这只是 JS 存在的一个悠久 Bug。在 JS 的最初版本中使用的是 32 位系统,为了性能考虑使用低位存储变量的类型信息,000 开头代表是对象然而 null 表示为全零,所以将它错误的判断为 object 。

      15. 详细说下instanceof

      instanceof它主要是**「用于检测某个构造函数的原型对象在不在某个对象的原型链上」**。

      算了,直接手写实现吧:

      function myInstanceof (left, right) {

      let proto = Object.getPrototypeOf(left);

      while (true) {

      if (proto === null) return false;

      if (proto === right.prototype) return true;

      proto = Object.getPrototypeOf(proto)

      }

      }

      16. 一句话描述一下this

      指向最后调用函数的那个对象,是函数运行时内部自动生成的一个内部对象,只能在函数内部使用

      17. 函数内的this是在什么时候确定的?

      函数调用时,指向最后调用的那个对象

      18. apply/call/bind的相同和不同

      19. webpack中的loader和plugin有什么区别

      (答案参考童欧巴的一篇webpack面试文章哦:「吐血整理」再来一打Webpack面试题(持续更新))

      loader它是一个转换器,只专注于转换文件这一个领域,完成压缩、打包、语言编译,「它仅仅是为了打包」。并且运行在打包之前。

      而plugin是一个扩展器,它丰富了webpack本身,为其进行一些其它功能的扩展。「它不局限于打包,资源的加载,还有其它的功能」。所以它是在整个编译周期都起作用。

      20. HTTP和TCP的不同

      HTTP的责任是去定义数据,在两台计算机相互传递信息时,HTTP规定了每段数据以什么形式表达才是能够被另外一台计算机理解。

      而TCP所要规定的是数据应该怎么传输才能稳定且高效的传递与计算机之间。

      (还可以再扩展)

      21. TCP和UDP的区别

      1. TCP是一个面向连接的、可靠的、基于字节流的传输层协议。

      2. UDP是一个面向无连接的传输层协议。

      TCP为什么可靠,是因为它有三次握手来保证双方都有接受和发送数据的能力。

      字节流服务:将大块数据分割为以报文段为单位的数据包进行管理

      22. 介绍一下虚拟DOM

      虚拟DOM本质就是用一个原生的JavaScript对象去描述一个DOM节点。是对真实DOM的一层抽象。

      由于在浏览器中操作DOM是很昂贵的。频繁的操作DOM,会产生一定的性能问题,因此我们需要这一层抽象,在patch过程中尽可能地一次性将差异更新到DOM中,这样保证了DOM不会出现性能很差的情况。

      另外还有很重要的一点,也是它的设计初衷,为了更好的跨平台,比如Node.js就没有DOM,如果想实现SSR(服务端渲染),那么一个方式就是借助Virtual DOM,因为Virtual DOM本身是JavaScript对象。

      Vue2.x中的虚拟DOM主要是借鉴了snabbdom.jsVue3中借鉴inferno.js算法进行优化。

      23. 盒模型

      24. 输入URL到页面的呈现

      看三元的《(1.6w字)浏览器灵魂之问,请问你能接得住几个?》

      https://juejin.im/post/5df5bcea6fb9a016091def69

      分别从网络,解析,渲染来说

      面试的问题基本都答出来了,当然后面还有一个技术总监的电话面,主要是问了一些工作相关的问题。

      其实这家公司开出的条件也挺让呆呆心动的,包括氛围感觉也挺好,只不过可能还不是自己想要的吧,所以最终也是没去,挺可惜的…如果面试我的那位小哥哥哥看到了这里,还请不要难过哈,我们江湖会再见的???。

      深圳某房地产公司


      4月27日

      一面

      5道笔试题

      并详细说一下前面三道

      (额,呆呆能力有限只答出来了前面三道)

      二面

      1. JSON的原理以及手写一个实现

      基本原理:主要就是利用 script 标签的src属性没有跨域的限制,通过指向一个需要访问的地址,由服务端返回一个预先定义好的 Javascript 函数的调用,并且将服务器数据以该函数参数的形式传递过来,此方法需要前后端配合完成。

      执行过程:

      • 前端定义一个解析函数(如: jsonpCallback = function (res) {})

      • 通过params的形式包装script标签的请求参数,并且声明执行函数(如cb=jsonpCallback)

      • 后端获取到前端声明的执行函数(jsonpCallback),并以带上参数且调用执行函数的方式传递给前端

      • 前端在script标签返回资源的时候就会去执行jsonpCallback并通过回调函数的方式拿到数据了。

      缺点:

      • 只能进行GET请求

      优点:

      • 兼容性好,在一些古老的浏览器中都可以运行

      代码实现:

      (具体可以看我的这篇文章:JSONP原理及实现:https://www.jianshu.com/p/88bb82718517)

      2. 浏览器为什么要跨域?如果是因为安全的话那小程序或者其他的为什么没有跨域?

      跨域的产生来源于现代浏览器所通用的同源策略,所谓同源策略,是指只有在地址的:

      1. 协议名

      2. 域名

      3. 端口名

      均一样的情况下,才允许访问相同的cookie、localStorage,以及访问页面的DOM或是发送Ajax请求。若在不同源的情况下访问,就称为跨域。

      例如以下为同源:

      http://www.example.com:8080/index.html

      http://www.example.com:8080/home.html

      以下为跨域:

      http://www.example.com:8080/index.html

      http://www3.example.com:8080/index.html

      注意⚠️:

      但是有两种情况:http默认的端口号为80https默认端口号为443

      所以:

      http://www.example.com:80 === http://www.example.com

      https://www.example.com:443 === https://www.example.com

      「为什么浏览器会禁止跨域?」

      「简答」

      首先,跨域只存在于浏览器端,因为我们知道浏览器的形态是很开放的,所以我们需要对它有所限制。

      其次,同源策略主要是为了保证用户信息的安全,可分为两种:Ajax同源策略和DOM同源策略。

      Ajax同源策略主要是使得不同源的页面不能获取cookie且不能发起Ajax请求,这样在一定程度上防止了CSRF攻击。

      DOM同源策略也一样,它限制了不同源页面不能获取DOM,这样可以防止一些恶意网站在自己的网站中利用iframe嵌入正规的网站并迷惑用户,以此来达到窃取用户信息。

      「深答」

      • 首先,跨域只存在于浏览器端。浏览器它为web提供了访问入口,并且访问的方式很简单,在地址栏输入要访问的地址或者点击某个链接就可以了,正是这种**「开放的形态」**,所以我们需要对它有所限制。

      • 所以同源策略它的产生主要是为了保证用户信息的安全,防止恶意的网站窃取数据。分为两种:Ajax同源策略与DOM同源策略:

      同源策略它算是浏览器安全的第一层屏障吧,因为就像CSRF攻击,它只能限制不同源页面cookie的获取,但是攻击者还可能通过其它的方式来达到攻击效果。

      (注,上面提到的iframe限制DOM查询,案例如下)

      // HTML

      // JS

      // 由于没有同源策略的限制,钓鱼网站可以直接拿到别的网站的Dom

      const iframe = window.frames[‘yinhang’]

      const node = iframe.document.getElementById(‘你输入账号密码的Input’)

      console.log(拿到了这个${node},我还拿不到你刚刚输入的账号密码吗)

        • Ajax同源策略它主要做了这两种限制:1.不同源页面不能获取cookie;2.不同源页面不能发起Ajax请求。我认为它是防止CSRF攻击的一种方式吧。因为我们知道cookie这个东西它主要是为了解决浏览器与服务器会话状态的问题,它本质上是存储在浏览器或本地文件中一个小小的文本文件,那么它里面一般都会存储了用户的一些信息,包括隐私信息。如果没有Ajax同源策略,恶意网站只需要一段脚本就可以获取你的cookie,从而冒充你的身份去给其它网站发送恶意的请求。
      • DOM同源策略也一样,它限制了不同源页面不能获取DOM。例如一个假的网站利用iframe嵌套了一个银行网站mybank.com,并把宽高或者其它部分调整的和原银行网站一样,仅仅只是地址栏上的域名不同,若是用户没有注意的话就以为这个是个真的网站。如果这时候用户在里面输入了账号密码,如果没有同源策略,那么这个恶意网站就可以获取到银行网站中的DOM,也就能拿到用户的输入内容以此来达到窃取用户信息的攻击。

      参考:

      • https://segmentfault.com/a/1190000015597029

      • https://juejin.im/post/5cad99796fb9a068ab40a29a

      3. CORS跨域的原理

      跨域资源共享(CORS)是一种机制,是W3C标准。它允许浏览器向跨源服务器,发出XMLHttpRequestFetch请求。并且整个CORS通信过程都是浏览器自动完成的,不需要用户参与。

      而使用这种跨域资源共享的前提是,浏览器必须支持这个功能,并且服务器端也必须同意这种"跨域"请求。因此实现CORS的关键是服务器需要服务器。通常是有以下几个配置:

      • 「Access-Control-Allow-Origin」

      • 「Access-Control-Allow-Methods」

      • 「Access-Control-Allow-Headers」

      • 「Access-Control-Allow-Credentials」

      • 「Access-Control-Max-Age」

      具体可看:https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Access_control_CORS#Preflighted_requests

      过程分析:

      「简单回答」

      • 当我们发起跨域请求时,「如果是非简单请求」,浏览器会帮我们自动触发预检请求,也就是 OPTIONS 请求,用于确认目标资源是否支持跨域。「如果是简单请求,则不会触发预检,直接发出正常请求。」

      • 浏览器会根据服务端响应的 header 自动处理剩余的请求,如果响应支持跨域,则继续发出正常请求,如果不支持,则在控制台显示错误。

      「详细回答」

      • 浏览器先根据同源策略对前端页面和后台交互地址做匹配,若同源,则直接发送数据请求;若不同源,则发送跨域请求。

      • 服务器收到浏览器跨域请求后,根据自身配置返回对应文件头。若未配置过任何允许跨域,则文件头里不包含 Access-Control-Allow-origin 字段,若配置过域名,则返回 Access-Control-Allow-origin + 对应配置规则里的域名的方式

      • 浏览器根据接受到的 响应头里的 Access-Control-Allow-origin 字段做匹配,若无该字段,说明不允许跨域,从而抛出一个错误;若有该字段,则对字段内容和当前域名做比对,如果同源,则说明可以跨域,浏览器接受该响应;若不同源,则说明该域名不可跨域,浏览器不接受该响应,并抛出一个错误。

      CORS中有简单请求非简单请求,简单请求是不会触发CORS的预检请求的,而非简单请求会。

      “需预检的请求”要求必须首先使用 OPTIONS  方法发起一个预检请求到服务器,以获知服务器是否允许该实际请求。"预检请求“的使用,可以避免跨域请求对服务器的用户数据产生未预期的影响。

      (关于更多CORS的内容可以看我的另一篇文章:CORS原理及实现:https://www.jianshu.com/p/b2bdf55e1bf5)

      4. CORS预请求OPTIONS就一定是安全的吗?

      5. 在深圳的网页上输入百度,是怎么把这个请求发到北京的

      这个当时面试官和我说的是,中间会经过很多的站点,比如会经过湖南,或者其它城市,由各个城市的这些站点一层一层分发下去。

      6. 输入URL到页面的呈现

      7. Vue的响应式原理

      8. 那在这个响应式中一个数据改变它是怎么通知要更新的,也就是如何把数据和页面关联起来?

      面的最惨的一次…因为这次面试是当天下午6点才去面的,在这之前呆呆已经经过了3轮面试的折磨,所以身心疲惫很不在状态。当然最主要的是自己确实准备的还不够充分,其实现在回过头来看看这些题都不太难的…

      当天也小小的自闭了一下,整理好状态第二天好好总结吧 ???。

      深圳某海外直播公司


      4月28日

      (当时是电话面,一个小时20分钟,问了我大概五六十道题,我能想到的一共是50题,还有一些记不起来了)

      1. CommonJS和ES6模块的区别

      • CommonJS模块是运行时加载,ES6 Modules是编译时输出接口

      • CommonJS输出是值的拷贝;ES6 Modules输出的是值的引用,被输出模块的内部的改变会影响引用的改变

      • CommonJs导入的模块路径可以是一个表达式,因为它使用的是require()方法;而ES6 Modules只能是字符串

      • CommonJS this指向当前模块,ES6 Modules this指向undefined

      • 且ES6 Modules中没有这些顶层变量:argumentsrequiremoduleexports__filename__dirname

      关于第一个差异,是因为CommonJS 加载的是一个对象(即module.exports属性),该对象只有在脚本运行完才会生成。而 ES6 模块不是对象,它的对外接口只是一种静态定义,在代码静态解析阶段就会生成。

      (具体可以看我的这篇文章:https://juejin.im/post/5eaacd175188256d4345ea3a)

      2. 模块的异步加载

      模块的异步加载可以使用AMD或者CMD规范。

      (具体可以看我的这篇文章:https://juejin.im/post/5eaacd175188256d4345ea3a)

      3. 开发一个模块要考虑哪些问题?

      封闭开放式原则、安全性

      (应该还有,但是没想到)

      4. 实现一个一组异步请求按顺序执行你有哪些方法?

      1. 利用reduce,初始值传入一个Promise.resolve(),之后往里面不停的叠加.then()。(类似于这里https://juejin.im/post/5e58c618e51d4526ed66b5cf#heading-51)

      2. 利用forEach,本质和reduce原理相同。(类似于这里https://juejin.im/post/5e58c618e51d4526ed66b5cf#heading-53)

      3. 还可以用ES9中的for...await...of来实现。

      5. Promise.all()是并发的还是串行的?

      并发的。不过Promise.all().then()结果中数组的顺序和Promise.all()接收到的数组顺序一致。

      6. 平时写过哪些正则表达式

      • 之前有用过用正则去除输入框的首尾空格,正则表达式为:var trimReg = /(^\s+)|(\s+$)/g;不过后来由于Vue中有一个修饰符.trim,使用起来更方便(如v-model.trim="msg")就用这种方式多一些;再或者也可以用ES10新出的trimStarttrimEnd来去除首尾空格。

      • 用于校验手机号的正则:var phoneReg = /^1[3456789]\d{9}$/g

      • 用正则写一个根据name获取cookie中的值的方法:

      function getCookie(name) {

      var match = document.cookie.match(new RegExp(‘(^| )’ + name + ‘=([^;]*)’));

      if (match) return unescape(match[2]);

      }

      详细介绍可以看这里:每日一题-JS篇-根据name获取cookie中值的方法:https://github.com/LinDaiDai/niubility-coding-js/blob/master/%E6%AF%8F%E6%97%A5%E4%B8%80%E9%A2%98/%E6%AF%8F%E6%97%A5%E4%B8%80%E9%A2%98-JS%E7%AF%87.md#%E7%94%A8%E6%AD%A3%E5%88%99%E5%86%99%E4%B8%80%E4%B8%AA%E6%A0%B9%E6%8D%AEname%E8%8E%B7%E5%8F%96cookie%E4%B8%AD%E7%9A%84%E5%80%BC%E7%9A%84%E6%96%B9%E6%B3%95

      7. 正则里的非如何实现的

      ^要是放在[]里的话就表示"除了^后面的内容都能匹配",也就是非的意思。

      例如:

      (除了l,其它都变成了"帅")

      var str = ‘lindaidai’;

      console.log(str.replace(/[^l]/g, ‘帅’));

      // l帅帅帅帅帅帅帅帅

      反之,如果是不在[]里的话则表示开头匹配:

      (只有l变成了"帅")

      var str = ‘lindaidai’;

      console.log(str.replace(/^l/g, ‘帅’));

      8. webpack几种hash的实现原理

      • hash是跟整个项目的构建相关,只要项目里有文件更改,整个项目构建的hash值都会更改,并且全部文件都共用相同的hash值。(粒度整个项目)

      • chunkhash是根据不同的入口进行依赖文件解析,构建对应的chunk(模块),生成对应的hash值。只有被修改的chunk(模块)在重新构建之后才会生成新的hash值,不会影响其它的chunk。(粒度entry的每个入口文件)

      • contenthash是跟每个生成的文件有关,每个文件都有一个唯一的hash值。当要构建的文件内容发生改变时,就会生成新的hash值,且该文件的改变并不会影响和它同一个模块下的其它文件。(粒度每个文件的内容)

      (具体可以看我简书上的这篇文章:https://www.jianshu.com/p/486453d81088)

      这里只是说明了三种hash的不同…至于原理暂时没了解。

      9. webpack如果使用了hash命名,那是每次都会重写生成hash吗

      这个问题在上一个问题中已经说明了,要看webpack的配置。

      有三种情况:

      • 如果是hash的话,是和整个项目有关的,有一处文件发生更改则所有文件的hash值都会发生改变且它们共用一个hash值;

      • 如果是chunkhash的话,只和entry的每个入口文件有关,也就是同一个chunk下的文件有所改动该chunk下的文件的hash值就会发生改变

      • 如果是contenthash的话,和每个生成的文件有关,只有当要构建的文件内容发生改变时才会给该文件生成新的hash值,并不会影响其它文件。

      10. webpack中如何处理图片的?

      webpack中有两种处理图片的loader

      • file-loader:解决CSS等中引入图片的路径问题;(解决通过url,import/require()等引入图片的问题)

      • url-loader:当图片小于设置的limit参数值时,url-loader将图片进行base64编码(当项目中有很多图片,通过url-loader进行base64编码后会减少http请求数量,提高性能),大于limit参数值,则使用file-loader拷贝图片并输出到编译目录中;

      详细使用可以查看这里:霖呆呆的webpack之路-loader篇:https://github.com/LinDaiDai/niubility-coding-js/blob/master/%E5%89%8D%E7%AB%AF%E5%B7%A5%E7%A8%8B%E5%8C%96/webpack/%E9%9C%96%E5%91%86%E5%91%86%E7%9A%84webpack%E4%B9%8B%E8%B7%AF-loader%E7%AF%87.md#file-loader

      11. 说一下回流和重绘

      「回流」

      触发条件:

      当我们对 DOM 结构的修改引发 DOM 几何尺寸变化的时候,会发生回流的过程。

      例如以下操作会触发回流:

      1. 一个 DOM 元素的几何属性变化,常见的几何属性有widthheightpaddingmarginlefttopborder 等等, 这个很好理解。

      2. 使 DOM 节点发生增减或者移动

      3. 读写 offset族、scroll族和client族属性的时候,浏览器为了获取这些值,需要进行回流操作。

      4. 调用 window.getComputedStyle 方法。

      回流过程:由于DOM的结构发生了改变,所以需要从生成DOM这一步开始,重新经过样式计算生成布局树建立图层树、再到生成绘制列表以及之后的显示器显示这整一个渲染过程走一遍,开销是非常大的。

      「重绘」

      触发条件:

      当 DOM 的修改导致了样式的变化,并且没有影响几何属性的时候,会导致重绘(repaint)。

      重绘过程:由于没有导致 DOM 几何属性的变化,因此元素的位置信息不需要更新,所以当发生重绘的时候,会跳过生存布局树建立图层树的阶段,直接到生成绘制列表,然后继续进行分块、生成位图等后面一系列操作。

      「如何避免触发回流和重绘」

      1. 避免频繁使用 style,而是采用修改class的方式。

      2. 将动画效果应用到position属性为absolutefixed的元素上。

      3. 也可以先为元素设置display: none,操作结束后再把它显示出来。因为在display属性为none的元素上进行的DOM操作不会引发回流和重绘

      4. 使用createDocumentFragment进行批量的 DOM 操作。

      5. 对于 resize、scroll 等进行防抖/节流处理。

      6. 避免频繁读取会引发回流/重绘的属性,如果确实需要多次使用,就用一个变量缓存起来。

      7. 利用 CSS3 的transformopacityfilter这些属性可以实现合成的效果,也就是CPU加速。

      参考来源:https://juejin.im/post/5df5bcea6fb9a016091def69#heading-57

      12. 盒模型及如何转换

      box-sizing: content-box(W3C盒模型,又名标准盒模型):元素的宽高大小表现为内容的大小。

      box-sizing: border-box(IE盒模型,又名怪异盒模型):元素的宽高表现为内容 + 内边距 + 边框的大小。背景会延伸到边框的外沿。

      13. 实现水平垂直居中的几种方式

      这里我是按照子弈的总结答的:https://juejin.im/post/5d690c726fb9a06b155dd40d#heading-81

      • Flex布局(子元素是块级元素)

      .box {

      display: flex;

      width: 100px;

      height: 100px;

      background-color: pink;

      }

      .box-center{

      margin: auto;

      background-color: greenyellow;

      }

      • Flex布局

      .box {

      display: flex;

      width: 100px;

      height: 100px;

      background-color: pink;

      justify-content: center;

      align-items: center;

      }

      .box-center{

      background-color: greenyellow;

      }

      • 绝对定位实现(定位元素定宽定高)

      .box {

      position: relative;

      height: 100px;

      width: 100px;

      background-color: pink;

      }

      .box-center{

      position: absolute;

      left: 0;

      right: 0;

      bottom: 0;

      top: 0;

      margin: auto;

      width: 50px;

      height: 50px;

      background-color: greenyellow;

      }

      14. flex的兼容性怎样

      「简单回答:」

      IE6~9不支持,IE10~11部分支持flex的2012版,但是需要-ms-前缀。

      其它的主流浏览器包括安卓和IOS基本上都支持了。

      「详细回答:」

      • IE10部分支持2012,需要-ms-前缀

      • Android4.1/4.2-4.3部分支持2009 ,需要-webkit-前缀

      • Safari7/7.1/8部分支持2012, 需要-webkit-前缀

      • IOS Safari7.0-7.1/8.1-8.3部分支持2012,需要-webkit-前缀

      15. 你知道到哪里查看兼容性吗

      可以到Can I use上去查看,官网地址为:https://caniuse.com/

      16. 移动端中css你是使用什么单位

      「比较常用的」

      • em:定义字体大小时以父级的字体大小为基准;定义长度单位时以当前字体大小为基准。例父级font-size: 14px,则子级font-size: 1em;font-size: 14px;;若定义长度时,子级的字体大小如果为14px,则子级width: 2em;width: 24px

      • rem:以根元素的字体大小为基准。例如htmlfont-size: 14px,则子级1rem = 14px

      • %:以父级的宽度为基准。例父级width: 200px,则子级width: 50%;height:50%;width: 100px;height: 100px;

      • vw和vh:基于视口的宽度和高度(视口不包括浏览器的地址栏工具栏和状态栏)。例如视口宽度为1000px,则60vw = 600px;

      • vmin和vmaxvmin为当前vw 和vh中较小的一个值;vmax为较大的一个值。例如视口宽度375px,视口高度812px,则100vmin = 375px;100vmax = 812px;

      「不常用的:」

      • ex和chex以字符"x"的高度为基准;例如1ex表示和字符"x"一样长。ch以数字"0"的宽度为基准;例如2ch表示和2个数字"0"一样长。

      「移动端布局总结」

      1. 移动端布局的方式主要使用rem和flex,可以结合各自的优点,比如flex布局很灵活,但是字体的大小不好控制,我们可以使用rem和媒体查询控制字体的大小,媒体查询视口的大小,然后不同的上视口大小下设置设置html的font-size。

      2. 可单独制作移动端页面也可响应式pc端移动端共用一个页面。没有好坏,视情况而定,因势利导

      (总结来源:玲珑)

      17. rem和em的区别

      「em:」

      定义字体大小时以父级的字体大小为基准;定义长度单位时以当前字体大小为基准。例父级font-size: 14px,则子级font-size: 1em;font-size: 14px;;若定义长度时,子级的字体大小如果为14px,则子级width: 2em;width: 24px

      「rem:」

      以根元素的字体大小为基准。例如htmlfont-size: 14px,则子级1rem = 14px

      18. 在移动端中怎样初始化根元素的字体大小

      一个简易版的初始化根元素字体大小。

      页面开头处引入下面这段代码,用于动态计算font-size

      (假设你需要的1rem = 20px)

      (function () {

      var html = document.documentElement;

      function onWindowResize() {

      html.style.fontSize = html.getBoundingClientRect().width / 20 + ‘px’;

      }

      window.addEventListener(‘resize’, onWindowResize);

      onWindowResize();

      })();

      • document.documentElement:获取document的根元素

      • html.getBoundingClientRect().width:获取html的宽度(窗口的宽度)

      • 监听windowresize事件

      一般还需要配合一个meta头:

      19. 移动端中不同手机html默认的字体大小都是一样的吗

      如果没有人为去改变根元素字体大小的话,默认是1rem = 16px;根元素默认的字体大小是16px

      20. 你做过哪些动画效果

      实话实说没太做过。

      21. 如果让你实现一个一直旋转的动画你会如何做

      css代码:

      html代码:

      22. animation介绍一下

      语法:

      animation: name duration timing-function delay iteration-count direction;

      | 值 | 描述 |

      | — | — |

      | animation-name | 规定需要绑定到选择器的 keyframe 名称。(mymove) |

      | animation-duration | 规定完成动画所花费的时间,以秒或毫秒计。(2s) |

      | animation-timing-function | 规定动画的速度曲线。(ease|linear|ease-in|cubic-bezier(n,n,n,n)) |

      | animation-delay | 规定在动画开始之前的延迟。(2s) |

      | animation-iteration-count | 规定动画应该播放的次数。(n | infinite) n次/无限 |

      | animation-direction | 规定是否应该轮流反向播放动画。(normal | alternate) 正常/反向 |

      23. animation有一个steps()功能符知道吗?

      一句话介绍:steps()功能符可以让动画不连续。

      地位和作用:和贝塞尔曲线(cubic-bezier()修饰符)一样,都可以作为animation的第三个属性值。

      和贝塞尔曲线的区别:贝塞尔曲线像是滑梯且有4个关键字(参数),而steps像是楼梯坡道且只有numberposition两个关键字。

      语法:

      steps(number, position)

      • number: 数值,表示把动画分成了多少段

      • position: 表示动画是从时间段的开头连续还是末尾连续。支持startend两个关键字,含义分别如下:

        • start:表示直接开始。
      • end:表示戛然而止。是默认值。

      具体可以看这里:https://www.zhangxinxu.com/wordpress/2018/06/css3-animation-steps-step-start-end/

      24. 用过哪些移动端的调试工具

      • Chrome浏览器 -> more tools -> Remote devices -> chrome://inspect/#devices

      • Mac + IOS + Safari

      25. 说一下原型链

      26. 详细说一下instanceof

      27. V8的垃圾回收是发生在什么时候?

      V8引擎帮助我们实现了自动的垃圾回收管理,「利用浏览器渲染页面的空闲时间进行垃圾回收。」

      28. 具体说一下垃圾回收机制

      (这里我用的是:https://juejin.im/post/5e8b261ae51d4546c0382ab4#heading-20 里的总结)

      「栈内存的回收:」

      栈内存调用栈上下文切换后就被回收,比较简单。

      「堆内存的回收:」

      V8的堆内存分为新生代内存和老生代内存,新生代内存是临时分配的内存,存在时间短,老生代内存存在时间长。

      新生代内存回收机制:

      • 新生代内存容量小,64位系统下仅有32M。新生代内存分为**「From、To」**两部分,进行垃圾回收时,先扫描From,将非存活对象回收,将存活对象顺序复制到To中,之后调换From/To,等待下一次回收

      老生代内存回收机制

      • 「晋升」:如果新生代的变量经过多次回收依然存在,那么就会被放入老生代内存中

      • 「标记清除」:老生代内存会先遍历所有对象并打上标记,然后对正在使用或被强引用的对象取消标记,回收被标记的对象

      • 「整理内存碎片」:把对象挪到内存的一端

      (当然想要详细了解的话也可以看我的这篇文章:JavaScript进阶-内存机制(表情包初探)

      29. 在项目中如何把http的请求换成https

      由于我在项目中是会对axios做一层封装,所以每次请求的域名也是写在配置文件中,有一个baseURL字段专门用于存储它,所以只要改这个字段就可以达到替换所有请求httphttps了。

      当然后面我也有了解到:

      利用meta标签把http请求换为https:

      30. 知道meta标签有把http换成https的功能吗?

      参考上一题???。

      31. http请求可以怎么拦截

      在浏览器和服务器进行传输的时候,可以被nginx代理所拦截,也可以被网关拦截。

      32. https的加密方式

      HTTPS主要是采用对称密钥加密和非对称密钥加密组合而成的混合加密机制进行传输。

      也就是发送密文的一方用"对方的公钥"进行加密处理"对称的密钥",然后对方在收到之后使用自己的私钥进行解密得到"对称的密钥",这在确保双发交换的密钥是安全的前提下使用对称密钥方式进行通信。

      33. 混合加密的好处

      对称密钥加密和非对称密钥加密都有它们各种的优缺点,而混合加密机制就是将两者结合利用它们各自的优点来进行加密传输。

      比如既然对称密钥的优点是加解密效率快,那么在客户端与服务端确定了连接之后就可以用它来进行加密传输。不过前提是得解决双方都能安全的拿到这把对称密钥。这时候就可以利用非对称密钥加密来传输这把对称密钥,因为我们知道非对称密钥加密的优点就是能保证传输的内容是安全的。

      数据结构与算法

      这一块在笔试、面试的代码题中考核较多,其中常考的数据结构主要有:数组、链表、队列、栈、Set、Map、哈希表等,不同数据结构有不同的方法以及储存原理,这些算是技术岗的必备知识。算法部分主要分为两大块,排序算法与一些其他算法题

      排序算法根据考频高低主要有:快速排序、归并排序、堆排序、冒泡排序、插入排序、选择排序、希尔排序、桶排序、基数排序、Timsort这十种,这类考核点要么是算法的时间、空间复杂度、稳定度,要么是直接手写代码,故在理解算法原理的同时,对JS语言版的排序算法代码也要加强记忆。

      • 二叉树层序遍历
      • B 树的特性,B 树和 B+树的区别
      • 尾递归
      • 如何写一个大数阶乘?递归的方法会出现什么问题?
      • 把多维数组变成一维数组的方法
      • 知道的排序算法 说一下冒泡快排的原理
      • Heap 排序方法的原理?复杂度?
      • 几种常见的排序算法,手写
      • 数组的去重,尽可能写出多个方法
      • 如果有一个大的数组,都是整型,怎么找出最大的前 10 个数
      • 知道数据结构里面的常见的数据结构
      • 找出数组中第 k 大的数组出现多少次,比如数组【1,2, 4,4,3,5】第二大的数字是 4,出现两次,所以返回 2
      • 合并两个有序数组
      • 给一个数,去一个已经排好序的数组中寻找这个数的位 置(通过快速查找,二分查找)

      网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

      需要这份系统化的资料的朋友,可以添加V获取:vip1024c (备注前端)
      img

      一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
      b4#heading-20 里的总结)

      「栈内存的回收:」

      栈内存调用栈上下文切换后就被回收,比较简单。

      「堆内存的回收:」

      V8的堆内存分为新生代内存和老生代内存,新生代内存是临时分配的内存,存在时间短,老生代内存存在时间长。

      新生代内存回收机制:

      • 新生代内存容量小,64位系统下仅有32M。新生代内存分为**「From、To」**两部分,进行垃圾回收时,先扫描From,将非存活对象回收,将存活对象顺序复制到To中,之后调换From/To,等待下一次回收

      老生代内存回收机制

      • 「晋升」:如果新生代的变量经过多次回收依然存在,那么就会被放入老生代内存中

      • 「标记清除」:老生代内存会先遍历所有对象并打上标记,然后对正在使用或被强引用的对象取消标记,回收被标记的对象

      • 「整理内存碎片」:把对象挪到内存的一端

      (当然想要详细了解的话也可以看我的这篇文章:JavaScript进阶-内存机制(表情包初探)

      29. 在项目中如何把http的请求换成https

      由于我在项目中是会对axios做一层封装,所以每次请求的域名也是写在配置文件中,有一个baseURL字段专门用于存储它,所以只要改这个字段就可以达到替换所有请求httphttps了。

      当然后面我也有了解到:

      利用meta标签把http请求换为https:

      30. 知道meta标签有把http换成https的功能吗?

      参考上一题???。

      31. http请求可以怎么拦截

      在浏览器和服务器进行传输的时候,可以被nginx代理所拦截,也可以被网关拦截。

      32. https的加密方式

      HTTPS主要是采用对称密钥加密和非对称密钥加密组合而成的混合加密机制进行传输。

      也就是发送密文的一方用"对方的公钥"进行加密处理"对称的密钥",然后对方在收到之后使用自己的私钥进行解密得到"对称的密钥",这在确保双发交换的密钥是安全的前提下使用对称密钥方式进行通信。

      33. 混合加密的好处

      对称密钥加密和非对称密钥加密都有它们各种的优缺点,而混合加密机制就是将两者结合利用它们各自的优点来进行加密传输。

      比如既然对称密钥的优点是加解密效率快,那么在客户端与服务端确定了连接之后就可以用它来进行加密传输。不过前提是得解决双方都能安全的拿到这把对称密钥。这时候就可以利用非对称密钥加密来传输这把对称密钥,因为我们知道非对称密钥加密的优点就是能保证传输的内容是安全的。

      数据结构与算法

      这一块在笔试、面试的代码题中考核较多,其中常考的数据结构主要有:数组、链表、队列、栈、Set、Map、哈希表等,不同数据结构有不同的方法以及储存原理,这些算是技术岗的必备知识。算法部分主要分为两大块,排序算法与一些其他算法题

      排序算法根据考频高低主要有:快速排序、归并排序、堆排序、冒泡排序、插入排序、选择排序、希尔排序、桶排序、基数排序、Timsort这十种,这类考核点要么是算法的时间、空间复杂度、稳定度,要么是直接手写代码,故在理解算法原理的同时,对JS语言版的排序算法代码也要加强记忆。

      • 二叉树层序遍历
      • B 树的特性,B 树和 B+树的区别
      • 尾递归
      • 如何写一个大数阶乘?递归的方法会出现什么问题?
      • 把多维数组变成一维数组的方法
      • 知道的排序算法 说一下冒泡快排的原理
      • Heap 排序方法的原理?复杂度?
      • 几种常见的排序算法,手写
      • 数组的去重,尽可能写出多个方法
      • 如果有一个大的数组,都是整型,怎么找出最大的前 10 个数
      • 知道数据结构里面的常见的数据结构
      • 找出数组中第 k 大的数组出现多少次,比如数组【1,2, 4,4,3,5】第二大的数字是 4,出现两次,所以返回 2
      • 合并两个有序数组
      • 给一个数,去一个已经排好序的数组中寻找这个数的位 置(通过快速查找,二分查找)

      [外链图片转存中…(img-BlsLel9R-1713090439396)]

      网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

      需要这份系统化的资料的朋友,可以添加V获取:vip1024c (备注前端)
      [外链图片转存中…(img-T09Y1Vcq-1713090439397)]

      一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

    • 21
      点赞
    • 28
      收藏
      觉得还不错? 一键收藏
    • 0
      评论
    评论
    添加红包

    请填写红包祝福语或标题

    红包个数最小为10个

    红包金额最低5元

    当前余额3.43前往充值 >
    需支付:10.00
    成就一亿技术人!
    领取后你会自动成为博主和红包主的粉丝 规则
    hope_wisdom
    发出的红包
    实付
    使用余额支付
    点击重新获取
    扫码支付
    钱包余额 0

    抵扣说明:

    1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
    2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

    余额充值