前端面试题积累 - 持续更新

174 阅读18分钟

1. 对语义化的理解(HTML ⭐)

用正确的标签做正确的事,有三个优势

  • 一是代码结构清晰,可读性高,方便维护,利于开发
  • 二是方便爬虫根据语义标签确定页面结构关键字的权重,利于SEO
  • 三是对于使用辅助技术(如屏幕阅读器)的用户来说,语义化标签能提供更多上下文信息,帮助用户理解和使用网页,优化用户体验

image.png

语义化标签:header、nav、aside、main、section、article、footer、canvas、video、audio

image.png

canvas标签的使用

媒体元素:video、audio

2. 移动端为什么添加meta viewport, 怎么写?(HTML ⭐)

作用:防止在移动端可以缩放 写法:

  <meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no">
  • 使用 viewport 来控制浏览器视口的宽度和缩放比例
  • 添加 width=device-width 以便让视口的宽度与设备一致
  • 添加 initial-scale=1.0 设置初始缩放比例为1.0
  • 添加 user-scalable=no 使得用户不能放大或缩小网页
    • minimum-scale=1.0, maximum-scale=1.0 是为了兼容ios10(不支持 user-scalable 导致用户仍可缩放)

3. 盒模型(CSS ⭐) MDN#怪异模式和标准模式

  • W3C标准盒模型

块总宽度 = 内容宽度(content) + margin(左右)+ padding(左右)+ border(左右)

  • IE怪异盒模型

块总宽度 = width(padding和border)+ margin(左右)

如果html顶部DOCTYPE缺失,在ie6、ie7、ie8就会触发怪异模式(Quirks mode) image.png

通过css box-sizing 来设置盒模型

image.png

image.png

代码示例

应用场景:需要盒子所占宽度为160px,边框1px和内边距10px的盒子时,设置box-sizing为border-box,不需要人为计算content宽度。

4. let,const,var比较(JS ⭐)

  • let和const是块级作用域,var是全局作用域或函数作用域。
  • var存在变量提升,let和const有暂时性死区
    • 变量提升:js预编译时,将var声明的变量提升到函数作用域最顶部
    • 暂时性死区:只有等到变量赋值成功后才能使用

gitee.com/carrierxia/…

  • var可以重复声明,let和const不行
  • var和let可以不用设置初始值,const要
  • let声明的变量可以更改指针指向,const不行
  • var在全局作用域声明的变量会挂载在window上
    • 在es5规定 顶层对象属性和全局变量等价,var和function声明的全局变量也是顶层对象
    • 在es6规定 var,function声明全局变量,依旧是顶层对象的属性;let,const,class声明的全局变量,不属于顶层对象的属性

image.png

5. http常见的状态码有哪些(HTTP ⭐)

1XX 消息
2XX 成功
3XX 重定向
4XX 客户端错误
5XX 服务端错误

200:请求成功
301:永久重定向(SEO友好,搜索引擎会把旧URL的权重转移到新URL,有助于新URL在搜索结果中排名)
302:临时重定向(搜索引擎不会把原URL的权重转移到新URL,而是将权重保留在原URL上)
304:自上次请求,未修改文件
400:请求无效错误
401:未授权,需要身份验证
403:请求被拒绝
404:资源缺失,接口不存在或请求的文件不存在等
500:服务端的未知错误
502:网关错误
503:服务暂时无法使用

6. cookie、session、localStorage、sessionStorage分别是?(浏览器 ⭐⭐)

cookie:存储在浏览器上的一小段数据,用来记录当页面关闭或刷新后仍要记录的信息(客户端会话跟踪技术)。

session:用户输入账号密码提交给服务端,服务端在验证通过后创建一个session记录用户相关信息。这个session可保存在服务器内存中或保存在数据库。

localStorage、sessionStorage:HTML5本地存储web storage特性的api,用于将数据保存在浏览器中。localStorage用于长期存储数据(5M,最大5M-10M,因浏览器而异),没有时间限制的数据存储,除非手动清除。sessionStorage临时存储会话数据(5M,最大几百KB-几MB,因浏览器而异),在浏览器关闭后数据会丢失。

7. cookie、localStorage、sessionStorage区别;cookie和session的区别(浏览器)

用途存储大小有效期
cookie用于客户端和服务端间的信息传递;服务器发给浏览器保存的(字符串)数据,一般用来记录用户信息,方便服务端确认用户身份4K默认关闭浏览器失效
localStorage本地存储,保存一些不太重要的数据,例如用户坐标、购物车信息等5M永久,除非js手动清除或清除浏览器缓存
sessionStorage本地存储,保存一些不太重要的数据,例如用户坐标、购物车信息等5M页面不关闭就不失效,重新加载或恢复页面也不失效。但在新标签或窗口打开一个页面会重新生成。(会话级别)

