浏览器缓存相关面试题一网打尽,理论结合实践,用代码学习缓存问题,建议关注+收藏,(含项目源代码)

2024-01-09

前言

浏览器缓存的问题是面试中关于浏览器知识的重要组成部分,也是性能优化题目的一部分,但是不要被吓到,我话放到这里,就那么点东西,我这一篇文章基本上就涵盖了所有相关的知识点,认真看一遍,所有的问题都是纸老虎。

一、准备工作

1.1 拉取仓库

本篇文章因为涉及到了在服务端设置缓存的内容,所以需要一个服务端的项目,可以跟着我的 这篇文章 搭建自己的服务端项目,或者直接克隆我的 仓库代码 。直接拉取最新的 master 分支的代码即可。

1.2 搭建服务器

1.2.1 新建 cache 文件夹

1.2.2 index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    cache 
</body>
</html>

1.2.3 index.js

const express = require('express')
const path = require('path')

const app = express()

app.get('/', (req, res) => {
    res.sendFile(path.resolve(__dirname, 'index.html') )
})

app.listen(3000)

1.2.4 运行

npm run dev cache

为什么运行参数要加一个 cache?

这是因为我的项目设置的,加一个参数,可以运行其文件夹下面的文件,具体请看 这篇文章

1.2.5 提交代码

二、准备知识

我们前端说的缓存一般有两种类型,一个是浏览器相关的缓存,一个是 CDN 的缓存,CDN 的缓存一般我们控制不了,是服务商设置的【如阿里云】,我们最多可以使用服务商的管理平台开启、关闭或者清空缓存。此外后端也有很多缓存比如 redis 缓存,但是我们可以先不用考虑。

所以,我们前端面试题目中经常出现的缓存基本都和浏览器有关,浏览器的缓存又有很多种我们来逐一击破。

2.1 前端缓存方式

前端缓存有一下几种方式

  1. Service Workers 【可以缓存资源的请求, 参考
  2. web Storage【LocalStorage/SessionStorage】
  3. IndexedDB【这个相当于浏览器中的数据库,请看 官网
  4. Cache API【这个我没用过,可以看 官网 ,是实验性技术】
  5. Http 缓存头【这个是本篇文章的重点】

本篇文章主要介绍使用 http 缓存头完成的缓存逻辑。

2.2 浏览器的多进程模型

在学习浏览器的缓存之前,我们需要先来学习一下浏览器的相关内容,内容不多,记住浏览器的主要的几个进程就可以。

  1. 浏览器主进程
  2. 网络进程
  3. 渲染进程
  4. 插件进程
  5. GPU 进程

具体的内容可以看一下我的 这篇文章

一般来说和 http 缓存头相关的缓存内容是浏览器的【网络进程】控制的

2.3 缓存的目的

如果网络进程在发送请求之前,发现本地有有效的缓存的文件和要请求的 URL 地址所匹配,那么就不需要发起后续的请求了。所以缓存的目的是减少网络请求,减少服务器的压力,提高页面加载的速度,提高网络的性能。特别是对于一些静态资源,不经常改动,那就一次请求,然后缓存下来,直到这个资源有改动,我们再去服务端拉去新的资源。

三、http 请求头缓存

下面所说的所有关于缓存的内容都是针对前端 http 请求头缓存的。

3.1 缓存位置

常见的缓存位置有两个分别是 disk cache 和 memory cache

memory cache 存在内存中,关闭浏览器标签页就释放,容量小,读取速度快
disk cache 存在磁盘中,容量大,读取速度慢

什么资源存储在 disk 中,什么资源存储在memory 中是浏览器的规则 ,一般来说肯定是大的资源比如字体啥的存在disk中,小的资源存取比较频繁的放在 memory 中,貌似没必要知道具体的详细的规则。

具体的缓存存在什么地方,我们在开发者工具中可以看到

3.2 刷新缓存

刷新页面的时候,不通的方式对缓存的处理对比

