前端杂学录(十)
1.axios 的底层实现
1. XMLHttpRequests
在浏览器环境中,Axios
使用 XMLHttpRequest
对象来发送请求。这是一个古老的 Web API,用于在浏览器中进行异步 HTTP 请求。
2. Node.js 的 http 模块
在 Node.js 环境中,Axios
使用 Node.js 的 http
或 https
模块来发送请求。这些模块提供了创建请求的基本功能。
3. Promise
Axios
将请求封装在 Promise 中,这使得你可以使用 .then()
和 .catch()
方法来处理异步操作的成功和失败情况,或者使用 async/await
语法。
4. 转换请求和响应数据
Axios
会自动处理请求和响应数据的转换,例如:
- 将 JSON 字符串转换为 JavaScript 对象。
- 处理不同格式的数据,如 JSON、FormData 等。
5. 请求和响应拦截器
Axios
允许你添加请求和响应拦截器,这些拦截器可以修改请求配置、响应数据或在请求/响应过程中执行其他操作。
6. 错误处理
Axios
提供了错误处理机制,它会抛出的错误对象包含请求信息、响应信息、JavaScript 异常等。
7. 取消令牌(CancelToken)
Axios
支持取消请求的功能,通过创建一个取消令牌(CancelToken),你可以在请求发送后取消它。
Axios 源码分析
Axios
的核心源码主要包含以下几个部分:
-
axios.js:这是
Axios
的入口文件,它创建了axios
函数和Axios
原型链上的方法,如get
、post
等。 -
defaults.js:定义了
Axios
的默认配置,如 baseURL、headers、transform 请求和响应数据的函数等。 -
core/Axios.js:实现了
axios
函数和Axios
原型链上的方法。这是Axios
请求的核心逻辑,包括发送请求、处理响应、应用拦截器等。 -
core/dispatchRequest.js:负责根据配置发送请求,并处理请求过程中的 Promise 链。
-
core/transformData.js:处理请求和响应数据的转换。
-
core/createError.js:创建
Axios
错误对象。 -
core/settle.js:处理请求完成后的 Promise 解决(resolve)或拒绝(reject)。
-
cancel/CancelToken.js 和 cancel/isCancel.js:实现了取消令牌的逻辑。
-
helpers/:包含了一些辅助函数,如 URL 处理、头部处理等。
Axios 请求流程
- 创建
axios
实例或直接使用axios
发送请求。 Axios
构造函数创建一个请求配置对象。- 如果提供了请求或响应拦截器,将它们添加到请求配置对象。
- 调用
dispatchRequest
方法发送请求。 dispatchRequest
方法根据请求配置对象发送 HTTP 请求,并返回一个 Promise。- 请求完成后,根据响应结果调用
Promise
的resolve
或reject
方法。
2.ECharts 底层是用什么绘制的
ECharts 的底层渲染引擎是 Canvas。Canvas 是 HTML5 提供的一个 API,允许通过 JavaScript 在网页上绘制图形。ECharts 利用 Canvas 的 2D 渲染上下文进行绘图,从而实现各种图表的渲染。
为什么选择 Canvas
- 性能:Canvas 提供了一种高效的方式来绘制图形,尤其是在处理大量数据和复杂动画时,Canvas 的性能通常优于 SVG。
- 灵活性:Canvas 提供了较低级别的绘图接口,使得开发者可以灵活地绘制各种自定义图形。
- 跨平台:Canvas 是 HTML5 的一部分,可以在现代浏览器中无缝工作,同时也可以通过一些库(如 node-canvas)在 Node.js 环境中使用。
ECharts 的工作流程
- 数据处理:ECharts 允许用户以 JSON 格式配置图表的数据和选项。
- 渲染流程:ECharts 内部会解析这些配置,然后使用 Canvas 绘制图表。
- 事件处理:ECharts 还提供了丰富的事件回调,例如点击、悬停等,以便开发者可以响应用户交互。
示例代码
以下是一个简单的 ECharts 折线图示例:
<!DOCTYPE html>
<html style="height: 100%">
<head><meta charset="utf-8">
</head>
<body style="height: 100%; margin: 0"><div id="container" style="height: 100%"></div><script src="https://cdn.jsdelivr.net/npm/echarts/dist/echarts.min.js"></script><script>var chartDom = document.getElementById('container');var myChart = echarts.init(chartDom);var option;option = {title: {text: '主标题'},tooltip: {},legend: {data:['销量']},xAxis: {data: ["衬衫","羊毛衫","雪纺衫","裤子","高跟鞋","袜子"]},yAxis: {},series: [{name: '销量',type: 'line',data: [5, 20, 36, 10, 10, 20]}]};option && myChart.setOption(option);</script>
</body>
</html>
在这个示例中,我们首先在 HTML 中创建了一个 div
容器,然后使用 ECharts 提供的 echarts.init
方法初始化一个图表实例,并指定容器。接着,我们定义了一个 option
对象来配置图表的标题、提示框、图例、坐标轴和系列数据。最后,我们通过调用 myChart.setOption(option)
方法来渲染图表。
3.husky的原理是什么
Husky 是一个 Git 钩子(hooks)管理器,用于在版本控制的生命周期中自动执行脚本,如提交前(pre-commit)、提交后(post-commit)、推送前(pre-push)等。Husky 通过在 Git 仓库中安装钩子来工作,它的原理主要基于以下几个方面:
1. Git 钩子(Git Hooks)
Git 钩子是 Git 提供的一种机制,允许在特定的动作发生时触发自定义脚本。这些钩子脚本可以用于执行各种任务,如代码格式化、运行测试、检查代码风格等。
2. Husky 的安装和配置
当你在项目中安装 Husky 时,它会在项目的 node_modules/.husky
目录下创建一个 Git 钩子目录。Husky 会修改项目的 .git/config
文件,将 Husky 脚本指向相应的 Git 钩子。
例如,如果你想要在提交前运行一些脚本,Husky 会在 .husky/pre-commit
文件中添加一个脚本,该脚本会在每次执行 git commit
命令时运行。
3. Husky 的工作流程
当执行 Git 操作(如提交、推送等)时,Git 会检查对应的钩子脚本是否存在,并执行它们。Husky 利用这一点来自动运行你配置的脚本。
- 安装 Husky:通过 npm 或 yarn 安装 Husky。
- 配置 Husky 钩子:使用
husky
配置对象在package.json
文件中设置钩子。 - 运行钩子脚本:当相应的 Git 操作被执行时,Husky 会触发配置的脚本。
4. 示例配置
{"husky": {"hooks": {"pre-commit": "npm run lint","pre-push": "npm test"}}
}
在这个示例中,我们配置了两个钩子:
pre-commit
:在提交前运行npm run lint
脚本。pre-push
:在推送前运行npm test
脚本。
5. 注意事项
- Husky 只在本地开发环境中工作,它不会影响其他开发者的 Git 钩子配置。
- Husky 需要 Node.js 环境,因此它通常用于 JavaScript 或 TypeScript 项目。
- Husky 4.0 及更高版本引入了对
pnpm
和yarn
工作区的支持。
4.Vite为什么快?是怎么打包的?
Vite 为什么快?
-
原生 ES 模块(ESM):
- Vite 利用了浏览器原生支持的 ES 模块特性,这意味着在开发过程中,Vite 可以直接使用
import
和export
语句来动态加载模块,而无需打包整个应用。
- Vite 利用了浏览器原生支持的 ES 模块特性,这意味着在开发过程中,Vite 可以直接使用
-
服务端渲染(SSR):
- 在开发过程中,Vite 作为一个静态文件服务器,通过 Node.js 服务端渲染模块,这避免了传统打包器在启动时需要进行的复杂打包操作。
-
按需编译:
- Vite 仅在需要时编译文件,例如当模块发生变化时,Vite 才会编译这些更改的模块,而不是每次都编译整个项目。
-
高效的热模块替换(HMR):
- Vite 提供了快速的热更新能力,这意味着开发者在修改代码后可以立即看到更改的效果,而无需刷新整个页面。
-
并行处理:
- Vite 利用多核处理器的能力,可以并行处理任务,例如并行编译和压缩文件。
-
优化的构建过程:
- 在构建(构建生产版本)过程中,Vite 使用了 Rollup,这是一个零配置的模块打包器,专注于速度和简洁的打包结果。
Vite 是怎么打包的?
-
开发模式:
- 在开发模式下,Vite 不会执行完整的打包过程。相反,它提供了一个开发服务器,该服务器处理模块的按需编译和提供热更新。
-
构建模式:
- 在构建模式下,Vite 使用 Rollup 作为其打包器。Rollup 会根据 Vite 的配置来打包应用程序。
- Vite 配置文件(如
vite.config.js
)允许你定义构建过程中的各种选项,如别名、插件、外部库等。
-
插件系统:
- Vite 提供了一个强大的插件系统,允许开发者根据需要添加插件来扩展其功能。这些插件可以在构建过程中的各个阶段介入,例如在打包之前或之后执行任务。
-
构建优化:
- Vite 会自动处理代码分割、摇树优化(Tree-shaking)和模块懒加载,以生成优化的生产代码。
-
预构建:
- Vite 支持预构建功能,允许你在构建过程中预编译模块,以加快后续构建的速度。
-
多页面应用支持:
- Vite 支持多页面应用的构建,允许你为每个页面生成独立的入口和输出。
5.position 都有什么属性
-
static:
- 默认值。元素按照正常的文档流进行布局,即它出现在HTML中的位置。
-
relative:
- 元素脱离正常文档流,相对于它原本的位置进行定位。未占用的空间会保留。
-
absolute:
- 元素脱离正常文档流,相对于最近的已定位(非 static)祖先元素进行定位。如果不存在这样的祖先元素,则相对于初始包含块(通常是HTML文档的
<html>
元素)。
- 元素脱离正常文档流,相对于最近的已定位(非 static)祖先元素进行定位。如果不存在这样的祖先元素,则相对于初始包含块(通常是HTML文档的
-
fixed:
- 元素脱离正常文档流,相对于浏览器窗口进行定位。即使滚动页面,元素也会停留在相同的屏幕位置。
-
sticky:
- 元素基于用户的滚动位置进行定位。它类似于
relative
,但当页面滚动超出一定区域时,元素的表现会转变为fixed
。
- 元素基于用户的滚动位置进行定位。它类似于
除了这些定位方式,position
属性还可以配合其他 CSS 属性来确定元素的确切位置,这些属性包括:
-
top:
- 指定元素的上边缘与父元素上边缘的距离。
-
right:
- 指定元素的右边缘与父元素右边缘的距离。
-
bottom:
- 指定元素的下边缘与父元素下边缘的距离。
-
left:
- 指定元素的左边缘与父元素左边缘的距离。
6.flex相关属性
容器属性(应用于父元素)
-
display:
display: flex;
或display: inline-flex;
定义了一个 Flex 容器。
-
flex-direction:
- 定义了主轴的方向(是水平还是垂直)。
- 值:
row
(默认)、row-reverse
、column
、column-reverse
。
-
flex-wrap:
- 定义了是否应该包裹,即允许子元素换行。
- 值:
nowrap
(默认)、wrap
、wrap-reverse
。
-
flex-flow:
- 是
flex-direction
和flex-wrap
的简写形式。
- 是
-
justify-content:
- 定义了子元素在主轴上的对齐方式。
- 值:
flex-start
、flex-end
、center
、space-between
、space-around
、space-evenly
。
-
align-items:
- 定义了子元素在交叉轴上的对齐方式。
- 值:
flex-start
、flex-end
、center
、baseline
、stretch
(默认)。
-
align-content:
- 当有多行子元素时,定义了行在交叉轴上的对齐方式。
- 值:
flex-start
、flex-end
、center
、space-between
、space-around
、stretch
。
项目属性(应用于子元素)
-
order:
- 定义了子元素的排序顺序。
- 值:整数,数值越小越靠前。
-
flex-grow:
- 定义了子元素的放大比例,即在分配多余空间时的增长能力。
- 值:无单位的数字(默认为 0)。
-
flex-shrink:
- 定义了子元素的缩小比例,即在空间不足时的缩小能力。
- 值:无单位的数字(默认为 1)。
-
flex-basis:
- 定义了子元素在分配多余空间之前的默认大小。
- 值:长度值(如
20%
、10px
等),auto
或content
。
-
flex:
- 是
flex-grow
、flex-shrink
和flex-basis
的简写形式,默认值为0 1 auto
。 - 值:
flex: none
、flex: auto
、flex: 2
等。
- 是
-
align-self:
- 允许单个子元素覆盖默认的
align-items
属性。 - 值:
auto
、flex-start
、flex-end
、center
、baseline
、stretch
。
- 允许单个子元素覆盖默认的
7.first-paint 首次绘制时间
const Fun = (list)=>{for(let entry of list.getEntries()){if(entry.name === 'first-paint'){observe.disconnect()const json = entry.toJSON();console.log(json)const data = {...json,type: 'performance',subType: entry.name,startTime: entry.startTime,pageUrl:window.location.href}console.log("data:",data)}}
}
const observe = new PerformanceObserver(Fun);
observe.observe({type: 'paint', buffered: true})
8.first-contentful-paint首次内容绘制
const Fun = (list)=>{for(let entry of list.getEntries()){if(entry.name === 'first-contentful-paint'){observe.disconnect()const json = entry.toJSON();console.log(json)const data = {...json,type: 'performance',subType: entry.name,}console.log(data)}}
}
const observe = new PerformanceObserver(Fun);
observe.observe({type: 'paint', buffered: true})
9.largest-contentful-paint最大内容绘制
const Fun = (list)=>{if(observe){observe.disconnect();}for(let entry of list.getEntries()){const json = entry.toJSON();console.log(json)const data = {...json,type:'lcp'}// console.log(data)}
}
const observe = new PerformanceObserver(Fun);
observe.observe({type:'largest-contentful-paint',buffered:true})
10load
function observeLoad(){window.addEventListener('pageshow',function(event){['load'].forEach(type=>{const data = {type: type,timeStamp: event.timeStamp,isReload: event.persisted}})})
}
11.监听资源
const Fun = (list)=>{for(let entry of list.getEntries()){observe.disconnect()const json = entry.toJSON();console.log(json)const data = {...json}}
}
const observe = new PerformanceObserver(Fun);
observe.observe({type:'resource',buffered:true})
12.监听axios
const originalProto = XMLHttpRequest.prototype;
const originalOpen = originalProto.open;
const originalSend = originalProto.send;function overWriteOpenAndSend(){originalProto.open = function newOpen(...args){this.method = args[0];this.url = args[1];originalOpen.apply(this,args)}originalProto.send = function newSend(...args){const statTime = Date.now();const onLoaded = ()=>{this.endTime = Date.now();this.duration = endTime - statTime;const {url,method,status,statTime,endTime,duration} = thisthis.removeEventListener('load',onLoaded,true)}this.addEventListener('load',onLoaded,true)originalSend.apply(this,args);}
}
13.错误监听
try...catch 只能捕获同步
异步使用 window.onerror ,但对于css、image的错误不能监控
使用window.addEventListenner(‘error’{},true)去捕获(设置true,因为在捕获阶段去处理),但对于promise的err不能捕获(当然可以加.catch去捕获)
promise没加catch的使用window.addEventListenner(‘unhandledrejection’)去捕获promise的err
当然针对promise和 async await的错误,把它throw err出去,然后使用window.addEventListenner(‘error’{},true)去捕获更好
window.addEventListener('error',function(e){//判断是不是js错误 css错误 image错误const target = e.target;if(target.src || target.href){return}const url = target.href || target.src;const data = {url,pageUrl:window.location.href,msg:e.message,line:e.lineno,col:e.colno}//todo 上报信息
},true)// js错误
window.onerror = function(msg,url,line,col,error){const data = {url,pageUrl:window.location.href,msg:error && error.stack || msg,line,col}//todo 上报信息
}//promise错误 async await 错误
window.addEventListener('unhandledrejection',function(e){const data = {url:window.location.href,msg:e.reason && e.reason.stack || e.reason || 'unhandledrejection',}//todo 上报信息
})
14.监听fetch
const originalFetch = window.fetch;
function overWriteFetch(){window.fetch = function newFetch(url,config){const startTime = performance.now();const data = {url,method:config.method,startTime}return originalFetch(url,config).then((res)=>{const endTime = performance.now();data.endTime = endTime;data.duration = endTime - startTime;const newRes = res.clone();data.status = res.status;data.success = res.ok;console.log(data);return res;}).catch((err)=>{const endTime = performance.now();data.endTime = endTime;data.duration = endTime - startTime;ata.status = 0;data.success = false;console.log(err);})}
}
相关文章:

前端杂学录(十)
1.axios 的底层实现 1. XMLHttpRequests 在浏览器环境中,Axios 使用 XMLHttpRequest 对象来发送请求。这是一个古老的 Web API,用于在浏览器中进行异步 HTTP 请求。 2. Node.js 的 http 模块 在 Node.js 环境中,Axios 使用 Node.js 的 ht…...

C++上机|编写函数invert实现对一维数组的倒序
//编写函数invert实现对一维数组的倒序 # include <iostream> using namespace std;class invert_array {private://int a[10]{0,1,2,3,4,5,6,7,8,9};public: void invert(int A[], int n){int i,j,temp;int m (n-1)/2;for(i0;i<m;i){jn-1-i;tempA[i];A[i]A[j];A[j]t…...

使用LSPatch+PlusNE修改手机软件
一、问题概述 国内使用一些软件,即使科学上网,打开都是网络错误,更换节点同样如此。 二、软件下载 通过官网或者正规商店(如Google play)下载并且安装。 是的,先要下载一个无法使用的版本,后续对其进行修改。 三、下…...

基于springboot的4S店车辆管理系统
作者:计算机学长阿伟 开发技术:SpringBoot、SSM、Vue、MySQL、ElementUI等,“文末源码”。 系统展示 【2024最新】基于JavaSpringBootVueMySQL的,前后端分离。 开发语言:Java数据库:MySQL技术:…...

C++从入门到起飞之——(multi)set与(multi)map的的使用 全方位剖析!
🌈个人主页:秋风起,再归来~🔥系列专栏:C从入门到起飞 🔖克心守己,律己则安 目录 1. 序列式容器和关联式容器 2. set系列的使⽤ 2.1 set和multiset参考⽂档 2.2 set类的介绍 2.3 se…...

HTML5实现古典音乐网站源码模板2
文章目录 1.设计来源1.1 主界面1.2 古典音乐界面1.3 著名人物界面1.4 古典乐器界面1.5 历史起源界面1.6 联系我们界面 2.效果和源码2.1 动态效果2.2 源代码 源码下载万套模板,程序开发,在线开发,在线沟通 作者:xcLeigh 文章地址&a…...

基于SpringBoot+Vue+uniapp的诗词学习系统的详细设计和实现
详细视频演示 请联系我获取更详细的演示视频 项目运行截图 技术框架 后端采用SpringBoot框架 Spring Boot 是一个用于快速开发基于 Spring 框架的应用程序的开源框架。它采用约定大于配置的理念,提供了一套默认的配置,让开发者可以更专注于业务逻辑而不…...

基于SpringBoot网上超市的设计与实现(论文+源码)_kaic
摘 要 网络技术和计算机技术发展至今,已经拥有了深厚的理论基础,并在现实中进行了充分运用,尤其是基于计算机运行的软件更是受到各界的关注。加上现在人们已经步入信息时代,所以对于信息的宣传和管理就很关键。因此超市商品销售信…...

《webpack深入浅出系列》
webpack深入浅出系列 ES6模块与CommonJS模块的主要区别 加载时机:ES6模块是编译时输出,即模块在编译阶段就已经确定了依赖关系;而CommonJS模块是运行时才加载,即运行到某个require语句时才加载对应的模块。 (也就是说…...

云服务器使用挂载的数据盘空间(自用)
最近在使用浪潮云服务器的时候遇到系统盘存储空间全部使用完了,而浪潮提供的服务器配置里面还有数据盘空间,但是在使用df -h无法查看到数据盘的相关信息,查找后才发现是因为新开服务器没有对数据盘进行挂载,因此无法使用。在网上找…...

snmp usm OID
在Java中,SNMP(简单网络管理协议)是一种用于网络管理的互联网标准协议。它允许网络管理员从中央位置监控网络设备,如服务器、工作站、路由器、交换机和打印机等。SNMP通过允许这些设备报告关于它们状态的信息,从而帮助…...

数据仓库分层设计概念
数据仓库分层设计是一种结构化方法,用于组织和管理数据仓库中的数据。这种设计方法通过将数据从原始数据逐步转换为满足业务分析需求的结构化数据,提高了数据处理效率、数据质量和一致性。数据仓库分层设计的主要目的包括支持数据的重用、优化性能、提高…...

【HTML】defer 和 async 属性在 script 标签中分别有什么作用?
需要这两个属性的原因? 首先我们要知道的是,浏览器在解析 HTML 的过程中,遇到了 script 元素是不能继续构建 DOM 树的。 它会停止解析构建,首先去下载 js 代码,并且执行 js 的脚本;只有在等到 js 脚本执行…...

扫视扫描路径预测的评估:主观评估数 据库和基于循环神经网络的度量 记录
记录一 随着势头的不断增强,扫视预测逐渐成 为培养视觉注意力的热门研究课题。在扫视预测中,每个模型通常生成一个覆盖一系列注视点的扫描路径,以模拟动态扫视行为。因此, 通常通过计算预测的扫描路径与所有人类扫描 路径之间的相…...

【Java数据结构】优先级队列(堆)
【本节目标】 1. 掌握堆的概念及实现 2. 掌握 PriorityQueue 的使用 一. 优先级队列 1 概念 前面学过队列,队列是一种先进先出 (FIFO) 的数据结构 ,但有些情况下, 操作的数据可能带有优先级,一般出队 列时,可…...

图书个性化推荐系统|基于springBoot的图书个性化推荐系统设计与实现(附项目源码+论文+数据库)
私信或留言即免费送开题报告和任务书(可指定任意题目) 目录 一、摘要 二、相关技术 三、系统设计 四、数据库设计 五、核心代码 六、论文参考 七、源码获取 一、摘要 本论文主要论述了如何使用JAVA语言开发一个图书个性化推荐系统&…...

通用车牌正则校验
要编写一个正则表达式来包含所有类型的车牌号,我们需要考虑以下几种常见的车牌类型: 1. 普通汽车车牌(蓝牌/黄牌) 规则:1个汉字 1个字母 5个字母或数字示例:京A12345、粤B5678X 2. 新能源车牌…...

使用 SSH 连接 GitLab 的常见问题及解决方案
使用 SSH 连接 GitLab 的常见问题及解决方案 在使用 SSH 连接到 GitLab 服务器时,可能会遇到类似于以下的错误信息: git192.168.xx.xxx: Permission denied (publickey).这个错误通常表示 SSH 无法验证你的公钥,导致无法访问 GitLab 仓库。…...

泛微E9开发 校验日期型字段是否符合要求
校验日期型字段是否符合要求 1、需求分析及展示效果1.1、需求确认1.2、展示效果 2、实现方法3、扩展知识——js日期相关函数 1、需求分析及展示效果 1.1、需求确认 “填报时间”是一个日期型字段,用户提出需求只能选择每个月的第二个周二,选择其他日期…...

ubuntu安装Vim和net-tools和htop
合并安装,快捷方便 sudo apt update sudo apt install net-tools vim htop在Ubuntu中安装Vim可以通过终端使用以下命令完成: sudo apt update sudo apt install vim这两条命令首先更新了本地的包索引,然后安装了Vim文本编辑器。 安装完成后…...

每天10个js面试题(六)
1、js数组方法? Array.push()此方法是在数组的后面添加新加元素,此方法改变了数组的长度Array.pop()此方法在数组后面删除最后一个元素,并返回数组,此方法改变了数组的长度 Array.shift()此方法在数组后面删除第一个元素…...

AIGC技术的学习 系列二
文章目录 前言一、AIGC是什么?1.1. 基本概念1.2机器学习分类二、 语言模型2.1. 基于统计的语言模型。2.2. 基于神经网络的语言模型。2.3. 基于预训练机制的的语言模型/大语言模型三、读入数据3.1. 不得不说的Transformer3.2. 影响力3.3. 根据人类反馈的强化学习3.4. 生成式AI3…...

惊艳!AI模型DIAMOND可模拟《反恐精英》,单张RTX 3090就能运行
最近,研究人员开发了一种名为 DIAMOND(Diffusion for World Modelling)的 AI 模型,它能够在神经网络中模拟著名的电脑游戏《反恐精英:全球攻势》(CS:GO)。 这个模型在一张 Nvidia RTX3090显卡上运行,能够达到每秒10帧…...

中波长线天线耦合的一个方法
围绕窗外墙外牵了10米的室外天线。 短波,fm都是很简单,一个夹子直接夹在拉杆天线上面,效果已经很好。 今天偶尔听到中波前面大约510khz的地方有个摩尔斯码。是成都附近机场的NDB。这个平时要在楼顶或者很空旷的地方才能收到。音量比较小&am…...

Java基础(6)
深拷贝和浅拷贝区别了解吗?什么是引用拷贝?关于深拷贝和浅拷贝区别,我这里先给结论:浅拷贝:浅拷贝会在堆上创建一个新的对象(区别于引用拷贝的一点),不过,如果原对象内部…...

[JAVAEE] 线程安全问题
目录 一. 什么是线程安全 二. 线程安全问题产生的原因 三. 线程安全问题的解决 3.1 解决修改操作不是原子性的问题 > 加锁 a. 什么是锁 b. 没有加锁时 c. 加锁时 d. 死锁 e. 避免死锁 3.2 解决内存可见性的问题 > volatile关键字 (易变的, 善变的) a. 不加…...

k8s 集群给用户生成 kubeconfig 文件
在 k8s 集群的 RBAC 里有用到用户、组的概念,但是它又不直接管理这些资源,而是通过外部身份验证机制(Authentication Mechanisms)来管理和定义的,比如证书进行签名时,将其配置为 Subject: O system:master…...

(八)Proteus仿真STM32单片机GPIO驱动数码管
1,参考上篇,将LED点阵屏更换成数码管如下图 2,修改驱动函数,数组seg[14]前10个是0-9数字的编码,后四个是空格,点,横线,下划线 char seg_decode(char num)//数字解码 {const char se…...

Python进阶知识1
Python函数 定义一个函数 1.什么是函数:函数是可以重复执行的语句块,可以重复调用 2.作用:用于封装语句块, 提高代码的重用性。 函数是面向过程编程的最小单位 def 语句 1.作用:用来定义( 创建)函数 2…...

单片机设计|基于STM32实现具有室内定位功能的智能手环的设计
作者简介:Java领域优质创作者、CSDN博客专家 、CSDN内容合伙人、掘金特邀作者、阿里云博客专家、51CTO特邀作者、多年架构师设计经验、多年校企合作经验,被多个学校常年聘为校外企业导师,指导学生毕业设计并参与学生毕业答辩指导,…...