cookie和session都是用来确认用户身份的。区别在于cookie保存在客户端,session保存在服务端。另外session是基于cookie的(服务器端生成session后,让客户端的cookie代为保存sessionID)

segmentfault.com/a/119000001…

思考:cookie禁用了,session还能用吗?

image.png

8. cookie的使用(浏览器 ⭐)

红宝书第4版751页

      const name = 'username';
      const value = 'ceshi';
      document.cookie = 'age=18'; // 设置:每次只能设置一对cookie
      document.cookie = `${name}=${value}`;
      const cookie = document.cookie; // 获取:获取cookie值, 获取特定的用循环
      console.log(cookie);

      // 删除:设置过期时间为过去的日期
      // document.cookie = 'username=ceshi1;expires=Thu, 01 Jan 1970 00:00:00 GMT;';

      const exp = new Date();
      exp.setTime(exp.getTime() + 2 * 60 * 1000); // 过期时间 2min
      document.cookie = `${name}=${escape(value)};expires=${exp.toUTCString()}`; // 过期时间需要GMT格式
      console.log(`${name}=${escape(value)};expires=${exp.toUTCString()}`);

如果不在浏览器中设置过期时间,cookie被保存在内存中,生命周期随浏览器的关闭而结束(这种cookie简称会话cookie)
如果在浏览器中设置了cookie的过期时间,cookie被保存在硬盘中,关闭浏览器后,cookie数据仍然存在,直到过期时间结束才消失

image.png

9. watch和computed的区别(Vue ⭐)

  • watch监听动作,computed是计算属性
  • watch没缓存,数据变化就执行。computed有缓存,只在属性变化的时候才计算
  • watch可以执行异步操作,computed不能
  • watch常用于一个数据影响多个数据,computed常用于多个数据影响一个数据

10. git reset和revert的区别(Git ⭐)

是用于撤销回滚提交的两个操作。使用 git reset 回滚后历史记录会被更改,需要用 git push -f 强制推送到远程分支,谨慎使用;git revert 则是创建新的提交,历史记录保留。

git reset 有以下几种模式:常用 --mixed(默认,指定的 commit-hash 之后提交保留到工作区), --soft(指定的 commit-hash 之后提交保留到暂存区,工作区不变), --hard(指定的 commit-hash 之后提交都移除不保留)

错误使用了 git reset --hard <commit>,可以使用 git reflog 找到要回滚的提交记录hash,重新使用git reset命令进行回滚。

git 的 reflog 不是一个持久的日志记录系统(Git不会限制reflog的大小,它会不断增长,直到你的存储空间耗尽),可以通过 git reflog expire 命令设置过期规则。

git reset -h
usage: git reset [--mixed | --soft | --hard | --merge | --keep] [-q] [<commit>]
   or: git reset [-q] [<tree-ish>] [--] <pathspec>...
   or: git reset [-q] [--pathspec-from-file [--pathspec-file-nul]] [<tree-ish>]
   or: git reset --patch [<tree-ish>] [--] [<pathspec>...]
   or: DEPRECATED: git reset [-q] [--stdin [-z]] [<tree-ish>]

    -q, --quiet           be quiet, only report errors
    --mixed               reset HEAD and index
    --soft                reset only HEAD
    --hard                reset HEAD, index and working tree
    --merge               reset HEAD, index and working tree
    --keep                reset HEAD but keep local changes
    --recurse-submodules[=<reset>]
                          control recursive updating of submodules
    -p, --patch           select hunks interactively
    -N, --intent-to-add   record only the fact that removed paths will be added later
    --pathspec-from-file <file>
                          read pathspec from file
    --pathspec-file-nul   with --pathspec-from-file, pathspec elements are separated with NUL character
    -z                    DEPRECATED (use --pathspec-file-nul instead): paths are separated with NUL character
    --stdin               DEPRECATED (use --pathspec-from-file=- instead): read paths from <stdin>

image.png

# 设置reflog过期时间为7天
git reflog expire --expire=7
 
# 删除所有过期的reflog条目
git reflog expire --all
 
# 手动运行垃圾收集以清理过期的reflog条目
git gc

11. 如何做H5的响应式布局(HTML ⭐⭐)

