2023年前端高频面试题 及其 对应问题解决答案!!!!!(问题记录下来、慢慢完善解决方案、主要根据自己在项目中真实情况记录答案)

前言

面试其实也是工作经验的总结,在工作之余,将工作中的问题记录总结,也是为下一份工作面试打好基础。

常规面试问题

1、项目中的跨域如何处理的。

跨域是一个比较大的话题,问题本身在开发过程中比较常见的问题,
对跨域的理解和解决方法可以点击这里

2、防抖与节流,什么场景用。

防抖:防止抖动、阻止用户行为多次触发请求。即是高频触发的事件,一定时间内、只有最后一次被触发生效。
使用场景:

  1. 监听页面数据变化重置页面布局,如:调整浏览器大小。
  2. 登录、发送短信、支付等避免用户点击太快导致多次触发请求。
  3. 表单、文档实现自动保存,监听在没任何操作后多长时间进行自动保存。

代码实现封装防抖:

function dobunce (fn, waitTime){
   
   
	let timer = null;
	return (...arg) => {
   
   
		if(timer) clearTimeout(timer)
		timer = setTimerout(()=>{
   
   
			fn(...arg)
		},waitTime)
	}
}

节流:节约流量、控制事件的发生频率,即是高频触发的事件、一定时间内只触发一次。
使用场景:

  1. 输入框实时输入搜索展示下拉框。
  2. 监听滚动条到指定位置触发加载更多。
  3. 每隔多长时间记录鼠标位置,

代码实现:

function throttle(fn,waitTime){
   
   
	let timer = null;
	return (...args)=>{
   
   
		if(timer) return
		timer = setTimeout(()=>{
   
   
			fn(...args)
			timer=null
		}, waitTime)
	}
}

3、HTTP协议 的理解。
4、懒加载如何判断元素出现在视口内?

判断元素是否在视口内:需要了解浏览器判断一个元素位置的方法。首先我们需要了解怎么判断浏览器的宽、高。

//兼容所有浏览,获取浏览器的宽高的方法;
const w=window.innerWidth
	|| document.documentElement.clientWidth
	|| document.body.clientWidth;

const h=window.innerHeight
	|| document.documentElement.clientHeight
	|| document.body.clientHeight;
//window 常用的方法
window.close() //关闭浏览器窗口
window.open()  // 开启浏览器窗口
window.resizeTo() // 调整浏览器窗口
window.moveTo()  //移动浏览器

同时我们还需要了解元素属性;

getBoundingClientRect();

Element.getBoundingClientRect() 方法返回一个 DOMRect 对象,其提供了元素的大小及其相对于视口的位置。拥有left, top, right, bottom, x, y, width, height属性。

使用 getBoundingClientRect 方法 判断元素是否在视口内部、公式为:

el.getBoundingClientRect().top < viewHight(视口高度)

代码实现:

const elIsInViewPort = (el) => {
   
   
	const viewHight = window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight;
	const elToViewHeight = el.getBoundingClientRect()?.top;
	return elToViewHeight <= viewHight + 100   //+100 目的是为了提前加载数据
}

IntersectionObserver 接口;

IntersectionObserver 接口(从属于 Intersection Observer API)提供了一种异步观察目标元素与其祖先元素
顶级文档视口(viewport)交叉状态的方法。其祖先元素或视口被称为根(root)

了解更多 IntersectionObserver API 移步到这里

使用 IntersectionObserver 判断元素是否在视口内 代码实现方法

//
const intersectionObserver = new IntersectionObserver((entries)=>{
   
   
	 // 如果 intersectionRatio 为 0,则目标在视野外,
	 if(entries.length < 1) return
	 entries.forEatch((target)=>{
   
   
	 	if(target.isIntersecting){
   
   
			//停止对元素的观察
			intersectionObserver.unobserve(target)
		}
	 })
})
const elArr = [...document.querySelectorArr('.selectEle')]
elArr.forEatch((item)=>{
   
   
	intersectionObserver.observe(item) //对元素进行监听;
})

5、ES6中let、const与ES5 var的区别。

