查看原文
其他

Redis 的持久化机制有哪些?

编程导航和鱼友们 面试鸭 2024-01-21

大家好呀,今天是编程导航 30 天面试题挑战的第十五天,一起来看看今天有哪些优质面试题吧。

后端

题目一

MVCC 是什么?InnoDB 是如何实现 MVCC 机制的?

官方解析

MVCC 是指多版本并发控制(Multiversion Concurrency Control),是一种并发控制机制,常用于数据库系统中,用于实现事务的并发控制。它允许在同一时间多个事务对同一个数据集合进行读取操作,同时防止数据不一致和其他并发问题。

InnoDB 是 MySQL 中最常用的存储引擎之一,它的 MVCC 实现是通过在每行记录中添加两个隐藏的列,分别记录行的创建时间和过期时间,以此来判断事务对该行记录的可见性。当一个事务需要读取一行记录时,InnoDB 首先读取这行记录的创建时间和过期时间,并根据这些信息判断该行记录是否可见。如果创建时间早于当前事务的开始时间,且过期时间晚于当前事务的开始时间,那么该行记录对当前事务可见。

在 InnoDB 中,MVCC 主要是通过实现以下几个机制来实现的:

  1. 事务版本号:每个事务都有一个唯一的版本号,用来标识该事务的创建时间。
  2. 读取视图:每个事务在开始时都会创建一个读取视图,记录该事务开始时间和其他信息。在事务执行期间,所有读取操作都要检查该视图,以确定读取哪些版本的数据。
  3. undo 日志:在事务执行期间,如果对数据进行修改,那么会先将原始数据复制一份到 undo 日志中。这样,在回滚操作时就可以使用 undo 日志中的数据来还原原始数据。
  4. 快照读取:在某些情况下,事务需要读取一个数据的历史版本,而不是当前版本。这时可以使用快照读取来实现,即在读取时根据事务开始时间和 undo 日志来读取历史版本的数据。

鱼友的精彩回答

Gundam 的回答

MVCC(Multi-Version Concurrency Control)是一种并发控制机制,它通过为每个读操作创建一个视图来实现读写分离保证了多个事务同时读写同一个数据时的一致性和并发性

InnoDB 是 MySQL 数据库中的一种存储引擎,它通过使用 MVCC 实现了高度并发的事务处理

在 InnoDB 中,每个事务读取的数据都会生成一个当前版本号,并将这个版本号与事务 ID 一起存储在数据行中。

在事务执行期间,如果某个事务想要修改一行数据,InnoDB 会首先为这个事务生成一个新的版本号,并将新的版本号和事务 ID 存储在新版本的数据行中。由于每个事务都有自己的版本号,因此不会出现读写冲突的情况,多个事务可以同时读取同一行数据,并发执行而不会相互影响。

为了保证 MVCC 机制的正确性,InnoDB 需要使用多版本链表(Multi-Version List)来存储数据。每个数据行都会有一个多版本链表,其中存储着该行数据的所有历史版本。当一个事务执行查询操作时,InnoDB 会根据该事务的 ID 和时间戳来确定该事务能够读取到的版本号,然后将这个版本号对应的数据返回给该事务。当一个事务执行插入、删除或更新操作时,InnoDB 会为这个操作生成一个新的版本,并将新版本的数据插入到多版本链表中。

InnoDB 中,为了实现 MVCC,还需要使用 undo log 和 read view 来存储数据

undo log 记录了每个事务对数据行进行修改的情况,read view 记录了每个事务开始时的数据版本号和当前系统时间,用于判断事务是否可以读取某个数据行的版本。当一个事务执行查询操作时,InnoDB 会根据 read view 来确定该事务能够读取到的数据版本号,并使用 undo log 来恢复该数据行的历史版本。

haha 的回答

MVCC

MVCC 指的是多版本并发控制,是指维护一条记录的多个版本,使得读写操作没有冲突

MVCC的实现

