likes
comments
collection
share

秋招百度提前批一面

作者站长头像
站长
· 阅读数 20

前言

最近秋招提前批已经陆续开启,抱着先投递几家给自己一些准备秋招的压力和动力的心态,一周前,找学长要了百度的内推链接,填上个人信息并且上传简历,还在公司做着手上的需求呢,没想到一周就开始安排我面试了。。。

秋招百度提前批一面

前一天中午在公司午休,结果一觉醒来告诉我第二天下午三点面试,准备过于仓促,感觉发挥的挺差劲的。

秋招百度提前批一面

正文

上来首先是经典的自我介绍,按照 我是谁+从哪里来+我做过什么+有什么成绩+为什么能胜任。 这个格式来,尽可能地把自己优点和能力展示给面试官。同时,在当下人工智能热潮,最好把自己对于人工智能在编码中的应用以及看法表达一下。

然后面试官开始拿着我的简历进行拷打:

1.简历上写你在项目中进行了性能优化,详细说说你是如何判断一个页面为什么需要进行性能优化,指标是什么,你是怎么做的,达到了什么效果?

我说我是通过本地运行项目,使用ChromeDevTools中的Lighthouse对页面进行分析,通过分析结果进行专项优化。使用Web WorkerTreeShakeinggzip等方法结合实际情况来实现性能优化。

秋招百度提前批一面

优化建议如下:

秋招百度提前批一面

秋招百度提前批一面

展开后有着对应优化项的优化建议,结合优化建议和项目实际情况尽可能地去进行性能优化。 比如这第一个建议,渲染时间最长的元素是广告区域的元素,这是盈利手段,总不能把这个元素不予展示吧,毕竟大家还是要吃饭的😘

2.说说CSS选择器有哪些?权重和优先级?

CSS选择器用于选择HTML元素并应用样式。常见的选择器有:

标题作用示例
元素选择器直接选择HTML元素p { color: red; }
类选择器选择指定类名的元素.classname { color: blue; }
ID 选择器选择指定 ID 的元素#idname { color: green; }
属性选择器选择具有指定属性的元素[type="text"] { color: purple; }
后代选择器选择某个元素的后代元素div p { color: yellow; }
子选择器选择某个元素的直接子元素div > p { color: orange; }
相邻兄弟选择器选择紧接在另一个元素后的兄弟元素h1 + p { color: pink; }
通用兄弟选择器选择所有在另一个元素之后的兄弟元素h1 ~ p { color: brown; }
伪类选择器选择特定状态的元素a:hover { color: cyan; }
伪元素选择器选择元素的某个部分p::first-line { color: grey; }
通用选择器选择所有元素* { color: black; }

权重和优先级

CSS 的样式类型:

  1. 内部样式:< style/style >
  2. 内联(行内)样式:< div style="color:red> ;
  3. 外部样式:< link > 或 @import引⼊

常见选择器及选择器权重

秋招百度提前批一面

!important声明的样式的优先级最⾼; 如果优先级相同,则最后出现的样式⽣效; 继承得到的样式的优先级最低; 通⽤选择器(*)、⼦选择器(>)和相邻同胞选择器(+)并不在这四个等级中,所以它们的权值都为0;

样式表的来源不同时,优先级顺序为:内联样式 > 内部样式 > 外部样式 > 浏览器⽤户⾃定义样式 > 浏览器默认 样式。

3.当一个div为<div class="class1 class2>时,浏览器在执行编译的时候顺序是怎么样的,假设claas1和class2都设定了相同的属性,生效的是哪个类的属性,为什么?

举个例子:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>

    <style>
        .class1 {
            color: red;
        }
    
        .class2 {
            background-color: yellow;
            color: blue;
        }
    </style>
  </head>
  <body>
    <div class="class1 class2">
        <h1>Class</h1>
        <p>
            The class attribute is used to define equal styles for elements with the
            same class name.
        </p>
        <p>
            A class name can be used by multiple HTML elements, and it can only be
            used by an HTML element once.
        </p>
    </div>
  </body>