地址栏回车/直接访问 URL 保留强缓存,保留协商缓存,走正常请求流程
点击浏览器刷新按钮 忽略强缓存,保留协商缓存
按f5【command + r】 忽略强缓存,保留协商缓存
ctrl + f5 【command + shift + r 】 忽略强缓存,忽略协商缓存,从服务器端请求最新资源【强制刷新】

如果你改了页面提测了,测试同学说,不对啊,页面没有更新!

这个时候,那么你就应该考虑是不是有缓存,一般你说 【强制刷新】试下呢?基本就好了

这个里面还有个问题,就是可以使用无痕模式/ 隐身模式,无痕模式在关闭浏览器窗口后会删除浏览会话的所有信息。

  1. 不存储历史记录
  2. 不存储表单数据
  3. 不存储 cookie
  4. 不存储缓存

注意!他这里的不存储是指在关闭无痕窗口之后不存储,不是你在无痕窗口打开的时候没有,比如说缓存吧,你在无痕窗口刷新页面该有缓存,还是会有缓存。

3.3 缓存类型

http 请求头的缓存就分为两种类型【强缓存】和【协商缓存】。先记住一点,强缓存是用浏览器本地的缓存,不需要服务器参与;协商缓存是需要和服务器协商的;但是本质两种缓存用的缓存文件还都是存在浏览器本地的,和服务器协商的目的是为了验证本地缓存是否有效。

而且这两种缓存的共同点是,都是用 http 请求头部控制,接下来我们分别详细介绍强缓存和协商缓存。

3.4 请求头部

缓存涉及的无论是响应头、请求头有且仅有下面几个

  1. expires 【响应头】
  2. cache-control【请求头】【响应头】
  3. Etag【响应头】  / if-none-match【请求头】
  4. last-modified【响应头】 / if-modified-since【请求头】

至于每个头部的取值和赋值的规则,下面的章节会有详细的介绍。

注意,http 头部是不区分大小写的。

四、强缓存

强缓存的涉及的请求头只有两个分别是 expires 和 cache-control。

4.1 expires 响应头

expires 只作为响应头出现在 http 请求的头部,expires  响应头设置一个服务器的绝对过期时间【必须是GMT时间,且需要考虑时差】,在这个时间之前资源都不用重新请求。

这是一个服务器的绝对时间,所以一定是由设置在响应头上的。

4.1.1 代码模拟

(1)修改 index.html

(2) 修改 index.js

注意这里面有一个坑,就是 express 服务回自动带上 ETag 但是这个是属于协商缓存的内容,我们暂时还没有用到,所以需要先禁用!

const express = require('express');
const path = require('path');

const app = express();
// 先禁用协商缓存的头部
app.disable('etag')

app.get('/', (req, res) => {
  res.sendFile(path.resolve(__dirname, 'index.html'));
});

app.get('/info', (req, res) => {
  try {
    // 设置一分钟后过期
    const now = new Date();
    // 计算时差
    const now2 = now.setTime(
      now.getTime() - now.getTimezoneOffset() * 60 + 1 * 60
    );
    // 转换成 GMT 时间
    const expiresDate = new Date(now2).toUTCString()
    // 设置响应头
    res.setHeader('expires', expiresDate);
    res.send('ok');
  } catch (err) {
    console.log(err);
  }
});

app.listen(3000);

(3)运行

npm run dev cache

我们的服务设置的 info 请求一分钟后过期

我们来看一下使用缓存的第二个请求的请求头是啥样的,注意这个时候返回的状态码依旧是 200,代表请求成功。

至此关于强缓存的第一个 http 头部,响应头 expries 就介绍完了。

(4)提交代码

4.2 cache-control

和 expires 不同的是,cache-control 不仅可以服务端设置作为响应头,还可以客户端设置作为请求头,至于到底是客户端端设置,还是服务端设置,结论在 这篇文章

我们可以看 mdn 官方文档 cache-control 有很多取值,请求头和响应头还不一样;下表中标红的是常见的,在这篇文章中我们也只研究标红的请求/响应头。