InnoDB 对于 MVCC 的实现,我主要从下面几个点来讲:

  1. 当前读快照读的概念
  2. MySQL 数据的隐藏字段
  3. undo 日志中的版本链
  4. readView(读视图)
  5. MVCC实现流程
当前读与快照读

当前读:就是读取的记录总是最新的,实现的原理就是对正在读的记录加锁,使得读写互斥,这样保证每次读取的都是数据库中最新的记录

快照读:每次读取的时候不一定是最新的数据,而是这条记录的快照版本,这样可以保证读写不互斥,能够并发执行

MySQL 的隐藏字段

MVCC 的实现主要依赖于:MySQL 的隐藏字段、undo log 中的版本链、readView

MySQL 中每条记录是有两个隐藏的字段,分别是:

  • 最近修改事务 ID:记录着上一次修改该条记录的日志 id
  • 回滚指针:指向上一个版本的记录的地址

另外,如果表中没有指定主键,那么还有有一个隐藏的主键

undo log 版本链

版本链顾名思义就是记录的版本的链表。

当事务并发执行修改某条记录的时候,不同的事物对这条数据的修改产生多个版本,每次修改之前都会记录下这条记录之前的数据,在隐藏字段中设置上本次操作事务的ID,并让回滚指针指向上一个版本,这样就会形成一条链表,就是所谓的版本链。

readView 读视图

readView 读视图记录并维护了当前系统活跃的事务 ID,为快照读时 MVCC 提供数据的依据。其主要有以下几个属性:

  1. 记录当前活跃事务的 ID 集合
  2. 最小活跃事务 ID
  3. 预分配事务 ID,就是最大活跃事务 ID + 1(因为事务 ID 是自增的)
  • readView 创建者的事务 ID
MVCC执行的流程

当并发事务执行的时候,执行查询操作的时候,会根据这个事务的 ID 和 readView 中的事务 ID 进行一些比较来确定读取哪个版本的快照记录,具体的规则为:

  • 记录中的最近修改事务的 ID 小于读视图中的最小事务 ID,说明记录的修改已经提交了,可以访问
  • 事务 ID 等于读视图中创建者 ID,说明这条记录就是当前事务修改的,可以访问
  • 事务 ID 大于等于读视图中预分配事务 ID,说明这条记录是在读视图创建之后修改的,不可访问当前版本,去访问下一个版本吧
  • 如果事务 ID 在最小事务 ID 和最大 ID 之间且不在 ID 集合中,说明当前版本的修改事务已经提交,可以访问
RC 和 RR 的区别

RC 级别时,在一个事务中,每执行一次查询都会生成一次读视图。

RR 级别时,在一个事务中,只有第一次查询会生成一个读视图,后面的查询都是复用这个读视图,保证了可重复读

回家养猪的回答

什么是 MVCC

MVCC 全称 Multi-Version Concurrency Control, 多版本并发控制。指维护一个数据的多个版本,使得读写操作没有冲突, 具体实现就是快照读, 快照读为 MySQL 实现 MVCC 提供了一个非阻塞读功能。MVCC 的具体实现,还需要依赖于数据库记录中的隐式字段、undo log 日志、readView

MVCC 的实现原理

MVCC 的具体实现,依赖于数据库记录中的隐式字段、undo log 日志、readView。

在内部实现中,InnoDB 通过数据行的 DB_TRX_ID(最近更新的事务id) 和 Read View 来判断数据的可见性,如不可见,则通过数据行的 DB_ROLL_PTR(回滚指针) 找到 undo log 版本链中的历史版本。这就是快照读

每个事务读到的数据版本可能是不一样的,在同一个事务中,用户只能看到该事务创建 Read View 之前已经提交的修改和该事务本身做的修改

MVCC 是怎么解决不可重复读的

在 RC 读已提交下, 在事务中每一次执行快照读时生成 ReadView, 这也就造成了每次读取就有不同 ReadView, 那么就会读到已提交的事务修改的内容, 造成不可重复读的问题.

解决 RR 不可重复读主要靠 readview, 在隔离级别为可重复读时, 仅在事务中第一次执行快照读时生成 ReadView, 后续复用该 ReadView.

