Skip to content

对 HTML 语义化的理解

使用恰当的标签来描述内容的含义与结构,不是全用新标签,在不增加复杂度的前提下,优先表达语义,其次是行为和样式

语义化标签:headerfooternavmainasidearticalsection
多媒体标签:audiovideo
其他:cavassvg

DOCTYPE 的作用

文档类型声明,告诉浏览器使用那种HTML标准解析当前页面,从而决定渲染模型

行内元素有哪些?块级元素有哪些? 空 (void)元素有那些?

行内元素:

plain
<span>、<a>、<img>、<input>、<button>、<label>、<select>、<textarea>、
<strong>、<em>、<b>、<i>、<u>、<s>、<br>、<code>、<script>

块元素:

plain
<div>、<p>、<h1>~<h6>、<ul>、<ol>、<li>、<header>、<footer>、<nav>、
<section>、<article>、<aside>、<main>、<table>、<form>、<hr>

空元素:

plain
<br>、<hr>、<img>、<input>、<link>、<meta>、<area>、<base>、<col>、
<embed>、<param>、<source>、<track>、<wbr>

常见的 CSS 布局单位

对 BFC 的理解,如何创建 BFC

元素的层叠顺序

如何解决 1px 问题?

CSS中的position属性有哪些有效值?

固定定位与粘性定位的区别?

CSS中的display属性有哪些有效值?

盒子模型有几种? 分别是什么?

用于定位和布局元素的概念,由外边距、边框、内边距和内容组成

CSS 优先级

CSS选择器

说一下常见的伪类和伪元素

移动端适配

CSS元素优先级是怎样的

内联样式>ID选择器>类选择器>元素选择器>通用选择器

CSS 布局技术

块级布局:文章流布局

浮动布局:多栏布局、图文环绕

定位:弹窗、固定元素

弹性布局:导航、按钮组、列表、居中、响应式

网格布局:九宫格、仪表盘、响应式

表格布局:数据表格

定位有哪几种

static:默认定位

relative:相对定位

absolute:绝对定位

fixed:固定定位

sticky:粘性定位

position 的 sticky 有什么应用场景?

头部导航栏

侧边内容目录

底部购物车

如何水平垂直居中?

方法一:使用flex布局

方法二:使用grid布局

方法三:使用定位和transform

方法四:高度和行高

css 中三栏布局的实现方案有哪些?

方法一:使用flex布局

方法二:使用grid布局

方法三:使用浮动布局

方法四:使用定位布局

如何清除浮动

  1. 添加一个新盒子并添加样式 clear:both
  2. 在父盒子上添加样式 overflow:hidden
  3. 在父盒子上添加伪类
css
.father::after{
    content:"";
    display:block;
    clear:both;
    height:0;
    visibility:hidden;
}

解释一下CSS盒模型

用于定位和布局元素的概念,由外边距、边框、内边距和内容组成

怎么解决样式冲突?

规范模块命名,防止命名冲突相互覆盖

CSS元素优先级是怎样的

内联样式>ID选择器>类选择器>元素选择器>通用选择器

CSS 布局技术

块级布局:文章流布局

浮动布局:多栏布局、图文环绕

定位:弹窗、固定元素

弹性布局:导航、按钮组、列表、居中、响应式

网格布局:九宫格、仪表盘、响应式

表格布局:数据表格

原子化CSS

通过小而精的类名进行更加灵活的复用

将样式分解为单一功能的类

定位有哪几种

static:默认定位

relative:相对定位

absolute:绝对定位

fixed:固定定位

sticky:粘性定位

position 的 sticky 有什么应用场景?

头部导航栏

侧边内容目录

底部购物车

如何水平垂直居中?

方法一:使用flex布局

方法二:使用grid布局

方法三:使用定位和transform

方法四:高度和行高

css 中三栏布局的实现方案有哪些?

方法一:使用flex布局

方法二:使用grid布局

方法三:使用浮动布局

方法四:使用定位布局

浏览器是如何对 HTML5 的离线储存资源进行管理和加载?

Canvas 和 SVG 的区别

说一下 HTML5 drag API

SPA和MPA的区别?

最主要的区别在于页面跳转方式不同
spa只有一个html页面,通过js动态更新页面内容,无需刷新,交互流畅但是首屏开销高,seo不友好
mpa拥有多个html页面,每次跳转都从服务器获取新页面,seo友好但是交互体验差

浏览器是怎么解析 HTML 文档的

通过http请求获取html文件,然后构建DOM树,解析css,生成渲染树,渲染布局并进行绘制,多层内容合并,执行js代码,最后进行事件监听与交互

如何避免重绘或者重排?

重排是dom元素几何属性集合或者结构发生变化,浏览器需要重新构建和渲染dom树。重排必定重绘
重绘是元素样式变化,浏览器重新绘制该元素
合并样式修改,避免逐条修改样式
批量修改dom节点
使用定位让元素脱离文档流
读写分离,先读后写
使用transformopacity替换几何动画
避免使用表格布局

SPA应用怎么进行SEO?

ssr服务端渲染:在服务器端执行框架代码,生成完整的html返回给浏览器
预渲染:使用无头浏览器访问spa的每个路由,抓取并保存渲染后的静态html

script 标签中 defer 和 async 的区别

var 、let 、const的区别

平常知道哪些ES6特性? 用过哪些?

JavaScript 有哪些数据类型,它们的区别?

数据类型检测的方式有哪些

null 和 undefined 区别

intan ceof 操作符的实现原理及实现

如何获取安全的 undefined 值?

Object.is() 与比较操作符 “===”、“==” 的区别?

什么是 JavaScript 中的包装类型?

为什么会有 Big Int 的提案?

如何判断一个对象是空对象.

const 对象的属性可以修改吗

如果 new 一个箭头函数的会怎么样

箭头函数的 this 指向哪里?

扩展运算符的作用及使用场景

Proxy 可以实现什么功能?

常用的正则表达式有哪些?

对 JSON 的理解

JavaScript 脚本延迟加载的方式有哪些?

什么是 DOM 和 BOM?

escape、encodeURI、encodeURIComponent 的区别

对 AJAX 的理解,实现一个 AJAX 请求

什么是尾调用,使用尾调用有什么好处?

ES6 模块与 CommonJS 模块有什么异同?

for...in和 for...of 的区别

ajax、axios、fetch 的区别

对原型、原型链的理解

原型链的终点是什么?如何打印出原型链的终点?

对作用域、作用域链的理解

对 this 对象的理解

call () 和 apply() 的区别?

异步编程的实现方式?

对 Promise 的理解

Promise 解决了什么问题

对 async/await 的理解

async/await 的优势

async/await 对比 Promise 的优势

对象创建的方式有哪些?

对象继承的方式有哪些?

哪些情况会导致内存泄漏

什么是函数式编程, 对函数式的理解

纯函数的概念, 好处和用途

防抖 , 节流 的定义及二者区别, 手写防抖的实现

异步方案讲一下? Promise请求可以取消吗? ajax请求可以取消吗?

js数组

promise方法加三种状态

object方法

.this指向

bind和apply区别?

事件冒泡事件捕获的不同

如何去掉一个字符串的重复字符 ( 考察字符串的api)

如何遍历字符串 ( s[i]有兼容性问题)

charAt()知道么

讲讲 js 原型链, 手写用 Object.create () 实现继承的代码 ( 不是直接实现继承, 而是实现一个继承功能的函数, 因此绕了个弯)

proxy的优缺点

JSON.stringify 的深度用法, 如何美化输入 ( 顺便拓展了一下前端做文本点击复制时如果复制JSON.stringify 转换的文本不能使用 Input 而应该是 textarea)

对象删除元素应该怎么做 ( 说了下 delete 和 Reflect, 具体的区别)

如何删除数组指定索引元素, 过滤等 ( 比较基础, 拓展了一下 immutable 与 mutable 之类的)

Promise相关实例和静态方法的概念, 如何在 Promise.all 失败的时候判断是哪个失败的

拿到对象的 key 有哪些方法, 使用 for...in 和 Object.keys 有什么不同

jQuery的选择器怎么实现的

VUE

Vue的基本原理

讲一下vue的特点吧

讲一下vue的生命周期

发起http请求在哪个钩子? 绑定事件在哪个钩子? 取消事件在哪个钩子?

讲一下组件间通信

双向数据绑定的原理

Vue3新特性?

什么是mvvm框架?

slot 是什么?有什么作用?原理是什么?

$nextTick 原理及作用

Vue 单页应用与多页应用的区别

Vue 中封装的数组方法有哪些,其如何实现页面更新

Vue data 中某一个属性的值发生改变后,视图会立即同步执行重新渲染吗?

简述 mixin、extends 的覆盖逻辑

子组件可以直接改变父组件的数据吗?

对 React 和 Vue 的理解,它们的异同

Vue 的优点

assets 和 static 的区别

delete 和 Vue.delete 删除数组的区别

Vue 模版编译原理

vue 初始化页面闪动问题

MVVM 的优缺点?

对 Vue 组件化的理解

对 vue 设计原则的理解

说一下 Vue 的生命周期

Vue 子组件和父组件执行顺序

created 和 mounted 的区别

一般在哪个生命周期请求异步数据

keep##alive 中的生命周期哪些

路由的 hash 和 history 模式的区别

Vue##router 跳转和 location.href 有什么区别

Vuex 的原理

Vuex 和 localStorage 的区别

Redux 和 Vuex 有什么区别,它们的共同思想

为什么要用 Vuex 或者 Redux

Vuex 有哪几种属性?

Vuex 和单纯的全局对象有什么区别?

为什么 Vuex 的 mutation 中不能做异步操作?

Vue3.0 有什么更新

defineProperty 和 proxy 的区别

Vue3.0 为什么要用 proxy?

虚拟 DOM 的解析过程

DIFF 算法的原理

Vue 中 key 的作用

vue怎么变成前端产物 、每个阶段做了什么 、解析阶段做了什么

vue##router懒加载实现原理

Vue中的响应式怎么实现

Vue中对数组也是这么做的吗

Vue模板编译说一下流程

介绍一下vdom

详细介绍下Vue里的响应式机制

讲下Vue里的diff原理

bable##core/bable##preset##env有什么区别?

Edge浏览器和Chrome浏览器有什么区别?

各个图片尺寸不同的雪碧图如何定位?

图片懒加载的原理

多个设备上的本地缓存如何同步?

react和vue的区别

使用框架一定比原生的或者jQuery好吗? 为什么

react和vue在虚拟DOM的diff算法有什么不同 ( 不了解react..)

那你讲一下Vue的diff算法

vue性能优化的方法

懒加载的原理

用过什么模块化解决方案吗? 比如webpack 、还有vue里面的?

自己写过loader和plugin吗

进程和线程的区别

plugin实现原理

代码输出, 解释一下 ( Promise 、Setimeout 、async/await混合)

python 、node 、java的区别

node为什么是异步

node如何充分利用CPU

node如果想多开几个进程该怎么操作

协程听过吗?

为什么要有协程? 协程的目的?

数据库索引为什么要用B+树?

联合索引听过吗?

是全栈开发, 东西都有涉及到吗

XSS和CSRF ( react天然对xss有防范)

数据上报是怎么做的

前端的一次请求会经过哪些缓存

ssr项目可以做什么优化

视频上传有哪些技术难点

前端分片的api叫什么