请求头 响应头
1 no-cache no-cache 使用协商缓存
2 no-store no-store 不缓存
3 max-age max-age 强缓存失效后,使用协商缓存
4 no-transform must-revalidate
5 min-fresh no-transform
6 only-if-cached public
7 private
8 proxy-revalidate
9 s-maxage

常用的头部其实只有3个,分别是 no-cache、no-store、max-age

cache-control取值 说明
no-cache 在发布缓存副本之前,强制要求缓存把请求提交给原始服务器进行验证 (协商缓存验证)。
no-store 缓存不应存储有关客户端请求或服务器响应的任何内容,即不使用任何缓存。
max-age=<seconds> 设置缓存存储的最大周期,超过这个时间缓存被认为过期 (单位秒)。与 Expires 相反,时间是相对于请求的时间。max-age =0 实际上和 no-cache 的行为一致

这个怎么记呢,尤其是 no-cache 和 no-store 总是容易弄混?

记住这个单词 store  有存储的意思,no-store,那就是不存储,无论如何都不存储,所以no-store 更狠一些,不存储任何东西,不使用任何缓存。

看看官网怎么说

The "no-store" request directive indicates that a cache MUST NOT store any part of either this request or any response to it. This directive applies to both private and shared caches. "MUST NOT store" in this context means that the cache MUST NOT intentionally store the information in non-volatile storage, and MUST make a best-effort attempt to remove the information from volatile storage as promptly as possible after forwarding it. “no-store”请求指令表明缓存不能存储此请求的任何部分或对其的任何响应。 这指令适用于私 有和共享缓存。
“一定不在此上下文中“存储”意味着缓存不得故意将信息存储在非易失性存储器中,并且必须制作  ,一个尽最大努力尝试从易失性存储中删除信息 转发后尽快。

对比之下 no-cache 就温和一点了,不使用缓存,但是还有协商缓存这一个口子

4.3 cache-control 响应头

我们先来看响应头设置 cache-control 的情况,对于强缓存的响应头其实只有一个 max-age

且max-age的值不能为0,max-age=0 等价于 no-cache

4.3.1 修改 index.html

4.3.2 no-store 响应头

no-store 响应头不做任何缓存,无论发送多少请求都是重新请求

4.3.3 no-cache 响应头

4.3.4 max-age

max-age 的单位是秒

(1)max-age=0

(2)max-age 不等于0

这个才是真正的强缓存,和之前说的 expires 头部一样,真正的强缓存。

设置 max-age=10  10秒之后过期。

4.4 cache-control 请求头

4.4.1 no-store

我们在之前的代码基础上,不修改 index.js 保留响应头 max-age=10 的设置

我们发现了,即便是请求头设置了不使用缓存,浏览器依旧使用了响应头的强缓存,这个就很神奇了。

4.4.2 no-cache

把请求头设置为 no-cache

4.4.3 max-age=0

4.4.4 max-age 不等于0

客户端和服务端同时设置了max-age,这里面以服务端设置的响应头为准了。

我们接下来吧响应头的 max-age去掉,仅保留请求头的,发现强缓存并未生效。

所以我得出了一个结论,就是在客户端设置 max-age 请求头值为非 0 的强况下,强缓存不会生效。

至少我测试的 express + chrome 浏览器是这样的,不通的浏览器可能对于缓存有不同的规则。

4.5 请求头 vs 响应头

通过上面的例子,我么你注意到 cache-control 的同一个值可以即由客户端设置在的请求头,又可以由服务度设置在响应头。但是你要问了,到底设置在哪边呢?

我的建议是不要纠结,同时设置到底以那个为准了,不通浏览器貌似有不同的处理。

对于客户端和服务端同时设置 cache-control 不通的值的时候还有很多组合,但是感觉没有逐个测试的意义,我们只要只要每个值的含义就行了,在实际应用过程中,如果客户端设置的不满足需求,我们就使用服务端设置就行了。

如果你还有其他的见解,也可以在评论区发表观点,我们一起讨论下。