由于后续复用了 ReadView, 所以数据对当前事务的可见性和第一次是一样的, 所以从 undolog 中读到的数据快照和第一次是一样的, 即便过程中有其他事务修改也读不到.

MVCC是怎么防止幻读的

InnoDB 存储引擎在 RR 级别下通过 MVCCNext-key Lock(临键锁) 来解决幻读问题

1、执行普通 select,此时会以 MVCC 快照读的方式读取数据

快照读: 避免加锁通过 MVCC 来进行控制, 使其他事务所做的更新对当前事务不可见, 从而防止幻读.

在快照读的情况下,RR 隔离级别只会在事务开启后的第一次查询生成 Read View ,并使用至事务提交。所以在生成 Read View 之后其它事务所做的更新、插入记录版本对当前事务并不可见,实现了可重复读和防止快照读下的 “幻读”

2、执行 select...for update/lock in share mode、insert、update、delete 等当前读

当前读: 通过临键锁 next-key-lock 锁住空隙, 防止其他事务在查询的范围内插入数据, 从而防止幻读.

在当前读下,读取的都是最新的数据,如果其它事务有插入新的记录,并且刚好在当前事务查询范围内,就会产生幻读!InnoDB 使用 Next-key Lock 临键锁来防止这种情况。当执行当前读时,会锁定读取到的记录的同时,锁定它们的间隙,防止其它事务在查询范围内插入数据。只要我不让你插入,就不会发生幻读

题目二

Redis 的持久化机制有哪些?说说各自的优缺点和应用场景?

官方解析

Redis 的持久化机制主要分为 RDBAOF 两种。

RDB 持久化机制

RDB 持久化机制是指将 Redis 在内存中的数据以快照的形式写入磁盘中,可以手动或自动执行快照操作,将数据集的状态保存到一个 RDB 文件中

RDB 机制的优点在于:

  • RDB 机制适合在数据集比较大时进行备份操作,因为它可以生成一个非常紧凑、经过压缩的数据文件,对于备份、恢复、迁移数据都很方便。

RDB 机制在 Redis 重启时比 AOF 机制更快地将 Redis 恢复到内存中。

RDB 机制的缺点在于:

  • RDB 机制可能会出现数据丢失,因为数据是周期性地进行备份,一旦 Redis 出现问题并且上一次备份之后还没有进行过数据变更,那么这部分数据将会丢失。
  • RDB 机制会造成一定的 IO 压力,当数据集比较大时,进行备份操作可能会阻塞 Redis 服务器进程。
AOF 持久化机制

AOF 持久化机制是指将 Redis 在内存中的操作命令以追加的形式写入到磁盘中的 AOF 文件,AOF 文件记录了 Redis 在内存中的操作过程,只要在 Redis 重启后重新执行 AOF 文件中的操作命令即可将数据恢复到内存中。

AOF 机制的优点在于:

  • AOF 机制比 RDB 机制更加可靠,因为 AOF 文件记录了 Redis 执行的所有操作命令,可以确保数据不丢失。
  • AOF 机制在恢复大数据集时更加稳健,因为 AOF 文件记录了数据的操作过程,可以确保每一次操作都被正确地执行。

AOF 机制的缺点在于:

  • AOF 机制生成的 AOF 文件比 RDB 文件更大,当数据集比较大时,AOF 文件会比 RDB 文件占用更多的磁盘空间。
  • AOF 机制对于数据恢复的时间比 RDB 机制更加耗时,因为要重新执行 AOF 文件中的所有操作命令。

综上所述,RDB 适合用于数据集较大、备份、恢复数据和迁移数据等场景,AOF 适合用于数据可靠性要求高、数据恢复稳健等场景。

鱼友的精彩回答

Starry 的回答

Redis 的持久化机制主要有两种:RDB(Redis Database)和 AOF(Append Only File)。

1、RDB 持久化

RDB 持久化机制会在指定的时间间隔内对数据集做快照,将快照存储到磁盘中。