视频封面怎么做的

如何判断一个视频封面是黑屏的

etag和last modified的区别

如果淘宝网内存泄漏导致页面登不上去或浏览器挂掉了, 那么要怎么快速定位到内存泄漏的位置呢

vue2 .0与vue3 .0在数据双向绑定的区别

讲一讲微前端有哪些实现策略

讲一讲你之前的项目采取了哪些安全策略? 讲一讲 XSS 攻击和 CSRF 攻击

实现 三栏布局 , 用 float + BFC 和 flex 两种方式

实现单行文本在父元素中不换行 , 溢出部分变成省略号形式

讲一讲 浏览器缓存机制 , 涉及到哪些 (http)报文字段?

讲一讲 js 事件循环机制 , 列举宏任务, 微任务有哪些? 看代码说结果

讲一讲微前端有哪几种实现策略?

你之前实习的项目用的是什么策略?

讲讲 mono repo 是什么

<iframe> 实现微前端, 有什么缺陷?

路由和样式受到限制, 不能正常使用浏览器的后退/前进按钮, 那你们的项目是如何解决这一点的?

我们之前的项目是在微前端落地页又重新实现了一遍 Tab 组件, 进入一个微前端子工程, 就在页面上新增一个重新实现的 Tab 页, 用户通过切换Tab 页的方式就不用点击后退/前进了. 相当于多挂载一个 iframe, 因此性能开销很大, 我们之前的项目限制同时最多打开 10 个 Tab 页 。

你们之前的项目为什么这么做? 理由是什么? 是一开始就定下来这样做的吗?

答: 不知道 一开始就是这么定的

qiankun 为什么不用 iframe, garfish 为什么不用 iframe

你之前的部门用的微前端什么方案

Webpack 打包原理; 你都知道哪些 plugin , 讲讲常见的 plugin 的功能和原理;

问了一堆 babel 的配置

除了 Webpack 你还接触过哪些前端打包工具? 讲讲 Webpack, rollup, vite 三者的区别

你们的项目是怎么解决样式隔离问题的? CSS Module 还是 CSS in JS

你说你之前的项目用的 CSS Module , 那它有哪些缺点? 你使用 :global() , 在微前端中如何做到样式隔离?

你使用 :global() 去定义 antd 底层 class, 如果 antd 版本更新, 底层 class 名变了, 你怎么办?

讲讲 mobx 原理, 用的什么设计模式

讲讲 vuex 和 mobx 区别? 或者说, 讲讲单例模式, 观察者模式和发布##订阅模式

讲讲什么是闭包

ts 里 type 和 interface 的区别以及使用场景

ts 的泛型接触过吗? 泛型主要为了解决什么问题

node.js 相对于原生 js 有哪些区别?

列举你知道的前端优化方案, 讲讲 React 的异步加载和懒引入原理

你刚才说到避免浏览器重排 如何获取某个 DOM 节点的位置? 用 clientTop 和 clinetLeft 为什么会导致浏览器重排?

你刚才说优化方案里讲到避免内存泄露, 说说如何排查内存泄漏? 火焰图接触过吗

讲讲前端工程化主要涉及哪些内容

你刚才提到规范化 那你讲讲你们项目的 git 提交规范吧

跨域相关

jsonp 实现, 有什么缺陷

知道事件代理吗, 什么时候要用到? ( 说了下概念, 哪些事件不推荐做事件代理, 哪些事件无法做事件代理, e.currentTarget 和 e.target区别啥的)

如何让一个div变为可聚焦 ( 加 tabIndex 属性)

如何预防 xss, 要渲染富文本 react 的 xss 问题怎么办 ( 解析 url, 判断白名单, 或者手写编译器,类似 babel 运行时解析, 再用 React.createElement 创建元素)

react diff

key 的作用 ( 不用 key 也能渲染, 只是每次都需要比对 fiber 节点, 有 key 就走 key )

webpack5 的新特性

vite 为什么这么快 ( 大致说了使用 esbuild 开发, 然后服务端对浏览器的网络请求做了映射, 在服务端动态解析路径和模块之类的)

React 生命周期

useEffect 主要的用途, 在项目中的使用场景

react hooks 性能优化

react 的数据流方案 ( 简易数据流方案 useContext + createContext + useImmer, 状态管理库: rematch 、recoil 这些)

不同的数据应该怎么存储 ( 全局共享放在Context, 组件内部放 State)

Node 如何分层合理一些 ( 后端那套吧)

什么是 IOC 机制, 如何在 Node 里面使用 ( 按照 nest.js 的思路答的, MVC + IOC + 元编程)

如何设计一个项目的国际化功能

你认为 node.js ,vue, react 各种出现的原因和各自优缺点是啥

devops 流程是怎么样的, 如何制作一个原子服务

eventloop

选择器的效率问题

Vue和React的vdom算法对比

Vue中组件通信的方法

持续集成的问题 ( 因为我的项目里有)

VueRouter两种模式的原理

阐述下宏任务和微任务

让我介绍下我对前端安全问题的理解 ( XSS和CSRF的出现和应对策略)

队列有什么特点和应用场景

问了几种排序算法

一个WebGL的项目

Webpack的loader和plugins原理

项目里的node是怎么实现的 ( 说了实现了3层消息中间件 各中间件实现了啥)

怎么判断登录的? 登录为什么用token不用cookie?

了解过其他网站的登录是怎么做的吗

讲一下es6有哪些新特性吧

为什么用vue 而不用jquery等等

鼠标点击和松开事件绑定

怎么实现图片随鼠标光标的移动

React

react框架了解吗?

react和vue框架的区别?

这两个框架的数据绑定方式?

react框架是mvvm框架还是mvc框架?

Mysql

数据库的主键约束和外键约束

什么是事务?

事务的原子性是什么?

MySQL中, select是怎么查询到数据的? 具体执行过程是什么?

如何监控服务器的剩余资源?

如何减少数据库的读写次数?

数据表设计

为什么加索引有提速

说一下用户提交表单到服务器, 再到渲染在页面上的整个过程, 用到了哪些协议?

了解热加载吗?

页面加载慢有哪些原因?

对于这些原因有哪些性能优化方案?

为什么有时候webp格怯的图片显示不出来?

图片有哪些压缩方法?

压缩算法有哪些? 原理是什么? 各种压缩算法对比