4.6 expires 和 cache-control

强缓存涉及到两个 http 头部,分别是 【expires】和【cache-control】其中【cache-control】的优先级高于【expires】,这是因为 【expires】是在http1.0 提出来的,【cache-control】是在http1.1 提出的。二者同时存在的时候以【cache-control】为准。

4.6.1 修改 index.html

4.6.2 修改 index.js

4.7 刷新强缓存

(1)使用浏览器的强制刷新功能就可以强制刷新缓存,比如 按下ctrl + f5【mac 电脑是 command+shift +R】,浏览器会忽略所有缓存,也不执行协商缓存。

(2)使用开发者工具禁用缓存,注意这个只在开发者工具打开的时候有效!关掉开发者工具,刷新缓存就只能用强制刷新。开发者工具的这个禁用缓存浏览器会忽略所有缓存,也不执行协商缓存。

小结

至此,强缓存相关的知识已经总结完毕,结论是设置响应头为 max-age 且值不为0 或者expires 时会使用强缓存。

五、协商缓存

如果命中强缓存,那就直接使用缓存内容即可,不需要发起后续请求,但是上面我们提到了,如果cache-control 设置了 no-cache / 或者 max-age=0 / 或者 max-age =xxx 过期了,就需要进行协商缓存。

5.1 协商缓存条件

协商缓存的条件有

  1. cache-control: no-cache 或者
  2. cache-control: max-age=xxx (单位是秒) 过期了/或者是 =0

协商缓存涉及到的请求头有 2 种方式,这两组一般是选其中一种,但是也可以同时设置,这两组请求头的第一个字段是需要后端在服务器代码中加上的(last-modified或者etag);第二个字段是浏览器根据上一个请求的响应头的 last-modified 或者 etag,自动设置的,不需要人工参与。

我们前端只需要在请求头上设置 cache-control 的值为 no-cache,或者设置 max-age=0,也要服务端配合设置响应头, 具体的规则参考这篇文章

注意 no-cache 和 max-age 是两个c ache-control 字段的取值,他俩可以同时使用(使用逗号分隔),也可以只使用其中的一个。

(1)仅设置了 no-cache 那么每次使用缓存之前,都需要去服务器确认资源;

(2)仅设置了 max-age 在未过期之前不需要向服务器确认资源的有效性;

(3)no-cache 和 max-age 同时设置的时候 no-cache 生效,每次都需要去服务器进行资源验证

如果你是服务端开发者,你就需要从下面 2 对协商缓存头中选一对。但是一般如果是使用的服务端的框架,对于缓存框架有默认的内部的处理,不需要手动设置,比如 express 就会默认携带etag,详情请看4.1.1,我们手动禁用了express 中的Etag

5.2 协商缓存头部

5.2.1 Last-Modified / If-Modified-Since【优先级低】

当浏览器首次请求一个资源时,服务器会返回资源的最后修改时间(服务端在响应头设置 Last-Modified )。当浏览器再次请求该资源时,会在请求头中自动包含 If-Modified-Since 字段,该字段的值是上次服务器返回的最后修改时间。如果资源在这个时间之后没有发生变化,服务器可能会返回状态码 304(Not Modified),告诉浏览器可以使用本地缓存。

这里面说的【服务器返回】,就不是浏览器的功能了,是后端开发人员手动写的,比如我们手动写的 express 服务 需要手动设置,last-modifed 的取值需要时 GMT 时间。

 res.setHeader('Last-Modified', xxx)

然后还需要获取请求头部的 If-Modified-Since 并且和 服务端保留的上一个请求的 last-mofified 字段进行对比,如果没有修改返回 304。大概的代码如下,这个例子使用的是express

let lastModifed = ''
app.get('/auth', function (req, res, next) {
  res.setHeader('cache-control', 'max-age=20')
  // 获取浏览器自动 加上的请求头
  const ifModifiySince = req.headers['if-modified-since']
  // 判断内容是否被修改
  // lastModifed 注意这个字段是上一个请求的
  if (ifModifiySince === lastModifed) {
    res.status(304) // 给浏览器返回304 状态码
    res.end('end')
    return
  }
  lastModifed = new Date().getTime()
  // 服务端设置 Last-Modified,这是给下一个请求设置的
  res.setHeader('Last-Modified', lastModifed)
  res.end('ok');
});