创建H5(HTML5)响应式布局意味着要确保网页可以在不同的屏幕尺寸和设备上提供一致的用户体验,有以下方式:

  1. 使用视口标签:在HTML文件头部添加视口标签,确保页面在移动设备上正确缩放
<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no">
  • 使用 viewport 来控制浏览器视口的宽度和缩放比例

  • 添加 width=device-width 以便让视口的宽度与设备一致

  • 添加 initial-scale=1.0 设置初始缩放比例为1.0

  • 添加 user-scalable=no 使得用户不能放大或缩小网页

    • minimum-scale=1.0, maximum-scale=1.0 是为了兼容ios10(不支持 user-scalable 导致用户仍可缩放)
  1. 使用媒体查询:媒体查询是CSS的条件语句,允许根据不同的设备特性应用不同的样式,比如屏幕宽度
@media(max-width: 768px) {
    /* 在小屏幕上应用的样式 */
}
@media(min-width: 769px) {
    /* 在大屏幕上应用的样式 */
}
  1. 弹性字体大小:使用rem或em设置字体大小,基于父元素的大小自动调整字体大小
  2. 移动优化:使用CSS touch-action 和 JS 来增强移动用户体验,确保触摸事件和手势在移动设备上正常工作。
  3. 图片适应:使用 max-width: 100% 确保图片在小屏幕上不会溢出父容器。可以使用不同分辨率的图片(srcset)或者使用响应式图片插件来优化图片加载。
  4. 流式布局:使用流式布局技术,让内容适用不同屏幕宽度。例如,使用弹性盒子(Flexbox)或网格布局(CSS Grid)来调整元素的位置和大小。
  5. 弹性布局:使用相对单位(例如百分比)而不是绝对单位(像素)来设置宽度和高度,以使页面元素根据屏幕尺寸自动调整大小。

12. 绝对定位是相对于什么定位的(CSS ⭐)

CSS中,绝对定位相对于具有定位属性的祖先元素进行定位。 绝对定位的元素会忽略其在文档流中的位置,根据其祖先元素的位置来确定自己的位置,如果没有找到具有定位属性的祖先元素,就相对于最外层容器(通常是<body>元素)
祖先元素通常是具有定位属性的元素,例如:position:relativeposition:absoluteposition:fixed 等。

<div class="relative-box">
    <div class="absolute-box">这是绝对定位的元素</div>
</div>
.relative-box {
    position: relative;
    width: 200px;
    height: 200px;
    background-color: red;
}

.absolute-box {
    position: absolute;
    width: 20px;
    height: 20px;
    background-color: blue;
}

13. 水平垂直居中有几种实现方式?(CSS ⭐)

有6种实现方式:

  1. CSS居中
    水平居中: text-align:center 使文本水平居中;margin:0 auto 使块级元素水平居中。
    垂直居中: 设置容器和子元素高度,并使用 line-height、vertical-align 实现文本居中;块级元素使用Flexbox和Grid布局技术实现
  2. Flexbox居中
display: flex;
justify-content: center; /* 水平居中 */
align-items: center; /* 垂直居中 */
  1. Grid布局居中
display: gird;
place-items: center; /* 同时实现水平和垂直居中 */
  1. 绝对定位居中
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
  1. 表格居中(不常用)
  2. JS居中:使用js计算容器和元素的尺寸,然后动态设置元素的位置来实现水平和垂直居中

14. 随着屏幕缩放,图片能够自适应保持长宽比16:9或1:1,图片不能压缩,怎么实现(CSS ⭐)

.image-box {
    position: relative;
    width: 100%; /* 100%宽度以适应屏幕 */
    padding-top: 56.25%; /* 16:9 宽高比的容器使用 padding-top:100% */
}
img {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%; /* 图像宽度始终占满容器 */
    height: 100%; /* 图像高度始终占满容器 */
    object-fit: cover; /* 保持宽高比,不压缩图片,可能会裁剪图片以适应容器 */
}

15. CSS的相关权重(优先级)都有什么(CSS ⭐)

由高到低排序如下:

  1. 重要性(Importance):使用 !important 声明的样式规则具有最高的权重,无法被覆盖
  2. 内联样式(Inline Styles):直接在html元素上使用 style 属性设置的样式
  3. ID选择器(ID Selectors):例如 #myElement {}
  4. 类选择器(Class Selectors)、属性选择器(Attribute Selectors)、伪类选择器(Pseudo-class Selectors):例如 .myClass {}、[data-attribute="value"] {}、:hover {}
  5. 元素选择器(Type or Tag Selectors):例如 p {}
  6. 通配符选择器(Universal Selector):通配符选择器 * 具有较低的权重
  7. 继承(Inheritance):继承的样式规则的权重最低,因为它们不涉及选择器

