当前位置: 首页 > news >正文

2024年字节抖音前端面经,这次问的很基础!

文章同步在公众号:萌萌哒草头将军,欢迎关注!!!

一面

es6新特性有哪些

新增了letconst关键字替换var声明变量,因为var会导致变量提升,在申明之前可以访问变量。新增了箭头函数,新增了promisesync await、还有一些高级特性,比如像proxy

Promise静态方法有哪些?

anyraceall等,(reject resolve也是静态方法)。

然后面试官让我说下,all的用法。我当时说多个Promise全部执行为才会调用all。但是面试官让我手写下用法,我给写错了,面试官耐心的引导我写出正确的,正确如下:

Promise.all([new Promise(), new Promise(), new Promise()]).then(values => console.log(values)).catch(err => console.log(err))

这时面试官又问我,如果把catch里的方法。作为then里的第二个参数,和现在的写法有啥区别吗?

Promise.all([new Promise(), new Promise(), new Promise()]).then(values => console.log(values),err => console.log(err))

如果任何一个Promise被拒绝,会调用then的第二个参数,而不会触发catch,因为错误在then中已经处理了。

普通函数和箭头函数的区别

普通函数内部是有this指向的,指向调用函数的对象,箭头函数本身是没有的,里面的this是箭头函数第一个有this的父作用域里的this

例如:

let obj = {}
function  fun1 () {console.log(this)
}
const fun2 = () => console.log(this)obj.a = fun1 // this指向obj
obj.b = fun2 // this指向window

接着面试官又问了我一个问题,箭头函数的this是调用的时候确定的还是定义的时候确定的?

我回答调用的时候,调用的时候,对象属于哪个作用域,就是确定为哪个。

实际是定义的时候确定的。

map和set的作用

你知道map和set的作用吗?

我回答了一半,Map允许使用任意类型的键,包括对象,而对象的键只能是字符串或符号。

其实除此之外,Map保留键值对的插入顺序,遍历时按插入顺序返回。Map在增删查操作上有更好的性能,特别是当键不是字符串时。

Set自动去除重复元素,确保集合内的值唯一,Set也提供了更高效的值查找、添加和删除操作。

js类定义静态方法

使用static关键字