如果是我们自己实现的服务端,那么就需要有这块的逻辑,但是如果用的后端的框架,一般框架都会带有这些逻辑,就不用自己写了。

5.1.2 ETag / If-None-Match 【优先级高】

类似于 Last-Modified ,服务器在响应头返回资源的唯一标识符(这个标识符由服务端自己定义可,一般是基于资源内容的哈希值),称为 ETag。浏览器在后续请求中,会在请求头中自动包含 If-None-Match 字段,该字段的值是上次服务器返回的ETag。如果资源的ETag匹配,服务器同样可以返回状态码 304,告诉浏览器可以使用本地缓存。

如果 Last-Modified 和 ETag 同时存在,那么优先判断 ETag / if-none-match,因为ETag 是http1.1 提出来的。

ETag 优先的意思是,判断完是否有 ETag ,如果有就不判断 last-modified了,如果没有 Etag 再判断 last-modifed

5.3 代码模拟

首先我们把所有的强缓存的头部去掉,客户端和服务端都不设置任何强缓存头部。

5.3.1 Last-Modified / If-Modified-Since

Last-Modified 的值需要时 GMT 时间,这一点和 expires 是一样的,但是其实我们可以设置任意值,因为对比 Last-Modified  和 If-Modified-Since 的逻辑是我们的服务端自己写的的。如果我们设置的值是非时间格式的,那么其实就和 ETag 一样了。

(1)修改 index.html

(2) 修改 index.js

(3)运行结果

字段给带上了,但是还没有使用缓存,因为 304 逻辑需要服务端自己实现。

(3)代码实现使用缓存

304 这个状态码记住,就是未修改的意思。

5.3.2 ETag / if-none-match

如果上面的 last-modified 不设置为时间,那么就是和 ETag 的逻辑一致。

(1)修改代码

(2)运行结果

5.4 小结

注意,我们整个协商缓存的代码都没有设置 cache-control, 也就是说可以理解为协商缓存的头部不是依赖于 cache-control 的,但是cache-control 如果设置了 no-cache/max-age=0/max-age 过期,接下来就会判断是否有协商缓存的头部。

5.4.1 强缓存+协商缓存

我们以 max-age 为例试一下。

总结

前端缓存,使用http请求头控制的缓存这块,如果用代码自己实现之后发现,就那么点东西。

内容比较多难免疏漏,有问题欢迎指正。

我的仓库地址是, yangjihong2113/learn-express

这是一系列文章,我会在我的专栏《 面试题一网打尽 》中持续更新,欢迎关注!

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