</html>

运行后是这样的:

秋招百度提前批一面

我们可以看到最后字体展示是蓝色的,也就是class2的color配置生效了。

因为class1class2在这个div是同级的,在CSS代码处class1class2先被读取到先编译,所以样式会被class2覆盖,所以最后呈现的是class2设定的字体颜色

4.超出则省略的样式该怎么实现?

这个简单展示一下:

.ellipsis { 
    width: 200px; /* 设置元素的宽度 */ 
    white-space: nowrap; /* 禁止换行 */ 
    overflow: hidden; /* 隐藏溢出内容 */ 
    text-overflow: ellipsis; /* 超出部分用省略号表示 */ 
}

5.说说rem和em他们之间的区别?

  • 继承与累积

    • em 单位依赖于父元素的字体大小,并且在嵌套时会累积。
    • rem 单位则始终相对于根元素,避免了累积效应。
  • 响应式设计

    • rem 更适合用于响应式设计,因为它提供了一种一致的方式来定义尺寸,无需担心嵌套元素的累积效应。
    • em 在某些情况下也很有用,比如当你希望某些元素相对于其父元素进行缩放时。
  • 可预测性

    • 使用 rem 单位更容易预测和维护,因为它只依赖于根元素的字体大小。
    • em 单位在深层次嵌套时可能变得复杂,不容易追踪和控制。

6.让你设计一个Modal对话框你会怎么设计?

我的回答是这样的,做个参考,不一定是最优雅的,有更好的思路欢迎在评论区补充:

  1. 首先要设置z轴高度,确保Modal在最表层;
  2. 然后使用固定定位,确保Modal始终相对于视窗是中心的(观感好一些);
  3. 然后可以有遮罩层,和页面内容做区分,遮罩层的z轴高度略低于Modal,可以使用rgba设置a的值调整透明度,顺带rgba的a和transparent的区别表述了一下(rgba的a设置的值可以在0~1之间,rgba的应用场景更广泛,可以自由定义颜色和透明度,但是在设置成全透明的使用情况下,transparent的性能略优于rgba的a=0,rgba有个计算融合的过程,transparent直接设置成了透明,性能差距很小可以胡萝卜鸡);
  4. Modal可以分headercontentfooter三部分,header中放title和关闭的‘X’符号,content中放内容,footer中放确认和取消等按钮。

7. HTTP响应的状态码,常用的以及含义?

200 OK:表示请求成功,服务器成功返回了请求的数据。 例如,当您访问一个正常的网页时,通常会收到 200 状态码。

201 Created:表示请求成功并且服务器创建了新的资源。 比如,您提交一个表单来创建一个新的用户账号,成功创建后可能会收到此状态码。

204 No Content:表示服务器成功处理了请求,但没有返回任何内容。 常用于删除操作成功时。

400 Bad Request:表示客户端发送的请求存在语法错误,服务器无法理解。 例如,请求参数格式不正确。

401 Unauthorized:表示请求需要用户认证,未提供有效的认证信息。 常见于未登录时尝试访问需要登录才能查看的内容。

403 Forbidden:表示服务器理解请求,但拒绝执行,通常是因为权限不足。 比如,您没有权限访问特定的文件或页面。

404 Not Found:表示服务器未找到请求的资源。 当您访问一个不存在的网页链接时会收到此状态码。

500 Internal Server Error:表示服务器内部错误,通常是服务器端代码出现了问题。 这是一种比较笼统的服务器错误状态码。

502 Bad Gateway:表示作为网关或代理的服务器,从上游服务器接收到了无效的响应。

503 Service Unavailable:表示服务器暂时不可用,通常是由于服务器过载或正在维护。

一般把这些常见的状态码和应用场景说出来就可以了。

8.防抖和节流的区别,使用场景?

防抖(Debounce)

原理

防抖的原理是:在连续事件触发时,只有在事件停止触发一定时间后,才执行一次函数。如果在等待时间内事件再次触发,则重新开始等待。