前端性能优化 ( 做个思路梳理, 网络 ##> html ##> css ##> js ##> 打包优化)

如果有很多if else, 怎么优化

讲一下一个URL请求后发生了什么

get和post的区别

什么样子的get请求会有缓存

如何解决谷歌浏览器6个TCP连接限制

浏览器缓存

http的请求方法( post, put,get,delete,patch,我说了这几个)

三次握手

TCP三次连接

TCP和UDP的区别 、应用场景

TCP的拥塞控制

讲一下HTTP缓存、对应的响应头

304状态码

项目跨域用的是什么

https流程

如何实现大文件分片上传与断点续传

将文件分割成若干块,每个分片携带标识上传,上传前先查询已上传部分并跳过,上传完所有分片按照序号合并

var、let与const的区别

var是函数作用域存在变量提升,let和const是块级作用域存在暂时性死区,const必须初始化并且不能重复赋值

如何在前端项目中实现动态路由?

  1. 定义静态路由包括一些无权限的公共路由
  2. 登录后获取后端数据
  3. 将数据转换为routes格式
  4. 使用router.addRoute()生成路由
  5. 添加路由守卫
  6. 根据路由渲染菜单

如何通过bind或箭头函数固定this指向?

bind:创建一个新函数,将this绑定传入的对象上

箭头函数:将箭头函数转换为一般函数

深拷贝与浅拷贝的区别

浅拷贝只拷贝了对象的一层属性,对于引用类型,则只拷贝了引用地址,而没有拷贝真实值

深拷贝是递归复制所有属性

常用到的深拷贝和浅拷贝有哪些

浅拷贝:object.assign() ,扩展运算符···

深拷贝:

this指向问题

普通函数的this指向全局

对象方法中的this指向对象

构造函数的this指向实例

箭头函数没有this,通过继承外层的this

防抖

节流

Vue相关

说明一下vue的生命周期

生命周期分为四个阶段,分别是初始化阶段、挂载阶段、更新阶段和销毁阶段

初始化阶段有beforeCreate和created

挂载阶段有beforemount和mounted

更新阶段有beforeupdate和updated

销毁阶段有beforeDestroy和destroyed

vue2和vue3主要区别在于函数名称,vue3在名称前加了on,同时setup函数代替了beforeCreate和created

什么是MVVM和MVC模型

说明git pull与git fetch的区别

pull相当于fetch+merge,fetch是只拉下来不合并,而pull是既拉下来也合并

说明git merge 与 git rebase的适用场景

二者都是用于合并分支的命令

git merge是创建一个新记录,保留历史提交

git rebase是将分支的提交重新提交到目标分支的顶端,改变历史提交

共享分支用merge,私有分支用rebase

如何将git同步分支到其他项目

git cherry-pick + 提交id值

git的常用操作有哪些

查看和创建新分支:git branch

切换分支:git checkout

创建并切换分支:git switch -c

删除分支:git branch -d

合并分支:git merge

变基:git rebase

推送分支:git push

手动提交:git add. git commit -m git push

响应式设计和自适应设计

JS数组去重的几种方式

如何进行移动端是适配

事件捕获与事件冒泡的区别

JSON.parse与JSON.stringify

JSON.parse是把字符串变对象或数组

JSON.stringify是把对象或数组变成字符串

闭包是什么,实际应用场景

什么是闭包

举例说明:
比如我按照需要写一个统计累加1到100,一般来说我会定义一个count还统计数值,后面写一个函数来返回1到100的累加值。但是这个count是在统计函数外面的,如果在外部改变了这个count的值,那么这个统计函数也会出错,所以我们会在外面再包一层函数。
这样就创建了一个私有变量,简单来说,闭包就是能读取其他函数内部变量的函数。

闭包的优缺点

优点:
1.可以创建私有环境
2.延长变量的生命周期

原型链,并说明它是如何实现对象继承的?

什么是原型

每个函数都有prototype属性,称为原型
一般我们有一个构造函数,可以用来构造一个实例,而这个实例有一个属性叫_proto_,这个属性则指向这个实例的原型对象

什么是原型链

一个函数或对象,它会有一个指向它的原型的一条链,但是它指向的原型也是一个对象,故,它的原型也会有_proto_属性继续往上找,直到为空,那么这条链就叫做原型链
原型是函数特有的,而原型链是大家都有的

如何实现双向绑定

什么是vue生命周期

对v-if和v-show的理解

为什么v-if和v-for不能同时使用

data属性是一个函数而不是一个对象

如何给对象添加新属性而页面不刷新

组件与插件有什么区别

组件间通信有哪些方式

对nexttick的理解

什么是SPA单页应用

SPA首屏加载慢怎么解决

SEO优化

v-model绑定原理

什么是路由

vue响应式原理

vue组件监听的方法

1.watch属性
watch属性是用来观察和响应vue实例上的数据变动,当设置的数据发生改变时,相关的回调函数会被执行。
2.computed计算属性
computed计算属性用来观察数据的变化,当依赖的数据发生改变时,计算属性会重新计算。
3.事件监听
通过v-on或@来监听DOM事件,并在vue组件中处理这些事件。
DOM是什么?DOM是文档对象模型,它是一个跨平台和语言独立的接口。它允许程序和脚本动态的访问和更新文档的内容、结构和样式。

vue的生命周期(重复),请求发送要写在哪里

beforeCreate,Created
beforeMount,Mounted
beforeUpdate,Updated
beforeDestrory,Destroryed
关于请求发送,一般在created()钩子中进行,因为这个时候,vue已经完成了数据的观测,但是还没有开始DOM渲染,因此可以在这个阶段进行数据请求。

vue跨组件通信的方式有哪些,介绍一下vuex,全局事件总线

父传子:props
子传父:$emits
无父子关系:全局事件总线
更加复杂的情况:vuex
全局事件总线:相当于一个中介,接收方订阅该中介的值,发送方通过发布调用这个中介里面的函数实现修改数值。
vuex:是一个专门为vue.js应用程序开发的状态管理模式
它里面有state,getters,mutiations,actions和modules
其中state包含所有需要共享的状态对象。类似data
getters类似计数属性,用来处理一些状态,比如过滤列表,计数等。
mutiations是唯一用来更改state的方式
actions:用来异步更改state,实际上还是调用mutation来更改state

浏览器发送请求的API有哪些,介绍一下axios的原理

XHR(xmlhtmlrequest):传统的浏览器api,用于在后端与浏览器交换数据
fetch API:用于在浏览器中发起http请求,返回的是一个promise,使得异步处理更加方便
websocket API:提供一个全双工通信的通道
axios原理:
1.创建请求:通过创建一个axios实例或直接使用axios函数来发布请求
2.请求拦截器:在发布请求前,允许你通过请求拦截器拦截请求,并对请求进行修改。
3.发送请求:axios会使用XHR或FetchAPI来发送请求
4.响应拦截器:在响应返回前,允许你通过响应拦截器来拦截响应数据,并对响应数据进行处理,例如感觉状态码进行错误处理
5.处理响应:当请求完成并返回数据时,axios会解析响应数据,并将其传送给promise的then方法,如果请求失败,axios会捕获错误,并通过promise的catch传递错误。

介绍一下diff算法大概的过程

1.首先,对于每个组件的每次渲染都会生成一个虚拟DOM树
2.diff算法是用来对比虚拟DOM树的差异
3.找到差异后再更新实际的DOM树,这样做减少了重绘和回流,提高了性能。
节点比较:
1.先比较标签,标签不同,整个节点都要换掉
2.如果标签相同则比较属性,找到属性的变化,并对相应的DOM树进行更新
3.如果有子节点,更新子节点

强缓存、协商缓存

强缓存:强缓存是指浏览器第一次向服务器请求资源时,会强制将资源存储在本地,在缓存有效期内,如果浏览器再请求相同的资源,浏览器会直接使用本地缓存资源。
协商缓存:协商缓存是指浏览器每次向服务器请求资源时,都会向服务器发送请求,服务器根据资源的最后修改时间来判断资源是否发生变化,如果没有发生变化,会返回304not modified状态码,来告诉浏览器可以使用本地资源。

输入url到页面加载的过程

  • DNS域名解析
  • 建立TCP连接
  • 发送HTTP请求
  • 服务器返回相应
  • 浏览器渲染

三次握手与四次挥手

TCP协议是面向连接、可靠的数据传输协议(按顺序、不丢失、不重复)

三次握手(建立连接)

  • 客户端发送报文SYN(听得到吗?)
  • 服务器接收报文并向客户端发送报文SYN+ACK(听得到,你说)
  • 客户端接收报文ACK(好,我开始说了)

为什么不是两次

  • 防止失效的连接又传递过来

四次挥手(断开连接)

  • 客户端发送报文FIN,停止发送数据(我要走了)
  • 服务器接收报文,发送确认报文ACK(好的,我知道了)
  • 服务器发送结束报文FIN(我也要走了)
  • 客户端接收结束报文,发送确认报文ACK,等待2MSL后关闭连接(好的,你走吧)

为什么不是三次

  • 二三次之间会有未发送完的数据

为什么等待2MSL

  • 确保最后一个ACK到达服务器
  • 防止之前的报文干扰

HTTP与HTTPS

特性HTTPHTTPS
协议TCPSSL/TLS
端口80443
安全性明文传输密文传输
身份认证CA数字证书
SEO不占优排名优先
性能不安全安全
开销连接更快连接更慢

websocket与http的区别

websocket与http的状态码

什么是跨域资源共享(CORS)

同源:协议、域名、端口相同

跨域:脚本请求非同源的资源

为何跨域

  • 浏览器防止跨站脚本XSS恶意请求

解决跨域

  • 跨域资源共享CORS,响应头中添加特定字段
plain
// 请求头
Origin: https://www.taobao.com

// 响应头 (服务器设置)
Access-Control-Allow-Origin: https://www.taobao.com // 或使用 * 允许任何源(但不能带凭证)
plain
app.use((req, res, next) => {
  // 允许来自所有域的请求(生产环境应指定具体域名,如:https://www.taobao.com)
  res.header('Access-Control-Allow-Origin', '*');
  // 允许的请求方法
  res.header('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS');
  // 允许的请求头
  res.header('Access-Control-Allow-Headers', 'Content-Type, Authorization');

  // 处理预检请求
  if (req.method === 'OPTIONS') {
    return res.sendStatus(200);
  }
  next();
});
  • 反向代理,服务器转发(不会被拦截)
plain
// vite.config.js
export default {
  server: {
    proxy: {
      '/api': { // 以 /api 开头的请求
        target: 'https://api.target.com', // 目标服务器
        changeOrigin: true, // 修改请求头中的 Origin 为目标地址
        rewrite: (path) => path.replace(/^\/api/, '') // 重写路径(可选)
      }
    }
  }
}
plain
// nginx
server {
  listen 80;
  server_name www.taobao.com;

  location /api/ { # 匹配 /api 路径的请求
    proxy_pass https://api.target.com/; # 转发到目标服务器
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
  }
}

cookie、localStorage与sessionStorage的区别

拖拽过程

plain
dragstart  // 开始拖动
drag       // 持续拖动
draend     // 拖动结束
dragenter  // 拖动进入目标
dragover   // 拖动到目标上方
dragleave  // 拖动离开目标
drop       // 松开鼠标

get与post的区别

token相关路由请求

父子组件生命周期加载顺序

虚拟dom与diff算法

csrf攻击原理

描述事件冒泡和事件捕获的流程,并说明在前端开发中如何阻止事件冒泡?

解释CSS中的盒模型(标准盒模型和IE盒模型),并说明如何在CSS中统一处理盒模型?

描述Promise的三个状态(pending、fulfilled、rejected)和三个方法(then、catch、finally),并说明Promise.all和Promise.race的区别?

解释异步编程的几种模式(回调函数、Promise、async/await),并说明它们各自的优缺点?

描述JavaScript中的事件委托机制,并说明它在性能优化方面的优势?

解释JavaScript中的异步函数(async/await)是如何处理异常的?

比较React和Vue的异同,并说明它们各自的优势和适用场景?

描述React中的虚拟DOM(VirtualDOM)是如何工作的,并说明它的优势?

解释Vue中的响应式原理,并说明它是如何实现数据双向绑定的?

描述ReactHooks的使用场景和优势,并说明常用的高阶Hook(如useEffect、useContext)?

解释Vue3中的CompositionAPI,并说明它与OptionsAPI的主要区别?

描述前端性能优化的几种常见方法(如懒加载、代码分割、缓存等),并说明它们各自的作用?

解释浏览器缓存的工作原理,并说明如何合理配置缓存策略?

描述前端性能监控的几种常见工具(如Lighthouse、WebPageTest),并说明它们的主要功能?

解释前端性能优化的几个关键指标(如LCP、FID、CLS),并说明它们各自的意义?

描述前端性能优化的常见陷阱(如重绘和回流),并说明如何避免它们?

描述XSS攻击的原理和常见防御措施?

描述CSRF攻击的原理和常见防御措施?

解释HTTPS的工作原理,并说明它在网络安全方面的优势?

描述前端安全的几种常见措施(如CSP、HSTS),并说明它们各自的作用?

解释前端数据加密的几种常见方法,并说明它们各自的优缺点?

描述Webpack和Vite的异同,并说明它们各自的优势和适用场景?

解释Babel的作用,并说明如何配置Babel以支持ES6+语法?

描述ESLint的作用,并说明如何配置ESLint以规范代码风格?

描述前端自动化测试的几种常见工具(如Jest、Cypres)

this指向问题

一般来说,谁调用它,就指向谁
需要注意的是:
1.箭头函数没有作用域,没有this
2.var定义的变量,作为一个属性挂载在window上面

你知道塌陷吗

知道,当父盒子有上外边距and子盒子也有上外边距的时候就会出现塌陷。
解决办法是给父盒子加一个上边框
border-top:1px solid transparent

你知道如何清除浮动吗

什么是浮动?浮动会脱离常规文档流,并向左或向右移动
清除浮动一般有2中方法
1.clear:both
2.overfloat:hidden
或者直接使用flex布局

display:none和visibility:hidden之间的区别?它们是否会触发重绘以及回流

1.display:none和visibility:hidden都会使元素看不到
2.区别在于,display:none是直接将这个元素置空,也就是这个元素在布局中都不占位置了。而visibility:hidden只是将这个元素隐藏起来了,这个元素本身还是存在的。
3.重绘是指属性的更改只影响外观而不影响布局,回流又叫重排,指的是会影响布局的操作。
4.所以,很明显,display:none会改变页面布局,所以会触发回流,而visibility:hidden则不会,它只会引起重绘。

js常见一些函数或结构

foreach()没有返回值,遍历的是value值
map()有返回值,接收的参数的是(key,value)

js中有哪些数据类型

字符串(string),空(null),数值(number),未定义(undefined),布尔类型,数组,对象

改变数组的一些方法

push(),pop(),sort(),reverse(),splice()

数组循环的方法有哪些

foreach()和map(),for循环,for in循环

js常见一些函数或结构

1.foreach()和map()
foreach()没有返回值,遍历的是value值
map()有返回值,接收的参数的是(key,value)

2.js中有哪些数据类型?
字符串(string),空(null),数值(number),未定义(undefined),布尔类型,数组,对象

3.改变数组的一些方法?
push(),pop(),sort(),reverse(),splice()

4.数组循环的方法有哪些?
foreach()和map(),for循环,for in循环

数组去重有哪些方法?

1.双层for循环
2.filter过滤方法
3.indexof判断该数值第一次出现的索引下标是不是和本身的索引下标一样,如果不一样就说明有重复

ES6新语法有哪些?

1.使用let和const定义变量(var,let,const区别?)
1.let,const都不可以重复声明,var可以
2.const一般是用来定义常量的,定义之后就不能修改了,而var和let则是用来定义变量的。
3.var存在变量提升问题,let和const则没有这个问题

引入箭头函数(箭头函数和普通函数的区别?)

1.this指向问题不同:this一般是谁调用它,它就指向谁,普通函数中this指向调用它的函数,箭头函数自身没有this,他的this指向它的父级普通函数的this
2.箭头函数都是匿名函数,普通函数可以匿名也可以具名
3.箭头函数不能用于构造函数,其他函数则可以(创建实例)
4.不能用于构造函数,也就没有prototype,即没有原型

模板字符串(可以解析变量,是解构赋值吗?)

Promise对象(promise常用的方法有哪些?它的API?promise.all,promise.race?)

1.promise捕获错误的方式
5.async/await异步编程

1.cookie是存在http请求头部的,而localStorage和sessionStorage则是只存在于客户端(即浏览器中)
2.cookie最多存4kb,其他2个则可以存5mb左右
3.cookie可以设置时效,localStorage除非手动清除,否则一直都在,sessionStorage关闭浏览器或者页面就会清除

浏览器输入url后的一个全过程

1.首先输入一个网址,会通过DNS(域名解析协议)将域名解析为相应的ip地址
2.通过该ip地址找到对应的服务器,并发起tcp三次握手,建立tcp连接
3.发送http请求,客户端请求资源
4.服务器端响应并返回相应的资源(html)
5.浏览器将html文档用html解析器解析成dom树
6.css解析器将css样式解析成css规则树
7.将生成的DOM树和CSS规则树合并生成Rendering Tree(渲染树)
8.根据渲染树,在网页上对元素进行布局
9.根据渲染树,将各个元素绘制到屏幕上

常见的状态码有哪些?

200 OK :请求成功
404 not found:找不到资源
500:服务器内部错误
403:拒绝访问

token相关的路由守卫

5.http的请求方法
6.get和post区别

如何解决跨域问题?(jsonp和cors)

15.wepback打包相关问题
1.webpack?介绍一下webpack的常用配置
2.webpack用过什么lorder,说一下作用
16.说一下vue的生命周期
其实就记住四个步骤
创建,挂载,更新,销毁
beforeCreate
Created
beforeMount
Mounted
beforeUpdate
Updated
beforeDestory
Destoryed

1.vue父子组件加载的时候生命周期执行顺序?
子组件挂载到父组件上面的时候,要保证子组件已经挂载好。
父beforeCreate–>父Created–>父beforeMount–>子beforeCreate–>子Created–>子beforeMount–>子Mounted–>父Mounted

17.说一下组件间通信
组件间通信分为2种,一种是父子间通信,一种是非父子间通信
1.父亲给儿子传值用props,儿子给父亲传值用$.emit
2.非父子间通信用事件总线的方法,如果系统很复杂的话,可以用vuex

1.说一下全局事件总线bus
比如组件A想给组件B发信息
但是他们之间没有父子关系
我们需要创造一个空的vue实例,作为A和B沟通的一个桥梁
1.组件A给组件B发信息,可以理解组件A有一个触发事件,发布消息传参
2.组件B接收消息,可以理解为他订阅了bus,他监听bus实例的事件。

2.说一下vuex
18.你知道哪些vue指令?
1.v-html,作用类似于innerHTML
2.v-model,双向数据绑定
3.v-if,v-show,控制元素显示
4.v-else,v-else-if,配合v-if使用
5.v-on,注册事件,添加监听+提供处理逻辑

1.说一下自定义指令
2.说一下路由传参
3.为什么data要写成一个函数
因为要通过data创建实例,只有data是一个函数的时候,才能创建多个实例,且各实例互相独立,互不影响

19.说一下防抖节流
20.vue响应式原理
21.computed会有缓存吗
有缓存

1.computed和methods的区别
computed是计算属性,主要用于数值计算,当其他属性值变化时,它会自动更新
methods是方法,它主要用于逻辑书写
注意的是,computed是会缓存,再次使用会直接调用缓存,依赖项变化会自动重新计算。

2.watch和computed的区别,watch的高级用法
22.jsonp怎么获取跨域的数据?
23.移动端适配怎么做?
1.使用flex布局,他是按比例布局的
2.不使用px单位,使用百分比单位
3.字体使用rem单位

24.什么是事件冒泡和事件捕获,说说它们的区别
25.虚拟dom和diff算法

websocket 和 http 的区别

websocket和http都是网络通信协议
不同的是
http每次交互都需要客户端向服务器端发一个请求,然后服务器端再返回响应,这意味着每次都要建立一个tcp连接,交互完成后立即断开连接。(传统网页)
websocket提供了一个全双工通信通道,一旦建立请求后,就可以在客户端和服务器端一直传输消息,知道有一方关闭。websocket在初始握手的时候使用的是http协议,后面便建立永久连接。(在线聊天室)

websocket 和 http 相关状态码

http相关状态码(重复)
200ok:连接成功
404 not find:无法找到该网页
403:拒绝访问
500:服务器内部错误
websocked:
1000正常关闭
1006异常关闭

http 和 https 区别

一个是安全的,一个不太安全
http不提供加密服务,在传输过程中有可能被第三方窃取
https在http的基础上加了ssl协议,提供了数据加密,完整性验证和身份认证,从而确保数据在运输过程中的安全性

讲一下 JS 的事件代理 冒泡

冒泡其实挺重要的,之前的面试就考到了(魔方文娱有一题js题就是这个)
js事件代理,又叫事件委托,是利用js的事件冒泡机制来管理多个事件处理程序的技术。

什么是事件冒泡?

事件冒泡是浏览器在处理DOM事件时的一个默认行为,和它的名字类似,冒泡就是一层一层往上冒泡,你点击一个按钮,浏览器默认事件会首先在触发它的元素上执行,然后再逐级上传到DOM树的更高级。直到到达文档的根元素。

什么是事件代理(委托)?

事件委托利用了事件冒泡机制。将点击事件放在父元素上,当点击子元素是,事件发生会冒泡到父元素,此时父元素接收到点击事件,会查看target来判断具体是哪个子元素触发了事件。
比如ui标签,里面包裹5个li标签
我们利用事件代理就不需要给每个li标签都加上点击事件,只需要在父元素ul上面添加就可以了。这样写不仅简化了代码,还减少了内存使用。

文件加载失败域名重试

需要设置一个最大尝试次数,然后设置备用域名
如果文件加载失败,就使用备用域名重试,但是需要设置一个最大尝试次数,超过这个次数就停止尝试。

CSRF攻击原理

CSRF是利用受害者的身份完成的一些非法操作
攻击流程如下:
1.用户登录到信任的网站A,并保留了登录凭证cookie
2.在用户不登出网站A的情况下,访问了恶意网站B
3.B网站包含一个指向A网站的恶意链接或表单
4.用户在恶意网站上执行操作(如点击链接,提交表单),这些操作请求会发送给网站A
5.因为用户还未登出网站A,浏览器会自动带上之前的cookie
6.网站A接收到了请求,并验证了携带的cookie,它就会认为这次请求是用户正常申请的。

讲一下事件循环

事件循环是计算机处理和调度事件的一种机制
就是将发生的事件存储在队列中
事件循环机制是一个连续的过程,它不断地从事件队列中取出事件,并调用相应的事件处理程序来处理事件。

1. 请解释CSS的盒模型是什么,并描述其组成部分。

答案:CSS的盒模型是用于布局和定位元素的概念。它由内容区域、内边距、边框和外边距组成,这些部分依次包裹在元素周围。

4. 解释CSS中的定位(position)属性及其不同的取值。

答案:定位(position)属性用于控制元素的定位方式。常见的取值有:static(默认,按照文档流定位)、relative(相对定位)、absolute(绝对定位)、fixed(固定定位)和sticky(粘性定位)。

5. 解释CSS中的层叠顺序(z-index)是如何工作的。

答案:层叠顺序(z-index)用于控制元素在垂直方向上的堆叠顺序。具有较高层叠顺序值的元素将显示在较低层叠顺序值的元素之上。默认情况下,层叠顺序值为auto。

6. 解释CSS中的伪类和伪元素的区别,并给出一个示例。

答案:伪类用于向选择器添加特殊的状态,如:hover、:active等。伪元素用于向选择器添加特殊的元素,如::before、::after等。例如:

latex
/* 伪类示例 */
a:hover {
  color: red;
}

/* 伪元素示例 */
p::before {
  content: "前缀";
}

7. 解释CSS中的盒子模型的两种模式:标准模式和怪异模式。

答案:标准模式是按照W3C标准解析渲染页面的模式。怪异模式是兼容旧版本浏览器的解析渲染页面的模式。可以通过<!DOCTYPE>声明来指定使用哪种模式。

8. 解释CSS中的BFC是什么,它的作用是什么?

答案:BFC(块级格式化上下文)是CSS中的一种渲染模式,它创建了一个独立的渲染环境,其中的元素按照一定的规则进行布局和定位。BFC的作用包括:清除浮动、防止外边距重叠等。

9. 解释CSS中的flexbox布局是什么,它的优势是什么?

答案:flexbox布局是一种用于创建灵活的、响应式的布局的CSS模块。它通过flex容器和flex项目的组合来实现强大的布局能力。其优势包括简单易用、自适应性强、对齐和分布控制灵活等。

10.解释CSS中的媒体查询是什么,它的作用是什么?

答案:媒体查询是CSS中的一种技术,用于根据设备的特性和属性来应用不同的样式。通过媒体查询,可以根据屏幕尺寸、设备类型、分辨率等条件来优化页面的布局和样式。

1. 解释JavaScript的数据类型,并举例说明每种类型。

答案:JavaScript有七种数据类型:字符串(String)、数字(Number)、布尔值(Boolean)、对象(Object)、数组(Array)、空值(Null)和未定义(Undefined)。例如:

latex
let str = "Hello";
let num = 10;
let bool = true;
let obj = { name: "John" };
let arr = [1, 2, 3];
let n = null;
let undef;

2. 解释JavaScript中的变量提升(Hoisting)是什么。

答案:变量提升是指在JavaScript中,变量和函数声明会在代码执行之前被提升到作用域的顶部。这意味着可以在声明之前使用变量和函数。例如:

latex
console.log(x); // 输出 undefined
var x = 5;

3. 解释JavaScript中的闭包(Closure)是什么,并举例说明。

答案:闭包是指函数可以访问并操作其词法作用域之外的变量。它通过在函数内部创建一个内部函数,并返回该内部函数来实现。例如:

latex
function outer() {
  let x = 10;
  function inner() {
    console.log(x);
  }
  return inner;
}

let closure = outer();
closure(); // 输出 10

4. 解释JavaScript中的事件冒泡和事件捕获(Event Capturing)。

答案:事件冒泡是指事件从最具体的元素开始向父元素逐级触发,直到触发到根元素。事件捕获是指事件从根元素开始,逐级向最具体的元素触发。可以使用addEventListener方法的第三个参数来控制是使用事件冒泡还是事件捕获。

5. 解释JavaScript中的原型继承(Prototype Inheritance)是什么。

答案:原型继承是JavaScript中实现对象之间继承关系的一种机制。每个对象都有一个原型对象,它包含了共享的属性和方法。当访问对象的属性或方法时,如果对象本身没有,则会沿着原型链向上查找。可以使用Object.create()方法或设置对象的__proto__属性来实现原型继承。

6. 解释JavaScript中的异步编程,并提供一个异步操作的示例。

答案:异步编程是指在代码执行过程中,不会阻塞后续代码执行的一种编程方式。常见的异步操作包括网络请求、定时器等。例如:

latex
console.log("开始");
setTimeout(function() {
  console.log("异步操作");
}, 1000);
console.log("结束");

7. 解释JavaScript中的闭包(Closure)是什么,并举例说明。

答案:闭包是指函数可以访问并操作其词法作用域之外的变量。它通过在函数内部创建一个内部函数,并返回该内部函数来实现。例如:

latex
function outer() {
  let x = 10;
  function inner() {
    console.log(x);
  }
  return inner;
}

let closure = outer();
closure(); // 输出 10

8. 解释JavaScript中的this关键字的作用和使用场景。

答案:this关键字在JavaScript中表示当前执行上下文的对象。它的具体取值根据函数的调用方式而定。在全局作用域中,this指向全局对象(浏览器环境中为window对象)。在函数中,this的指向取决于函数的调用方式,可以通过call、apply、bind等方法来显式地指定this的值。

9. 解释JavaScript中的事件委托(Event Delegation)是什么,并提供一个使用事件委托的示例。

答案:事件委托是指将事件处理程序绑定到父元素上,而不是直接绑定到每个子元素上。当事件触发时,事件会冒泡到父元素,然后通过判断事件的目标来执行相应的处理逻辑。这样可以减少事件处理程序的数量,提高性能。例如:

latex
<ul id="list">
  <li>Item 1</li>
  <li>Item 2</li>
  <li>Item 3</li>
</ul>
<script>
document.getElementById("list").addEventListener("click", function(event) {
  if (event.target.tagName === "LI") {
    console.log(event.target.textContent);
  }
});
</script>

10. 解释JavaScript中的模块化编程,并提供一个使用模块的示例。

答案:模块化编程是指将代码划分为独立的模块,每个模块负责特定的功能,并通过导入和导出来实现模块之间的依赖关系。ES6引入了模块化的语法,可以使用import和export关键字来导入和导出模块。例如:

latex
// module.js
export function sayHello() {
  console.log("Hello!");
}

// main.js
import { sayHello } from "./module.js";
sayHello(); // 输出 "Hello!"

11. 解释JavaScript中的事件冒泡(Event Bubbling)和事件捕获(Event Capturing)。

答案:事件冒泡是指当一个事件在DOM树中触发时,它会从最内层的元素开始向外传播至最外层的元素。事件捕获是指当一个事件在DOM树中触发时,它会从最外层的元素开始向内传播至最内层的元素。

12. 什么是原型链(Prototype Chain)?如何利用原型链实现继承?

答案:原型链是JavaScript中对象之间的连接关系,每个对象都有一个指向其原型(prototype)的引用。通过原型链,对象可以继承其原型对象的属性和方法。可以使用原型链实现继承,通过将一个对象的原型指向另一个对象,从而使得该对象可以访问另一个对象的属性和方法。

13. 解释JavaScript中的防抖(Debounce)和节流(Throttle)。

答案:防抖和节流都是用于控制函数执行频率的技术。防抖指的是在某个时间段内,只执行最后一次触发的函数调用。节流指的是在某个时间段内,按照固定的时间间隔执行函数调用。

14. 什么是事件循环(Event Loop)?请解释JavaScript中的事件循环机制。

答案:事件循环是JavaScript中处理异步操作的机制。事件循环不断地从任务队列中取出任务并执行,直到任务队列为空。事件循环由主线程和任务队列组成,主线程负责执行同步任务,异步任务会被放入任务队列中,等待主线程空闲时被执行。

15. 解释JavaScript中的深拷贝和浅拷贝

答案:深拷贝是指创建一个新对象,将原始对象的所有属性和嵌套对象的属性都复制到新对象中。浅拷贝是指创建一个新对象,将原始对象的属性复制到新对象中,但嵌套对象的引用仍然是共享的。

16. 什么是异步编程?请列举几种处理异步操作的方法。

答案:异步编程是一种处理可能耗时的操作而不阻塞主线程的编程方式。常见的处理异步操作的方法有回调函数、Promise、async/await和事件监听等。

17. 解释JavaScript中的Hoisting(变量提升)。

答案:变量提升是指在JavaScript中,变量和函数的声明会被提升到当前作用域的顶部。这意味着可以在声明之前使用变量和函数,但它们的赋值或定义仍然在原来的位置。

18. 什么是柯里化(Currying)?请给出一个柯里化的示例。

答案:柯里化是一种将接受多个参数的函数转换为接受一个参数并返回一个新函数的过程。示例:

latex
function add(a) {
  return function(b) {
    return a + b;
  }
}

var add5 = add(5);
console.log(add5(3)); // 输出:8

19. 解释JavaScript中的严格模式(Strict Mode)。

答案:严格模式是一种JavaScript的执行模式,它提供了更严格的语法和错误检查。在严格模式下,一些不安全或不推荐的语法会被禁用,同时会引入一些新的特性,如变量必须先声明才能使用、禁止使用this指向全局对象等。

TypeScript

1. 解释TypeScript和JavaScript之间的关系。

答案:TypeScript是JavaScript的超集,它添加了静态类型和其他一些特性。TypeScript代码可以编译成JavaScript代码,因此可以在任何支持JavaScript的环境中运行。

2. TypeScript中的类型注解是什么?如何使用类型注解?

答案:类型注解是指在变量、函数参数、函数返回值等地方显式地声明类型信息。可以使用冒号(:)后跟类型来添加类型注解。例如:

latex
let num: number = 10;

function add(a: number, b: number): number {
  return a + b;
}

3. TypeScript中的接口是什么?如何定义和使用接口?

答案:接口是一种用于定义对象的结构和类型的语法。可以使用interface关键字来定义接口。例如:

latex
interface Person {
  name: string;
  age: number;
}

function greet(person: Person) {
  console.log(`Hello, ${person.name}!`);
}

let john: Person = { name: "John", age: 25 };
greet(john); // 输出 "Hello, John!"

4. TypeScript中的类是什么?如何定义和使用类?

答案:类是一种用于创建对象的蓝图,它包含属性和方法。可以使用class关键字来定义类。例如:

latex
class Person {
  name: string;
  age: number;

  constructor(name: string, age: number) {
    this.name = name;
    this.age = age;
  }

  greet() {
    console.log(`Hello, ${this.name}!`);
  }
}

let john = new Person("John", 25);
john.greet(); // 输出 "Hello, John!"

5. TypeScript中的泛型是什么?如何使用泛型?

答案:泛型是一种用于创建可重用代码的工具,它允许在定义函数、类或接口时使用占位符类型。可以使用尖括号(<>)来指定泛型类型。例如:

latex
function identity<T>(value: T): T {
  return value;
}

let result = identity<string>("Hello");
console.log(result); // 输出 "Hello"

6. TypeScript中的枚举是什么?如何定义和使用枚举?

答案:枚举是一种用于定义命名常量集合的语法。可以使用enum关键字来定义枚举。例如:

latex
enum Color {
  Red,
  Green,
  Blue,
}

let color: Color = Color.Green;
console.log(color); // 输出 1

7. TypeScript中的模块是什么?如何导出和导入模块?

答案:模块是用于组织和封装代码的单元。可以使用export关键字将模块中的变量、函数、类等导出,以便其他模块可以使用。可以使用import关键字来导入其他模块的导出。例如:

latex
// module.ts
export function greet(name: string) {
  console.log(`Hello, ${name}!`);
}

// main.ts
import { greet } from "./module";
greet("John"); // 输出 "Hello, John!"

8. TypeScript中的类型推断是什么?如何使用类型推断?

答案:类型推断是指TypeScript根据上下文自动推断变量的类型,而无需显式地添加类型注解。例如:

latex
let num = 10; // 推断为 number 类型
let str = "Hello"; // 推断为 string 类型

9. TypeScript中的命名空间是什么?如何定义和使用命名空间?

答案:命名空间是一种用于组织和封装代码的机制,它避免了全局命名冲突。可以使用namespace关键字来定义命名空间。例如:

latex
namespace MyNamespace {
  export function greet(name: string) {
    console.log(`Hello, ${name}!`);
  }
}

MyNamespace.greet("John"); // 输出 "Hello, John!"

10. TypeScript中的类型别名是什么?如何定义和使用类型别名?

答案:类型别名是给类型起一个别名,以便在代码中更方便地引用。可以使用type关键字来定义类型别名。例如:

latex
type Point = { x: number; y: number };

function printPoint(point: Point) {
  console.log(`(${point.x}, ${point.y})`);
}

let p: Point = { x: 1, y: 2 };
printPoint(p); // 输出 "(1, 2)"

1. Vue.js是什么?它有哪些特点?

答案:Vue.js是一个用于构建用户界面的JavaScript框架。它具有以下特点:

响应式数据绑定:通过使用Vue的数据绑定语法,可以实现数据的自动更新。 组件化开发:Vue允许将页面划分为独立的组件,提高了代码的可维护性和复用性。 虚拟DOM:Vue使用虚拟DOM来跟踪页面上的变化,并高效地更新实际的DOM。 指令系统:Vue提供了丰富的内置指令,用于处理常见的DOM操作和逻辑控制。 生态系统:Vue拥有庞大的生态系统,包括插件、工具和第三方库,可以满足各种开发需求。

2. Vue中的双向数据绑定是如何实现的?

答案:Vue中的双向数据绑定是通过v-model指令实现的。v-model可以在表单元素(如<input>、<textarea>、<select>)上创建双向数据绑定。当用户输入改变表单元素的值时,数据模型会自动更新;反之,当数据模型的值改变时,表单元素也会自动更新。

3. Vue中的生命周期钩子有哪些?它们的执行顺序是怎样的?

答案:Vue中的生命周期钩子包括beforeCreate、created、beforeMount、mounted、beforeUpdate、updated、beforeDestroy和destroyed。它们的执行顺序如下:

beforeCreate created beforeMount mounted beforeUpdate updated beforeDestroy destroyed

4. Vue中的计算属性和监听器有什么区别?

答案:计算属性是基于依赖的属性,它根据其依赖的数据动态计算得出值。计算属性具有缓存机制,只有在依赖的数据发生变化时才会重新计算。监听器是用于监听数据的变化并执行相应的操作。当数据发生变化时,监听器会立即执行指定的回调函数。

5. Vue中的组件通信有哪些方式?

答案:Vue中的组件通信方式包括:

父子组件通信:通过props向子组件传递数据,子组件通过事件向父组件发送消息。 子父组件通信:子组件通过$emit触发事件,父组件通过监听事件并响应。 兄弟组件通信:通过共享的父组件来传递数据或通过事件总线(Event Bus)进行通信。 跨级组件通信:通过provide和inject来在祖先组件中提供数据,然后在后代组件中使用。

6. Vue中的路由是如何实现的?

答案:Vue中的路由是通过Vue Router实现的。Vue Router是Vue.js官方提供的路由管理器,它允许开发者在Vue应用中实现单页面应用(SPA)。Vue Router通过配置路由映射关系,将URL路径与组件进行关联,并提供导航功能,使用户可以在不刷新页面的情况下切换视图。

7. Vue中的指令有哪些?举例说明它们的用法。

答案:Vue中常用的指令包括:

v-if:根据表达式的值条件性地渲染元素。 v-for:根据数组或对象的数据进行循环渲染。 v-bind:用于动态绑定属性或响应式地更新属性。 v-on:用于监听DOM事件并执行相应的方法。 v-model:用于在表单元素上实现双向数据绑定。 例如:

latex
<div v-if="show">显示内容</div>
<ul>
  <li v-for="item in items" :key="item.id">{{ item.name }}</li>
</ul>
<img v-bind:src="imageUrl">

<button v-on:click="handleClick">点击按钮</button>
<input v-model="message">

8. Vue中的watch和computed有什么区别?

答案:watch和computed都可以用于监听数据的变化,但它们的用法和实现方式略有不同。watch用于监听指定的数据变化,并在数据变化时执行相应的操作。computed用于根据依赖的数据动态计算得出一个新的值,并将该值缓存起来,只有在依赖的数据发生变化时才会重新计算。

9. Vue中的mixin是什么?它有什么作用?

答案:Mixin是一种用于在多个组件之间共享代码的方式。Mixin可以包含组件选项(如数据、方法、生命周期钩子等),并将其合并到使用Mixin的组件中。这样可以实现代码的复用和组件的扩展,减少重复编写相似代码的工作。

10. Vue中的keep-alive是什么?它有什么作用?

答案:是Vue中的一个内置组件,用于缓存动态组件。当组件包裹在中时,组件的状态将被保留,包括它的实例、状态和DOM结构。这样可以避免在组件切换时重复创建和销毁组件,提高性能和用户体验。

11. 请解释Vue.js中的依赖注入(Dependency Injection)是什么?它在Vue中的应用场景是什么?

答案:依赖注入是一种设计模式,用于将依赖关系从一个组件传递到另一个组件。在Vue中,依赖注入通过provide和inject选项实现。父组件通过provide提供数据,然后子组件通过inject注入这些数据。它在跨多个层级的组件通信中非常有用。

12. Vue.js中的渲染函数(Render Function)是什么?它与模板(Template)有什么区别?

答案:渲染函数是一种用JavaScript代码编写组件的方式,它可以动态地生成虚拟DOM。与模板相比,渲染函数提供了更大的灵活性和控制力,可以处理更复杂的逻辑和动态渲染需求。

13. Vue.js中的插槽(Slot)是什么?请提供一个具有命名插槽和作用域插槽的示例。

答案:插槽是一种用于在组件中扩展内容的机制。命名插槽允许父组件向子组件插入具有特定名称的内容,而作用域插槽允许子组件将数据传递给父组件。示例:

latex
<!-- 父组件 -->
<template>
  <div>
    <slot name="header"></slot>
    <slot :data="data"></slot>
  </div>
</template>
<!-- 子组件 -->
<template>
  <div>
    <slot name="header">默认标题</slot>
    <slot :data="computedData">{{ computedData }}</slot>
  </div>
</template>

14. Vue.js中的动画系统是如何工作的?请提供一个简单的动画示例。

答案:Vue.js的动画系统通过CSS过渡和动画类实现。通过在元素上添加过渡类或动画类,可以触发相应的过渡效果或动画效果。示例:

latex
<transition name="fade">
  <div v-if="show">显示内容</div>
</transition>
<!-- CSS样式 -->
<style>
.fade-enter-active, .fade-leave-active {
  transition: opacity 0.5s;
}
.fade-enter, .fade-leave-to {
  opacity: 0;
}
</style>

15. Vue.js中的错误处理机制是什么?如何捕获和处理Vue组件中的错误?

答案:Vue.js提供了全局的错误处理机制和组件级别的错误处理机制。全局错误处理可以通过errorCaptured钩子函数捕获和处理错误。组件级别的错误处理可以通过errorCaptured钩子函数或errorHandler选项捕获和处理错误。

16. Vue.js中的服务端渲染(SSR)是什么?它有哪些优势和限制?

答案:服务端渲染是指在服务器上生成HTML内容并将其发送到浏览器进行渲染的过程。Vue.js可以进行服务端渲染,提供更好的首次加载性能和SEO优化。然而,服务端渲染也带来了一些限制,如增加了服务器负载和开发复杂性。

17. Vue.js中的响应式数组有哪些限制?如何解决这些限制?

答案:Vue.js的响应式系统对于数组的变异方法(如push、pop、splice等)是无法追踪的。为了解决这个限制,Vue提供了一些特殊的方法,如Vue.set、vm.$set和Array.prototype.splice。这些方法可以用于更新数组并保持响应式。

18. Vue.js中的性能优化有哪些常见的技巧?

答案:常见的Vue.js性能优化技巧包括:

使用v-if和v-for时注意避免不必要的渲染。 合理使用computed属性和watch监听器。 使用keep-alive组件缓存组件状态。 使用异步组件进行按需加载。 避免在模板中使用复杂的表达式。 使用key属性管理组件和元素的复用。 合理使用懒加载和分割代码。

19. Vue.js中的路由导航守卫有哪些?它们的执行顺序是怎样的?

答案:Vue.js中的路由导航守卫包括全局前置守卫、全局解析守卫、全局后置守卫、路由独享守卫和组件内守卫。它们的执行顺序如下:

全局前置守卫(beforeEach) 路由独享守卫(beforeEnter) 解析守卫(beforeResolve) 组件内守卫(beforeRouteEnter、beforeRouteUpdate、beforeRouteLeave) 全局后置守卫(afterEach)

20. Vue.js中的单元测试是如何进行的?请提供一个简单的单元测试示例。

答案:Vue.js的单元测试可以使用工具如Jest或Mocha进行。示例:

latex
// 组件代码
// MyComponent.vue
<template>
  <div class="my-component">
    <span>{{ message }}</span>
    <button @click="increment">增加</button>
  </div>
</template>
<script>
export default {
  data() {
    return {
      message: 'Hello',
      count: 0
    }
  },
  methods: {
    increment() {
      this.count++
    }
  }
}
</script>
// 单元测试代码
// MyComponent.spec.js
import { shallowMount } from '@vue/test-utils'
import MyComponent from './MyComponent.vue'

describe('MyComponent', () => {
  it('renders message correctly', () => {
    const wrapper = shallowMount(MyComponent)
    expect(wrapper.find('span').text()).toBe('Hello')
  })

  it('increments count when button is clicked', () => {
    const wrapper = shallowMount(MyComponent)
    wrapper.find('button').trigger('click')
    expect(wrapper.vm.count).toBe(1)
  })
})

VUE3

1. Vue.js 3中的Composition API是什么?它与Options API有什么区别?

答案:Composition API是Vue.js 3中引入的一种新的组织组件逻辑的方式。它允许开发者通过函数的方式组织和重用逻辑,而不是通过选项对象。相比之下,Options API是Vue.js 2中常用的组织组件逻辑的方式,通过选项对象中的属性来定义组件的数据、方法等。

2. Vue.js 3中的Teleport是什么?请给出一个Teleport的示例。

答案:Teleport是Vue.js 3中引入的一种机制,用于将组件的内容渲染到DOM树中的任意位置。示例:

latex
<template>
  <div>
    <button @click="showModal = true">打开模态框</button>
    <teleport to="body">
      <modal v-if="showModal" @close="showModal = false">模态框内容</modal>
    </teleport>
  </div>
</template>

3. Vue.js 3中的响应式系统是如何工作的?它与Vue.js 2中的响应式系统有什么区别?

答案:Vue.js 3中的响应式系统使用了Proxy对象来实现。与Vue.js 2中的响应式系统相比,Vue.js 3的响应式系统具有更好的性能和更细粒度的追踪,能够更准确地检测到数据的变化,并且支持嵌套的响应式数据。

4. Vue.js 3中的Suspense是什么?它的作用是什么?

答案:Suspense是Vue.js 3中引入的一种机制,用于处理异步组件的加载状态。它可以在异步组件加载完成之前显示一个占位符,并在加载完成后渲染异步组件的内容。这样可以更好地处理异步组件的加载过程,提供更好的用户体验。

5. Vue.js 3中的provide和inject有什么作用?请给出一个provide和inject的示例。

答案:provide和inject用于实现组件之间的依赖注入。通过在父组件中使用provide提供数据,然后在子组件中使用inject注入这些数据。示例:

latex
// 父组件
const Parent = {
  provide: {
    message: 'Hello'
  },
  // ...
}

// 子组件
const Child = {
  inject: ['message'],
  created() {
    console.log(this.message); // 输出:Hello
  },
  // ...
}

6. Vue.js 3中的动画系统有哪些改进?请列举几个改进之处。

答案:Vue.js 3中的动画系统相比Vue.js 2有以下改进之处:

更好的性能:Vue.js 3的动画系统使用了更高效的动画引擎,提供了更好的性能。 更简洁的语法:Vue.js 3的动画系统使用了更简洁的语法,使得动画的定义和使用更加直观和方便。 支持更多的动画特性:Vue.js 3的动画系统支持更多的动画特性,如交互式动画和更复杂的动画效果。 Vue.js 3中的静态提升(Static Tree Hoisting)是什么?它有什么优势? 答案:静态提升是Vue.js 3中的一项优化技术,通过在编译阶段将静态节点提升为常量,从而减少了运行时的开销。这项优化技术可以提高组件的渲染性能,并减少生成的代码体积。

7. Vue.js 3中的Fragment是什么?它的作用是什么?

答案:Fragment是Vue.js 3中引入的一种机制,用于在组件中返回多个根节点。在Vue.js 2中,组件的模板只能有一个 Vue.js 3中的Composition API中的ref和reactive有什么区别?什么时候使用哪个? 答案:ref用于创建一个响应式的基本数据类型,而reactive用于创建一个响应式的对象。当需要创建一个简单的响应式数据时,可以使用ref,当需要创建一个包含多个属性的响应式对象时,可以使用reactive。

8. Vue.js 3中的watchEffect和watch有什么区别?什么时候使用哪个?

答案:watchEffect用于监听响应式数据的变化,并在回调函数中执行相应的操作。它会自动追踪依赖,并在依赖变化时重新运行回调函数。watch用于监听指定的响应式数据,并在其变化时执行相应的操作。它可以精确地指定要监听的数据,并提供更多的配置选项。一般来说,如果只需要监听一个响应式数据的变化并执行相应操作,可以使用watchEffect;如果需要更细粒度的控制,可以使用watch。

9. Vue.js 3中的v-model指令在使用时有哪些注意事项?

答案:在使用v-model指令时,有以下注意事项:

v-model指令必须与一个表单元素一起使用,如<input>、<select>、<textarea>等。 当使用自定义组件时,组件内部必须实现modelValue属性和update:modelValue事件,以支持v-model的双向绑定。 可以使用.lazy修饰符实现在输入框失去焦点时更新数据。 可以使用.trim修饰符自动去除输入框内容的首尾空格。 可以使用.number修饰符将输入框的值转换为数字类型。

10. Vue.js 3中的provide和inject是否支持响应式数据?

答案:默认情况下,provide和inject不支持响应式数据。如果需要在provide中提供一个响应式数据,可以使用ref或reactive将数据包装起来。然后在inject中使用toRefs或toRef将数据解构出来,以获取响应式的引用。

11. Vue.js 3中的nextTick方法有什么作用?在什么情况下使用它?

答案:nextTick方法用于在下次DOM更新循环结束之后执行回调函数。它可以用来确保在更新DOM后执行某些操作,如操作更新后的DOM元素或获取更新后的计算属性的值。通常在需要等待DOM更新完成后进行操作的情况下使用nextTick。

12. Vue.js 3中的和组件有什么区别?

答案:组件用于将组件的内容渲染到DOM树中的任意位置,而组件用于在组件进入或离开DOM树时应用过渡效果。主要用于组件的位置移动,而主要用于组件的显示和隐藏过渡。

13. Vue.js 3中的v-for指令中的key属性有什么作用?为什么要使用它?

答案:v-for指令中的key属性用于给每个迭代项设置一个唯一的标识符。它的作用是帮助Vue.js跟踪每个节点的身份,以便在数据发生变化时高效地更新DOM。使用key属性可以避免出现错误的节点更新或重新排序的问题。

React

1. 什么是React?它的核心概念是什么?

答案:React是一个用于构建用户界面的JavaScript库。它的核心概念是组件化和声明式编程。React将用户界面拆分为独立的可重用组件,并使用声明式语法描述组件的状态和UI的关系,使得构建复杂的UI变得简单和可维护。

2. 什么是JSX?它与HTML有什么区别?

答案:JSX是一种JavaScript的语法扩展,用于在React中描述UI的结构。它类似于HTML,但有一些区别:

3. 什么是React组件?它们有哪两种类型?

答案:React组件是构建用户界面的独立单元。React组件有两种类型:

函数组件:使用函数来定义组件,接收props作为参数,并返回一个React元素。 类组件:使用ES6类来定义组件,继承自React.Component类,通过render方法返回一个React元素。

4. 什么是状态(state)和属性(props)?它们之间有什么区别?

答案:状态(state)是组件自身管理的数据,可以通过setState方法来更新。属性(props)是从父组件传递给子组件的数据,子组件无法直接修改props,只能通过父组件的更新来改变props。

区别:

状态(state)是组件内部的数据,可以在组件中自由修改和管理。 属性(props)是从父组件传递给子组件的数据,子组件无法直接修改,只能接收和使用。

5. 什么是React生命周期方法?列举一些常用的生命周期方法。

答案:React生命周期方法是在组件不同阶段执行的特定方法。以下是一些常用的React生命周期方法:

componentDidMount:组件挂载后立即调用。 componentDidUpdate:组件更新后调用。 componentWillUnmount:组件卸载前调用。 shouldComponentUpdate:决定组件是否需要重新渲染。 getDerivedStateFromProps:根据props的变化来更新状态。

6. 什么是React Hooks?它们的作用是什么?

答案:React Hooks是React 16.8版本引入的一种特性,用于在函数组件中使用状态和其他React特性。Hooks提供了一种无需编写类组件的方式来管理状态和处理副作用,使得函数组件具有类组件的能力。

7. 什么是React Router?它的作用是什么?

答案:React Router是React中用于处理路由的库。它提供了一种在单页面应用中实现导航和路由功能的方式。React Router可以帮助开发者实现页面之间的切换、URL参数的传递、嵌套路由等功能。

8. 什么是React Context?它的作用是什么?

答案:React Context是一种用于在组件树中共享数据的机制。它可以避免通过props一层层传递数据,使得跨组件的数据共享变得更加简单和高效。React Context提供了一个Provider和Consumer组件,用于提供和消费共享的数据。

9. 什么是React的协调(Reconciliation)过程?它是如何工作的?

答案:React的协调过程是指React在进行组件更新时,通过比较新旧虚拟DOM树的差异,仅对需要更新的部分进行实际的DOM操作。协调过程的工作方式如下:

React会逐层比较新旧虚拟DOM树的节点,并找出差异。 对于每个差异,React会生成相应的DOM操作指令,如插入、更新或删除节点。 React会将所有的DOM操作指令批量执行,以减少对真实DOM的操作次数。

10. 什么是React的事件合成(SyntheticEvent)?它的作用是什么?

答案:React的事件合成是一种在React中处理事件的机制。它是React为了提高性能和跨浏览器兼容性而实现的一种事件系统。事件合成的作用包括:

提供了一种统一的方式来处理事件,无需考虑浏览器兼容性。 可以通过事件委托的方式将事件处理程序绑定到父组件,提高性能。 可以访问原生事件对象的属性和方法。

11. 什么是React的Fiber架构?它解决了什么问题?

答案:React的Fiber架构是React 16版本引入的一种新的协调算法和架构。它旨在解决长时间渲染阻塞主线程的问题,提高应用的性能和用户体验。Fiber架构通过将渲染过程分解为多个小任务,并使用优先级调度算法来动态分配时间片,使得React可以在每个帧中执行一部分任务,从而实现平滑的用户界面和更好的响应性能。

12. 什么是React的错误边界(Error Boundary)?它的作用是什么?

答案:React的错误边界是一种用于处理组件错误的机制。它允许组件捕获并处理其子组件中发生的JavaScript错误,以避免整个应用崩溃。错误边界的作用包括:

捕获并处理组件树中的错误,防止错误导致整个应用崩溃。 提供一种优雅的方式来显示错误信息或备用UI。 可以用于记录错误和发送错误报告。

网络

1. 什么是HTTP?它是如何工作的?

答案:HTTP(Hypertext Transfer Protocol)是一种用于在Web上传输数据的协议。它使用客户端-服务器模型,客户端发送HTTP请求到服务器,服务器返回HTTP响应。HTTP的工作流程如下:

客户端发送HTTP请求到指定的URL。 服务器接收请求并处理,然后返回HTTP响应。 客户端接收响应并解析,从中获取所需的数据。

2. 什么是HTTPS?与HTTP有什么区别?

答案:HTTPS(Hypertext Transfer Protocol Secure)是HTTP的安全版本,通过使用SSL(Secure Sockets Layer)或TLS(Transport Layer Security)协议对通信进行加密和身份验证。与HTTP相比,HTTPS具有以下区别:

数据在传输过程中通过加密进行保护,提供更高的安全性。 使用数字证书对服务器进行身份验证,防止中间人攻击。 使用默认端口443。

3. 什么是跨域请求?它是如何解决的?

答案:跨域请求是指在浏览器中向不同域名、端口或协议发送的请求。由于浏览器的同源策略(Same-Origin Policy)限制,跨域请求会受到限制。为了解决跨域问题,可以使用以下方法:

JSONP(JSON with Padding):通过动态创建<script>标签来加载跨域的JavaScript文件。 CORS(Cross-Origin Resource Sharing):在服务器端设置响应头,允许指定域名的跨域请求。 代理服务器:在同域名下设置一个代理服务器,将跨域请求转发到目标服务器。

4. 什么是缓存?在前端中如何使用缓存来提高性能?

答案:缓存是将数据或资源存储在临时存储中,以便在后续请求中重复使用,从而提高性能和减少网络流量。在前端中,可以使用以下方式来利用缓存:

HTTP缓存:通过设置适当的缓存头(如Cache-Control和Expires)来指示浏览器缓存响应。 资源缓存:使用文件指纹或版本号来重命名静态资源文件,以便在文件内容变化时使浏览器重新下载。 数据缓存:使用内存缓存、浏览器本地存储(如localStorage)或服务端缓存(如Redis)来存储数据,避免重复请求。

5. 什么是CDN?它的作用是什么?

答案:CDN(Content Delivery Network)是一种分布式网络架构,用于在全球各地提供高性能、低延迟的内容传输服务。CDN的作用包括:

将静态资源(如图片、样式表、脚本等)缓存到离用户更近的服务器上,提供更快的加载速度。 分发网络流量,减轻源服务器的负载压力。 提供内容压缩、数据压缩和缓存等优化技术,提高用户体验。

6. 什么是网页加载性能优化?可以采取哪些措施来改善网页加载性能?

答案:网页加载性能优化是指通过各种技术手段来减少网页加载时间并提高用户体验。可以采取以下措施来改善网页加载性能:

压缩和合并资源文件(如CSS和JavaScript),减少文件大小和请求数量。 使用图像压缩和适当的格式选择来减小图像文件大小。 使用浏览器缓存和HTTP缓存头来缓存静态资源。 使用懒加载延迟加载非关键资源,提高初始加载速度。 使用CDN(内容分发网络)来分发静态资源,减少网络延迟。 优化关键渲染路径,尽早呈现页面内容。

7. 什么是网页性能监测和分析?可以使用哪些工具来监测和分析网页性能?

答案:网页性能监测和分析是指通过测量和收集有关网页加载和交互性能的数据,以便识别性能瓶颈并进行优化。可以使用以下工具来监测和分析网页性能:

Web性能API:浏览器提供的JavaScript API,可通过performance对象来收集性能数据。 Lighthouse:一种开源工具,可提供关于网页性能、可访问性和最佳实践的综合报告。 WebPagetest:在线工具,可测量网页加载时间并提供详细的性能分析报告。 Chrome开发者工具:浏览器内置的开发者工具,提供了性能分析、网络监控和页面审查等功能。

8. 什么是渐进式图像加载(Progressive Image Loading)?它如何改善网页加载性能?

答案:渐进式图像加载是一种技术,通过逐步加载图像的模糊或低分辨率版本,然后逐渐提高图像的清晰度,以改善网页加载性能和用户体验。渐进式图像加载的好处包括:

用户可以更快地看到页面内容,提高感知速度。 逐步加载图像可以减少网页整体的加载时间。 渐进式图像加载可以提供平滑的过渡效果,避免页面内容突然闪烁或变化。

9. 什么是前端资源优先级(Resource Prioritization)?如何设置资源的优先级?

答案:前端资源优先级是指为不同类型的资源分配加载优先级,以优化网页加载性能。可以使用以下方法设置资源的优先级:

使用<link rel="preload">标签来指定资源的预加载,以确保关键资源尽早加载。 使用<link rel="prefetch">标签来指定可能在未来页面中使用的资源,以提前加载。 使用<link rel="dns-prefetch">标签来指定要预解析的域名,以减少DNS查找时间。 使用<link rel="preconnect">标签来指定要预连接的域名,以减少建立连接的时间。

浏览器

1.解释一下浏览器的工作原理。

答案:浏览器的工作原理包括以下几个关键步骤:

解析:浏览器将接收到的HTML、CSS和JavaScript代码解析成DOM树、CSSOM树和JavaScript引擎可执行的代码。 渲染:浏览器使用DOM树和CSSOM树构建渲染树,然后根据渲染树进行布局(计算元素的位置和大小)和绘制(将元素绘制到屏幕上)。 布局和绘制:浏览器根据渲染树的变化进行布局和绘制,然后将最终的页面呈现给用户。 JavaScript引擎执行:浏览器的JavaScript引擎解释和执行JavaScript代码,并根据需要更新渲染树和重新渲染页面。

3. 什么是事件冒泡和事件捕获?它们之间有什么区别?

答案:事件冒泡和事件捕获是指浏览器处理事件时的两种不同的传播方式。

事件冒泡是指事件从最内层的元素开始触发,然后逐级向上传播到父元素,直到传播到最外层的元素。

事件捕获是指事件从最外层的元素开始触发,然后逐级向下传播到最内层的元素。

区别在于传播方向的不同。事件冒泡是从内向外传播,而事件捕获是从外向内传播。

4. 解释一下同步和异步的JavaScript代码执行方式。

答案:同步代码是按照顺序执行的代码,每个任务必须等待前一个任务完成后才能执行。同步代码会阻塞后续代码的执行,直到当前任务完成。

异步代码是不按照顺序执行的代码,它会在后台执行,不会阻塞后续代码的执行。异步代码通常使用回调函数、Promise、async/await等方式来处理异步操作的结果。

通过异步执行,可以避免阻塞主线程,提高页面的响应性能。

5. 什么是事件循环(Event Loop)?它在JavaScript中的作用是什么?

答案:事件循环是JavaScript中处理异步代码执行的机制。它负责管理调度和执行异步任务,并将它们添加到执行队列中。

在JavaScript中,事件循环的作用是确保异步任务按照正确的顺序执行,并且不会阻塞主线程。它通过不断地从执行队列中取出任务并执行,以实现非阻塞的异步操作。

6. 解释一下浏览器的垃圾回收机制是如何工作的。

答案:浏览器的垃圾回收机制是一种自动管理内存的机制,用于检测和回收不再使用的对象,以释放内存资源。

垃圾回收机制通过标记-清除算法实现。它的工作原理如下:

标记阶段:垃圾回收器会从根对象(如全局对象)开始,递归遍历所有对象,并标记仍然可访问的对象。 清除阶段:垃圾回收器会扫描堆内存,清除未被标记的对象,并回收它们所占用的内存空间。 垃圾回收机制的目标是识别和回收不再使用的对象,以避免内存泄漏和提高内存利用率。

7. 解释一下浏览器的同源策略(Same-Origin Policy)及其限制。

答案:同源策略是浏览器的一项安全机制,用于限制来自不同源的网页之间的交互。同源是指协议、域名和端口号完全相同。

同源策略的限制包括:

脚本访问限制:不同源的脚本无法直接访问彼此的数据和操作。 DOM访问限制:不同源的网页无法通过JavaScript访问彼此的DOM元素。 Cookie限制:不同源的网页无法读取或修改彼此的Cookie。 AJAX请求限制:不同源的网页无法通过AJAX请求访问彼此的数据。 同源策略的存在可以防止恶意网站获取用户的敏感信息或进行恶意操作。

8. 什么是Web Workers?它们在浏览器中的作用是什么?

答案:Web Workers是一种浏览器提供的JavaScript API,用于在后台线程中执行耗时的计算任务,以避免阻塞主线程。

Web Workers的作用是提高浏览器的响应性能,使得在执行复杂计算或处理大量数据时,不会影响用户界面的流畅性。

Web Workers通过将任务委托给后台线程来实现并行处理,从而充分利用多核处理器的能力。它们可以与主线程进行通信,但不能直接访问DOM或执行UI相关的操作。

9. 解释一下浏览器缓存(Browser Cache)是什么,以及它的作用是什么?

答案:浏览器缓存是浏览器在本地存储Web页面和资源的副本,以便在后续访问时可以快速加载。它的作用是减少对服务器的请求次数和网络传输量,提高页面加载速度和用户体验。

浏览器缓存通过在首次请求时将资源保存到本地,并在后续请求时检查资源是否已经存在并且没有过期来工作。如果资源已经存在且未过期,浏览器会直接从缓存中加载资源,而不是从服务器重新下载。

10. 什么是重定向(Redirect)?它在浏览器中的作用是什么?

答案:重定向是指当浏览器请求一个URL时,服务器返回一个不同的URL,从而将浏览器的请求重定向到新的URL上。

重定向在浏览器中的作用是实现页面的跳转、URL的修改或资源的重定向。它可以用于多种情况,例如处理旧链接的跳转、实现URL的规范化、处理用户认证等。

重定向通过在HTTP响应中设置特定的状态码(如301永久重定向、302临时重定向)和Location头部字段来实现。

11. 什么是浏览器存储(Browser Storage)?它有哪些不同的存储机制?

答案:浏览器存储是浏览器提供的一种在客户端存储数据的机制,用于在不同的网页间共享数据或持久保存数据。

浏览器存储有以下不同的存储机制:

Cookie:小型文本文件,可以存储少量数据,并在每次HTTP请求中自动发送到服务器。 Web Storage(localStorage和sessionStorage):可以存储较大量的数据,以键值对的形式存储在浏览器中。 IndexedDB:一种高级的客户端数据库,可以存储大量结构化数据,并支持索引和事务操作。 Cache API:用于缓存网络请求的响应,以便离线访问或提高页面加载速度。 不同的存储机制适用于不同的需求,开发者可以根据具体情况选择合适的存储方式。

实现一个模态框:1. 在父盒子中上下左右居中 2. 宽高不固定, 由内容撑开 3. 外层有灰色蒙版,透明度为0.5 4. 自下向上弹出(可选)

JavaScript实现一个带并发限制的异步调度器, 保证同时最多运行2个任务

一个乱序的包含不重复的从1到100的数组, 现在去掉一个数字, 怎么找出这个数字,要求空间复杂度最小

一共有100本书, 你和另一人每次只能拿1~5本, 如果你先拿, 如何保证自己拿到最后一本?

给定一个正整数数组和n, 求最短子数组, 要求子数组之和大于等于n

爬楼梯

反转数组

方法一:数组方法

javascript
const arr = [1,2,3,4,5]
function reverse(arr){
    return arr.reverse()
}

console.log('原数组:',arr)
console.log('反转数组:',reverse(arr))

方法二:左右指针

javascript
const arr = [1,2,3,4,5]
function reverse(arr){
    let left = 0;
    let right = arr.length - 1;
    while(left < right){
        [arr[left],arr[right]] = [arr[right],arr[left]];
        left++;
        right--;
    }
    return arr;
}

console.log('原数组:',arr)
console.log('反转数组:',reverse(arr))

实现每隔s秒执行n次函数

单例模式

观察者模式

怎么让页面上的某块区域全屏展示?

关键部分

javascript
const fullDiv = document.querySelector('.container');
function enterFullScreen(){
    if(fullDiv.requestFullscreen){
        fullDiv.requestFullscreen()
    }

}
function exitFullScreen(){
    if(document.exitFullscreen){
        document.exitFullscreen()
    }
}

完整代码

html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>全屏展示</title>
</head>
<body>
    <div class="container">
        <div>待全屏展示内容</div>
        <button onclick="enterFullScreen()">全屏展示</button>
        <button onclick="exitFullScreen()">退出全屏</button>
    </div>
</body>
<style>
    .container{
        width: 300px;
        height: 200px;
        background-color: lightcoral;
    }
</style>
<script>
    const fullDiv = document.querySelector('.container');
    function enterFullScreen(){
        if(fullDiv.requestFullscreen){
            fullDiv.requestFullscreen()
        }
        
    }
    function exitFullScreen(){
        if(document.exitFullscreen){
            document.exitFullscreen()
        }
    }
    document.addEventListener('fullscreenchange',()=>{
        if(document.fullscreenElement){
            console.log('进入全屏')
        }else{
            console.log('退出全屏')
        }
    })
</script>
</html>

怎么在页面上获取用户的定位信息?

关键代码

javascript
navigator.geolocation.getCurrentPosition(showPosition,showError)

function showPosition(position){
    const latitude = position.coords.latitude;
    const longitude = position.coords.longitude;
    info.innerHTML = `您的位置是:纬度${latitude},经度${longitude}`;
    console.log('位置精度',position.coords.accuracy,'米');
}

完整代码

html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>定位</title>
</head>
<body>
    <button id="getLocationBtn">获取我的位置</button>
    <p id="locationInfo"></p>
</body>
<script>
    const btn = document.getElementById('getLocationBtn');
    const info = document.getElementById('locationInfo');

    btn.addEventListener('click',()=>{
        info.innerHTML = '正在获取位置···';
        navigator.geolocation.getCurrentPosition(showPosition,showError)
    })

    function showPosition(position){
        const latitude = position.coords.latitude;
        const longitude = position.coords.longitude;
        info.innerHTML = `您的位置是:纬度${latitude},经度${longitude}`;
        console.log('位置精度',position.coords.accuracy,'米');
    }

    function showError(error){
        switch(eerror.code){
            case error.PERMISSION_DENIED:
                info.innerHTML = "用户拒绝了地理定位请求。";
                break;
            case error.POSITION_UNAVAILABLE:
                info.innerHTML = "位置信息不可用。";
                break;
            case error.TIMEOUT:
                info.innerHTML = "请求超时。";
                break;
            case error.UNKNOWN_ERROR:
                info.innerHTML = "发生未知错误。";
                break;
        }
    }
</script>
</html>

在 DOM 中,如何判定 a 元素是否是 b 元素的子元素?

关键代码

plain
const a = document.querySelector('.parent');
const b = document.querySelector('.child');
console.log(a.contains(b));

完整代码

html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>包含</title>
</head>
<body>
    <div class="parent">
        <div class="child"></div>
    </div>
</body>
<script>
    const a = document.querySelector('.parent');
    const b = document.querySelector('.child');
    console.log(a.contains(b));
</script>
</html>

三列布局

完整代码

html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>三列布局</title>
</head>
<body>
    <div class="container">
        <div>flex布局</div>
        <div class="flexbox">
            <div class="flex box">左</div>
            <div class="flex box">中</div>
            <div class="flex box">右</div>
        </div>
        <div>grid布局</div>
        <div class="gridbox">
            <div class="box">左</div>
            <div class="box">中</div>
            <div class="box">右</div>
        </div>
        <div>浮动布局</div>
        <div class="floatbox">
            <div class="float box">左</div>
            <div class="float box">中</div>
            <div class="float box">右</div>
        </div>
        <div>定位布局</div>
        <div class="positionbox">
            <div class="position box">左</div>
            <div class="position box">中</div>
            <div class="position box">右</div>
        </div>
    </div>
</body>
<style>
.container{
    width: 100%;
}

.box{
    height: 200px;
    box-sizing: border-box;
    border: 1px solid black;
}

.flexbox{
    display: flex;
    gap: 10px;
}

.flex{
    flex: 1;
}

.gridbox{
    display: grid;
    gap: 10px;
    grid-template-columns: repeat(3,1fr);
}

.floatbox{
    overflow: hidden;
}

.float{
    float: left;
    width: calc((100% - 20px) / 3);
    margin-right: 10px;
}

.float:last-child{
    margin-right: 0;
}

.positionbox{
    position: relative;
    height: 200px;
    width: 100%;
}

.position{
    position: absolute;
    width: calc((100% - 20px) / 3);
}

.position:nth-child(1){
    left: 0;
}

.position:nth-child(2){
    left: calc((100% - 20px) / 3 + 10px);
}

.position:nth-child(3){
    left: calc((100% - 20px) / 3 * 2 + 20px);
}

</style>
</html>

卡片翻转

完整代码

html
<!doctype html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>卡片翻转</title>
  </head>
  <body>
    <div class="container">
      <div class="cardbox">
        <div class="card">
          <div class="front">正面</div>
          <div class="back">反面</div>
        </div>
      </div>
    </div>
  </body>
  <style>
    .container {
      width: 100%;
      display: flex;
      justify-content: center;
      align-items: center;
      padding-top: 50px;
    }

    .cardbox{
      perspective: 1000px;
      width: 200px;
      height: 300px;
      border-radius: 30px;
    }

    .card {
      width: 100%;
      height: 100%;
      position: relative;
      transform-style: preserve-3d;
      transition: transform 0.6s;
      cursor: pointer;
    }

    .cardbox:hover .card{
        transform: rotateY(180deg);
    }

    .card .front,
    .card .back{
      width: 100%;
      height: 100%;
      border-radius: 15px;
      position: absolute;
      display: flex;
      justify-content: center;
      align-items: center;
      backface-visibility: hidden;
    }

    .card .front{
        background: #3498db;
        transform: rotateY(0deg);
    }

    .card .back{
        background: #e74c3c;
        transform: rotateY(180deg);
    }
  </style>
</html>