let ,const, var 都是js 中使用来申明变量的方法。
var 声明的变量 为全局变量,及是 window 下的变量,存在变量提升问题。
let、 const 为es6 新提出的申明变量的方法,申明的变量为块级作用域、
const 声明 的变量为常量、必须初始化值、不能修改变量值、否则会报错。
let 申明的块级作用域变量,可以修改变量值。
let const 声明的变量都不能重复声明,重复声明会报错。var 声明重复变量不报错会覆盖前面变量的值。

6、Promise的理解。

promise js 使用来异步执行代码的方法,由于js 执行代码为同步的,一次只执行一次任务,阻塞其他任务。

7、JavaScript有哪些数据类型?如何判断这些类型。

js中数据类型:

类型 typeOf 返回值
Null “Object”
Undefined “Object”
Boolean “boolean”
Number “number”
BigInt “bigint”
String “string”
Symbol “symbol”

判断数据类型方法
方法一:typeOf
能够精确的返回数据的基本数据类型,但是不能明确判断出, Null、 Underfined 对象值,

方法二: instanceOf
可以拿根据 instanceOf 判断对象是继承哪一个原始类型,判断方法为根据js原型链特性,逐级向上找到根节点
代码实现instanceOf

const myInstanceOf = (obj,type) =>{
   
   
	if(typeOf obj !== 'object' || obj == null) return false
	let proto = Object.getProtoTypeOf(obj)
	while(true){
   
   
		if(proto === null) return false
		else if(proto === type.protoType){
   
   
			return true
		}else {
   
   
		proto = Object.getProtoTypeOf(proto)
		}
	}
}
 //使用方法
 const s = 'abc'
 myInstanceOf(s, 'string')    // true

方法三: Object.protoType.toString.call(obj)

toString 方法为对象原型上的方法,直接调用toString 方法 返回 “[object: ‘Xxxxx’]” , ‘Xxxxx’ 就为对象的类型,object 调用toString 方法 直接返回 “[object: ‘object’]” 字符串, 其他类型的值调用需要使用call() 调用才能返回正确的值。

Object.protoType.toString({
   
   })   // "[object Object]"
Object.protoType.toString.call('str') //"[object String]"
Object.protoType.toString.call(124) // "[object Number]"

其他也可以使用 数据类型的转换

如: Boolean() 类型转换 Number() 类型转换

8、Axios与Ajax的区别。

Axios和Ajax是两种不同的技术,用于实现前后端数据交互。

  1. Axios是一个基于Promise的HTTP客户端,可以用于浏览器和Node.js环境。它支持跨域请求、拦截请求和响应、取消请求等功能。Axios可以通过简单的API发送HTTP请求,并且可以处理响应结果。它是一个相对较新的技术,逐渐取代了旧的Ajax技术。

  2. Ajax(Asynchronous JavaScript and XML)是一种用于创建异步请求的技术。它可以使网页在不重新加载的情况下更新部分内容,提升用户体验。Ajax可以使用XMLHttpRequest对象来发送HTTP请求,并通过回调函数处理响应结果。

所以,主要区别如下:

  • Axios是一个基于Promise的HTTP客户端,而Ajax是一种用于创建异步请求的技术。
  • Axios可以用于浏览器和Node.js环境,而Ajax只能用于浏览器环境。
  • Axios支持更多的功能,如跨域请求、拦截请求和响应、取消请求等。
  • 使用Axios时,可以通过简单的API发送HTTP请求,而使用Ajax需要手动创建XMLHttpRequest对象。
  • Axios相对来说是较新的技术,逐渐取代了Ajax的使用。
9、HTML中的DOM操作是指使用JavaScript来操作HTML文档中的各个元素和属性。DOM(文档对象模型)提供了一种访问和操作HTML文档的标准方式。

通过DOM操作,可以实现以下功能:

  1. 获取元素:使用document对象的方法,如getElementById、getElementsByTagName、getElementsByClassName等来获取HTML文档中的元素。

  2. 修改元素的内容:使用innerHTML属性来修改元素的内容,或使用textContent属性来修改文本内容。

  3. 修改元素的样式:使用style属性来修改元素的样式,如颜色、背景、字体等。

  4. 修改元素的属性:使用setAttribute方法来修改元素的属性,如class、id、src等。

  5. 创建和删除元素:使用createElement方法创建新的元素,并使用appendChild或insertBefore方法将其插入到指定位置,使用removeChild方法将元素从文档中删除。

  6. 监听事件:使用addEventListener方法来监听元素上的事件,如点击、鼠标移动等。

  7. 修改表单数据:可以使用JavaScript来获取和修改表单元素的值,如input、select、textarea等。