RDB 的优缺点:对于数据恢复速度比较快,同时存储的文件也比 AOF 小,缺点是可能会出现数据丢失的情况,因为快照的时间间隔越长,数据丢失的可能性就越大

2、AOF 持久化

AOF 持久化机制则会将每一次的写操作都追加到一个文件中,这个文件就是 AOF 文件。

AOF 文件保存了 Redis 服务器接收到的所有写命令,当 Redis 重启时,就可以使用 AOF 文件重建数据集。

AOF 的优缺点:数据丢失的可能性比 RDB 低,缺点是文件比 RDB 大,恢复速度比较慢

3、RDB + AOF 混合使用

除了 RDB 和 AOF 外,Redis 还支持混合持久化机制,即同时使用 RDB 和 AOF 两种持久化机制,以此来发挥它们的优点。

在混合持久化机制中,使用 AOF 持久化机制保存每次写操作使用 RDB 持久化机制保存指定时间点的数据快照,以此来达到数据恢复速度数据完整性的平衡

应用场景:

  • RDB 适合用于数据集比较大数据恢复速度比较快的场景,例如备份、灾难恢复等;
  • AOF 适合用于数据集比较小数据完整性比较重要的场景,例如金融、电商等行业。
李狗蛋的回答

Redis的持久化机制

Reids的持久化机制主要有两种,一种是 RDB 快照,指使用快照的形式将内存中的全部数据写入到磁盘中,存的是非常紧凑经过压缩的数据文件。一种是 AOF 日志,指以追加的形式,一条一条地将操作命令写入到 AOF 日志中。

优缺点:

  • 占用空间方面:

    • RDB存的是压缩过的数据集,占用空间更小

    • AOF存的是每一条操作命令,占用空间更大

  • 速度方面:

    • RDB存储慢:周期性备份,每次都是内存中的全部数据,但恢复时更快

    • AOF存储快:追加的形式一条条地写入,每次写入一条指令,但恢复时更慢(需执行全部指令)

  • 安全性方面:

  • RDB 是周期性备份,可能会丢失没来得及备份的数据

  • AOF 根据策略而定,可以记录全部数据的操作过程,更可靠

  • 资源消耗方面:

    • RDB 会造成 IO 压力,数据集比较大时可能会阻塞正常的服务进程

    • AOF 每次记录一条,消耗资源更低

场景:

  • 关闭持久化:数据不敏感,且可以从其他地方重新生成找回。

  • RDB:数据集较大、备份、恢复数据和迁移数据等场景,可以承受数分钟级的数据丢失。

  • AOF:适合用于数据可靠性要求高、数据恢复稳健等场景。

补充:

  • AOF 的启动优先级比 RDB 高

4.0 后,多了一种混合持久化,前半段时 RDB 的全量数据,后半段是 AOF 的增量数据

优点是充分发挥了二者的优点,RDB 提供加载速度,AOF 提供数据可靠性保障

缺点是兼容性差,4.0 之前的版本不兼容,并且前半段的 RDB 可读性较差

追问:

生成 RDB 期间,Redis 可以同时处理写请求吗?

回答:

可以,Redis 使用操作系统的多进程写时复制技术 COW(Copy On Write)来实现快照持久化,保证数据一致性。

在持久化时,会调用 glibc 的函数 fork 产生一个子进程,快照持久化完全交给子进程处理,父进程继续处理客户端请求。当主进程执行写指令修改数据的时候,这个数据就会复制一份副本,子进程读取这个副本数据写到 RDB 文件。既保证了快照的完整性,也允许主进程同时对数据进行修改,避免了对正常业务的影响。

林寻的回答

Redis 支持 RDB 持久化、AOF 持久化、RDB-AOF 混合持久化这三种持久化方式。

RDB:

RDB(Redis Database)是 Redis 默认采用的持久化方式,它以快照的形式将进程数据持久化到硬盘中。

RDB会创建一个经过压缩的二进制文件,文件以“.rdb”结尾,内部存储了各个数据库的键值对数据等信息。

