深圳地区近期面试100多道题汇总(含超详细答案)

深圳某电商公司


4月22日下午

1. null和undefined的区别

  • null表示一个"无"的对象,也就是该处不应该有值;而undefined表示**「未定义」**。

  • 在转换为数字时结果不同,Number(null)0,而undefinedNaN

使用场景上:

null

  • 作为函数的参数,表示该函数的参数不是对象

  • 作为对象原型链的终点

undefined:

  • 变量被声明了,但没有赋值时,就等于undefined

  • 调用函数时,应该提供的参数没有提供,该参数等于undefined

  • 对象没有赋值属性,该属性的值为undefined

  • 函数没有返回值时,默认返回undefined

2. 冒泡排序算法和数组去重

「冒泡排序」

function bubbleSort (arr) {

for (let i = 0; i < arr.length; i++) {

let flag = true;

for (let j = 0; j < arr.length - i - 1; j++) {

if (arr[j] > arr[j + 1]) {

flag = false;

let temp = arr[j];

arr[j] = arr[j + 1];

arr[j + 1] = temp;

}

}

if (flag) break;

}

}

这个是优化过后的冒泡排序。用了一个flag来优化,它的意思是:如果**「某一次」**循环中没有交换过元素,那么意味着排序已经完成了。

冒泡排序总会执行(N-1)+(N-2)+(N-3)+…+2+1趟,但如果运行到当中某一趟时排序已经完成,或者输入的是一个有序数组,那么后边的比较就都是多余的,为了避免这种情况,我们增加一个flag,判断排序是否在中途就已经完成(也就是判断有无发生元素交换)

「数组去重」

  1. Array.form(new Set(arr))

  2. [...new Set(arr)]

  3. for循环嵌套,利用splice去重

  4. 新建数组,利用indexOf或者includes去重

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

当然还有很多,例如用filter、reduce、Map、Object等,具体可以看:

JavaScript数组去重(12种方法):https://segmentfault.com/a/1190000016418021

Array.form(new Set(arr))[...new Set(arr)]

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

console.log(Array.from(new Set(arr)))

// console.log([…new Set(arr)])

for循环嵌套,利用splice去重」

function unique (origin) {

let arr = [].concat(origin);

for (let i = 0; i < arr.length; i++) {

for (let j = i + 1; j < arr.length; j++) {

if (arr[i] == arr[j]) {

arr.splice(j, 1);

j–;

}

}

}

return arr;

}

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

console.log(unique(arr))

「新建数组,利用indexOf去重」:

function unique (arr) {

let res = []

for (let i = 0; i < arr.length; i++) {

if (!res.includes(arr[i])) {

res.push(arr[i])

}

}

return res;

}

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

console.log(unique(arr))

「先用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题,还有一些记不起来了)

      自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

      深知大多数前端工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

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

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

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

      如果你觉得这些内容对你有帮助,可以添加V获取:vip1024c (备注前端)
      img

      总结一下

      面试前要精心做好准备,简历上写的知识点和原理都需要准备好,项目上多想想难点和亮点,这是面试时能和别人不一样的地方。

      还有就是表现出自己的谦虚好学,以及对于未来持续进阶的规划,企业招人更偏爱稳定的人。

      万事开头难,但是程序员这一条路坚持几年后发展空间还是非常大的,一切重在坚持。

      为了帮助大家更好更高效的准备面试,特别整理了《前端工程师面试手册》电子稿文件。

      前端面试题汇总

      JavaScript

      性能

      linux

      前端资料汇总

      前端工程师岗位缺口一直很大,符合岗位要求的人越来越少,所以学习前端的小伙伴要注意了,一定要把技能学到扎实,做有含金量的项目,这样在找工作的时候无论遇到什么情况,问题都不会大。

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

      2550223751)]
      [外链图片转存中…(img-gLKI1WjO-1712550223751)]
      [外链图片转存中…(img-bg7YiBEf-1712550223751)]
      [外链图片转存中…(img-M4YytQVf-1712550223752)]
      [外链图片转存中…(img-2BrLSCtd-1712550223752)]

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

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

      如果你觉得这些内容对你有帮助,可以添加V获取:vip1024c (备注前端)
      [外链图片转存中…(img-M08umvPj-1712550223753)]

      总结一下

      面试前要精心做好准备,简历上写的知识点和原理都需要准备好,项目上多想想难点和亮点,这是面试时能和别人不一样的地方。

      还有就是表现出自己的谦虚好学,以及对于未来持续进阶的规划,企业招人更偏爱稳定的人。

      万事开头难,但是程序员这一条路坚持几年后发展空间还是非常大的,一切重在坚持。

      为了帮助大家更好更高效的准备面试,特别整理了《前端工程师面试手册》电子稿文件。

      前端面试题汇总

      JavaScript

      性能

      linux

      前端资料汇总

      前端工程师岗位缺口一直很大,符合岗位要求的人越来越少,所以学习前端的小伙伴要注意了,一定要把技能学到扎实,做有含金量的项目,这样在找工作的时候无论遇到什么情况,问题都不会大。

      一个人可以走的很快,但一群人才能走的更远。不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎扫码加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
      [外链图片转存中…(img-7osMK1Cn-1712550223753)]

    评论
    添加红包

    请填写红包祝福语或标题

    红包个数最小为10个

    红包金额最低5元

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

    抵扣说明:

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

    余额充值