前言
我愿称这篇为本校招小倒霉(为什么倒霉就不细说了,抱怨无用,干就完事)睁眼看世界的收获(残酷但收获满满),分享金三银四过程中遇到的真实前端校招、社招笔试+面试考题,小、中、大厂考题均有。
暂时不囊括我遇到的算法相关题目,后续有时间再来补上。
这里按知识类别整理成博文,仅供参考。
后续本篇博文也会根据我的面试笔试情况持续更新补充,欢迎关注我👏🏻
关键词:前端笔试、面试
HTML
如何理解 HTML 语义化?
概念
语义化是指 代码语义化 及 内容结构化(也就是内容语义化)选择合适的标签(语义化标签)放到对应的位置,总的来说就是 对的人做对的事。
好处
1.提高代码可读性和代码结构性
2.有利于SEO(搜索引擎优化)
3.语义化还支持读屏软件根据文章自动生成目录
常见语义化标签
<header></header>
定义文档头部
<nav></nav>
定义导航栏
<section></section>
区块(有语义的div)
<main></main>
主要区域
<article></article>
主要内容
<aside></aside>
侧边栏
<footer></footer>
底部
script 标签中 defer 和 async 的区别?
<script defer>
表示把脚本推迟到文档渲染完毕后再执行。推迟的脚本原则上按被列出的次序执行。
<script async>
表示脚本不需要等待其他脚本,同时也不阻塞文档渲染,即异步加载,异步脚本不能保证次序执行。
<script>
补充:
<noscrpt>
可以指定在浏览器不支持脚本时的显示内容,若浏览器支持并启用了脚本,<noscrpt>
元素中任何内容都不会被渲染。
谈谈meta元素及相关使用
这一题可以看看其他博主总结的这篇:
CSS
实现垂直居中(定高与不定高度)
可以看这篇,博主总结的很好 面试官:你能实现多少种水平垂直居中的布局(定宽高和不定宽高)
CSS选择器优先级
这里有一个通过权重来计算css选择器优先级的概念 面试官:请说下CSS选择器优先级
介绍下你所了解的这些单位以及这些单位的区别:px em rem vw vh
参考资料:px rem em vh vw之间的区别到底是啥? 主要清楚px是绝对单位,其他是相对单位及相关的使用方式即可。
手写双飞翼布局
可以看看这篇:【CSS】这次带你彻底搞清楚经典的 双飞翼布局 与 圣杯布局 - margin负值 - 浮动 - padding
谈谈你所了解的盒模型
基本概念
- 标准模型+IE模型,包括margin,border,padding,content 区别
- IE盒模型的width/height = content + border + padding
- 标准盒模型的width/height = content
css如何改变盒模型
- content-box(默认值): 标准盒模型
- border-box: 怪异模式:width = border + padding + 内容的width,height = border + padding + 内容的height。
- inherit: 规定应从父元素继承 box-sizing 属性的值
谈谈BFC
概念 BFC(Block formatting context)直译为"块级格式化上下文"。它是一个独立的渲染区域,只有 Block-level box 参与,它规定了内部的 Block-level Box 如何布局,并且与这个区域外部毫不相干。 特点
- BFC元素垂直方向边距发生重叠,属于不同BFC外边距不会发生重叠
- BFC元素不会与浮动元素的布局重叠
- BFC元素是一个独立的容器,外面的元素不会影响里面的元素,里面的也不会影响外面的
- 计算BFC高度的时候,浮动元素也会参与计算(清除浮动) 如何创建BFC
- overflow不为visible
- float值不为none
- position值不为static或者relative
- display属性为inline-blocks,table,table-cell,table-caption,flex,inline-flex
伪元素和伪类的区别与联系
参考资料:一篇搞清伪类和伪元素
伪元素在CSS3
之前就已经存在,只是没有伪元素的说法,都是归纳为伪类,所有很多人分不清楚伪类和伪元素。比如常用的:before
和:after
,它们是伪类还是伪元素?其实在CSS3
之前被称为伪类,直到CSS3
才正式区分出来叫伪元素
那如何区分伪元素和伪类,记住两点:
1. 伪类表示被选择元素的某种状态,例如:hover
2. 伪元素表示的是被选择元素的某个部分,这个部分看起来像一个独立的元素,但是是"假元素",只存在于css中,所以叫"伪"的元素,例如:before
和:after
核心区别在于,是否创造了“新的元素”]
JavaScript 基础
谈谈你所了解的JS数据类型
JavaScript中所有对象都是都是Object的实例么?请举例说明。
不是的,如BOM和DOM对象,Bom和Dom是外部规定的,他们可以遵守也可以不遵守ECMA的规定。所以他们的内置对象可能是Object的实例,也可能不是。
var a = {n: 1};var b = a;a.x = a = {n:2};请问a = ? b = ? a.x = ?
这个问题其实在考察js的连等赋值机制,需要我们理解:
- 内存的的运行机制
- JS引擎的解析过程,从左往右
- 连等赋值的执行方向,从右往左
var a = {n: 1};
var b = a;
a.x = a = {n:2};
console.log(a.x); //undefined
console.log(a); // {n: 2}
console.log(b); // {n: 1, x: {n: 2}}
具体可参考:wancheng7.github.io/post/c080ee…
JavaScript 手写
手写防抖节流
手写promise.all
手写深拷贝
手写解析URL(API调用)
计算机网络
GET方法和POST方法有啥区别
默认的http请求的内容, 在网络中传输, 明文的形式传递的 (https 对内容加密)
GET方法 | POST方法 | |
---|---|---|
数据传输⽅式 | 通过URL传输数据 (地址栏拼接参数) | 通过请求体传输 |
数据安全 | 数据暴露在URL中,可通过浏览历史记录、缓存等很容易查到数据信息 | 数据因为在请求主体内, 所以有⼀定的安全性保证 |
数据类型 | 只允许 ASCII 字符 | ⽆限制 |
GET⽆害 | 刷新、后退等浏览器操作是⽆害的 | 可能会引起重复提交表单 |
功能特性 | 安全且幂等(这⾥的安全是指只读特性,就是使⽤这个⽅法不会引起服务器状态变化。幂等的概念是指同⼀个请求⽅法执⾏多次和仅执⾏⼀次的效果完全相同) | ⾮安全(会引起服务器端的变化)、⾮幂等 |
HTTP的迭代发展(每一代的区别与联系)
可以看看这篇,写的详细明晰: HTTP1、HTTP2、HTTP3
HTTP如何实现的长连接
参考资料:HTTP长连接实现原理
长连接概念
-
浏览器向服务器进行一次HTTP会话访问后,并不会直接关闭这个连接,而是会默认保持一段时间,那么下一次浏览器继续访问的时候就会再次利用到这个连接。
-
在
HTTP/1.1
版本中,默认的连接都是长连接,我们可以通过Connection: keep-alive
字段进行指定。 实现
HTTP协议本质是OSI七层参考模型中的应用层协议,而网络进行通信的时候都是通过上层协议封装头部后作为下层协议的数据部分进行封装的,而实际中我们经常接触的是TCP/IP协议簇,也就是传输层利用TCP协议和网络层利用IP协议。因此HTTP协议的长连接本质上就是TCP的长连接。 而TCP可以通过保活机制实现长连接,详情请看参考资料。
HTTPS为什么安全
HTTPS
的全称是 Hypertext Transfer Protocol Secure
,它用来在计算机网络上的两个端系统之间进行安全的交换信息(secure communication)
,它相当于在 HTTP 的基础上加了一个 Secure 安全
的词眼,那么我们可以给出一个 HTTPS 的定义:HTTPS 是一个在计算机世界里专门在两点之间安全的传输文字、图片、音频、视频等超文本数据的约定和规范。 HTTPS 是 HTTP 协议的一种扩展,它本身并不保传输的证安全性,那么谁来保证安全性呢?在 HTTPS 中,使用传输层安全性(TLS)
或安全套接字层(SSL)
对通信协议进行加密。也就是 HTTP + SSL(TLS) = HTTPS。
具体建议大家看这篇:
看完这篇 HTTPS,和面试官扯皮就没问题了
一个完整的URL包括什么内容
首先我们需要知道URL是什么: URL一般指统一资源定位系统。 统一资源定位系统(uniform resource locator;URL)是因特网的万维网服务程序上用于指定信息位置的表示方法.
一个具体的URL具体包括: 协议+域名+端口号+路径与请求的参数
常用状态码详解
常用的HTTP状态码列表
状态码 | 状态码英文名称 | 中文描述 |
---|---|---|
200 | OK | 请求成功 。一般用于GET与POST请求 |
204 | No Content | 无内容。服务器成功处理,但未返回内容 。在未更新网页的情况下,可确保浏览器继续显示当前文档 |
206 | Partial Content | 是对资源某一部分的请求 ,服务器成功处理了部分GET请求,响应报文中包含由Content-Range指定范围的实体内容。 |
301 | Moved Permanently | 永久性重定向 。请求的资源已被永久的移动到新URI,返回信息会包括新的URI,浏览器会自动定向到新URI。今后任何新的请求都应使用新的URI代替 |
302 | Found | 临时性重定向 。与301类似。但资源只是临时被移动。客户端应继续使用原有URI |
303 | See Other | 查看其它地址 。与302类似。使用GET请求查看 |
304 | Not Modified | 未修改。所请求的资源未修改,服务器返回此状态码时,不会返回任何资源。客户端通常会缓存访问过的资源,通过提供一个头信息指出客户端希望只返回在指定日期之后修改的资源 |
307 | Temporary Redirect | 临时重定向 。与302类似。使用GET请求重定向,会按照浏览器标准,不会从POST变成GET。 |
400 | Bad Request | 客户端请求报文中存在语法错误,服务器无法理解 。浏览器会像200 OK一样对待该状态吗 |
401 | Unauthorized | 请求要求用户的身份认证 ,通过HTTP认证(BASIC认证,DIGEST认证)的认证信息,若之前已进行过一次请求,则表示用户认证失败 |
402 | Payment Required | 保留,将来使用 |
403 | Forbidden | 服务器理解请求客户端的请求,但是拒绝执行此请求 |
404 | Not Found | 服务器无法根据客户端的请求找到资源(网页)。通过此代码,网站设计人员可设置"您所请求的资源无法找到"的个性页面。也可以在服务器拒绝请求且不想说明理由时使用 |
500 | Internal Server Error | 服务器内部错误,无法完成请求 ,也可能是web应用存在bug或某些临时故障 |
501 | Not Implemented | 服务器不支持请求的功能,无法完成请求 |
503 | Service Unavailable | 由于超载或系统维护,服务器暂时的无法处理客户端的请求 。延时的长度可包含在服务器的Retry-After头信息中 |
存储
谈谈你所了解的cookie、session、localStorage、sessionStorage的区别与联系
参考资料:理解cookie、session、localStorage、sessionStorage的关系与区别
浏览器
进程和线程的区别与联系
进程是 CPU 资源分配的最小单位(是能拥有资源和独立运行的最小单位) 对于操作系统来说,一个任务就是一个进程,比如打开一个浏览器就是启动了一个浏览器进程,打开一个 Word 就启动了一个 Word 进程。
线程是 CPU 调度的最小单位(是建立在进程基础上的一次程序运行单位) 有些进程同时不止做一件事,比如 Word,它同时可以进行打字、拼写检查、打印等事情。在一个进程内部,要同时做多件事,就需要同时运行多个“子任务”,我们把进程内的这些“子任务”称为线程。
详细聊聊你所了解的浏览器的多进程
这个建议大家通过chrome提供的工具实际感受下:
打开更多工具中的任务管理器即可知道当前你的浏览器正在运行什么进程:
这里列一个浏览器包含的线程列表:
- 主进程 Browser Process
- 渲染进程 Renderer Process (也称之为浏览器内核)
- 第三方插件进程Plugin Process
- GPU进程 GPU Process
- 网络进程 network process
- 存储进程 storage process
- 设备进程 device process
为什么js是单线程的
单线程就意味着不能像多线程语言那样把工作委托给独立的线程或进程去做。JavaScript 的单线程可以保证它与不同浏览器 API 兼容。假如 JavaScript 可以多线程执行并发更改,那么像 DOM 这样的 API 就会出现问题。 ——《JavaScript高级程序设计(第4版)》
讲一讲你了解到的事件循环(分浏览器+nodejs说)
参考资料:阿里一面:熟悉事件循环?那谈谈为什么会分为宏任务和微任务。
Vue
Vue传值方式一览
props
和 $emit + v-on
通过 props
将数据在组件树中进行⾃上⽽下的传递;
通过 $emit
和 v-on
来作信息的向上传递。
父与子通讯:
父传子数据如果原始值,不可修改,如果是引用值,只要不修改它的引用地址,改里面的属性都是可以的,
如果某些数据希望父子双向绑定,只需要传一个引用值
堆随便修改,栈不可修改
2.x v-model
子组件标签 :value="faterValue" @input="faterValue=$event" v-model="faterValue"
子组件
props:['value123']
model:{
prop:'value123',
event:'input123'
},
this.$emit('input123',希望修改后的值)
3.x v-model
子组件标签 v-model='faterValue' :modelValue="faterValue" @update:modelValue="faterValue=$event"
子组件内
props:['modelValue']
修改
setup(props,{emit}){
emit('update:modelValue',希望修改后的值)
}
EventBus
可通过 EventBus 进⾏信息的发布与订阅。
vue2.x
Vue.prototype.$bus=new Vue()
监听: this.$bus.$on('事件名',(形参)=>{})
触发: this.$bus.$emit('事件名',参数)
销毁: this.$bus.$off('事件名')
Vuex
全局状态管理库。可通过它来进行全局数据流的管理。
$attrs
和 $listeners
在 Vue 2.4 版本中加⼊的 $attrs
和 $listeners
可以用来作为跨级组件之间的通信机制。
谈谈你所了解的Vue的生命周期
生命周期 | 阶段 | 描述 |
---|---|---|
beforeCreate | 创建前 | 进行数据和方法的初始化( 生命周期为创建前的时候el和data都还没有初始化,所以也不能访问 data、computed、 watch、 methods的方法和数据) |
created | 创建后 | 已经完成数据和方法的初始化(生命周期为创建后的时候,data初始化完成了已经,像data、computed、watch、methods上的方法和数据都是可以访问的。但是el还不能访问,这个时候可以做一些初始化的代码,比如进行axios请求等 (但是这个时候页面还没有被渲染出来,如果请求时间过长的时候会出现白屏的状态) |
beforeMount | 模板载入前 | 开始渲染dom(当生命周期为挂载前的时候,data和el都已经完成了初始化,但是页面中的内容还是Vue 的占位符,data里面的数据还没有挂载到dom节点上) |
mounted | 模板载入后 | 可以渲染dom(当生命周期是挂载后的时候,el已经挂载好了,将上一个阶段写好在内存中的虚拟dom真正挂载到页面上。可以进行dom操作) |
beforeUpdate | 组件更新前 | 组件更新之前调用 |
updated | 组件更新后 | 组件更新之后调用 |
beforeDestroy | 组件销毁前 | 实例即将被销毁(当生命周期为销毁前的时候,此时实例还在还是可以做操作的,在这里可以做一些,移除监听啊,事件解绑什么的。) |
destroyed | 组件销毁后 | 实例已经被销毁( 当生命周期为销毁后的时候,整个生命周期已经完成了销毁,生命周期数据与视图之间的关系将会断开 这就是差不多在面试的时候你需要说出来的点,特别是Created ,Mounted ,BeforeDestroy 这三个生命周期问得最多,一个是完成初始化,一个是dom加载完成,一个是销毁之前。) |
分享一篇带实例验证的博文,开箱即用: 11、Vue的生命周期执手天涯@的博客-CSDN博客vue的生命周期
因为博主也是uniapp玩家,所以这里也Po一下我看到的其他博主整理的uniapp生命周期与vue生命周期的对比: uniapp的生命周期及其和vue生命周期的对比 - huihuihero - 博客园
谈谈你所了解的Vue Router(路由机制)
这种谈一谈类型可以挑你熟悉的点入手:vue路由概念、嵌套路由、路由视图、动态路由、路由匹配、编程式导航、history、hash模式管理、命名视图、重定向与别名、导航守卫、路由元信息、滚动与懒加载、导航故障处理
谈谈你所了解的Vue3(这里重点其实是聊你所知道的与Vue2的区别)
因为面试前并没有使用过Vue3,所以更多的是参考文档和博客去对比体验,我参考的是这篇:聊一聊 Vue3 的 9 个知识点
React
目前正在自学React中(后续的工作技术栈也是React),但是简历里没有react相关项目所以被问到的比较少,后续有机会来补充。
React与Vue的区别说说看
谈区别的话当然是抓住核心要点展开谈区别,这里也推荐一篇我觉得比较好的谈区别的文章: 前端框架用vue还是react?清晰对比两者差异
node
node中间件的作用有
首先需要弄清楚什么是node中间件:中间件就是请求req和响应res之间的一个应用
作用:对于Web应用而言,我们并不希望了解每一个细节性的处理工作,而是希望能够把主要精力集中在业务的开发上,以达到提升开发效率的目的, 所以引入了Node中间件来简化和封装这些基础逻辑处理细节。node中间件本质上就是在进入具体的业务处理之前,先让特定过滤器处理。
参考资料:深入浅出node中间件原理
模块导入
link与@import导入的区别
简要概括下:
link是异步操作->遇到link不会开辟新的HTTP线程去获取资源 GUI继续渲染页面;
@import是同步的->GUI渲染页面的时候遇到@import会等它获取新的样式回来后继续渲染
CommonJS 和 ES6 Module 区别?
可以看这篇: CommonJS 和 ES6 Module 究竟有什么区别?
协作工具
git fetch和git pull的区别,直接git pull可能会发生什么?
git pull 相当于 git fetch 和 git merge,即更新远程仓库的代码到本地仓库,然后将内容合并到当前分支。
git merge: 将内容合并到当前分支。
git pull 相当于是从远程获取最新版本并 merge 到本地命令从中央存储库中提取特定分支的新更改或提交,并更新本地存储库中的目标分支。
git fetch 相当于是从远程获取最新版本到本地,不会自动 merge。当你执行 git fetch 时,它会从所需的分支中提取所有新提交,并将其存储在本地存储库中的新分支中。
直接git pull可能会导致本地代码被覆盖或者出现无法从远程更新的情况,合理的做法是先git stash或git add本地改动+git commit再git pull。
如果让你实现一个git,你会想怎么实现
说实话当时拿到这到题目的时候我挺是懵的,但是现在回过头来看面试官其实考察的是你对git的实现原理的了解程度,这里po一个其他博主的简单实现。 git原理学习记录:从基本指令到背后原理,实现一个简单的git
性能优化
防抖节流的应用场景以及为什么他们能实现性能的优化
参考资料:7分钟理解JS的节流、防抖及使用场景
requestAnimationFrame有所了解吗
参考资料:【今天你更博学了么】一个神奇的前端动画 API requestAnimationFrame
不同类型图片的特点及使用场景
针对这个问题我们需要知道的是有什么类型以及每个类型的特点,可以看看下面这篇: 聊一聊几种常用web图片格式:gif、jpg、png、webp
格式 | 优点 | 缺点 | 适用场景 |
---|---|---|---|
gif | 文件小,支持动画、透明,无兼容性问题 | 只支持256种颜色 | 色彩简单的logo、icon、动图 |
jpg | 色彩丰富,文件小 | 有损压缩,反复保存图片质量下降明显 | 色彩丰富的图片/渐变图像 |
png | 无损压缩,支持透明,简单图片尺寸小 | 不支持动画,色彩丰富的图片尺寸大 | logo/icon/透明图 |
webp | 文件小,支持有损和无损压缩,支持动画、透明 | 浏览器兼容性不好 | 支持webp格式的app和webview |
设计模式
常考的如单例模式、观察者模式、发布-订阅模式、命令模式都可以去了解加体验一下。 这里po一个集锦: 前端渣渣唠嗑一下前端中的设计模式(真实场景例子)
项目+相关概念
前后端做了什么样的性能优化、如何量化我们实现的性能优化
这里我是根据自己的实际开发情况以及修言前辈写的一本小册《前端性能优化原理与实践》总结的自己的回答。
前端的话主要是通过不同图片的合理使用、合理使用客户端存储、精简前端代码、添加防抖节流等方式优化性能,通过计算首屏渲染时间实现量化。(建议各位从网络、存储、渲染等方面考虑自己做过的前端方向的性能优化)
后端的话是建立合适的索引以及尽量避免联表查询而是使用批处理,加快查询速度,通过计算取数据函数的耗时实现量化。
Vue开发中遇到的困难以及对应的解决方式?
这个的话见仁见智,可以依据自己在项目中遇到的问题具体回答,这里提供一个潜在问题列表。 Vue 项目里戳中你痛点的问题及解决办法(更新)
前后端分离的概念与优劣?
参考资料:前后端分离开发模式介绍_dakesong的博客-CSDN博客_前后端...
概念 前后端分离是目前一种非常流行的开发模式,它使项目的分工更加明确:
- 后端:负责处理、存储数据
- 前端:负责显示数据
前端和后端开发人员通过 接口 进行数据的交换。
优点
1.前后端可以身心愉快地专注于各自擅长的领域
2.避免后端写前端代码(基本上1天时间,20%写后端代码,80%写页面…)
3.前端配置后端代码运行环境(简直是要疯… 装一堆环境,而且有些开发环境是windows,前端是macos,装环境就要装好几天)
4.避免前后端产生矛盾…
5.提高开发效率
6.分离有助于前端大放异彩,后端专注于三高(高并发、高性能、高可用)
缺点
1.当接口改变的时候,非常麻烦
2.需要前后端人员联调–联调开发的时间(开发+测试+联调)占项目的 15%–60%
其他
正则相关
推荐参考资料:就因为这三个知识点,我彻底学废了”正则表达式“ 讲的很明晰
正则基本概念
正则表达式是匹配模式,要么匹配字符,要么匹配位置
手写一个手机号的正则
当前可以是任意字符(小数点)
? 表示零次或一次
* 表示零次或多次
+ 表示一次或多次
() 对某个存在的正则进行分组 组的使用 \组号 $组号
{} 当前的规则可以出现的次数
{2} 正好 2次 {m,} 最少m次 {m,n} 最少m次 最多n
[ ] 当前位置上可以是中括号中某个字符
[abc] [^abc]
\\d 当前位置上可以数字
当前位置上可以是字母 数字 下划线
\b 单词边界
^ 行开始
$ 行结尾
function isLeagalMobile(mobile){
let mobileReg = new RegExp("^1[3578]\\d{9}$");
if(mobileReg.test(mobile)){
return true;
}
return false;
}
console.log(isLeagalMobile(110)); // false
console.log(isLeagalMobile(13711111111));// true
找工作感受分享
很多时候并不是凭借努力就能达到目标,合适的努力才更有可能让自己达到理想的效果。举个例子,面试A公司该司需要的是A方向的知识,那其实为了提高面试效率我们应该在面试前应该提前了解并准备好A方向的相关项目(如果有的话)。
以及除了上述的面试前在合适方向上的准备外,更重要的还是日常在前端领域的积累,尤其是想进大厂的朋友们,建议务必提前感知该厂算法难度并提前大量训练。个人认为有选择的输入并通过项目或博客实战性的倒闭输出才能做到真正游刃有余。
最后通过大量的面试也发现自己在前端领域确实还有很多可以学习和深耕的内容,期待后续在真实的工作岗位能有更广更深更扎实的学习。
未完待续
在此想感谢一起讨论技术的大家对我的支持、鼓励以及耐心的催更~!这里只是先放出一部分题目加解析,后续会不断填坑位并加入新鲜内容的。
分享一句很喜欢的话:“人生唯一确定的就是不确定的人生,对于可控的事情要保持谨慎,对于不可控的事情要保持乐观。人只能做自己能力范围内的事情,要接受这个事实,并且以乐观的心去应对这一切。 ”
祝大家都能早日斩获心仪的offer,已有工作的可以一份耕耘就一份甚至多份收获。
也希望这篇文章像能帮到我一样帮到你,我们很快再见👋🏻