RDB持久化的触发方式有两种:

  • 手动触发:通过 SAVE 或 BGSAVE 命令触发 RDB 持久化操作,创建“.rdb”文件;
  • 自动触发:通过配置选项,让服务器在满足指定条件时自动执行 BGSAVE 命令。

其中,SAVE 命令执行期间,Redis 服务器将阻塞,直到“.rdb”文件创建完毕为止。

而 BGSAVE 命令是异步版本的 SAVE 命令,它会使用 Redis 服务器进程的子进程,创建“.rdb”文件。BGSAVE 命令在创建子进程时会存在短暂的阻塞,之后服务器便可以继续处理其他客户端的请求。总之,BGSAVE 命令是针对 SAVE 阻塞问题做的优化,Redis 内部所有涉及 RDB 的操作都采用 BGSAVE 的方式,而 SAVE 命令已经废弃!

RDB 持久化的优缺点如下:

  • 优点:RDB 生成紧凑压缩的二进制文件,体积小,使用该文件恢复数据的速度非常快;
  • 缺点:BGSAVE 每次运行都要执行 fork 操作创建子进程,属于重量级操作,不宜频繁执行,所以 RDB 持久化没办法做到实时的持久化。
AOF:

AOF(Append Only File),解决了数据持久化的实时性,是目前 Redis 持久化的主流方式。AOF 以独立日志的方式,记录了每次写入命令,重启时再重新执行 AOF 文件中的命令来恢复数据。AOF 的工作流程包括:命令写入(append)、文件同步(sync)、文件重写(rewrite)、重启加载(load)

AOF持久化的优缺点如下:

  • 优点:与 RDB 持久化可能丢失大量的数据相比,AOF 持久化的安全性要高很多。通过使用 everysec 选项,用户可以将数据丢失的时间窗口限制在1秒之内。
  • 缺点:AOF 文件存储的是协议文本,它的体积要比二进制格式的”.rdb”文件大很多。AOF 需要通过执行 AOF 文件中的命令来恢复数据库,其恢复速度比 RDB 慢很多。AOF 在进行重写时也需要创建子进程,在数据库体积较大时将占用大量资源,会导致服务器的短暂阻塞。
RDB-AOF 混合持久化:

Redis 从 4.0 开始引入 RDB - AOF 混合持久化模式,这种模式是基于 AOF 持久化构建而来的。

用户可以通过配置文件中的“aof-use-rdb-preamble yes”配置项开启 AOF 混合持久化。Redis 服务器在执行 AOF 重写操作时,会按照如下原则处理数据:

  • 像执行 BGSAVE 命令一样,根据数据库当前的状态生成相应的 RDB 数据,并将其写入 AOF 文件中;
  • 对于重写之后执行的 Redis 命令,则以协议文本的方式追加到 AOF 文件的末尾,即 RDB 数据之后。

通过使用 RDB - AOF 混合持久化,用户可以同时获得 RDB 持久化和 AOF 持久化的优点,服务器既可以通过 AOF 文件包含的 RDB 数据来实现快速的数据恢复操作,又可以通过 AOF 文件包含的 AOF 数据来将丢失数据的时间窗口限制在 1s 之内。

题目三

Nginx 是什么?它有哪些应用场景?

官方解析

Nginx(发音为“engine-x”)是一个高性能的开源 Web 服务器反向代理服务器,可以处理大量的并发连接和请求。它使用事件驱动的异步架构和多线程设计,可以高效地处理并发请求,同时也支持反向代理、负载均衡、动态HTTP缓存、SSL/TLS终止、基于模块的扩展等功能。