应用场景

防抖适用于那些希望事件停止触发后才执行的场景,如:

  • 搜索框输入:用户输入时实时进行搜索建议更新,但只在用户停止输入后发送请求。
  • 窗口大小调整:在用户停止调整窗口大小后,重新计算和布局页面内容。
  • 表单验证:用户停止输入后再进行表单字段验证。
代码实现
function debounce(func, wait) {
    let timeout;
    return function(...args) {
        const context = this;
        clearTimeout(timeout);
        timeout = setTimeout(() => func.apply(context, args), wait);
    };
}

// 示例应用:输入框防抖
const searchInput = document.getElementById('search');
searchInput.addEventListener('input', debounce(function() {
    console.log('Search query:', this.value);
}, 300));

节流(Throttle)

原理

节流的原理是:在连续事件触发时,保证在一定时间内只执行一次函数。即每隔一段时间,执行一次函数,即使在此期间事件频繁触发。

应用场景

节流适用于那些希望在规定时间内多次触发事件但只执行一次的场景,如:

  • 滚动事件:在用户滚动页面时,每隔一定时间进行一次处理(如加载更多内容或计算位置)。
  • 窗口调整大小:在用户频繁调整窗口大小时,每隔一定时间更新一次布局。
  • 按钮点击:防止用户在短时间内多次点击按钮触发多次请求。
代码实现
function throttle(func, limit) {
    let lastFunc;
    let lastRan;
    return function(...args) {
        const context = this;
        if (!lastRan) {
            func.apply(context, args);
            lastRan = Date.now();
        } else {
            clearTimeout(lastFunc);
            lastFunc = setTimeout(function() {
                if ((Date.now() - lastRan) >= limit) {
                    func.apply(context, args);
                    lastRan = Date.now();
                }
            }, limit - (Date.now() - lastRan));
        }
    };
}

// 示例应用:滚动事件节流
window.addEventListener('scroll', throttle(function() {
    console.log('Scroll event fired');
}, 200));

9.看你的项目经历都是Vue,用过React吗?

个人的项目经历确实都是Vue,在公司闲暇时间阅读过一些React的官方文档,但是具体的项目还没使用过,简单聊了一下自己阅读React的相关文档自己的体会就下一题了。

10.webpack用过吗,与Vite的比较?

我说公司项目以及自己个人写的练手项目都是使用Vite为主,公司较老的项目中也有Vue-cliVue-cli打包过程的本质还是webpack,最大的体会就是Vite启动的项目确实快不少。虽然面试官到这里没有深问的打算了,但是抓到这个机会,我就顺带把Vite为什么比webpack快等相关问题顺带都聊了出来。

webpack:一个高度可配置的JavaScript模块打包工具,可以将各种资源(JavaScript、CSS、图片等)转换为浏览器可以理解的格式。Webpack通过加载器(loaders)和插件(plugins)系统,实现对不同类型资源的处理和构建过程的定制化。

秋招百度提前批一面

webpack在项目调试之前,要把所有文件的依赖关系收集完,打包后才能运行,这是它慢的主要原因,随着项目规模的激增,编译的时间也许长达数分钟,极其影响体验,所以社区推出了基于ES Module的Vite。

Vite:一个基于ES Module的新型构建工具,采用了现代浏览器的特性来提升开发体验和构建速度。它通过原生ES模块的即时加载和热模块替换(HMR)提供快速的开发体验。

秋招百度提前批一面

现代浏览器普遍支持ES6模块功能(import/export),使得JavaScript可以通过原生的方式引入其他文件。只需在<script>标签上添加type="module"属性,即可在JavaScript文件中使用import语法进行动态导入:

<script type="module" src="/src/main.js"></script>

此时,main.js文件可以直接使用import语法引入其他JavaScript文件,省去了使用Webpack等打包工具的需求。这种原生模块化方法简化了代码组织。