浏览器缓存相关面试题一网打尽,理论结合实践,用代码学习缓存问题,建议关注+收藏,(含项目源代码) 的相关文章

  • AngularJS'无法读取未定义的'then'属性'

    我遇到这个问题 当我单击登录按钮时 chrome 控制台会记录以下内容 angular min js 117 TypeError 无法读取未定义的属性 then 在 m scope logIn loginModuleController j
  • 如何使用 jsPDF 和 HTML2Canvas 从网站获取多页 pdf?

    我有一个使用 HTML2Canvas 来截取屏幕截图的脚本div在页面中 然后使用 jsPDF 将其转换为 pdf 问题是生成的 pdf 只有一页 而屏幕截图在某些情况下需要不止一页 例如 屏幕截图大于 8 5x11 宽度很好 但我需要它来
  • Javascript:在 For 循环中创建函数

    最近 我发现自己需要创建一系列函数 这些函数使用 XML 文档中的值 并且我使用 for 循环运行适当的节点 然而 在执行此操作时 我发现数组中的所有函数仅使用过 XML 表的最后一个节点 对应于 for 循环的最后一次运行 以下是展示这一
  • 如何使用 Javascript 弹出一个新窗口,其 html 与其父窗口几乎相同

    我想从单个页面创建多个版本的适合打印的页面 我正在考虑这样做 在原始页面上放置几个按钮 然后单击一个按钮将弹出一个新窗口 其html与其父窗口相同 但进行了一些修改 例如 将某些DIV的显示属性设置为没有任何 可以使用javascript来
  • Angular2:如何在实现 routerCanDeactivate 时防止/取消历史操作?

    routerCanDeactivate 成功阻止导航离开组件 routerCanDeactivate nextInstruction ComponentInstruction prevInstruction ComponentInstruc
  • 如何在chrome中启用sharedArrayBuffer而不进行跨域隔离

    我有一个仅在本地计算机上运行的实验 例如 我加载外部网页https example com和 puppeteer 我注入一个 javascript 文件 该文件由http localhost 5000 到目前为止还没有问题 但是 这个注入的
  • 淘汰赛“闪烁”问题

    我正在使用 KO 构建 SPA 单页应用程序 该应用程序看起来像一本书 用户可以翻页 问题是 每次加载页面时 都会有一小段时间页面 闪烁 用户会看到页面的无样式版本 我猜这是因为很多样式都依赖于 ko 绑定 所以在 ko 完成它 神奇 之前
  • 如何在nodejs中获取字符串长度(以字节为单位)?

    如何在nodejs中获取字符串长度 以字节为单位 如果我有一个字符串 像这样 那么 str length 将返回 4 但是如何获得该字符串 有多少字节组成 这是一个例子 str console log str str length char
  • 在表单提交时发送 div 的值

    我正在尝试提交一个包含几个不同输入的表单 这些输入都工作正常 然而 输入之一是文本区域 某种程度 我必须将其更改为内容可编辑的 div 主要是因为我创建了自己的粗体 斜体和下划线按钮 这些按钮不适用于普通文本区域 问题是提交时的表单没有将文
  • 在 Javascript 中获取不带模 (%) 运算符的余数,占 -/+ 符号

    对于家庭作业 我需要返回 num1 除以 num2 后的余数 而不使用内置模 运算符 我可以使用以下代码让大多数测试通过 但我一直不知道如何解释给定数字的 符号 我需要保留 num1 上的任何一个符号 并且如果 num2 为负数 还返回一个
  • Javascript:使用箭头键导航表格输入

    我正在为客户制作 HTML 成绩册 我使用 PHP 生成成绩册 然后输出一个 HTML 表 如下例所示 每个 td 包含一个带有 td
  • Javascript:确认、确定、取消按钮上的自定义文本

    我有一个验证 我想显示 继续 和 返回 而不是 确定 和 取消 但我无法找到准确的解决方案 任何人都可以帮助我
  • JS:按每个类别的最大值过滤对象数组

    什么是最有效 优雅的方式来实现类似sql的过滤效果 我想过滤它们并只获取某个组中最大值的对象 这是我的代码 它可以工作 但可能不是最好的方法 uniqueValues arr gt new Set arr getMaxTimeOf arr
  • Excel 到 JSON 的 JavaScript 代码?

    我想将excel表格数据转换为json 它必须是动态的 因此有一个上传按钮 用户可以在其中上传 Excel 工作表 然后将数据转换为 json 您能给我提供 javascript 代码吗 我尝试了 SheetJS 但无法弄清楚 我更喜欢直接
  • 如何在Redis中进行持久化存储?

    关闭redis服务器后 使用set存储的值被破坏 在这里我找到了使用持久性存储的方法 有人帮助我 如何使用javascript实现这一点 我想将客户端的一些值存储在 redis 数据库中 并且必须在其他客户端中使用该值 您需要配置 Redi
  • 向 ChartJS 数据点添加逗号

    我需要在 ChartJS 图表中的数字中添加逗号 前任 数据点可能是 1032 05 4334 75 8482 46 我需要它显示为 1 032 05 4 334 75 8 482 46 以下是包含当前代码的开发网站的链接 投资计算器 ww
  • 按数字字段排序,其中时间戳位于 Cloud Firestore 中的给定日期?

    在我的 Firestore 数据库中 我的集合中有一些文档 如下所示 name Item 1 count 2 timestamp January 29 2018 at 3 43 12 PM UTC 8 我正在尝试查询这个集合 以便文档按以下
  • 如何获取表单的onSubmit事件?

    我想知道如何抢onsubmit表单中的事件来进行一些表单验证 因为我无权直接访问它 我正在编写一个用于评论的 WordPress 插件 因此无法直接访问表单标签或提交按钮 我在尝试为我的插件执行此操作时感到非常沮丧 因此我在下面编写了一个
  • grunt:如何生成 HTML 形式的 jshint 输出

    我正在尝试使用 grunt 运行 jshint 这可行 但现在我希望输出为 HTML 这是我的 grunt 文件 module exports function grunt Project configuration grunt initC
  • Materialize CSS,显示自动完成芯片的图像

    文档物化芯片 http materializecss com chips html展示您可以用图像制作芯片 div class chip img src images yuna jpg alt Contact Person Jane Doe

