文章目录
前言
最近几天也有面试两家了,虽然结果都不怎么理想,但也算是刷刷面试经验了。
下面是我对这两次面试的问题的一个复盘,也算是一个小小的经验。
一、重庆XX公司
1.简单介绍
当天上午去现场投的简历,下午就收到了面试官的电话,进行技术面,挺突然的,啥都没有准备好,以至于面的很一般,面试时长:半个小时,面试方式:电话面试。
2.面试内容
a.自我介绍
由于面试的突然,自我介绍做的比较简单,并没有很好讲出自己的优势,和自己具备的能力。
b.React
这一部分发挥的太差了,八股文还没看到React,也没想到一来就考框架的八股,算给我当头一棒。但是面试官人很好,在他的引导下,慢慢回答上了。
1.聊聊React中的Hooks吧
在以前,函数组件也被称为无状态的组件,只负责渲染的一些工作。而现在,Hooks可以让函数组件拥有类组件的特性,例如组件内的状态、生命周期等。常见的Hooks有useState,useEffect,useMemo,useCallback等。使用hooks能够解决大多数问题,并且还拥有代码复用机制,通过自定义hook能够更好的封装我们的功能。
2.useEffect是什么,可以用来做什么
useEffect可以让我们在函数组件中进行一些带有副作用的操作。
1.useEffect第一个参数接受一个回调函数,默认情况下,useEffect会在第一次渲染和更新之后都会执行,相当于在componentDidMount和componentDidUpdate两个生命周期函数中执行回调。
2.如果某些特定值在两次重渲染之间没有发生变化,可以跳过对 effect 的调用,这时候只需要传入第二个参数。
3.回调函数中可以返回一个清除函数,这是effect可选的清除机制,相当于类组件中componentwillUnmount生命周期函数,可做一些清除副作用的操作。
3.setState是同步还是异步的
在React合成事件中,更新都会被批量处理,回调函数都被包裹了一个叫做batchUpdates的函数, setState是同步还是异步,要看它是否命中batchUpdate机制,也就是看isBatchingUpdates的值是true还是false,而能够命中batchUpdate机制的有生命周期和它调用的函数,React中注册的事件和它调用的函数;不能够命中batchUpdate机制的有setTimeout, setInterval,以及我们自定义的Dom事件。简单来说就是React管得到的地方setState是异步的,在React管不到的地方是同步的。
4.React-Router6是怎么使用的
通过npm包可以直接安装最新的React-Router版本,也就是React-Router6。其中分为hashRouter和BrowerRouter,两者直观的感受就是HashRouter的网页路径带#,而BrowerRouter的网页路径不带#。
如果我们使用BrowerRouter的话,
1.首先要在index.tsx这个文件内从react-router-dom中按需引入BrowerRouter,并对入口组件进行包裹。
2.注册路由,可以直接使用Routes包裹Route进行嵌套,配合Outlet实现路由组件的显示;或者使用useRoutes()来实现路由配置,使用js来生成路由,不依赖jsx,返回相应结构的路由组件树。
3.然后可以使用Link和NavLink来进行路由跳转,NavLink的style或者className可以使用回调函数的方式实现高亮。
4.路由传参,使用useNavigate进行路由跳转的时候,可以通过设置search字段来进行传参,对应组件使用useSearchParams这个hook来接受参数;或者通过动态路由传参,使用useParams来接受参数;也可以state传参,通过Link,NavLink,useNavigate进行跳转时,都可以传递state参数。
c.项目相关
项目实现的基本功能是什么
项目中怎么进行状态管理
怎么处理错误边界
说说react-query你是怎么用的
为什么在这个XX项目中没有用redux来进行全局状态管理
d.反问
略
3.简单总结
这算是我的第三次线上面试,但还是由于准备不充分,面的很拉跨,但是遇到了一个很不错的面试官,面试的体验也很不错。
二、上海某医疗科技公司(一面)
1.简单介绍
这家是在某聘上面约到的面试,明明应该是周六进行的,由于周五刚面完一家,认识到自己的不足,且周六没有恰当的时间,所以就推到了周一,也有了较为充分的准备时间。面试时长:二十多分钟,面试形式:腾讯会议视频面。
2.面试内容
a.自我介绍
提前做了准备,但还是有点紧张。
b.CSS
1.谈谈粘性定位
1.CSS粘性定位是CSS3新增的一种定位方式,它可以将一个元素定位在父容器中某个阈值范围内,并且当页面滚动到这个阈值时,元素将会“粘”在屏幕上,停留在固定位置,直到用户滚动到另一个阈值位置。
2.具体实现可以通过在元素上设置position: sticky属性,并且指定top、bottom、left、right中至少一个值。这样,元素将会在其容器的滚动范围内,距离指定边距不超过指定值时,保持相对定位,而不是固定定位或绝对定位。
3.粘性定位通常被用于实现一些常见的用户体验,例如网站导航栏在页面滚动时始终可见,或者某个表头在滚动表格时始终可见。
4.兼容性,粘性定位在不同浏览器上可能有不同的实现方式和表现效果,需要进行适当的测试和兼容性处理。
5.粘性定位元素的父容器需要设置overflow: auto或overflow: scroll属性,以便元素在其容器的滚动范围内生效。
2.怎么实现一个盒子水平垂直居中
1.使用 CSS 的 position 和 transform 属性来实现盒子的居中。将盒子的 position 属性设置为 absolute,并使用 top、bottom、left 和 right 属性将盒子置于父元素的中心位置。然后使用 transform 属性的 translate 方法将盒子向上和向左移动其宽度和高度的一半,以实现水平垂直居中。
.parent {
position: relative;
}
.box {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
2.使用 CSS 的 flexbox 布局来实现盒子的居中。将父元素的 display 属性设置为 flex,并使用 justify-content 和 align-items 属性将盒子水平垂直居中。
.parent {
display: flex;
justify-content: center;
align-items: center;
}
.box {
/* 不需要设置宽度和高度 */
}
3.使用 CSS 的 grid 布局来实现盒子的居中。将父元素的 display 属性设置为 grid,并使用 place-items 属性将盒子水平垂直居中。
.parent {
display: grid;
place-items: center;
}
.box {
/* 不需要设置宽度和高度 */
}
3.怎么实现一个元素消失的效果
1.使用 CSS 的 display 属性来控制元素的可见性。将元素的 display 属性设置为 none,这将使元素消失。
2.使用 CSS 的 opacity 属性来控制元素的不透明度,将元素的 opacity 属性设置为 0。
3.使用 CSS 的 visibility 属性来控制元素的可见性。将元素的 visibility 属性设置为 hidden,这将使元素不可见,但仍会占据布局空间。
4.使用 JavaScript 代码来获取元素并将其从文档中删除,比如父节点调用removeChild删除其子节。
4.说说visibility设置成hidden和display设置为none的区别
1.display设置为none,会让元素完全从渲染树中消失,而visibility设置为hidden不会让元素从渲染树中消失,只是内容不可见。
2.两者都无法进行DOM事件。(才发现面试的时候答错了┭┮﹏┭┮)
3.display修改元素会造成文档回流,性能消耗较大;而visibility修改元素只会造成元素的重绘,性能消耗较小。
4.display是非继承属性,而visibility是继承属性,子孙结点会由于继承了visibility:hidden属性而消失。
5.盒模型有哪些
1.首先先说一下盒模型是什么吧,当对一个文档进行布局的时候,浏览器的渲染引擎会根据标准之一的 CSS 基础框盒模型,将所有元素表示为一个个矩形的盒子。
2.一个盒子由四个部分组成:content(实际内容)、padding(内边距)、border(边框)、margin(外边距)。
3.盒模型分为W3C 标准盒子模型和IE怪异盒子模型。
4.标准盒子模型,是浏览器默认的盒子模型。它的盒子总宽度 = width + padding + border + margin;它的盒子总高度 = height + padding + border + margin,也就是说,标准盒模型的width和height 只是内容高度,不包含 padding 和 border 值。
5.IE 怪异盒子模型,它的盒子总宽度 = width + margin;它的盒子总高度 = height + margin;也就是说,IE 怪异盒子模型的width和height 包含了 padding 和 border 值。
6.在CSS中,我们可以设置 box-sizing 属性来定义了引擎应该如何计算一个元素的总宽度和总高度,其中,content-box 默认值,元素的 width/height 不包含padding,border,与标准盒子模型表现一致;border-box 元素的 width/height 包含 padding,border,与怪异盒子模型表现一致;而另一个属性inherit 指定 box-sizing 属性的值,应该从父元素继承
6.css选择器有哪些,说说它们的优先级
1.常见的选择器有
id选择器(#box):选择id为box的元素,
类选择器(.one):选择类名为one的所有元素,
标签选择器(div):选择标签为div的所有元素,
后代选择器(#box div):选择id为box元素内部所有的div元素,
子选择器(.one>one_1):选择父元素为.one的所有.one_1的元素,
相邻同胞选择器(.one+.two):选择紧接在.one之后的所有.two元素,
群组选择器(div,p):选择div、p的所有元素,
除此之外还有伪类选择器,伪元素选择器
2.内联 > ID选择器 > 类选择器 > 标签选择器;
内联样式的优先级最高,如果外部样式需要覆盖内联样式,就需要使用!important;
到具体的计算层⾯,优先级是由 A 、B、C、D 的值来决定的,其中它们的值计算规则如下:
如果存在内联样式,那么 A = 1, 否则 A = 0;
B的值等于 ID选择器出现的次数
C的值等于 类选择器 和 属性选择器 和 伪类 出现的总次数
D 的值等于 标签选择器 和 伪元素 出现的总次数
记作(A,B,C, D)
比较规则如下:
a.从左往右依次进行比较 ,较大者优先级更高
b.如果相等,则继续往右移动一位进行比较
c.如果4位全部相等,则后面的会覆盖前面的
c.JavaScript
1.聊聊JS中的基本数据类型
JavaScript 中有七种基本数据类型,分别是数字(Number),字符串(String),布尔值 (Boolean),空值 (null),未定义 (undefined),以及ES6新增的符号 (Symbol),表示唯一的标识符,还有BigInt,来表示大整数。
2.怎么判断一个变量的数据类型
1.对基本数据类型的变量,可以直接使用typeof 操作符进行类型判断,其中typeof null 会返回 “object”,因为在JS的最初版本中,使用000开头表示是对象,而null表示为全零,所以将它错误的判断为了"object",然后被ECMAScript沿用了。
2.instanceof 运算符用于检测构造函数的 prototype 属性是否出现在某个实例对象的原型链上,可以准确地判断复杂引用数据类型,但是不能正确判断基础数据类型。
3.采用Object.prototype.toString,调用该方法,统一返回格式“[object Xxx]” 的字符串。
3.客户端可以直接修改Cookie吗
这要看cookie是否设置HttpOnly,默认情况下,客户端可以通过JS代码去访问Cookie,但是如果cookie设置了HttpOnly,cookie就只能通过服务端来设置,服务端可以在返回response的时候通过set-cookie来设置cookie,支持设置的属性有expires,domain,path,httpOnly。
4.怎么阻止事件冒泡
1.首先,什么是事件冒泡。所谓的事件冒泡就是指当子元素事件触发后,会依次向上传递,直到触发根元素。
2.在W3C中,使用event.stopProgation()
方法来阻止事件冒泡
3.在IE下,设置event.cancelBubble=true
可以阻止事件冒泡
5.闭包
1.闭包是指有权访问另一个函数作用域中变量的函数,创建闭包的最常见的方式就是在一个函数内创建另一个函数,创建的函数可以访问到当前函数的局部变量。
2.闭包有两个常用的用途:
闭包的第一个用途是使我们在函数外部能够访问到函数内部的变量。通过使用闭包,我们可以通过在外部调用闭包函数,从而在外部访问到函数内部的变量,可以使用这种方法来创建私有变量。
函数的另一个用途是延长变量的生命周期,使已经运行结束的函数上下文中的变量对象继续留在内存中,因为闭包函数保留了这个变量对象的引用,所以这个变量对象不会被回收。
6.说说原型和原型链
在 js 中我们是使用构造函数来新建一个对象的,每一个构造函数的内部都有一个 prototype 属性值,这个属性值是一个对象,这个对象包含了可以由该构造函数的所有实例共享的属性和方法。当我们使用构造函数新建一个对象后,在这个对象的内部将包含一个指针,这个指针指向构造函数的 prototype 属性对应的值,在 ES5 中这个指针被称为对象的原型。
当我们访问一个对象的属性时,如果这个对象内部不存在这个属性,那么它就会去它的原型对象里找这个属性,这个原型对象又 会有自己的原型,于是就这样一直找下去,也就是原型链的概念。原型链的尽头一般来说都是 Object.prototype,所以新建的对象都能够使用 toString() 等方法。
总结
总的来说,这两次面试,特别是最后一次,让我明白八股文有多么重要,虽然问的问题都是一些常见的问题,但是在之前没有争对这些问题,梳理一遍回答逻辑,组织语言的表达,在真正面试的时候,不是逻辑有问题,答的乱七八槽的,就是遗漏要点,可能会导致面试官都没理解我想表达的意思(T_T)。接下来得沉下心继续背八股文,我这半吊子的八股文完全经不起推敲。