当多个具有不用权重的样式规则应用同一个元素上时,具有更高权重的规则将覆盖具有较低权重的规则。使用过多 !important 可能会导致样式表难以管理和维护,谨慎使用。

16. 什么是圣杯布局?如何实现(HTML5+CSS3 ⭐)

圣杯布局时一种经典的网页布局模式,通常用于创建一个具有主内容区域、左侧边栏和右侧边栏的三栏布局。确保中间内容部分始终占据最大的空间,两边的侧边栏保持固定宽度,并且三栏布局在页面种垂直高度自适应。 image.png

使用flex实现:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>圣杯布局 - Flexbox</title>
    <style>
      * {
        padding: 0;
        margin: 0;
      }
      html,
      body {
        height: 100%;
      }
      .container {
        display: flex;
        height: 100%;
      }
      .main {
        flex: 1;
        padding: 20px;
        border: 1px solid red;
        border-radius: 10px;
        margin: 0 10px;
        color: red;
        font-weight: bold;
      }
      .left,
      .right {
        width: 200px;
        background-color: red;
        padding: 20px;
        border-radius: 10px;
        color: #ffffff;
        font-weight: bold;
      }
      .left {
        order: -1;
      }
    </style>
  </head>
  <body>
    <div class="container">
      <div class="left">左侧栏 定宽</div>
      <div class="main">主内容区 自适应</div>
      <div class="right">右侧栏 定宽</div>
    </div>
  </body>
</html>

17. 什么是双飞翼布局?如何实现(HTML5+CSS3 ⭐)

双飞翼布局也是三栏布局中的经典方式,主要目的是实现中间内容区域自适应,两侧的侧边栏保持固定宽度。
与圣杯布局的核心区别在于:双飞翼布局通常通过 绝对定位负边距 来实现布局。

image.png

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>双飞翼布局</title>
    <style>
      * {
        padding: 0;
        margin: 0;
      }
      html,
      body {
        height: 100%;
      }
      .container {
        position: relative;
        min-height: 100vh;
      }
      .main {
        margin: 0 200px; /* 为左右侧边栏预留200px空间 */
        height: 100vh;
        border: 1px solid red;
        border-radius: 10px;
        box-sizing: border-box;
        color: red;
        font-weight: bold;
      }
      .left {
        position: absolute;
        left: 0;
        top: 0;
        bottom: 0;
        width: 200px;
        background-color: red;
        color: #ffffff;
        font-weight: bold;
      }
      .right {
        position: absolute;
        right: 0;
        top: 0;
        bottom: 0;
        width: 200px;
        background-color: red;
        color: #ffffff;
        font-weight: bold;
      }
    </style>
  </head>
  <body>
    <div class="container">
      <div class="left">左侧栏 定宽</div>
      <div class="main">主内容区(其背景包括了左右两边) 自适应</div>
      <div class="right">右侧栏 定宽</div>
    </div>
  </body>
</html>

18. 实现自适应网站可以用哪些技术,css方向(CSS3 ⭐⭐⭐)

  1. 响应式布局:使用CSS网格布局、Flexbox布局或传统的盒模型创建布局,以确保页面的元素会根据屏幕大小和方向进行自适应调整。
  2. 媒体查询:使用媒体查询来检测设备的特性,如屏幕宽度、高度、方向等,然后为不同屏幕条件应用不同的样式。
  3. 弹性图片和媒体:使用 max-width:100% 或 width:100% 的CSS规则来确保图片和媒体元素能够根据其容器的宽度进行自适应调整,避免图片拉伸或溢出
  4. 相对单位:使用相对单位如百分比、em和rem,而不是绝对单位(px),以使文本和元素的大小相对于其父元素进行自适应调整。
  5. 流式布局:创建流式布局,使内容能够根据屏幕大小自动调整,而不会出现水平滚动条。这通常涉及百分比宽度、弹性盒模型和流式网格。
  6. 移动优先设计:设计网站时,优先考虑小屏幕设备(如移动手机),然后逐渐增加功能和样式以适应更大的屏幕。有助于确保在小屏幕上网站能更好地运行。
  7. 字体自适应:使用相对单位 rem 或 em 来设置字体大小,以便字体可以根据屏幕大小自适应调整,而不会变得太小或太大。
  8. CSS 网格布局:使用Grid布局来创建复杂的多列布局,以实现网站的自适应性
  9. CSS Flexbox布局:使用Flexbox布局来管理页面内的元素排列,使其能够自适应不同的容器尺寸。
  10. 字体图标和矢量图形:使用字体图标或矢量图形,以确保图标和图形在不同分辨率下都能清晰显示。