js继承类怎么在方法内部调用方法
class A {a() {console.log('Method a from class A');}
}
class B extends A {b() {// this.a()super.a()}
}const instance = new B();
instance.b(); // 输出: Method a from class A
ts的泛型

有个加法函数,有两个参数,参数类型和返回值类型始终一致,string或者number怎么实现,我说可以用泛型实现。

const add = <T extends number | string>(a: T, b: T): T => a + b

返回值的类型可以不写,因为会自动推断

然后面试官问我,还有别的方法可以实现吗?我想了半天说没有。

其实还有别的方法,利用函数重载机制。

function add(a: number, b: number): number;
function add(a: string, b: string): string;
function add(a: any, b: any): any {return a + b;
}
ts参数可选

可以使用?指定可选,或者使用工具函数指定可选。Omit

怎么防止多个文件打包进去多余的js和类,按需加载

分割代码,多使用动态import语句

const PageA = lazy(() => import("./Module/PageA"))

使用tree-shaking优化,不过需要使用ESModule,而不是CommondJStree-shaking可以通过AST语法树,分析代码中没有使用的模块,或者无用代码的导出。

按需引入代码,而不是引入所有

import { Button } from "antd/lib/Button"
下面的代码有啥问题,怎么修复
function C () {const [p, setP] = useState(10)return <Page p={[10, 20,]} onChange={(v) => {setP(v); fetch(p)}} />
}

发送请求时,都是使用上次的值,而不是最新值,这是因为useState更新值时是异步的。(react会进行一次批处理优化)解决方法有两种

// 方法1
function C () {const [p, setP] = useState(10)return <Page p={[10, 20,]} onChange={(v) => {setP(v); fetch(v)}} />
}
//方法2
function C () {const [p, setP] = useState(10)useEffect(() => fetch(p), [p]}return <Page p={[10, 20,]} onChange={(v) => {setP(v)}} />
}

二面

找代码问题

聊完我的项目经历后,立马问我,下面的代码会出现什么问题,怎么解决。

function Counter() {const [count, setCount] = useState(0);useEffect(() => {const id = setInterval(() => {setCount(count + 1);}, 1000);return () => clearInterval(id);}, []);return <h1>{count}</h1>;
}

上面的代码更新count有问题,因为每次更新count都使用旧的值,而不是最新的,

setCount((prevCount) => prevCount + 1); // 使用函数式更新

接着又给我下面的例子,问我有啥问题

function Counter() {const [count, setCount] = useState(0);const [step, setStep] = useState(1);useEffect(() => {const id = setInterval(() => {setCount(c => c + step);}, 1000);return () => clearInterval(ref.current);}, [step]);return (<><h1>{count}</h1><input value={step} onChange={e => setStep(Number(e.target.value))} /></>);
}

上面的组件出现的问题是:每次当step的值发生改变时,都会重新创建新的定时器

修改方法如下,

function Counter() {const [count, setCount] = useState(0);const [step, setStep] = useState(1);const ref = useRef(null)useEffect(() => {if (!ref.current) {ref.current = setInterval(() => {setCount(c => c + step);}, 1000);}// const id = setInterval(() => {//   setCount(c => c + step);// }, 1000);return () => clearInterval(ref.current);}, [step]);return (<><h1>{count}</h1><input value={step} onChange={e => setStep(Number(e.target.value))} /></>);
}
实现ts里的Picker 和 Omit

这个问题我当时是不会的,说实话,这两个工具函数我用的都很少,更别说实现了

webpack 和 vite 的 tree chunking的区别

tree chunking是一种清除无用代码的方案,主要是通过分析静态的代码导出和导入关系,寻找无用代码,然后删除它,不将它打包,从而优化代码体积,webpack需要开启es module,并且开启optimization选项,而vite天生就是支持es module的,不过vite是使用依赖的es模块加载机制优化的。

webpack loader 和 plugin 的区别

功能区别:Webpack原生只能理解jsJSON文件,而Loader扩展了其能力,使其能够处理非js文件,Loader是文件级别的转换工具,允许你在模块打包时对文件进行处理。plugin是对Webpack的整个构建过程进行扩展和增强.

原理的区别:webpackloader拿到的是特定类型文件,而plugin可以根据hook处理webpack的各个流程。另外插件的本质是个是个带有apply方法的类,apply方法中参数是complier对象,可以通过这个对象提供的hook监听特定文件的变化进行编译。而loader是个函数,参数是匹配到的文件源码。

module.exports = class MyPlugin {apply(compiler) {compiler.hooks.done.tap('MyPlugin', (Compilation) => {console.log('MyPlugin: Compilation finished!');});}
}

用法区别:loader需要根据正则匹配特定的类型的文件,plugin需要实例化插件

commondJS 和 ESModule 的区别

commondJS是动态的,只有在运行时才能确定具体导入的内容,而ESModule是静态的,在编译时就能确定引入和导出的模块

commondJS导入使用的是requirerequire可以出现在代码任何地方(所以是动态的),导出使用exports或者module.exports

ESModule导入语句是importimport只能出现在文件顶部。(所以是静态的,import方法除外),导出使用export

commondJS实际上是被包裹在一个函数中,可以使用this,而ESModule没有this

commondJS会缓存模块。重新加载返回的是缓存,ESModule也是缓存,后续的导入将共享相同的实例

下面的输出内容是啥
// a.js
const b = require('./b');
console.log(exports.x);
exports.x = 'x';
require('./c');// b.js
const a = require('./a');
console.log(a);
a.x = 'y';// c.js
const a = require('./a');
console.log(a.x);

输出结果如下

{}
undefined
x

分析步骤:

加载a.js,首先遇到require('./b'),它会开始加载b.js。此时a.js尚未完全加载完成,它处于未完成的状态,因此,Node.js会将一个空的exports对象暴露给b.js

接着加载b.js,在b.js中,有const a = require('./a'),由于a.js还在加载中(未完成),所以 a 会是当前的未完成a.js的导出对象,此时是空的 {}。所以执行console.log(a),打印结果为{}, 接着执行a.x = 'y',这会修改a模块的导出内容,将{} 变为 { x: 'y' }。但是由于 a.js还未完成执行,exports.x = 'x'; 还没有执行,所以x暂时变为y

然后回到a.js继续执行:

首先执行console.log(exports.x),此时 exports 对象还没有被赋值,exports.xundefined。 然后执行exports.x = 'x',将a.jsexports对象更新为{ x: 'x' },覆盖了之前b.js 中将x赋值为'y'的修改。

接着,加载require('./c'),开始加载 c.js。

c.js中,有const a = require('./a')。由于a.js已经完成了加载,因此a的值是最终导出的 exports对象{ x: 'x' }。 执行console.log(a.x),此时a.x'x',所以会输出 'x'

写一个加法函数sum,支持sum(1)(2)(3,4)(5,6,7....), console.log(sum(1,2,3)(4)) => 输出 10

我当时写完的函数是这样的,虽然差不多意思,但是不太对。有知道的大佬可以在告诉我下。

const sum = (...args) => {const add = (x) =>{if (x === undefined) {return args.reduce((a, b) => a + b, 0)} else {args.push(x)return add(...args)}}return add(...args)
}

三面

简单问了下项目经历,聊了下项目里的亮点,四十分钟不到结束了。这里就不多赘述了。

总结

从结果来看虽然通过了,但是真的觉得自己很菜,很多底层的东西,可能只是知其然,并没有知其所以然。

虽然es6已经横空出世好多年了,但是里面的内容真的搞懂的不是很多。所以后续还需要多翻书,多研究细节。

最后希望这篇文章可以帮到找工作的同学,也可以翻看我前面的几篇面试文章。

文章中出现错误的地方欢迎指正!

相关文章:

2024年字节抖音前端面经,这次问的很基础!

文章同步在公众号&#xff1a;萌萌哒草头将军&#xff0c;欢迎关注&#xff01;&#xff01;&#xff01; 一面 es6新特性有哪些 新增了let、const关键字替换var声明变量&#xff0c;因为var会导致变量提升&#xff0c;在申明之前可以访问变量。新增了箭头函数&#xff0c;新…...

vscode提交修改Failed to connect to github.com port 443: Timed out

参考内容&#xff1a;timed out 只需3步&#xff1a;设置代理、取消代理、再次提交。&#x1f449; 2.1 设置代理 $ git config --global https.proxy 1 &#x1f449; 2.2 取消代理 $ git config --global --unset https.proxy 1之后关闭bash&#xff0c;再去vscode里面pull …...

通过docker镜像安装elasticsearch和kibana

目录 前言安装elasticsearch:7.17.21安装对应版本的kibana 前言 本文主要参考&#xff1a;https://blog.csdn.net/qq_23859799/article/details/138521052&#xff0c;内容基本一致&#xff0c;改动了部分错误 安装elasticsearch:7.17.21 拉取镜像&#xff1a;docker pull d…...

seaCMS v12.9代码审计学习(下半)

文章目录 admin/admin_safe.php任意文件下载CSRF 添加管理员账户CSRF配合XSS弹cookie admin/admin_safe.php任意文件下载 在admin_safe.php文件下有着这么一段代码&#xff0c;他的作用时检查action的值是否为download&#xff0c;如果为download那么将你传入的文件直接打印给…...

麒麟信安CentOS安全加固案例获评中国信通院第三届“鼎新杯”数字化转型应用奖

“鼎新杯”数字化转型应用大赛&#xff0c;由中国通信标准化协会主办、中国信息通信研究院承办&#xff0c;以落实国家“十四五”规划关于“加快数字化发展&#xff0c;建设数字中国”的总体要求为目标&#xff0c;意在打造一批具有产业引领与推广应用效应的企业数字化转型应用…...

Java 中消除 If-else 技巧总结

“过于依赖 if-else 不仅会让代码变得臃肿不堪&#xff0c;还会使维护成本大大增加。其实&#xff0c;if-else 虽然是最基础的条件分支&#xff0c;但它并不是万能的解决方案。简单粗暴的 if-else 很容易让代码可读性差、结构复杂。 今天&#xff0c;我将带大家了解一些取代 i…...

每个平台团队都应该跟踪的API指标

目录 识别关键 API 度量 基础架构/DevOps 应用工程/平台 产品管理 业务/增长 基础架构API指标 正常运行时间 CPU使用率 内存使用率 应用程序API指标 相应时间 平均和最大延迟 吞吐量 可用性 缓存命中率 每分钟错误数 每个业务事务的API调用 如何收集优化API指…...

Windows 11 24H2版本有哪些新功能_Windows 11 24H2十四大新功能介绍

距离上次发布的23H2版本已经过去了一年时间&#xff0c;现在&#xff0c;Win 11的24H2版本终于等到了&#xff0c;微软已经全面公开发布Win11 24H2版本&#xff0c;版本号为26100.1742&#xff0c;此次官宣的版本包括了消费者版、商业版、LTSC 2024版等&#xff0c;各种语言版本…...

渗透测试 之 AD域渗透 【Kerberoasting】 攻击技术讲解 对应得工具详细介绍哟~ 以及相关示例 按照步骤做你也会哟

说明 Kerberoasting 攻击发生在Kerberos协议的TGS_REP阶段&#xff0c;KDC的TGS服务返回一个由服务Hash加密的ST给客户端。由于该ST是用服务Hash进行加密的&#xff0c;因此客户端在拿到该ST后可以用于本地离线爆破。 攻击的过程 攻击者提供一个正常的域用户密码对域进行身份…...

如何在Ubuntu上更改MySQL数据存储路径

文章目录 0 背景1 备份现有数据库数据2 停止 MySQL 服务3 复制现有的 MySQL 数据到新目录4 修改 MySQL 配置文件5 更新 AppArmor 或 SELinux 配置&#xff08;如有启用&#xff09;6. 修改 MySQL 系统文件中的 datadir7. 启动 MySQL 服务8. 验证更改参考资料 0 背景 在原先划分…...

Cortex-M 内核的 OS 特性

目录 一、通用堆栈知识二、双堆栈用法三、PendSV 中断介绍和用法四、SVC 软中断介绍和用法五、特权级和非特权级使用方法 一、通用堆栈知识 在前面讲解 STM32 启动文件的时候就已经提到过&#xff0c;有关堆栈大小的设置是在启动文件中设置的&#xff1a; Heap 主要用于 Mal…...

第十六章 RabbitMQ延迟消息之延迟插件优化

目录 一、引言 二、优化方案 三、核心代码实现 3.1. 生产者代码 3.2. 消息处理器 3.3. 自定义多延迟消息封装类 3.4. 订单实体类 3.5. 消费者代码 四、运行效果 一、引言 上一章节我们提到&#xff0c;直接使用延迟插件&#xff0c;创建一个延迟指定时间的消息&…...

[单master节点k8s部署]32.ceph分布式存储(三)

基于ceph rbd生成pv 在集群中认证ceph 用下面代码生成ceph的secret .创建 ceph 的 secret&#xff0c;在 k8s 的控制节点操作&#xff1a; 回到 ceph 管理节点创建 pool 池&#xff1a; [rootmaster1-admin ~]# ceph osd pool create k8stest 56 pool k8stest created [rootm…...

git 相关问题解决一一记录

文章目录 gitssh.github.com: Permission denied (publickey)1. 检查 SSH 密钥生成新的 SSH 密钥添加 SSH 密钥到 GitHub 2. 配置 SSH 代理启动 SSH 代理添加私钥到 SSH 代理 3. 检查 SSH 配置文件4. 测试 SSH 连接5. 检查防火墙和网络设置6. 检查 GitHub 账户设置详细步骤 更新…...

UE4 材质学习笔记04(着色器性能优化)

一.着色器性能优化 1.衡量着色器的性能 衡量着色器性能的主要方法有三个 第一个&#xff1a;可以使用场景的视图模式的优化视图模式的着色器复杂度 下面的滑条代表了着色器指令的复杂度 如果场景大部分是绿色的&#xff0c;说明着色器耗能低&#xff0c;反之白色则是很糟糕…...

3、Redis Stack扩展功能

文章目录 一、了解Redis产品二、申请RedisCloud实例三、Redis Stack体验1、RedisStack有哪些扩展&#xff1f;2、Redis JSON1、Redis JSON是什么2、Redis JSON有什么用3、Redis JSON的优势 3、Search And Query1、传统Scan搜索2、Search And Query搜索 4、Bloom Filter1、布隆过…...

Flythings学习(二)控件相关

文章目录 1 前言2 通用属性2.1 控件ID值2.2 控件位置2.3 背景色2.4 背景图2.5 显示与隐藏2.6 控件状态2.7 蜂鸣器控制 3 文本类TextView4 按键类 Button4.1 系统按键4.2 处理按钮长按事件4.3 处理按键触摸事件 5 复选框CheckBox6 单选组 RadioGroup7 进度条&#xff0c;滑块7.1…...

关于multiprocessing使用freeze_support()方法

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、freeze_support()&#xff1f;二、使用方法总结 **注意下面** 如果有车载讨论需要的小伙伴&#xff0c;可以私信加我微信&#xff0c;拉你进群&#xff0c;…...

基于rk356x u-boot版本功能分析及编译相关(一)

🎏技术驱动源于热爱,祝各位学有所成。 文章目录 uboot的分支是next-dev历史版本v2017-09uboot支持DM框架uboot前级pre-loader支持及引导下级uboot分区支持uboot支持固件格式secure bootuboot编译脚本位置build.shuboot/make.shrkbin仓库uboot的分支是next-dev历史版本v2017-…...

Jenkins---01

什么是敏捷开发 敏捷开发以用户的需求进化为核心&#xff0c;采用迭代、循序渐进的方法进行软件开发。在敏捷开 发中&#xff0c;软件项目在构建初期被切分成多个子项目&#xff0c;各个子项目的成果都经过测试&#xff0c;具备可视、 可集成和可运行使用的特征。换言之&…...

第十五届蓝桥杯C++B组省赛

文章目录 1.握手问题解题思路1&#xff08;组合数学&#xff09;解题思路2&#xff08;暴力枚举&#xff09; 2.小球反弹做题思路 3.好数算法思路&#xff08;暴力解法&#xff09;---不会超时 4.R格式算法思路 5.宝石组合算法思路---唯一分解定理 6.数字接龙算法思路----DFS 7…...

线程 vs 虚拟线程:深入理解及区别

Java 提供了两种线程机制&#xff1a;普通线程&#xff08;平台线程&#xff09;和 虚拟线程。普通线程是 Java 中经典的并发处理方式&#xff0c;而虚拟线程是随着 Java 21 引入的新特性&#xff0c;旨在提升并发性能和开发体验。本文将详细探讨它们的区别&#xff0c;并帮助你…...

【WEB应用安全测试指南–蓝队安全测试2】--超详细-可直接进行实战!!!亲测-可进行安全及渗透测试

安全基础理论入门知识参考上一篇《WEB应用安全测试指南蓝队安全测试1》 WEB应用安全测试指南2 一、文件 I/O 类1.1、任意文件上传1.2、任意文件下载1.3、文件包含 二、接口安全类2.1、短信炸弹2.2、邮件炸弹2.3、短信内容可控2.4、邮件内容可控 三、逻辑流程类3.1、越权3.2、未…...

使用HTML、CSS和JavaScript创建滚动弹幕效果

使用HTML、CSS和JavaScript创建滚动弹幕效果 在现代网页设计中&#xff0c;滚动文本是一种常见的动态效果&#xff0c;可以吸引用户的注意力并增强交互体验。在这篇博客文章中&#xff0c;我们将详细介绍如何使用HTML、CSS和JavaScript实现滚动文本效果。 效果 步骤1&#xf…...

【C语言】--数组

&#x1f60a;个人主页: 起名字真南 &#x1f60b;个人专栏:【数据结构初阶】 【C语言】 【C】 目录 1 数组的概念2 一维数组的创建和初始化2.2 数组的初始化2.3 数组类型 3 一维数组的使用3.1 数组下标3.2 数组的输入 4 一维数组在内存中的存储5 sizeof计算数组中的元素6 二维…...

面向B2B市场的Spring Boot医疗病历系统开发

第1章绪论 计算机已经从科研院所&#xff0c;大中型企业&#xff0c;走进了平常百姓家&#xff0c;Internet遍及世界各地&#xff0c;在网上能够用计算机进行文字草拟、修改、打印清样、文件登陆、检索、综合统计、分类、数据库管理等&#xff0c;用科学的方法将无序的信息进行…...

闭着眼学机器学习——支持向量机分类

引言&#xff1a; 在正文开始之前&#xff0c;首先给大家介绍一个不错的人工智能学习教程&#xff1a;https://www.captainbed.cn/bbs。其中包含了机器学习、深度学习、强化学习等系列教程&#xff0c;感兴趣的读者可以自行查阅。 1. 算法介绍 支持向量机(Support Vector Mach…...

今日指数项目day8实战权限管理器(上)

3.权限管理器 3.1 权限列表展示功能 1&#xff09;原型效果 2&#xff09;接口说明 功能描述&#xff1a; 查询所有权限集合 服务路径&#xff1a; /api/permissions 服务方法&#xff1a;Get 请求参数&#xff1a;无响应数据格式: {"code": 1,"data":…...

《机器学习与数据挖掘综合实践》实训课程教学解决方案

一、引言 随着信息技术的飞速发展&#xff0c;人工智能已成为推动社会进步的重要力量。作为人工智能的核心技术之一&#xff0c;机器学习与数据挖掘在各行各业的应用日益广泛。本方案旨在通过系统的理论教学、丰富的实践案例和先进的实训平台&#xff0c;帮助学生掌握机器学习…...

linux中软连接和硬链接的区别

定义与概念 硬链接&#xff08;Hard Link&#xff09;&#xff1a;硬链接是文件系统中的一个概念&#xff0c;它直接指向文件系统中的物理数据块。可以把硬链接看作是原始文件的一个别名&#xff0c;它们共享相同的inode&#xff08;索引节点&#xff09;编号。在Linux文件系统…...