Nginx 的应用场景非常广泛,以下是其中的几个:

  • Web 服务器:Nginx 可以作为 HTTP 服务器,处理并发的静态请求和动态请求,并且可以支持负载均衡和缓存,为网站提供高性能和高可用性。
  • 反向代理服务器:Nginx 可以作为反向代理服务器,接收客户端请求并将其转发到后端服务器,同时也可以支持负载均衡和缓存。
  • 邮件代理服务器:Nginx 可以作为邮件代理服务器,支持 POP3、IMAP 和 SMTP 协议,并且可以支持 SSL/TLS 加密和反垃圾邮件功能。
  • 流媒体服务器:Nginx 可以作为流媒体服务器,支持 RTMP、HLS 和 DASH 协议,可以用于实现直播、点播和视频-on-demand(VoD)等场景。

总之,Nginx 具有高性能、可扩展性和可靠性等特点,被广泛应用于大型网站、互联网公司、云计算、视频流媒体、游戏等领域。

鱼皮补充:这题建议大家说一下自己是怎么使用 Nginx 的,这是一个很重要、但是缺容易被忽略的后端技术

鱼友的精彩回答

一万小時的回答

nginx 是一个高性能的 http 和反向代理服务器 和 tomcat 一样也是 web 服务器。

tomcat 能够应对的并发 一般在 400 左右, 也就是支持 400 个请求 并发访问,比如学校选课的时候 尤其一些选修课 。你在进入选课系统的时候会很卡,再如比如说 经历一次春运,票放出来的一瞬间,就没了,这一瞬间的请求买票可能高达上亿,会瞬间冲垮服务器 导致宕机(死机),所以 我们为了应对这种高并发 能够经受高负载这种场景 我们选择使用 nginx 服务器

nginx 服务器可以应对 50000 个并发连接

nginx 作为一个 web 服务器,它是不支持 java 程序的,tomcat 是支持 java 程序的,那么如果我想要让 nginx 能够部署我的 java 项目 那么需要借助 tomcat 来帮助,所以我们需要将 nginx 和 tomcat 进行合作

反向代理,反向代理起始就是代理服务器端,也就是使用 nginx 去代理 tomcat

前端

题目一

什么是 HTML 语义化?为什么要语义化?

官方解析

HTML 语义化是指在编写 HTML 代码时,使用具有含义的标签来描述页面内容的结构和意义,而不是只关注页面的表现形式。比如使用 <header> 标签来表示页面头部,使用 <nav> 标签来表示页面导航,使用 <article> 标签来表示文章内容等。

HTML 语义化的目的在于增强页面的可读性和可维护性,使得开发人员和搜索引擎更容易理解页面的结构和内容。此外,语义化的 HTML 代码也更符合无障碍标准,使得视力受限的用户等特定人群能够更方便地访问页面。

除此之外,语义化的 HTML 代码还有利于 SEO(搜索引擎优化),可以使得搜索引擎更好地抓取页面内容,提高网站在搜索引擎中的排名。

综上所述,HTML 语义化可以使得页面更易读、易维护、易访问和易优化。

鱼友的精彩回答

H.lj🎏ᯤ⁶ᴳ的回答

HTML语义化是指在编写HTML文档时,使用恰当的标签和属性,以及正确的结构来描述文档的内容、结构和意义。HTML语义化可以让Web开发人员更好地组织和呈现页面内容,使页面更具有可读性和可访问性,同时也有助于提高SEO优化效果。

具体来说,HTML语义化可以带来以下几个好处:

  1. 代码可读性:通过语义化的标签和结构,可以更好地描述文档的结构和意义,使代码更加清晰易懂,方便维护和修改。
  2. 改善用户体验:语义化的HTML结构可以提高页面的可读性和可访问性,使页面内容更容易被用户理解和使用,从而提高用户体验。
  3. 提高SEO优化效果:语义化的HTML结构可以提高搜索引擎对页面的理解和评价,使网站更容易被搜索引擎收录和排名,从而提高SEO优化效果。
  4. 更好的跨平台支持:语义化的HTML结构可以使页面更好地适应不同的浏览器和设备,提高页面的跨平台支持性和兼容性。
  5. 更好的可维护性:通过语义化的HTML结构,可以更好地区分页面的内容和样式,使CSS和JavaScript的编写更加简单和直观,从而提高代码的可维护性。