随机推荐

  • Linux中如何查看开启了哪些端口?

    在Linux中 端口是设备与外界通讯交流的出口 常用于指TCP IP协议中的端口 其按照端口号可以分为三类 分别是 公认端口 注册端口 动态端口 那么Linux中如何查看开启了哪些端口 以下是常用命令介绍 1 使用netstat命令 net
  • 【OpenCV学习笔记02】- 图像入门

    内容 这里介绍了图像处理的入门操作 你将学习如何读取图像 如何显示图像以及如何将其保存回去 你将学习以下功能 cv imread cv imshow cv imwrite 简单使用OpenCV 读取图像 使用 cv imread 函数读取图
  • rknn加载onnx时报错 GLIBC=2.29 no found librknnc.so

    rknn 中onnx转rknn在虚拟机中运行时发现报错 GLIBC 2 29 no found librknnc so 昨天还正常的 今天装了个ftp 和宝塔面板就出错了 我估计根据报错地址 找到了librknnc so文件 权限也给了77
  • Java毕业设计基于springboot企业车辆管理系统设计与实现

    一 项目介绍 随着时代在飞速进步 每个行业都在努力发展现在先进技术 通过这些先进的技术来提高自己的水平和优势 企业车辆管理系统当然不能排除在外 企业车辆管理系统是在实际应用和软件工程的开发原理之上 运用Java语言以及SpringBoot框
  • 全功能tgbot/Telegram机器人多功能有后台版源码

    全功能tgbot telegram机器人多功能有后台版源码 打包好的可以直接上手 trx兑换 闪兑 关键字监控 群管 usdt监控 余额查询 推广分享 等几乎常见的tg机器人功能都有
  • 期权怎么开户:期权开户免费吗,需要什么样的门槛?

    期权开户是免费的 只有交易才会产生费用 开通期权账户需要满足50万的资金 以及融资融券交易经验或者金融期货交易经验 当然也有免50万门槛的开户方式 下文为大家科普期权怎么开户啊 期权开户免费么 一般情况下 期权是可以通过在营业部网点进行开户
  • 深入浅出《Delta-Sigma Data Converters》(可下载)

    在数字信号处理领域 数据转换器是实现模拟与数字世界之间无缝转换的关键组件 而在这个子领域中 Delta Sigma Data Converter s 一书以其全面和深入的内容 为工程师 学者甚至爱好者们提供了一个极其宝贵的资源 今天将为大家
  • go cannot find package “github.com/gorilla/websocket“解读

    Go无法找到包 github com gorilla websocket 的解决方案 在Go开发过程中 我们经常会依赖第三方库来简化开发工作 而使用 go get 命令安装这些库时 有时候我们可能会遇到类似于以下错误的情况 plaintex
  • java.io.IOException: Broken pipe

    做1个接口 处理前端请求图片跨域的问题 由于前端拿图片的时候 有跨域问题 所以让后台先拿到图片 然后再写给前台 本来下面的代码没什么太大的问题 但是如果前台请求的图片一多 1个页面中有很多图片 有些请求就会报错 java io IOExce
  • 数据采集才是MES系统的核心内容

    一 数据采集在MES管理系统中的应用 1 设备数据采集 MES管理系统通过与生产设备的连接 可以实时采集设备运行状态 产量 质量等相关数据 这有助于企业及时掌握设备运行状况 优化设备资源配置 提高设备利用率 2 工艺数据采集 MES管理系统
  • Typecho 最新XC主题 去除域名授权全解密源码

    简介 Typecho 最新XC主题 去除域名授权全解密源码 这是一款多样式主题 首页支持六种主题样式 支持Pjax优化访问速度 多种单页 如友链 说说等 评论支持表情 自定义编辑器 支持其他样式功能 该主题功能性挺高 比较花里胡哨 感觉有一
  • Java毕业设计基于springboot汽车服务管理系统

    一 项目介绍 随着社会的发展 汽车服务的管理形势越来越严峻 越来越多的用户利用互联网获得信息 但汽车服务信息鱼龙混杂 信息真假难以辨别 为了方便用户更好的获得汽车服务信息 因此 设计一种安全高效的汽车服务管理系统极为重要 为设计一个安全便捷
  • 适用于任何公司的网络安全架构

    1 第一等级 基础级 优势 可防范基本有针对性的攻击 使攻击者难以在网络上推进 将生产环境与企业环境进行基本隔离 劣势 默认的企业网络应被视为潜在受损 普通员工的工作站以及管理员的工作站可能受到潜在威胁 因为它们在生产网络中具有基本和管理员
  • 【OCR】实战使用 - 如何提高识别文字的精准度?

    实战使用 如何提高文字识别的精准度 我们在平常使用OCR的时候 经常会出现文字识别不精准的情况 我们改如何提高文字识别的精度呢 以下是一些提高OCR Optical Character Recognition 光学字符识别 文字识别精准度的
  • CMAKE_MAKE_PROGRAM is not set 解读

    目录 CMAKE MAKE PROGRAM 未设置 错误原因 解决方案 示例1 GNU Make 示例2 Ninja CMakeLists txt 的结构 示例 CMakeLists txt 文件 总结 CMAKE MAKE PROGRAM
  • 【每日论文阅读】Do Perceptually Aligned Gradients Imply Robustness?

    近似人眼梯度 https icml cc virtual 2023 oral 25482 对抗性鲁棒分类器具有非鲁棒模型所没有的特征 感知对齐梯度 PAG 它们相对于 输入的梯度与人类的感知非常一致 一些研究已将 PAG 确定为稳健训练的副
  • 黑豹程序员-字符串中查找出重复的字符串

    Collections frequency codeList element 字符串element 在codeList集合中重复的次数 List
  • 字节码指令例子分析

    什么是字节码指令 字节码指令就是由一个字节长度的操作吗和操作数组成 有些只有操作码 没有操作数 例如 bipush 10 第一个参数就是操作码 第二个是操作数 a 和i 有什么区别 public static void main Strin
  • Linux搭建测试环境详细步骤

    本文讲解如何在Linux CentOS下部署Java Web项目的步骤 环境准备 1 Linux系统 2 JDK 3 Tomcat 4 MySQL 工具下载 一 Linux系统 本文主要是Linux CentOS7为例 自己在家练习小项目的
  • 浏览器缓存相关面试题一网打尽,理论结合实践,用代码学习缓存问题,建议关注+收藏,(含项目源代码)

    前言 浏览器缓存的问题是面试中关于浏览器知识的重要组成部分 也是性能优化题目的一部分 但是不要被吓到 我话放到这里 就那么点东西 我这一篇文章基本上就涵盖了所有相关的知识点 认真看一遍 所有的问题都是纸老虎 一 准备工作 1 1 拉取仓库