三章之终章完结,众里寻他百度——我的大三生活虽落幕但也是新的开始!

前言

  1. 书接上上回:大厂第一次给了字节,虽被丢进鱼塘但也开启了命运之门~

  2. 书接上回:字节无缘后,迎来了滴滴二面,好家伙鏖战三小时!

笔试是清明前写的,节后通知过了约面试,面的是百度的搜索部门,部门很大,人也很多,所以面试里会着重围绕着项目和 js 来问,框架基本不问。

因为隔了实在太久有些问题忘记了,所以就把印象深的列举出来,其他感兴趣的uu可以自己查阅或跳转😋😋

一面面试官: 是一个看上去很精神的人,一看就是商业精英的那种,最主要的是,他居然会自我介绍欸,什么???🐭🐭没听错吧???面试官居然会自我介绍???打败全世界99.9%的面试官!!!

二面面试官: 是一个很温柔的小姐姐,第一印象居然是长得非常像我班长,真的太像了,问的很简单,题目聊完后就纯聊天了(应该不是kpi吧,应该吧......

一面

1.jwt + token

2.语义化标签

3.块级、行内、行内块元素

1. 块级(display:block): 例如 div、p、h、ul、li等,可以设宽高,会占据一整行;

2. 行内(display:inline): 例如 span、a、strong等,是按标签内容来决定宽高,不可设置宽高但可设置边距

3. 行内块(display:inline-block): 例如 img、input、button等,可设宽高,可以并排放置不会占据整行。

题外话: display 还可设 flex、grid、table-cell、none 等。

4.数组有哪些方法

5.原始类型和引用类型

6.js有哪些类型判断方法

typeof、instanceof、Array.isArray()、Object.prototype.toString.call()

7.bfc(你说的太详细了 - [全是背的,实际用起来不会,面试官不好点破我😭😭])

8.事件循环

9.js阻塞html解析(define 和 async 属性)

<script>标签阻塞浏览器对HTML解析,如获取JS脚本网络请求迟迟得不到响应或JS脚本执行时间过长,都会导致白屏,用户看不到页面内容

<script defer>获取该脚本的网络请求的不阻塞浏览器解析 HTML ,一旦网络请求完成之后,如果此时 HTML 还没有解析完,浏览器不会暂停解析HTML,而是等待 HTML 解析完毕再执行 JS 代码。

<script async>网络请求是异步的不会阻塞浏览器解析HTML ,旦网络请求完成之后(也就是脚本加载完成之后)如HTML还没解析完浏览器会暂停解析,先让执行JS脚本代码,执行完毕后再解析HTML。

10.js有哪些获取dom结构的方法

  1. getElementById(id):通过元素的唯一标识符(id)获取DOM元素。

  2. getElementsByClassName(className):通过类名获取DOM元素,返回一个包含所有指定类名的元素的 HTML集合。

  3. getElementsByTagName(tagName):通过标签名获取DOM元素,返回一个包含所有指定标签名的元素的 HTML集合。

  4. querySelector(selector):通过 CSS 选择器选择一个匹配的元素。

  5. querySelectorAll(selector):通过 CSS 选择器选择所有匹配的元素,返回一个 NodeList。

  6. getElementsByName(name):通过元素的name属性获取DOM元素,返回一个包含所有指定name属性值的元素的 NodeList。

11.var、let、const

12.输出题

js 复制代码
var a = 1
function a(){}
console.log(a)

js 具有声明提升这个功能,函数声明会被提升到作用域的顶部var 变量声明也会被提升,但是只有声明会被提升,赋值操作不会提升

虽然函数 a 在变量 a 之后被声明,但是由于函数声明会被提升到作用域的顶部,所以在 console.log(a) 执行时,变量 a 已经被赋值为 1,而函数声明 function a(){} 被提升至作用域的顶部,但是由于变量 a 已经被赋值为 1,所以函数声明不会对变量 a 产生影响。因此,console.log(a) 输出的是 1,而不是函数体。

简单可以这么理解:

13.手写图片懒加载

一开始前面回答获取dom结构的方法不尽人意,所以面试官想用这题考考我,但是这题我太熟了呀,听到这题的时候🐭🐭心里别提多开心了。

html 复制代码
<body>
    <!-- 图片容器 -->
    <div class="container">
        <!-- 初始时使用空src,并在data-src中指定真实图片路径 -->
        <img src="" data-src="../image/saibo.png"> 
        <img src="" data-src="../image/saibo.png">
        <img src="" data-src="../image/saibo.png">
        <img src="" data-src="../image/saibo.png">
        <img src="" data-src="../image/saibo.png">
        <img src="" data-src="../image/saibo.png">
    </div>
    <script>
        // 获取所有图片元素
        var images = document.querySelectorAll('img');

        // 懒加载函数
        function lazyLoad() {
            // 获取滚动条距离顶部的距离
            var scrollTop = document.body.scrollTop || document.documentElement.scrollTop;
            console.log('滚动条距离顶部的距离' + scrollTop);
            // 获取窗口高度
            var winHeight = window.innerHeight;
            console.log('窗口高度' + winHeight);
            console.log('可视窗口的底部到最顶部的距离' + (scrollTop + winHeight));
            // 遍历所有图片元素
            for (var i = 0; i < images.length; i++) {
                // 如果图片距离顶部的距离小于窗口高度
                if (images[i].offsetTop < scrollTop + winHeight) {
                    // 将 data-src 中的真实图片路径赋值给 src,触发图片加载
                    images[i].src = images[i].getAttribute('data-src');
                }
            }
        }
        // 监听滚动事件,当页面滚动时执行懒加载函数
        window.onscroll = lazyLoad;
    </script>
</body>

详细原理看这 -> 一眼就能明白的懒加载实现原理!

面试官:js基础还需要继续加强,我不会问你框架问题,但你会js底层就一定会框架,就这样吧,后续等通知。

我:😥😥

我本想着百度无望后就去滴滴了,但两天后hr通知我二面了😚😚

🐭🐭好像有细糠吃了~

二面

1.怎么自定义的全局懒加载指令(本人项目中所用到的优化方式)

看这 -> 面试官:会用自定义指令来实现懒加载吗?

2.IntersectionObserver 和 ResizeObserver

当时聊实现原理聊到了 IntersectionObserver,然后面试官又给我介绍了一个 ResizeObserver。

IntersectionObserver -> mdn:IntersectionObserver

IntersectionObserver 用于监测目标元素与其祖先元素或 viewport(视口)之间交叉状态的API。它允许我们在元素进入或退出视口时执行相应的操作,而无需使用传统的事件监听器或轮询来检测元素的位置。特别适用于实现无限滚动加载、懒加载图片和元素动画等场景。通过指定阈值(thresholds)和根元素(root element),可以灵活地定义何时触发交叉状态的变化。

js 复制代码
const intersectionObserver = new IntersectionObserver((entries) => {
  // 如果 intersectionRatio 为 0,则目标在视野外,
  // 我们不需要做任何事情。
  if (entries[0].intersectionRatio <= 0) return;

  loadItems(10);
  console.log("Loaded new items");
});
// 开始监听
intersectionObserver.observe(document.querySelector(".scrollerFooter"));

ResizeObserver -> mdn:ResizeObserver

ResizeObserver 用于监听元素的尺寸变化,与传统的resize事件不同,ResizeObserver 可以一次观察多个元素的尺寸变化。我们可以在元素尺寸发生变化时立即获得通知,并且可以针对性地执行相应的操作,而无需像以前那样依赖于resize事件或者定时器来检查元素的尺寸变化。

3.讲讲 pinia 和 vuex

4.怎么封装组件(着重说的复用性和耦合性)

5.创建几个仓库实例以及怎么调用的(这问题问的挺怪的,应该着重考你思维)

这里我本人的仓库是先封装一个通用基类(例如存储用户信息等常见信息),剩余的仓库是基于基类来创建各自的仓库(例如基于通用基类分别创建购物车仓库、订单仓库等),这种仓库对于通用数据方便管理且模块化分明,最后再引入到一个总仓库,需要用到某个仓库时直接调用总仓库再解构对应仓库就行。

6.vue 组件通信(对比vue2和vue3来讲,vue3事件总线EventBus已被剔除,需mitt插件才能用)

7.js有哪些类型判断方法(被问俩次了)

8.知道哪些可以遍历的方法

1. for...in 和 for...of (看这 -> 那些 for in 和 for of 以及遍历迭代踩过的坑)

2. forEach:......

3. map: 创建一个新数组,其中的每个元素都是原始数组元素调用回调函数的结果。它接受一个回调函数作为参数,该回调函数会被传入当前元素、当前索引和数组本身。

4. set: 它存储唯一值,并且可以迭代这些值

5. filter: 创建一个新数组,其中包含原始数组中所有满足条件的元素。它接受一个回调函数作为参数,该回调函数会被传入当前元素、当前索引和数组本身,并返回一个布尔值表示是否保留当前元素。

6. reduce: 对数组中的每个元素执行一个提供的 reducer 函数(升序执行),将其结果汇总为单个返回值。它接受一个回调函数和一个初始值作为参数,回调函数接收累加器和当前元素作为参数。

7. every: 用于检测数组中的所有元素是否都符合指定条件。它会对数组中的每个元素调用一个提供的回调函数,直到找到一个返回 false 的元素,此时停止遍历,并返回 false。如果所有元素都通过了测试,则返回 true

9.着重问了 reduce 方法以及使用场景

reduce() 是一个高阶函数,它用于对数组中的每个元素执行一个指定的函数,并将结果累积起来,最终返回一个单一的值,它方法接受两个参数:

  1. 回调函数 (callback):这个函数接受四个参数:

    • accumulator:累加器,累积器累积回调函数的返回值。它是上一次调用回调函数时的返回值,或者是提供的初始值(如果提供了)。
    • currentValue:当前元素,数组中正在处理的元素。
    • currentIndex:当前索引,数组中正在处理的当前元素的索引。
    • array:原始数组。(这个我当时是真的不知道,一直以为只有三个参数......)
  2. 初始值 (initialValue) :作为第一次调用回调函数时的第一个参数 accumulator 的初始值。如果没有提供初始值,则将使用数组的第一个元素作为初始值,并从数组的第二个元素开始调用回调函数。

js 复制代码
.reduce((accumulator, currentValue, currentIndex) => (), initialValue);

常见reduce() 方法的使用场景:

  1. 数组求和:计算数组中所有元素的总和。
javascript 复制代码
const numbers = [1, 2, 3, 4, 5];
const sum = numbers.reduce((accumulator, currentValue) => accumulator + currentValue, 0);
console.log(sum); // 输出 15
  1. 操作数组:将数组中的元素按照一定规则转换成其他数据结构或者格式。
javascript 复制代码
const numbers = [1, 2, 3, 4, 5];
const doubled = numbers.reduce((accumulator, currentValue) => {
    accumulator.push(currentValue * 2);
    return accumulator;
}, []);
console.log(doubled); // 输出 [2, 4, 6, 8, 10]
  1. 查找最大值或最小值:找出数组中的最大值或最小值。
javascript 复制代码
const numbers = [10, 5, 20, 3, 15];
const max = numbers.reduce((accumulator, currentValue) => Math.max(accumulator, currentValue), -Infinity);
console.log(max); // 输出 20
  1. 对象转换:将数组中的元素转换成对象。
javascript 复制代码
const fruits = ['apple', 'banana', 'cherry'];
const fruitObject = fruits.reduce((accumulator, currentValue, currentIndex) => {
    accumulator[currentValue] = currentIndex;
    return accumulator;
}, {});
console.log(fruitObject); // 输出 { apple: 0, banana: 1, cherry: 2 }

10.手写深拷贝(面到这的时候真的太简单了,被kpi的感觉愈发强烈)

js 复制代码
// 浅拷贝
// 创建一个对象的浅拷贝,只复制对象的直接属性,不递归复制嵌套对象的属性。
function shallowclone(obj){
    // 创建一个空对象
    let newobj = {}
    // 遍历原对象的直接属性
    for(let key in obj){
        // 确保只复制对象的直接属性,排除原型链上的属性
        if(obj.hasOwnProperty(key))
            newobj[key] = obj[key]
    }
    // 返回新对象
    return newobj
}

// 深拷贝
// 创建一个对象的深拷贝,递归复制对象的所有嵌套属性,包括数组和函数等复杂对象。
function deepclone(obj){
    // 对null值特殊处理
    if(obj === null) return null
    // 特殊处理Date和RegExp对象
    if(obj instanceof Date) return new Date(obj)
    if(obj instanceof RegExp) return new RegExp(obj)
    // 非对象类型直接返回
    if(typeof obj !== 'object') return obj
    // 创建新对象
    let newobj = new obj.constructor()
    // 遍历所有属性,递归复制嵌套对象
    for(let key in obj){
        if(obj.hasOwnProperty(key)){
            newobj[key] = deepclone(obj[key])
        }
    }
    // 返回深拷贝后的对象
    return newobj
}

11.问了学习前端的历程以及怎么看待ai和前端的结合

最后

一面一个小时,二面还不到45分钟...?

预感不妙,实在太简单,跟面试官放大招,放手一搏了,在不搏就没机会搏了😫😫

面试官:最近在学些什么呢?

我:在学习react中,学习完后会重新去把js学习一遍,因为不管框架有多少种最后还是离不开js底层。

面试官:有什么想问的吗?

我:请问什么时候会有结果呢?

面试官:2-3天后吧。

我:我希望能够尽快出结果,因为我手头上有个滴滴的offer了,它那叫我月末过去,但我对于百度的这种顶级互联网公司真的很向往,正好临走之前百度的笔试题过了,来约面试,所以我想来试一试贵公司的招聘,想取得一个更好的学习机会😻😻

面试官:好的我理解了。

最后的最后

上午面完,下午通过我过了......

我真的只是运气好???

二面面试官小姐姐是天使!!!(超大声🎉🎉🎉!!!)

最后的最后的最后

下周三报到了,准备北漂了🎈🎈🎈

真最后了

低开高走还是高开低走?滴滴面了3小时还是有用的嘛~😂😂

相关推荐
NiNg_1_23418 分钟前
JS模块化工具requirejs详解
开发语言·javascript·ecmascript
果子切克now23 分钟前
vue2与vue3知识点
前端·javascript·vue.js
积水成江1 小时前
Vite+Vue3+SpringBoot项目如何打包部署
java·前端·vue.js·windows·spring boot·后端·nginx
一丝晨光1 小时前
Web技术简史、前后端分离、游戏
前端·javascript·css·游戏·unity·前后端分离·cocos
假客套1 小时前
2024 uniapp入门教程 01:含有vue3基础 我的第一个uniapp页面
前端·uni-app·vue3·hbuilder x
柒小毓1 小时前
网站开发基础:HTML、CSS
前端·css·html
哪 吒2 小时前
华为OD机试 - 冠亚军排名(Python/JS/C/C++ 2024 E卷 100分)
javascript·python·华为od
&白帝&3 小时前
Vue.js 过渡 & 动画
前端·javascript
总是学不会.3 小时前
SpringBoot项目:前后端打包与部署(使用 Maven)
java·服务器·前端·后端·maven
Fanfffff7204 小时前
深入探索Vue3组合式API
前端·javascript·vue.js