因此,HTML语义化是 Web 开发中非常重要的一个概念,它可以帮助开发人员更好地组织和呈现页面内容,提高页面的可读性、可访问性和 SEO 优化效果,同时也有助于提高代码的可维护性和可扩展性

题目二

怎么用 JS 实现大型文件上传?要考虑哪些问题?

官方解析

在前端实现大型文件上传,需要考虑以下几个问题:

分片上传:将大文件切割成多个小块进行上传,可以避免一次性上传大文件导致的上传时间过长,网络中断等问题。通常情况下,每个块大小为 1MB 左右。

断点续传:由于网络等因素,上传过程中可能出现中断,此时需要能够从中断的地方恢复上传。

并发上传:多个文件同时上传,需要对上传队列进行管理,保证上传速度和顺序。

上传进度显示:及时显示上传进度,让用户知道上传进度和状态。

可以通过使用第三方库来实现大型文件上传,比如 Plupload、Resumable.js 等。

以下是一个使用 Plupload 实现大型文件上传的示例:

<!-- 引入 Plupload 的 JavaScript 和 CSS 文件 -->
<script type="text/javascript" src="plupload.full.min.js"></script>
<link rel="stylesheet" href="plupload.css">

<!-- 上传控件的容器 -->
<div id="uploader">
  <p>Your browser doesn't have Flash, Silverlight or HTML5 support.</p>
</div>