通过以上DOM操作,可以实现动态地更新HTML文档的内容、样式和行为,使网页具有更好的交互性和用户体验。HTML中的DOM操作。

10、普通函数和自定义hook的区别。
  1. 使用方式:

    • 普通函数可以在任何地方被调用,可以接受任意参数并返回一个值。
    • 自定义hook只能在函数组件中使用,并且必须按照规定的方式调用和使用返回的值。
  2. 设计思路:

    • 普通函数通常用于解决具体的问题,实现一些特定的功能逻辑。
    • 自定义hook是一种将复用逻辑进行抽象和封装的方式,它可以将组件之间的共享逻辑提取出来,并使其更容易被理解、测试和维护。
  3. 命名规范:

    • 普通函数没有特定的命名规范,可以根据需求起一个合适的名称。
    • 自定义hook的命名必须以"use"开头,这是React的约定,以便开发者能够识别出它们是hooks。

总结起来,普通函数主要用于解决具体问题,而自定义hook主要用于复用和共享逻辑。自定义hook的设计目标是将组件之间的逻辑提取出来,使得逻辑更加清晰、可重用,并且符合React的设计理念。普通函数与自定义hook的区别。

11、SSR服务端渲染的理解。

SSR(Server-Side Rendering)是一种Web开发技术,它在服务器端生成完整的HTML内容,然后将其发送到客户端浏览器进行展示。与传统的客户端渲染(CSR)不同,客户端渲染是指在浏览器中使用JavaScript来动态生成HTML内容。

SSR的主要优势是改善了网页的加载性能和搜索引擎优化(SEO)。由于页面在服务器端生成,用户在请求页面时会直接获得完整的HTML内容,因此首次加载速度比CSR更快,且可以提供更好的搜索引擎抓取和索引。

SSR的实现需要使用一些特定的框架或库,如React的Next.js、Vue的Nuxt.js等。这些工具提供了服务端渲染的功能,可以将组件在服务器端渲染为HTML,并将其与浏览器端的JavaScript进行关联,以实现客户端的交互功能。

SSR的基本流程包括以下几个步骤:

  1. 服务器接收到请求,并根据请求的URL确定需要渲染的组件。
  2. 服务器使用组件渲染引擎(如React的服务器端渲染引擎)将组件渲染为HTML字符串。
  3. 服务器将生成的HTML字符串作为响应发送给客户端浏览器。
  4. 客户端浏览器接收到HTML响应后,会执行其中的JavaScript代码并构建页面的DOM结构。
  5. 客户端渲染工具会接管页面的控制,并处理用户的交互行为,如点击、输入等。
  6. 当用户进行交互时,客户端会通过Ajax或WebSocket等技术与服务器进行通信,获取数据并更新页面。

需要注意的是,由于SSR需要在服务器端进行组件渲染,因此对服务器的负载有一定的影响。此外,SSR也增加了开发的复杂性,因为需要同时处理服务器端和客户端的渲染逻辑。

12、浏览器如何做静态资源缓存?

浏览器可以通过以下几种方式进行静态资源缓存:

  1. 设置HTTP缓存头:浏览器通过设置响应头中的缓存相关字段,指示浏览器对静态资源进行缓存。常用的响应头字段有:

    • Expires: 指定静态资源的过期时间,浏览器在过期时间之前不会重新请求该资源。
    • Cache-Control: 控制缓存的行为,如设置为max-age=3600表示资源在一个小时内有效。
    • Last-Modified/If-Modified-Since: 服务器返回资源的最后修改时间,浏览器在下一次请求时通过If-Modified-Since字段将上次的最后修改时间发送给服务器,如果资源在服务器上的最后修改时间仍然一致,服务器会返回一个304 Not Modified的响应,表示资源未变化,浏览器可以使用缓存的版本。
  2. ETag/If-None-Match: 服务器对于每个资源生成一个唯一的标识符,称为ETag,浏览器在下一次请求时通过If-None-Match字段将上次请求中服务器返回的ETag发送给服务器,如果这个资源的ETag仍然一致,服务器会返回一个304 Not Modified的响应。

  3. Service Worker缓存:通过Service Worker技术,浏览器可以在离线状态或网络不稳定的情况下,拦截对静态资源的请求并返回缓存的版本。

  4. localStorage/IndexedDB: 将静态资源缓存到本地存储(localStorage或IndexedDB)中,下次使用时直接从本地读取。