19. 伪元素和伪类的区别(CSS ⭐)

  1. 语法区别:伪类以单冒号(:)开头,而伪元素以双冒号(::)开头。
  2. 功能区别:伪类用于选择元素的特定状态或位置,而伪元素允许在元素的特定位置创建虚拟的元素。
  • 伪元素(Pseudo-elements)
    作用:用于在元素的特定位置插入虚拟的元素,允许样式化文档中的某些部分,比如 ::before(在元素内容前插入内容)、::after(在元素内容后插入内容)等。 语法:双冒号(::)开头,紧跟伪元素的名称

  • 伪类(Pseudo-classes) 作用:用于选择元素的特定状态或位置,比如 :hover(鼠标悬停时)、:active(激活状态)、:first-child(第一个子元素)、:nth-child(特定位置的子元素,odd 选择奇数位置的子元素)等。 语法:冒号(::)开头,紧跟伪类的名称

20. Promise构造函数是异步执行还是同步执行(JS ⭐)

Promise构造函数是同步执行的。 创建一个Promise对象时,Promise构造函数会立即执行。异步操作通常会在Promise构造函数内部启动(异步操作的结果将在后续微任务队列中执行),但构造函数本身不等待异步操作的完成。

d5b1d69a32fb92fcddbda9e3674237b.png

console.log('开始');
const myPromise = new Promise((resolve, reject) => {
  console.log('Promise构造函数正在执行');
  resolve('Promise 响应成功');
});

myPromise.then((res) => {
  console.log(`Promise响应结果:${res}`);
});

console.log('结束');

21. 闭包(JS ⭐⭐⭐)

  1. 什么是闭包

闭包是指函数在创建时保留了对其定义作用域的引用,即使函数执行在其词法作用域之外,也能访问该作用域中的变量。(在编程领域,它表示一种函数,绑定了执行环境的函数)

闭包的组成部分:环境部分(环境:函数的词法环境,执行上下文的一部分;标识符列表,函数中用到的位声明的变量)、表达式部分(函数体)

执行上下文:JS标准把一段代码(包括函数),执行所需的所有信息定义为“执行上下文”

闭包在JS中常见的表现形式:函数嵌套函数,内部函数访问外部函数的变量。
由于JS的函数时”第一类公民“,可以作为值返回、传递或保存,因此在外部函数返回后,闭包依然保留对外部变量的访问权限。

function outerFn() {
    let counter = 0;

    return function innerFn() {
      counter++;
      console.log(counter);
    };
}

const increment = outerFn();
increment(); // 输出:1
increment(); // 输出:2

innerFn是一个闭包,可以访问outerFn中的变量counter,即使outerFn已经执行完毕

  1. 闭包导致内存泄露的场景

在JS中,闭包有时会导致内存泄露,这是因为闭包在访问外部作用域的变量时会让这些变量无法被垃圾回收,从而导致不必要的内存占用。

常见的内存泄露场景:未清理的事件监听、定时器

  • 未清理的事件监听 事件监听器引用了外部作用域中的变量,且在不需要时未移除,导致闭包一直存在,无法释放内存
function addEvent() {
    const element = document.getElementById('button');
    const someData = 'important data';
    element.addEventListener('click', () => {
      console.log(someData); // 闭包引用了外部变量 someData
    });
}
addEvent();
//  如果不手动移除事件监听器,则 someData 永远不会释放,造成内存泄露
  • 未清理的定时器

在定时器的回调函数中使用了闭包,但在不需要时未清除定时器,导致回调函数及其引用的外部变量无法被回收

function createTimer() {
    const largeData = new Array(10000).fill('*');
    setInterval(function () {
      console.log(largeData); // 定时器闭包持有largeData的引用
    });
}
createTimer();
//  如果不清除定时器,则 largeData 永远不会释放,造成内存泄露
  1. 为什么循环引用会导致内存泄露

  2. 如何检测循环引用

  3. 如何避免循环引用导致的内存泄露

22. Class如何实现继承?可以多继承吗(JS ⭐⭐)

23. 什么场景下会有跨域,怎么解决(浏览器 ⭐⭐)

24. 浏览器同时打开多个tab,有哪些方式可以通讯(浏览器 ⭐⭐)

25. 用户打开URL到浏览器完全渲染的全过程(浏览器 ⭐⭐)

26. 浏览器工作原理(浏览器 ⭐⭐)