<!-- 初始化上传控件 -->
<script type="text/javascript">
  var uploader = new plupload.Uploader({
    browse_button: '
uploader', // 上传控件的容器
    url: '
/upload', // 上传文件的 URL
    multi_selection: false, // 是否允许同时上传多个文件
    filters: {
      max_file_size: '
100mb', // 最大上传文件大小
      mime_types: [
        { title: '
Image files', extensions: 'jpg,jpeg,gif,png' },
        { title: '
Zip files', extensions: 'zip,rar' }
      ]
    },
    init: {
      // 添加文件到上传队列之前触发的事件
      BeforeUpload: function (up, file) {
        console.log('
BeforeUpload:', file.name);
      },
      // 开始上传文件时触发的事件
      UploadFile: function (up, file) {
        console.log('
UploadFile:', file.name);
      },
      // 上传进度改变时触发的事件
      UploadProgress: function (up, file) {
        console.log('
UploadProgress:', file.percent);
      },
      // 上传成功时触发的事件
      FileUploaded: function (up, file, info) {
        console.log('
FileUploaded:', file.name, info.response);
      },
      // 上传出错时触发的事件
      Error: function (up, err) {
        console.log('
Error:', err.message);
      }
    }
  });

  // 初始化上传控件
  uploader.init();
</script>

在后端,需要根据上传控件发送的请求,来实现文件的接收和存储。具体实现方式视具体情况而定,可以使用 SpringMVC、Express.js 等框架来实现。同时,也需要考虑上传文件大小限制、上传速度控制等问题。

鱼皮补充:建议大家可以尝试手写下大文件上传,这里涉及很多知识和可优化点,写好了就是一个独立的项目

题目三

如何提高 webpack 的打包速度?

官方解析

Webpack 的打包速度受多个因素影响,以下是一些提高打包速度的方法:

  1. 升级 webpack 版本:Webpack 不断更新优化打包速度,升级到最新版本可以获得更好的性能。
  2. 使用更快的文件系统:使用更快的文件系统(如 RAM 磁盘)可以提高读写速度,加快 webpack 打包速度。
  3. 减少文件搜索范围:在 Webpack 的配置中指定更少的文件搜索路径,可以减少文件搜索的范围,提高打包速度。
  4. 使用 loader 缓存:Webpack 的 loader 会缓存处理后的结果,加快下次打包的速度。可以使用 cache-loader 和 hard-source-webpack-plugin 等插件来进一步优化 loader 的缓存。
  5. 拆分代码块:将代码拆分为更小的代码块,可以减少打包时间。可以使用 Webpack 的 code splitting 功能或手动将代码拆分为多个文件。
  6. 避免不必要的插件和 loader:减少不必要的插件和 loader 可以减少打包时间。
  7. 使用 Happypack:Happypack 可以将 Webpack 的 loader 转换为多线程模式,加快打包速度。
  8. 启用 Tree Shaking:Tree Shaking 可以排除未使用的代码,减少打包大小,加快打包速度。

总之,提高 webpack 打包速度需要从多个方面综合考虑,需要不断进行尝试和优化。

鱼皮补充:这题建议大家自己尝试一下,学好打包工具可以让你的前端水平上升一个档次,不再是像我一样的页面仔

鱼友的精彩回答

H.lj🎏ᯤ⁶ᴳ的回答

以下是一些提高Webpack打包速度的技巧:

  1. 升级Webpack版本:Webpack的新版本通常具有更快的构建速度和更好的性能。
  2. 减少模块解析范围:通过设置resolve.modules、resolve.extensions、resolve.alias等选项,可以让Webpack减少查找和解析模块的范围,从而加快构建速度。
  3. 使用LoaderOptionsPlugin插件:该插件可以将Loader的选项提取到Webpack的配置中,避免在每个Loader中重复设置相同的选项,从而提高构建速度。
  4. 使用HappyPack插件:该插件可以将Webpack的构建任务分解成多个子进程并行执行,从而加快构建速度。
  5. 使用DllPlugin和DllReferencePlugin插件:该插件可以将常用的第三方库预先编译成一个单独的文件,从而避免重复打包,提高构建速度。
  6. 开启缓存:通过设置cache选项或使用cache-loader等插件,可以让Webpack在第二次构建时复用已经处理过的结果,从而加快构建速度。
  7. 压缩代码:使用UglifyJsPlugin等插件可以将代码压缩,从而减少文件大小和加载时间,提高性能。
  8. 移除不必要的插件和Loader:删除不必要的插件和Loader可以减少Webpack的处理时间,从而加快构建速度。
  9. 使用Tree shaking:使用ES6的import和export语句以及Webpack的tree shaking功能可以减少打包后的文件大小,从而提高构建速度和性能。
  10. 使用多个entry和output:使用多个entry和output可以将不同的代码分别打包成多个文件,从而减少每个文件的大小,提高构建速度和性能。

星球活动

1.欢迎参与 30 天面试题挑战活动 ,搞定高频面试题,斩杀面试官!

2.欢迎已加入星球的同学 免费申请一年编程导航网站会员

3.欢迎学习 鱼皮最新原创项目教程,手把手教你做出项目、写出高分简历!

加入我们

欢迎加入鱼皮的编程导航知识星球,鱼皮会 1 对 1 回答您的问题、直播带你做出项目、为你定制学习计划和求职指导,还能获取海量编程学习资源,和上万名学编程的同学共享知识、交流进步。

💎 加入星球后,您可以:

1)添加鱼皮本人微信,向他 1 对 1 提问,帮您解决问题、告别迷茫!点击了解详情

2)获取海量编程知识和资源,包括:3000+ 鱼皮的编程答疑和求职指导、原创编程学习路线、几十万字的编程学习知识库、几十 T 编程学习资源、500+ 精华帖等!点击了解详情

3)找鱼皮咨询求职建议和优化简历,次数不限!点击了解详情

4)鱼皮直播从 0 到 1 带大家做出项目,已有 50+ 直播、完结 3 套项目、10+ 项目分享,帮您掌握独立开发项目的能力、丰富简历!点击了解详情

外面一套项目课就上千元了,而星球内所有项目都有指导答疑,轻松解决问题

星球提供的所有服务,都是为了帮您更好地学编程、找到理想的工作。诚挚地欢迎您的加入,这可能是最好的学习机会,也是最值得的一笔投资!

长按扫码领优惠券加入,也可以添加微信 yupi1085 咨询星球(备注“想加星球”):

继续滑动看下一个

Redis 的持久化机制有哪些?

编程导航和鱼友们 面试鸭
向上滑动看下一个

您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存