需要注意的是,浏览器缓存是由浏览器自行处理的,开发人员只需在服务器端设置合适的响应头字段和缓存策略即可。另外,浏览器缓存只适用于静态资源,动态资源每次访问都会向服务器发起请求。

13、样式覆盖如何处理?

在前端开发中,样式覆盖是处理样式冲突的重要问题。以下是一些常见的处理样式覆盖的方法:

  1. 使用更具体的选择器:如果多个样式规则应用于同一个元素,可以使用更具体的选择器来指定优先级。例如,使用id选择器比class选择器具有更高的优先级。

  2. 使用!important:使用!important声明可以将样式规则的优先级提升到最高级别,但应谨慎使用此方法,因为它可能会导致样式无法继承和覆盖。

  3. 修改HTML结构:通过修改HTML结构可以改变元素的嵌套关系,从而达到覆盖样式的目的。例如,将要覆盖样式的元素移到不受其他样式影响的位置。

  4. 使用内联样式:通过将样式规则直接写在元素的style属性中,可以覆盖外部样式表中的样式。但这种方法比较繁琐,而且不易维护。

  5. 使用CSS权重:CSS权重是指样式规则的优先级,根据选择器的权重大小来决定样式的应用顺序。可以利用选择器的权重来控制样式覆盖的顺序。

  6. 使用CSS预处理器:使用CSS预处理器(如Sass或Less)可以更方便地管理样式覆盖问题。预处理器提供了变量、混