然而,Vite的快速构建能力不仅依赖于浏览器的模块功能。Vite使用esbuild来解析和处理JavaScript文件,这显著提升了构建速度。esbuild是一个用Go语言编写的高性能JavaScript打包器,支持JavaScript和TypeScript语法。相比传统工具链,esbuild的性能优势非常明显。

在前端工程化领域,越来越多的工具开始采用Go和Rust等高效编程语言,以优化性能。这些高效语言带来的性能提升,使得工具在处理和打包代码时更加快速,从而显著提高开发者的开发体验和构建效率。

11.==和===,typeof和instanceof的数据结果判断

大致的问题如下:

console.log({} == {}); //false
console.log(!{} == {}); //false
console.log(![] == []); //true
console.log(NaN == NaN); //false
console.log(1 === new String('1')); //false
console.log(typeof(null)); //object
console.log([] instanceof Object); //true
console.log(/a/ == /a/); //false

var arr = [NaN]
console.log(arr.indexOf(NaN));//-1

碰到这种题目,不能单纯地只回答结果,还需要讲清楚为什么是这个输出结果,所以这个判断输出题同时也考察了=====的区别、typeofinstanceof

等于操作符==在比较中会先进行类型转换,再确定操作数是否相等:

  • 两个都为简单类型,字符串和布尔值都会转换成数值,再比较
  • 简单类型与引用类型比较,对象转化成其原始类型的值,再比较
  • 两个都为引用类型,则比较它们是否指向同一个对象
  • null 和 undefined 相等
  • 存在 NaN 则返回 false

全等操作符===,只有两个操作数在不转换的前提下相等才返回 true。即类型相同,值也需相同。

undefined 和 null 与自身严格相等

let result1 = (null === null) //true

let result2 = (undefined === undefined) //true

typeof(null) 结果是object,这是历史原因,MDN是这么说的:

在JavaScript 最初的实现中,JavaScript 中的值是由一个表示类型的标签和实际数据值表示的。对象的类型标签是 0。由于 null 代表的是空指针(大多数平台下值为 0x00),因此,null 的类型标签是 0,typeof null 也因此返回 "object"

/a/正则表达式本质是object,所以沿用对象比较的规则。

12.手写数组扁平化后排序

function flatArr(arr) {
    let len = arr.length - 1
    let res = []
    for (let i = 0; i <= len; i++) {
        if (Array.isArray(arr[i])) {
            res = res.concat(flatArr(arr[i]))
        } else {
            res.push(arr[i])
        }
    }
    return res.sort((a, b) => a - b)
}

var arr = [[1,2,2],[3,4,5],[6,7,8,9,[11,12,[12,13,14,[15]]]],10];

console.log(flatArr(arr));

太久没看手写,在面试考察的时候我一直卡在了判断元素为数组后,对递归后数组的处理方式,导致这题没有答出来,面试官逐步引导的时候提示我也可以使用ES6数组上的新增方法。也就是arr.flat(n),问我是不知道还是没想到,我说面试的时候考察扁平化一般都是考察手写,就没考虑用数组自带的flat方法,这也提醒大家别陷入惯性思维,先把题目解出来再去拓展其他解法。

手写题结束后也没考算法,因为一开始面试官就表示这场面试大概持续一小时,手写题卡住了导致后面也没时间了所以就没考我算法,我猜测是gg了。

然后就问了问我,平常也有写文章,为什么会有这个行为?我说写文章的过程也是逐步拆解知识点的过程,就和学生时代会写题和能教会别人写题是两种不一样的境界。

最后问我有啥想问他的,简单聊了一下,最后我再表达了一些实习过程中的心得体会,面试就结束了。面试官人还是挺和蔼的,自己准备的时间太紧,没想到前一天中午通知,第二天下午就面。。。

结语

秋招已经开始,建议大家时刻准备着,不打无准备的仗,诸君共勉!!!

秋招百度提前批一面

如有错误欢迎在评论区指正,创作不易对各位有所帮助的话点赞收藏支持一波吧

转载自:https://juejin.cn/post/7398038222969880615
评论
请登录