<think>嗯,用户这次想了解后工程师面试中如何评估候选人是否匹配人才。从对话历史看,用户之已经详细询问过后工程师的职责和技能要求,现在明显进入了更落地的招聘实操层面。用户提供的三篇引用材料其实和当问题关联度不高:引用1讲软件测试面试题,引用2针对技术管理岗面试,引用3强调项目深挖技巧。不过这些材料倒暗示了用户可能需要的评估维度——既要考察技术硬实力(类似引用3的项目深挖),也要评估工程方法论(类似引用1的测试思维),甚至隐含了对管理潜力的关注(呼应引用2)。真正需要重点参考的是我上次关于后职责的系统回答。当时提到架构设计、接口开发、性能优化等核心能力,现在应该转化为可评估的面试指标。比如"可扩展系统设计能力"对应到面试中,可能需要候选人现场设计一个分布式系统。用户提问里特别强调"判断匹配人才的标准",说明ta关注的是人岗契合度,而非泛泛的面试技巧。这需要区分不同级别:初级岗更重基础编码和问题排查,高级岗则要看系统设计深度和解决方案的trade-off分析能力。注意到用户用词非常精准——"匹配人才"而非"优秀人才",暗示ta需要避免过度设计。有些候选人能滔滔不绝讲高并发方案,但实际岗位只是维护内部管理系统,这种错配反而浪费资源。所以评估标准必须结合业务场景。上次回复中提到的技术栈趋势(Java在金融电商占比高,Go适合高并发)也值得融入评估体系。如果面的是证券公司的后岗,却大谈Golang的协程优势,显然缺乏行业适配意识。安全方面上次只简单提了SQL注入防护,面试中其实需要深入考察:能否说清OAuth2的四种授权模式区别?是否知道JWT令牌如何防篡改?这些才是真实项目必须面对的细节。性能优化指标要量化。比如候选人说"用Redis提升QPS",应该追问具体数值和测试方法。参考上次案例中"秒杀系统QPS从1000到5万"的表述,这才是可信的交付能力。突然想到用户可能是技术主管或HRBP——因为ta问的是"如何判断"而非"如何准备"。回复应该提供可直接落地的评估工具,比如设计题评分表(架构合理性30%+扩展性20%+容错设计15%...),这样下周就能用在面试里。最后要注意避免理论化。与其说"考察系统设计能力",不如直接给题:"设计一个支持千万级用户的短链服务,请描述存储方案和API防刷机制"。然后附上评分要点:短链算法选择(哈希vs发号器)、数据库分片策略、限流配置阈值等。</think>根据技术团队的实际招聘标准和行业实践,后工程师面试评估候选人匹配度通常从以下五个维度展开,并采用具体评估方法: --- ### 一、技术能力深度评估(占比40%) 1. **编码实战测试** - 现场实现核心算法(如红黑树插入)或系统模块(分布式ID生成器) - 评估点:代码健壮性($\text{异常处理覆盖率} \geq 90\%$)、时间复杂度优化能力 *示例:要求用 Golang 实现带超时控制的并发任务调度器[^3]* 2. **系统设计推演** - 设计高并发系统(如10万QPS的支付系统) - 评估点:数据库分片策略、缓存穿透解决方案、服务降级机制 $$ \text{系统评分} = 0.3 \times \text{扩展性} + 0.4 \times \text{容错性} + 0.3 \times \text{成本控制} $$ 3. **运维问题诊断** - 分析服务器CPU飙升的线程堆栈文件 - 评估点:快速定位死锁/内存泄漏的能力(需在15分钟内给出解决方案) --- ### 二、工程方法论验证(占比25%) | 评估方向 | 具体方法 | |----------------|-------------------------------------------------------------------------| | **代码质量** | 审查其GitHub项目:单元测试覆盖率($\geq 70\%$)、CI/CD流水线设计合理性 | | **技术选型** | 对比方案优劣(如Kafka vs RabbitMQ选型,需说明吞吐量$\Delta$和消息可靠性) | | **安全防护** | 模拟攻击场景(如SQL注入Payload:`' OR 1=1--`),考察防御方案有效性 | --- ### 三、业务场景适配性(占比20%) 1. **领域建模能力** - 将电商订单业务转化为UML状态机(需包含超时自动取消等状态流转) $$ S_{\text{订单}} = \{ \text{待支付}, \text{已支付}, \text{配送中}, \text{已完成} \} \cup \Delta_{\text{异常状态}} $$ 2. **需求拆解逻辑** - 给定模糊需求(如“提升系统性能”),要求输出可执行方案(需包含量化指标) --- ### 四、软技能评估(占比10%) 1. **协作沟通** - 模拟跨团队冲突场景(如前端要求2天交付接口,实际需5天) - 评估解决方案的共赢性 2. **技术决策表达** - 口头描述技术方案时能否用$O(n\log n)$等专业表述替代“比较快”等模糊描述 --- ### 五、文化匹配度(占比5%) - **技术热情**:对开源贡献、技术博客等非强制项的关注度 - **学习路径**:考察技术栈更新轨迹(如从Spring Boot到Quarkus的转型动机) > 某头部互联网企业实际评估公式: > $$ \text{匹配度} = \frac{\sum_{i=1}^5 \text{维度分} \times \text{权重}}{ \text{岗位基准分} } \times 100\% $$ > 候选人需总分$\geq 85$分且任一核心维度(技术/工程)$\geq 80$分方可通过[^1][^2]。 --- ### 典型评估流程 ```mermaid graph TD A[简历筛选] --> B[技术笔试:算法+SQL] B --> C{笔试≥80分?} C -->|是| D[架构设计面试] C -->|否| E[淘汰] D --> F[编码实操测试] F --> G[系统运维场景模拟] G --> H[业务需求拆解] H --> I[跨团队协作模拟] I --> J[综合评估] ``` --- ### 高频淘汰原因分析 1. **技术深度不足**:无法解释MySQL索引最左匹配原则的底层实现(B+树结构) 2. **工程思维缺失**:提议用Redis持久化替代数据库,忽略AOF性能损耗 3. **业务敏感度低**:设计IM系统时未考虑消息时序性(导致“先收到撤回后收到消息”) 建议候选人重点强化分布式系统原理和领域驱动设计(DDD)能力,这两项在2023年头部企业面试中的考核权重提升达35%[^2]。 ---
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值