Linux常见的21条面试命令
文章目录 简单文件查看+权限文件搜索find() 文件内容(查看查找处理)catgrepsedpastesortcomm 系统进程内存输入输出 常见的shell 命令循环,判断,变量函数awkgrepsedsortuniqwctr 常见题目词频统计转置文件查看文件第10行找关键字的上下10行删除大于50m的文件Linux如果内存占用过高怎么 简单文件 查看+权限 cp, cd, pwd, ls, mv, rmchmod +-等 777 u=rw go=r, o, :所有者权限,组权限,其他用户权限chownchgrp 文件搜索find() find / -name file:从根目录下搜索find / -user filefind /usr/bin : 搜索具体目录下的find / -sizewhereis pip 显示二进制文件、源码或者man的位置which pip显示二进制文件或者可执行文件的完整路径 文件内容(查看查找处理) cat cat filetac filecat -n file:显示文件行数more filehead -n +1000 filetail -n +1000 file:从1000行开始显示,显示1000行以后的cat filename | head -n 3000 | tail -n +1000:显示1000行道3000行cat file | tail -n +3000 | head -n 1000 从3000行开始显示,显示1000行 tail表示偏移量
前言 总结一些常见的算法题目,每一个题目写一行思路,方便大家复习。具体题目的来源是下面的网站。
剑指offer
剑指offe2
leetcode200题
leetcode 100题
leetcode150题
leetcode 75题
文章目录 前言二叉树非递归遍历牛客JZ31 栈的压入、弹出序列 (8/4)JZ4 二维数组中的查找JZ11 旋转数组中的最小数字JZ44数字序列中某一位的数字JZ42 连续子数组的最大和 leetcode 100题思路整理前10题10-19题20-29题30-39题40-50 题 leetcode 150题数组/字符串双指针/滑动窗口矩阵30-40题 牛客动态规划回溯0-1背包 二叉树非递归遍历 前序遍历方法一
直接右边放入栈,然后左边放入栈。 public List<Integer> preorderTraversal(TreeNode root) { List<Integer>ans = new ArrayList<>(); if (root == null) return ans; Stack<TreeNode>st = new Stack<>(); st.add(root); while (!st.empty()) { TreeNode node = st.pop(); ans.add(node.val); if (node.right != null) st.add(node.right); if (node.left != null) st.add(node.left); } return ans; } // 方法二 public List<Integer> preorderTraversal(TreeNode root) { List<Integer>ans = new ArrayList<>(); Stack<TreeNode>st = new Stack<>(); TreeNode node = root; while (node !
目录 1.正态分布是什么2.正态分布有什么用途3.如何确定数据服从正态分布 本文简单介绍正态分布的基本概念和用途。
1.正态分布是什么 正态分布,也称为高斯分布,是由德国数学家卡尔·弗里德里希·高斯在研究测量误差时提出的。他发现许多自然现象和统计数据,如人的身高、考试成绩等,其分布形状都呈现出一种特定的钟形曲线,这就是正态分布。
正态分布的数学表达式是:
f(x) = 1 / (σ√2π) * e^(-(x-μ)^2 / 2σ^2) 其中,μ是均值,σ是标准差,e是自然对数的底数(约等于2.71828),π是圆周率(约等于3.14159)。
这个公式描述了正态分布的概率密度函数,即对于给定的x值,其对应的概率密度是多少。这个函数的图形是一个关于均值对称的钟形曲线,曲线在均值处达到峰值,然后两边逐渐下降,接近水平轴。
正态分布的得出是基于大量的观察和实验数据,以及数学推导。它是统计学和自然科学中的一个重要工具,被广泛应用于数据分析、质量控制、风险管理等领域。
在统计学的许多方面有着重大的影响,特别是在参数估计和假设检验上。
正态分布的特点:
形状:正态分布的图形是关于平均值对称的钟形曲线。曲线在平均值处达到峰值,然后两边逐渐下降,接近水平轴。均值、中位数和众数:在正态分布中,均值、中位数和众数是相等的,都等于分布的峰值。标准差:标准差决定了分布的宽度。标准差越大,分布越宽;标准差越小,分布越窄。曲线下的面积:正态分布曲线下的面积(即概率)总和为1。68-95-99.7规则:在正态分布中,约68%的数据值位于均值的一个标准差范围内,约95%的数据值位于均值的两个标准差范围内,约99.7%的数据值位于均值的三个标准差范围内。 2.正态分布有什么用途 正态分布在统计学和自然科学中有广泛的应用,以下是一些主要的用途:
数据分析:正态分布是许多统计分析方法的基础,例如假设检验、置信区间、线性回归等。如果数据服从正态分布,那么我们可以使用这些方法进行分析。质量控制:在工业生产中,正态分布常用于质量控制。例如,产品的尺寸、重量等通常会围绕一个目标值上下波动,这种波动通常可以用正态分布来描述。风险管理:在金融和保险领域,正态分布常用于风险管理。例如,投资组合的收益率、保险索赔的金额等通常假设为正态分布,以便进行风险评估和决策。自然科学:在自然科学中,许多现象的观测值都服从正态分布,例如人的身高、血压等。因此,正态分布常用于这些领域的研究。中心极限定理:中心极限定理是统计学中的一个重要定理,它表明,如果我们从任何形状的分布中抽取足够大的样本,那么样本均值的分布将接近正态分布。这使得正态分布在大样本统计推断中有广泛的应用。 3.如何确定数据服从正态分布 确定数据是否服从正态分布,通常可以通过以下几种方法:
直方图:将数据绘制成直方图,观察其形状是否接近正态分布的钟形曲线。这是一种直观的方法,但可能受到数据量和分组方式的影响。QQ图:QQ图是一种图形化的方法,可以用来检验数据是否服从某种分布。如果数据点在QQ图上接近一条直线,那么可以认为数据服从正态分布。偏度和峰度:偏度是衡量数据分布偏斜程度的统计量,峰度是衡量数据分布峰态的统计量。如果数据服从正态分布,那么其偏度应接近0,峰度应接近3。统计检验:有一些统计检验可以用来检验数据是否服从正态分布,例如Shapiro-Wilk检验、Kolmogorov-Smirnov检验、Anderson-Darling检验等。这些检验会给出一个p值,如果p值大于某个显著性水平(例如0.05),那么我们不能拒绝数据服从正态分布的假设。 以上方法都有各自的优点和局限性,通常需要结合使用。并且,即使数据不完全服从正态分布,也可能可以通过一些变换(例如对数变换、平方根变换等)使其接近正态分布。
基础50题
聚合函数 项目员工,连接 + avg + group by各项函数用户的注册率:直接单表操作,count函数的使用,结合round进行保留小数。1211. 查询结果的质量和占比:简单的avg, sum(if(,,))的使用1193. 每月交易 I:年月日期函数的应用。data_format(date, '%Y-%m')获取类似01 02的这种月份。550. 游戏玩法分析 IV:连接后where过滤,on其实也可以起到过滤的作用。不过最好用where进行过滤。1174. 即时食物配送 II:每一行加上一个最小值列,然后让配送时间等于最小值列的时间,选出这个的数量 / 不同用户的数量。 排序和分组 1045. 买下所有产品的客户:简单分组, having子句过滤
619. 只出现一次的最大数字:子查询 + 分组 + 过滤
1729. 求关注者的数量:排序
596. 超过5名学生的课:
1084. 销售分析III:distinct的使用,可以从数量上进行统计。在这个区间的数量等于总的数量。
having count(sale_date between '' and '' or null):注意如果为空的情况 1141. 查询近30天活跃用户数:datadiff和<=处理时间
2356. 每位教师所教授的科目种类的数量:分类计数,分类计数,分类计数。使用group by。
子查询 换座位:和最小的进行比较,然后使用case when进行选择部门排名前3的薪水 高级连接查询 1907. 按分类统计薪水:列转行1204. 最后一个能进入巴士的人:如果存在超重的人,第一个超重的人(超重的人中turn最小的那一个)它的前一个就是,如果没有,最大的turn对应的人。ifnull放的位置。1164. 指定日期的产品价格:找到小于规定日期的最大日期,然后进行连接,过滤可以得到有修改的。最后通过product_id临时表连接这个表,使用ifnull(price, 10)得到答案。180. 连续出现的数字:连接或者子查询都可以判断三角形:ABS(x - y),保证任意两边之和大于第三边,任意两边只差小于第三边1731. 每位经理的下属员工数量:count(id):如果id是null的情况下,会统计成0.1789. 员工的直属部门:union使用的范例。 子查询 585. 2016年的投资:不用连接可以直接子查询。1321. 餐馆营业额变化增长:distinct的使用 小结 行列转换:
目录 1.数据库归档是什么2.MySQL 归档工具有哪些 本文主要介绍数据库归档基本概念和目的,以及对于MySQL来说,有哪些归档工具。
1.数据库归档是什么 数据库归档是一种数据管理策略,它涉及将旧的、不经常访问的数据移动到一个单独的存储设备,以便在需要时可以检索,同时保持数据库的性能和效率。
数据库归档的主要目的是:
提高性能:通过减少数据库中的数据量,可以提高查询速度和数据库性能。节省存储空间:归档的数据通常存储在成本较低的存储设备上,这可以节省高性能存储设备的空间。符合法规要求:许多行业和地区的法规要求公司在一定期限内保留某些数据。通过归档,公司可以满足这些要求,同时不影响数据库的性能。数据保护:归档的数据通常会进行备份和保护,以防数据丢失。数据分析和报告:归档数据可以用于长期的数据分析和报告,特别是对于历史趋势分析等需要大量历史数据的场景。 总的来说,数据库归档是一种有效的数据管理策略,可以帮助组织提高数据库性能,节省存储空间,满足合规要求,保护数据,并支持数据分析。
数据库归档可以手动进行,也可以使用自动化工具进行。在进行数据库归档时,需要考虑数据的重要性、访问频率、法规要求等因素,以确定何时和如何进行归档。
2.MySQL 归档工具有哪些 对于MySQL数据库,以下是一些常用的归档工具:
MySQL Enterprise Backup:这是MySQL官方提供的一个备份和恢复工具,它支持在线备份,可以在不中断服务的情况下进行备份和恢复。Percona XtraBackup:这是一个开源的MySQL备份工具,它支持在线备份,可以在不中断服务的情况下进行备份和恢复。MyDumper/MyLoader:MyDumper是一个高性能的MySQL数据导出工具,MyLoader是对应的数据导入工具。它们可以用于数据迁移和归档。mysqldump:这是MySQL自带的一个数据导出工具,它可以将数据导出为SQL文件,然后通过MySQL命令行工具或其他MySQL客户端导入。pt-archiver:这是Percona Toolkit的一个工具,用于高效地归档和移动MySQL表中的数据。 以上工具都可以用于MySQL数据的归档,但具体使用哪个工具,需要根据你的具体需求和环境来决定。
time limit per test
1 second
memory limit per test
256 megabytes
input
standard input
output
standard output
You are given three digits a�, b�, c�. Two of them are equal, but the third one is different from the other two.
Find the value that occurs exactly once.
Input
The first line contains a single integer t� (1≤t≤2701≤�≤270) — the number of test cases.
The only line of each test case contains three digits a�, b�, c� (0≤a0≤�, b�, c≤9�≤9).
一、算法复杂度及代码运行步骤
确定决定算法运行时间的组成步骤。找到执行该步骤的代码,标记为 1。查看标记为 1 的代码的下一行代码。如果下一行代码是一个循环,则将标记 1 修改为 1 倍于循环的次数 1 * n。如果包含多个嵌套的循环,则将继续计算倍数,例如 1 * n * m。找到标记到的最大的值,就是运行时间的最大值,即算法复杂度描述的上界。 二、代码示例
1. 代码(1)
decimal Factorial(int n) { if (n == 0) return 1; else return n * Factorial(n - 1); } 阶乘(factorial),给定规模 n,算法基本步骤执行的数量为 n,所以算法复杂度为 O(n)。
2. 代码(2)
int FindMaxElement(int[] array) { int max = array[0]; for (int i = 0; i < array.Length; i++) { if (array[i] > max) { max = array[i]; } } return max; } 这里,n 为数组 array 的大小,则最坏情况下需要比较 n 次以得到最大值,所以算法复杂度为 O(n)。
当前示例源码github地址:
https://github.com/vilyLei/voxwebgpu/blob/feature/material/src/voxgpu/sample/VertexUpdateTest.ts
当前示例运行效果:
此示例基于此渲染系统实现,当前示例TypeScript源码如下:
export class VertexUpdateTest { private mRscene = new RendererScene(); initialize(): void { this.mRscene.initialize({ canvasWith: 512, canvasHeight: 512, rpassparam: { multisampled: true } }); this.initScene(); this.initEvent(); } private mPlane: PlaneEntity; private initScene(): void { let rc = this.mRscene; let plane = new PlaneEntity({ axisType: 1, geometryDynamic: true, extent: [-600, -600, 1200, 1200] }); this.mPlane = plane; rc.addEntity(plane); } private initEvent(): void { const rc = this.
wsl Ubuntu默认只能打开命令行,看不到图形化界面,有些操作不方便。这里介绍两种方法来远程连接到wsl里
VNC 因为win10的wsl不支持systemd, 所以这种方式只能是Windows11的系统,Window10只能用xrdp
1、禁用WSLg 在c:\users\用户名下新建一个.wslconfig文件,内容如下:
[wsl2] guiApplications=false 2、安装桌面程序 可以先安装桌面程序的一个管理程序: sudo apt install tasksel -y
然后运行sudo tasksel,选择需要的桌面程序安装(空格是选中,上下键切换,tab切到OK键),我这里选择Ubuntu desktop。 3、安装vnc服务端 sudo apt install tigervnc-standalone-server -y
4、设置vnc密码 vncpasswd 为当前用户设置
sudo -H vncpasswd 为root设置
sudo -H -u gdm vncpasswd 为gdm用户设置
建议都设置一遍
5、修改Xorg文件 如果某次执行apt upgrade后,连接不上vnc了,应该就是这个文件被恢复成了默认,你再改回来就可以了。
chatgpt关于这个文件的解释:
sudo mv /usr/bin/Xorg /usr/bin/Xorg_old sudo vim /usr/bin/Xorg_new写入以下内容:
#!/bin/bash for arg do shift case $arg in # Xvnc doesn't support vtxx argument. So we convert to ttyxx instead vt*) set -- "
目录 前言0. 简述1. CUDA-BEVFusion浅析2. CUDA-BEVFusion环境配置2.1 简述2.2 源码下载2.3 模型数据下载2.4 基础软件安装2.5 protobuf安装2.5.1 apt 方式安装2.5.2 源码方式安装 2.6 编译运行2.6.1 配置 environment.sh2.6.2 利用TensorRT构建模型2.6.3 编译运行程序 2.7 拓展-Python接口2.8 拓展-Debug调试配置 3. 推理结果浅析总结下载链接参考 前言 自动驾驶之心推出的 《CUDA与TensorRT部署实战课程》,链接。记录下个人学习笔记,仅供自己参考
本次课程我们来学习下课程第八章——实战:CUDA-BEVFusion部署分析,一起去分析 CUDA-BEVFusion 的优化策略与环境搭建和测试
Note:CUDA-BEVFusion 是多模态 BEV 感知算法 BEVFusion 的部署框架,需要大家对 BEV 感知算法和 BEVFusion 有一定的了解,这样可能对课程内容的理解更加深刻,如果大家想了解 BEV 感知算法的可以看看 一. BEV感知算法介绍,想了解 BEVFusion 多模态感知算法的可以看看 三. LiDAR和Camera融合的BEV感知算法-BEVFusion
课程大纲可以看下面的思维导图
0. 简述 从这节开始我们进行第八章 CUDA-BEVFusion 部署分析,这一章节也是这个课程的最后一个章节,那关于 BEVFusion 的部署相信大家从开始就一直期待,为什么呢,是因为 BEVFusion 其实涉及到的东西非常多,不仅仅是一个 classifier 或者 detection 那么简单,它里面涉及到的内容其实就是我们前面第一章到第七章的一个大汇总。我们前面讲过的东西在这里或多或少都会有所涉及,所以作为一个比较大也是比较难的项目,我们一起去学习一下它,看看它的开源代码是怎么做的
那这个章节会讲得比较细,主要分为以下九个部分:
1. 分析 CUDA-BEVFusion 的优化策略与环境搭建和测试2. 学习 spconv 的原理3.
1. Nginx服务器
原因是请求实体太长了。一般出现种情况是Post请求时Body内容Post的数据太大了
如上传大文件过大; 如POST数据比较多
处理方法修改nginx.conf的值就可以解决了。
client_max_body_size 2M 改为 client_max_body_size 10M
2. Apache服务器
修改下Apache配置文件中的LimitRequestBody配置,如果是虚拟主机,请联系空间商帮助修改。
具体步骤:
在apache环境中上传较大软件的时候,有时候会出现413错误,出现这个错误的原因,是因为apache的配置不当造成的,
找到apache的配置文件目录也就是conf目录,和这个目录平行的一个目录叫conf.d打开这个conf.d,里面有一个php.conf
目录内容如下:
# PHP is an HTML-embedded scripting language which attempts to make it
# easy for developers to write dynamically generated webpages.
LoadModule php4_module modules/libphp4.so
# Cause the PHP interpreter handle files with a .php extension.
SetOutputFilter PHP
SetInputFilter PHP
LimitRequestBody 6550000
# Add index.php to the list of files that will be served as directory
详解Med-PaLM 2,基于PaLM 2的专家级医疗问答大语言模型 - 知乎
目录
摘要:
1 介绍
2 相关工作
3 方法
3.1 数据集
3.2 建模
3.3 多项选择评估
3.4 重叠分析 (Overlap analysis )
3.5 长形式评估(Long-form evaluation )
4 结果
4.1 多项选择评估
4.2 长形式评估
5 讨论&结论等:
我的一些思考:
5月16日,Google Research和DeepMind发布了Med-PaLM 2,迈向专家级医疗问答的大语言模型(Towards Expert-Level Medical Question Answering with Large Language Models)。
论文地址:[2305.09617] Towards Expert-Level Medical Question Answering with Large Language Models (arxiv.org)
以下是我根据论文等整理的内容,相对于论文有所调整。
摘要: 最近的人工智能(AI)系统在围棋到蛋白质折叠等“大难题”中达到里程碑。与医生相当地检索医学知识、推理和回答医疗问题的能力长期被视为这样的一个大难题。
大型语言模型(LLM)催生了医疗问答的重大进步;Med PaLM是第一个超过美国医师执照考试(USMLE)样例问题“合格”分数的模型,在MedQA数据集上得分67.2%。不过,这项工作和其他类似的工作表明,和临床医生的答案相比,模型的答案仍有很大的提高空间。
这里我们提出Med-PaLM 2,它利用一系列LLM改进(PaLM 2)、医学领域微调和提示策略(包括一种新的集成精炼方法ensemble refifinement approach)来弥补这些差距。
非书中全部内容,只是写了些自认为有收获的部分
神经网络 生物神经元的特点 (1)人体各种神经元本身的构成很相似
(2)早期的大脑损伤,其功能可能是以其他部位的神经元来代替实现的
(3)神经元具有稀疏激活性,尽管大脑具有高达五百万亿个神经元,但真正同时被激活的仅有1%~4%
神经元模型 (1)ReLu是一种特殊的Maxout函数
(2)理论上可以多种激活函数混用,但在实践中较少这样应用
感知机困境 (1)对于非线性问题,感知机只有通过人工提取特定的特征——在这些特征中将非线性的因素包含进来——使得特征仅用线性关系就可判别,才能达到目标。但这意味着非线性的引入需要靠人工完成,感知机完全帮不上忙
目标函数的选取 交叉熵的损失函数的偏导数结果简介、漂亮
初始化模型 2006年Hinton发表的Science论文提出了一种深度模型的可行训练方法,其基本思想是利用生成模型受限玻尔兹曼机一层一层地进行初始化训练,然后再利用真实数据进行参数微调
受限玻尔兹曼机(RBM) (1)受限玻尔兹曼机由可视层和隐层构成
(2)RBM属于生成模型,用于建模观察数据和输出标签之间的联合概率分布
能量模型(EBM) (1)系统越杂乱无序或概率分布越趋近于均匀分布,系统对应的能量越大
(2)当E(x) = -wx,EBM就是Softmax
带隐藏单元的能量模型 (1)在很多情况下,并不能直接观测到所有的x值,这时候往往需要引入隐藏变量
(2)
受限玻尔兹曼机基本原理 (1)玻尔兹曼机是一种特殊的对数线性马尔可夫随机场,因为其能量函数是参数的线性形式.。其隐藏单元既要依赖于观察单元,也要依赖于其他隐藏单元;观察单元可能既依赖于隐藏单元,也依赖于同层的其他观察单元
(2)受限玻尔兹曼机:同层之间不存在相互依赖关系,只有观察层和隐藏层之间存在关系
(3)能量函数:
(4)从概率图的角度来看,给定所有观察变量的值时隐藏变量之间相互独立;对称的,给定所有隐藏变量的值时观察变量之间相互独立
二值RBM (1)规定所有的观察变量v和隐藏变量h的取值范围都为(0,1)
对比散度 (1)由于隐层未知且v,h的组合空间很大,联合概率分布p(v,h)是很难计算的,因而<vh>model往往采用采样的方法
(2)一般MCMC方法需要较多的采样步数,而针对RBM训练的对比散度(CD)算法只需要较少的步数
Q:why?
A:RBM通过最大化输入数据的对数似然来进行训练,这需要计算数据的概率分布,而在高维空间中直接计算这个概率分布是非常困难的。
传统的MCMC方法在高维空间中采样时会遇到困难,因为随着维度的增加,采样点的数量呈指数增长,这使得采样过程变得非常低效。
而对比散度算法是一种高效的替代方法,它不需要进行大量的采样步骤,原因如下:
(1)高效的能量梯度估计:CD算法通过在RBM中引入一个相对简单的对比能量函数来估计能量梯度的期望值。这个能量函数是基于模型在训练数据上的表现,而不是基于模型在未标记数据上的整体概率分布。因此,CD算法可以直接利用训练数据进行高效的能量梯度估计,而不需要进行耗时的MCMC采样。
(2)快速的迭代更新:由于CD算法避免了复杂的MCMC采样过程,它可以在每个训练迭代中快速地计算和更新模型参数。这使得训练过程更加高效,减少了所需的迭代步数。
(3)适应性采样:CD算法中包含了一种适应性采样技术,这种技术可以在训练过程中动态地调整采样步骤,以适应模型的学习速度。这种适应性采样确保了在训练的不同阶段都能够进行有效的采样,而不需要固定的较大采样步数。
(3)k步对比散度以训练样本为起点,执行k步吉布斯采样
自动编码器 (1)自动编码器一般由编码器网络和解码器网络组成
降噪自动编码器 (1)编码器的输入是包含噪声的,而用作解码目标的输入是去除了噪声的
(2)人为添加噪声的方法包括:添加高斯噪声、添加二维码噪声,类似于Dropout,将部分输入神经元直接置为0
栈式自动编码器 (1)叠加的自动编码器,使得第n个隐层最大程度保留第n-1个隐层的信息
(2)最后一个隐层会得到足够有效的特征
(3)可以用梯度下降之类的优化算法微调参数
深度信念网络 (1)又被称为贝叶斯网络,是一种有向无环图
(2)可以在任意叶子节点生成无偏的样本集合
(3)通过不断积累RBM形成。每当一个RBM被训练完成时,其隐藏单元又可以作为后一层RBM的输入
(4)DBN的基本思想是允许每一次RBM模型接收数据的不同表示
卷积神经网络 卷积算子 (1)在统计学中,加权的滑动平均是一种卷积
(2)在声学中,回声可以用原声与一个反映各种反射效应的函数相卷积来表示
(3)在电子工程与信号处理中,任意一个线性系统的输出都可以通过将输入信号与系统函数做卷积获得
(4)在物理学中,任何一个线性系统都存在卷积
(5)卷积核在自变量为负的区间取值为0,否则将会使用未来的读数对当前值进行加权,这种情况是超越了现实系统能力的
Q:这里找了很久都没找到为什么会时间穿越
卷积的特征 稀疏连接、参数共享、等价表达
(1)越高层的卷积层“可视野”对应到原始输入图像上的区域越大,也为提取到更高层的语义信息提供了可能
Vue 2.x 和 Vue 3.x 在数组方面有一些不同之处,主要涉及到 Vue 3.x 中对响应式系统的改进。以下是 Vue 2.x 和 Vue 3.x 中数组的一些区别:
Vue 2.x 1.不同步响应式: Vue 2.x 中的数组不会在原地同步响应式。即,通过索引直接修改数组的元素,Vue 2.x 无法检测到这种变化。
// Vue 2.x 中的数组 data: { list: [1, 2, 3] } // 下面的修改无法被 Vue 2.x 检测到 this.list[0] = 10; 2.特殊方法: Vue 2.x 为了确保数组操作的响应性,提供了一些特殊的数组方法(例如 push、pop、shift、unshift 等)。当使用这些方法时,Vue 2.x 能够检测到数组的变化
// Vue 2.x 中的数组操作 this.list.push(4); Vue 3.x 1.Proxy 反应性系统: Vue 3.x 使用了 Proxy 反应性系统,可以更准确地追踪对象和数组的变化。在 Vue 3.x 中,对数组的操作更为灵活,可以直接通过索引修改数组元素,也可以使用一些原生数组方法
// Vue 3.
配置: 日志库文件github:
GitHub - gabime/spdlog: Fast C++ logging library.
新建vendor文件夹
将下载好的spdlog放入
配置YOTOEngine的附加包含目录:
配置Sandbox的附加包含目录:
包装spdlog: 在YOTO文件夹下创建Log.cpp和log.h
log.h:
#pragma once #include"Core.h" #include<spdlog/spdlog.h> #include "spdlog/sinks/stdout_color_sinks.h" namespace YOTO { class YOTO_API Log { public: static void Init(); //inline是为了提高性能,相当于直接把函数里的代码段放在那里 //返回的是Logger,分为服务器logger和核心logger inline static std::shared_ptr<spdlog::logger> GetCoreLogger() { return s_CoreLogger; } inline static std::shared_ptr<spdlog::logger> GetClientLogger() { return s_ClientLogger; } private: static std::shared_ptr<spdlog::logger> s_CoreLogger; static std::shared_ptr<spdlog::logger> s_ClientLogger; }; } //Core 的log 的简化 #define YT_CORE_ERROR(...) ::YOTO::Log::GetCoreLogger()->error(__VA_ARGS__) #define YT_CORE_WARN(...) ::YOTO::Log::GetCoreLogger()->warn(__VA_ARGS__) #define YT_CORE_INFO(.
139. Word Break
import copy class Solution: def wordBreak(self, s: str, wordDict: List[str]) -> bool: dp =[0 for i in range(len(s)+1)] words=set(wordDict) dp[0]=1 for i in range(1,len(s)+1): for j in range(i-1,-1,-1): if dp[j]==0:continue if s[j:i] in words: dp[i]=1 break return dp[len(s)]
一.GitHub Copilot的基本介绍 GitHub Copilot 是由 GitHub 和 OpenAI 合作推出的一款代码自动补全工具,它基GPT(Generative Pre-trained Transformer)技术,可以为程序员提供实时的代码提示和建议。以下是 GitHub Copilot 的基本使用方法:
安装插件: 首先,确保你的开发环境支持 GitHub Copilot。目前支持的编辑器包括 Visual Studio Code 和 JetBrains 的一些 IDE(例如 IntelliJ IDEA、PyCharm 等)。你需要在支持的编辑器中安装 GitHub Copilot 插件。 配置语言和风格: 在使用 GitHub Copilot 之前,你可以选择所使用的编程语言和编码风格。在编辑器的设置中,你可以配置 Copilot 的语言和风格选项。 编写代码: 在编辑器中打开一个代码文件,开始编写代码。当你输入代码的时候,GitHub Copilot 会显示实时的代码建议。 选择建议: 在 Copilot 给出的建议中,你可以通过按下 Tab 键或者其他指定的快捷键来接受建议。Copilot 会生成一些可能的代码片段,你可以从中选择适合你需求的部分。 修订和调整: Copilot 提供的建议不一定总是完全准确或符合你的需求。你可以在接受建议后进行进一步的修改和调整,以确保生成的代码符合你的期望。 学习和反馈: GitHub Copilot 受到用户反馈的影响,并会不断学习和改进。如果你发现了一些问题,或者有改进建议,可以通过 GitHub Copilot 插件提供的反馈机制向开发团队报告。 二.安装插件 安装 GitHub Copilot 插件需要在支持的编辑器中执行相应的步骤。目前,GitHub Copilot 主要支持 Visual Studio Code 和 JetBrains 的一些 IDE(例如 IntelliJ IDEA、PyCharm 等)。下面分别介绍在这两个编辑器中安装 GitHub Copilot 的步骤:
目录
下载 Win 10 ISO 镜像文件
VMware 创建新的虚拟机
解决启动报错:此主机支持 Intel VT-x,但 Intel VT-x 处于禁用状态
网络连接方式介绍
桥接模式(bridge)
NAT 网络地址转换模式
HostOnly 仅主机模式
共享文件夹给虚拟机
使用第三方软件
共享文件夹-方式1
共享文件夹-方式2
下载 Win 10 ISO 镜像文件 1、虽然有许多第三方网站上都可以下载 windows 系统,但是里面通常内置了许多软件或者广告,甚至其它一些坏心思。
2、建议从微软官网下载 Windows10 系统镜像,操作非常简单:参考:微软官网下载 Win 10 系统 ISO 镜像。
3、下载好 Windows.iso 镜像文件后就可以安装到虚拟机了。
VMware 创建新的虚拟机 与安装 Linux 系统 即便类似,其中重要的步骤介绍如下,其它的默认即可,本文使用的是 VMware® Workstation 15 Pro 版本:
1、 打开 VMware 软件,文件 -> 新建虚拟机 -> 选择自定义(高级)。
2、选择虚拟机硬件兼容性:默认即可。
3、安装客户机操作系统:选择稍后安装操作系统。
4、选择客户机操作系统:选择微软的 window,版本与下载好的镜像文件一致即可。
5、命名虚拟机:虚拟机名称自定义即可,安装位置建议不要安装在C盘。
6、固件类型:选择 BIOS。
文章目录 01-标签语法标签结构 03-HTML骨架04-标签的关系05-注释06-标题标签07-段落标签08-换行和水平线09-文本格式化标签10-图像标签图像属性 11-路径相对路径绝对路径 12-超链接标签13-音频14-视频 01-标签语法 HTML 超文本标记语言——HyperText Markup Language。
超文本:链接标记:标签,带尖括号的文本 标签结构 标签要成对出现,中间包裹内容<>里面放英文字母(标签名)结束标签比开始标签多 /标签分类:双标签和单标签 <strong>需要加粗的文字<strong> <br> <hr> 03-HTML骨架 html:整个网页head:网页头部,用来存放给浏览器看的信息,例如 CSS title:网页标题 body:网页主体,用来存放给用户看的信息,例如图片、文字 <html> <head> <title>网页标题</title> </head> <body> 网页主体 </body> </html> 提示
VS Code 可以快速生成骨架:在 HTML 文件(.html)中,!(英文)配合 Enter / Tab 键
04-标签的关系 作用:明确标签的书写位置,让代码格式更整齐
父子关系(嵌套关系):子级标签换行且缩进(Tab键)
兄弟关系(并列关系):兄弟标签换行要对齐
05-注释 概念:注释是对代码的解释和说明,能够提高程序的可读性,方便理解、查找代码。
注释不会再浏览器中显示。
在 VS Code 中,添加 / 删除注释的快捷键:Ctrl + /
<!-- 我是 HTML 注释 --> 06-标题标签 一般用在新闻标题、文章标题、网页区域名称、产品名称等等。
<h1>一级标题</h1> <h2>二级标题</h2> <h3>三级标题</h3> <h4>四级标题</h4> <h5>五级标题</h5> <h6>六级标题</h6> 显示特点:
目录
一.FileZilla简介
二.FileZilla的使用
2.1 安装服务端
2.2 添加组和用户
2.3 本机访问FileZilla
2.4 外部访问FileZilla
三.FileZilla的主动模式与被动模式
3.1 主动模式
3.2 被动模式
四.思维导图
一.FileZilla简介 FileZilla是一个免费开源的FTP软件,分为客户端版本和服务器版本,具备所有的FTP软件功能。 可控性、有条理的界面和管理多站点的简化方式使得Filezilla客户端版成为一个方便高效的FTP客户端工具,而FileZilla Server则是一个小巧并且可靠的支持FTP&SFTP的FTP服务器软件。对比Windows自带FTP服务 使用更加便捷 下载地址:
FileZilla - The free FTP solution (filezilla-project.org)https://filezilla-project.org/
二.FileZilla的使用 2.1 安装服务端 首先通过远程连接的方式把下载好的FileZilla安装包复制到虚拟机内。双击名字带server的进行服务端的安装。(傻瓜式安装即可)设置服务器管理密码。设置完成后就可以看到服务器管理界面了。 2.2 添加组和用户 打开FileZilla服务端管理界面,选择左上角编辑,就可以进行组和用户的添加了。(先添加组再添加用户)点击组后,会出现弹框,点击右侧添加,为组取名再点确定即可添加成功。同理,点击用户后也会出现弹框,点击右侧添加后,为该用户取名和选择刚刚添加的组,然后再点击确定即可添加成功。(记得给用户设置密码!)创建一个文件夹,准备给添加的用户分权限。打开刚刚的添加用户弹窗,选择左侧第二个Shared folders选择项,为不同用户添加其对应的文件夹并将该文件夹设置为主目录,当然别忘了给予该用户对文件夹的权限。 2.3 本机访问FileZilla 安装客户端,和安装服务端相同(傻瓜式安装即可),安装完成后来到此页面。打开客户端页面后,输入主机ip,用户名和密码,再点击快速连接,即可连接到该用户与之对应的权限文件夹,用户可以在自己权限内的文件夹里任意增删改查内容。 2.4 外部访问FileZilla 回到服务端管理界面点击编辑选择设置,选择被动模式设置,勾选自定义端口范围。(这里自定义端口范围要控制在49000-65535之间)打开防火墙的高级设置,新建一个入站规则,选择端口,输入21。
这里的21端口是ftp的命令端口,只有防火墙开启此端口,外部才可访问。
新建一个入站规则,选择端口,输入刚刚自定义的端口范围。
此端口是传输数据的端口。
新建完成后启用这两个端口。这个时候外部设备就可以访问了。(可根据需求上传外部设备的文件到ftp文件夹里,当然也可以导出文件夹里的内容到设备上查看。) 三.FileZilla的主动模式与被动模式 3.1 主动模式 男孩请女孩吃晚餐,女孩回应“好啊,晚上去哪吃”,这视为主动存在的问题:服务器主动数据传输,不知道客户端开放的端口是多少 3.2 被动模式 男孩请女孩吃晚餐,女孩回应“不好意思,我周末才有空”,这视为被动解决方案:服务器被动,但是已经告诉客户端数据传输端口,只要客户端想要传输数据,就可以通过端口访问服务器 四.思维导图
一、引言 1.1 Redis集群的必要性 Redis集群的必要性主要体现在以下几个方面:
高可用性: 集群允许在多个节点上分散数据,从而减少了单点故障的风险。在一个节点出现故障时,其他节点可以继续提供服务,确保系统的高可用性。横向扩展: 随着业务的增长,单个Redis节点的性能可能变得不足以处理大规模的负载。通过将数据分布在多个节点上,可以实现横向扩展,提高系统的整体性能。负载均衡: Redis集群可以自动将数据分布在不同的节点上,实现负载均衡。这确保了每个节点上的负载相对均匀,避免了单个节点成为性能瓶颈。容量扩展: 集群允许动态地添加或删除节点,以适应数据量的变化。这种灵活性使得系统能够根据需要进行容量扩展,而无需中断服务或进行大规模的迁移。故障恢复: Redis集群具备自动故障转移的能力。当一个节点发生故障时,集群会自动将该节点上的数据迁移到其他健康节点,从而保证系统的稳定性。数据复制与备份: 集群可以配置不同的复制策略,确保数据的备份和可靠性。通过将数据复制到多个节点,可以防止数据丢失,并在需要时进行恢复。性能优化: Redis集群允许并行处理多个请求,从而提高整体性能。通过合理配置和管理集群,可以更好地利用硬件资源,提供更高的吞吐量和更低的延迟。 1.2 Redis 单节点的局限性 Redis单节点存在一些局限性,特别是在处理大规模数据、高并发请求和提供高可用性方面。以下是一些常见的Redis单节点的局限性:
内存限制: Redis将所有数据存储在内存中,因此受到物理内存容量的限制。当数据量超过可用内存时,性能会急剧下降,甚至导致系统崩溃。这使得处理大规模数据的应用变得困难。单点故障: Redis单节点是一个单点,一旦该节点出现故障,整个系统就会中断服务。这种单点故障可能导致数据不可用,影响业务的正常运行。有限的读写能力: 单节点的读写性能有限,无法充分利用多核处理器和其他硬件资源。这在高并发场景下可能成为性能瓶颈,限制了系统的扩展能力。有限的网络带宽: 单节点的网络带宽也是有限的。在需要大量数据传输的场景下,网络带宽可能成为性能瓶颈,影响数据的传输速度。缺乏自动故障转移: Redis单节点没有内置的自动故障转移机制。一旦发生故障,需要手动进行故障排除和恢复,这增加了系统的管理和维护成本。缺乏水平扩展: 单节点无法水平扩展,即无法通过添加更多的节点来提高系统的整体性能和容量。这使得处理大规模负载的应用变得复杂。有限的持久化选项: 单节点的持久化选项有限,可能无法满足对数据持久性和安全性要求较高的应用场景。 为了解决这些局限性,特别是为了提高系统的可用性、性能和扩展性,通常会考虑使用Redis集群或其他分布式架构。Redis集群通过分布数据、提供故障转移和支持水平扩展等特性,能够更好地满足大规模应用的需求。
二、Redis 集群的基本概念 2.1 分布式系统基础知识 分布式系统是由多个独立的计算机节点组成的系统,这些节点通过网络进行通信和协调,以共同完成某个任务或提供某项服务。分布式系统的设计目标通常包括高性能、可靠性、可扩展性和容错性。以下是分布式系统的一些基础知识:
分布式系统概念: 多节点: 分布式系统由多个节点组成,这些节点可以是计算机、服务器或其他设备。网络通信: 节点通过网络进行通信,可以是局域网或广域网。并发性: 分布式系统的节点可以并发地执行任务,相互之间不一定同步。 CAP 定理: 一致性(Consistency): 所有节点在同一时间具有相同的数据视图。可用性(Availability): 每个非故障节点在任何时刻都能提供服务。分区容错性(Partition Tolerance): 系统能够在节点之间发生通信故障时继续运行。 BASE 模型: 基本可用性(Basic Availability): 系统保证可用性,但不保证强一致性。软状态(Soft State): 系统中的状态可以有一段时间的不一致,但最终会趋向于一致。最终一致性(Eventual Consistency): 系统保证在一段时间内达到一致状态。 分布式数据存储: 分片(Sharding): 将数据划分成多个片段,存储在不同的节点上,以提高性能和扩展性。副本(Replication): 复制数据到不同的节点,以提高可用性和容错性。一致性哈希(Consistent Hashing): 动态地映射数据到节点,减少节点的加入或退出对系统的影响。 分布式通信: 消息传递(Message Passing): 节点通过消息进行通信,可以是同步或异步的。远程过程调用(RPC): 允许一个进程调用另一个进程的过程,就像调用本地过程一样。发布-订阅模式(Publish-Subscribe): 允许节点订阅和接收特定类型的消息。 分布式一致性: 两阶段提交(2PC): 保证所有节点要么都提交一个事务,要么都回滚。三阶段提交(3PC): 在2PC的基础上引入超时机制,减少因为某节点故障导致的阻塞。Paxos 和 Raft: 是一些用于分布式一致性的算法。 分布式安全: 身份验证与授权: 对节点进行身份验证,并定义节点之间的权限。加密通信: 通过使用加密算法保护节点之间的通信。分布式安全策略: 确保系统在面对攻击时具有适当的安全性。 深入了解这些基础知识有助于理解分布式系统的设计原则、挑战和解决方案。在构建分布式系统或在分布式存储系统中工作时,这些概念将成为重要的参考点。
文章目录 矩阵1. 重塑矩阵1.1 题目描述1.2 方法一:简单模拟1.3 方法二:原地遍历 2. 转置矩阵2.1 题目描述2.2 方法:模拟 3. 矩阵置零3.1 题目描述3.2 方法一:辅助标记3.3 方法二:原地算法 4. 旋转图像4.1 题目描述4.2 方法一:模拟一4.3 方法二:模拟二4.4 方法三:原地算法 5. 螺旋矩阵5.1 题目描述5.2 方法:模拟 矩阵 矩阵是二维数组相关的应用题型,常见的有矩阵水平翻转、矩阵对角线翻转、矩阵遍历等。
1. 重塑矩阵 1.1 题目描述 leetcode跳转:566. 重塑矩阵
1.2 方法一:简单模拟 借助一个一维数组用来保持按行列遍历的结果,然后再按照新的行列遍历生成即可。
public int[][] matrixReshape(int[][] mat, int r, int c) { int m = mat.length; int n = mat[0].length; if (r * c != m * n) { return mat; } // 按原行列遍历 int[] temp = new int[r * c]; int idx = 0; for (int i = 0; i < m; i++) { for (int j = 0; j < n; j++) { temp[idx++] = mat[i][j]; } } // 按新行列遍历 int[][] ans = new int[r][c]; idx = 0; for (int i = 0; i < r; i++) { for (int j = 0; j < c; j++) { ans[i][j] = temp[idx++]; } } return ans; } 1.
一、以tar.xz压缩包为安装源 网址:https://downloads.mysql.com/archives/community/
二、解压压缩包 首先,将压缩包从windows传输到linux上
解压到/usr/local下,并且将解压的目录名称改为mysql
tar -xvf /tmp/mysql-8.1.0-linux-glibc2.28-x86_64.tar.xz -C /usr/local/ # 解压 mv /usr/local/mysql-8.1.0-linux-glibc2.28-x86_64/ /usr/local/mysql # 重命名 三、建立用户和组 先查看一下,当前的Linux中是否存在mysql的用户和组 (我这里并不存在)
cat /etc/passwd | grep mysql cat /etc/group | grep mysql 添加用户和组
groupadd mysql useradd -r -g mysql mysql 四、创建目录并修改权限 mkdir -p /data/mysql 查看一下 /data/mysql 以及刚刚解压缩的 /usr/local/mysql 的权限,发现其所属用户和组均为root
ls -dl /usr/local/mysql/ ls -dl /data/mysql/ 将所有者和组均改为mysql
chown -R mysql.mysql /usr/local/mysql chown -R mysql.mysql /data/mysql 五、初始化mysql /usr/local/mysql/bin/mysqld --user=mysql --basedir=/usr/local/mysql/ --datadir=/data/mysql --initialize 初始化时,会生成一个初始的密码,需要记录一下,待会儿使用 “qGlt6e<yeDa=”
定义类和构造方法 class SimpleClass(var x: Int, val y: String){} //创建类不需要new关键字 val simpleClass = SimpleClass(9, "Hello") 构造方法放在类名的后面,如果x和y前面加了var或val, x和y会分别在类中定义一个属性以及对应的getter和setter方法,不需要额外写,否则必须手动写getter和setter实现。类前面不需要修饰符public private等,跟java不一样,默认是public的。
像下面这样:
class Person(age: Int, name: String) { var age: Int = age //property get() { return field } set(value) { println("setAge: $value") field = value } var name: String = name get() { return field // backing field } set(value) { field = value } } kotlin中,get和set方法可以显示写出来,但是一般默认不需要显示写出来,所以可以直接这样简写:
class Person(age: Int, name: String) { var age: Int = age var name: String = name } 这样也会默认生成get和set方法,除非你需要自定义get和set方法中的逻辑,那时就需要显示写出来了。
一、suspending consoles打印 代码位置:Kernel/power/suspend.c
函数调用流程:devices_and_enter(suspend_state_t state) --> suspend_console();
void suspend_console(void)
{
if (!console_suspend_enabled) 注释这一行,可以看到休眠后printk的打印
return;
printk("Suspending console(s) (use no_console_suspend to debug)\n");
console_lock();
console_suspended = 1;
up(&console_sem);
}
二、打印linux 内核 bus总线休眠唤醒流程 代码位置:Kernel/drivers/base/power/main.c
dpm_suspend() --> device_suspend() --> __device_suspend() 修改位置:
static void pm_dev_dbg(struct device *dev, pm_message_t state, char *info) { dev_printk(KERN_ERR,dev, "%s%s%s\n", info, pm_verb(state.event), ((state.event & PM_EVENT_SLEEP) && device_may_wakeup(dev)) ? ", may wakeup" : ""); } 内核 log如下:
bus suspend:
[ 329.576315] reg-fixed-voltage soc:emac_lan_vreg: bus suspend
文章目录 NAT 概述创建 NAT 虚拟网络配置vm的ip地址 NAT 概述 NAT 使用主计算机的 IP 地址和端口通过内部 Hyper-V 虚拟网关向虚拟机授予对网络资源的访问权限。
网络地址转换 (NAT) 是一种网络模式,旨在通过将一个外部 IP 地址和端口映射到更大的内部 IP 地址集来转换 IP 地址。 基本上,NAT 使用流量表将流量从一个外部(主机)IP 地址和端口号路由到与网络上的终结点(虚拟机、计算机和容器等)关联的正确内部 IP 地址
此外,NAT 允许多个虚拟机托管需要相同(内部)通信端口的应用程序,方法是将它们映射到唯一的外部端口。
出于所有这些原因,NAT 网络对于容器技术是很常见的
创建 NAT 虚拟网络 以管理员身份打开 PowerShell 控制台。创建内部交换机。 New-VMSwitch -SwitchName "natsw" -SwitchType Internal natsw是自己定义的名称
查找刚创建的虚拟交换机的接口索引。 可以通过运行 Get-NetAdapter 来查找接口索引
你的输出应类似下面的形式:
PS C:\Windows\system32> Get-NetAdapter Name InterfaceDescription ifIndex Status MacAddress LinkSpeed ---- -------------------- ------- ------ ---------- --------- vEthernet (natsw) Hyper-V Virtual Ethernet Adapter #3 56 Up 00-15-5D-00-02-01 10 Gbps 以太网 Intel(R) 82579LM Gigabit Network Con.
以下是一个简单的MQTT连接库文件,其中包含了连接、断开、订阅主题、发送数据和接收数据等函数。请注意,这只是一个示例,你可能需要根据自己的实际需求进行修改。
#include <iostream> #include <cstring> #include <sys/types.h> #include <sys/socket.h> #include <arpa/inet.h> #include <unistd.h> const std::string SERVER_ADDRESS = "mqtt.server.com"; const int SERVER_PORT = 1883; // MQTT固定报头结构 struct MqttFixedHeader { uint8_t controlPacketType; uint8_t remainingLength; }; // MQTT连接报文结构 struct MqttConnectPacket { MqttFixedHeader fixedHeader; uint8_t variableHeader[10]; uint8_t payload[20]; }; // MQTT订阅报文结构 struct MqttSubscribePacket { MqttFixedHeader fixedHeader; uint16_t packetIdentifier; uint8_t topic[20]; uint8_t qos; }; // MQTT发布报文结构 struct MqttPublishPacket { MqttFixedHeader fixedHeader; uint16_t topicLength; uint8_t topic[20]; uint8_t payload[100]; }; class MqttClient { public: MqttClient() : sockfd(-1), connected(false) {} ~MqttClient() { if (connected) { disconnect(); } } bool connect(const std::string& clientId) { sockfd = socket(AF_INET, SOCK_STREAM, 0); if (sockfd < 0) { std::cerr << "
配置yum 源 首先,去到mysql网站,找到它的rpm的资源包 “mysql80-community-release-el9-5.noarch.rpm”
我们将其下载下来,然后配置yum源(下面两种方式二选一即可)
① 使用xftp传输,然后配置yum源
rpm -Uvh mysql80-community-release-el9-5.noarch.rpm 配置完成后,检查一下可用的mysql yum 源
yum repolist enabled | grep "mysql.*-community.*" ② 使用wget直接下载rpm资源,然后进行配置
wget -c dev.mysql.com/get/mysql80-community-release-el9-5.noarch.rpm 配置yum源
rpm -Uvh mysql80-community-release-el9-5.noarch.rpm 同样,检查一下
yum repolist enabled | grep "mysql.*-community.*" 安装mysql yum install mysql-community-server 配置mysql服务 ① 开机自启 systemctl enable mysql
② 启动服务并查看是否成功启动
systemctl start mysql systemctl status mysql 查看并修改root用户的默认密码 在日志文件中,可以看到mysql初始化的密码
cat /var/log/mysqld.log # 查看mysql日志 可以看到默认密码为 “T(,QH-(>w4hX”
mysql -uroot -p # 输入密码: T(,QH-(>w4hX 第一次进入数据库只能修改密码,不能做任何事情,然后默认的mysql密码对复杂度有一定的要求
# ALTER USER 'root'@'localhost' IDENTIFIED BY 'newpassword'; ALTER USER 'root'@'localhost' IDENTIFIED BY '2020SOLO@root'; 修改密码默认复杂度策略
web网站的工作流程和开发模式 基于Java Script封装的高级技术:Vue、Element、Nginx(前端程序部署的服务器) 初识Web前端 Web标准
1.介绍 基于给定的植物百科数据,实现植物数据的管理与分析。 植物相关数据存储在8个文本文件中,相应的文件信息说明如表1所示。其中,各个文件中不同的数据项之间均使用“#”分隔,如文件plant.txt中每一植物的植物名称、学名、分布地、详情描述之间使用“#”分隔,而分布地可能包括多个省份,各省份之间使用“@”分隔。图1给出了文件plant.txt中植物“独叶草”对应的数据示例。
“植物百科数据的管理与分析”实践项目由植物基本信息管理模块、植物分布地分析模块和植物从属关系检索模块三个子模块组成。各功能模块具体功能如下所示:
(1)增加、删除和修改植物信息:从plant.txt中读取植物的基本信息,创建一个植物信息的链表,基于该链表,实现植物基本信息的增加、删除和修改功能。
(2)基于顺序表的顺序查找:从plant.txt中读取植物的基本信息,实现基于顺序表的顺序查找。
(3)基于链表的顺序查找:从plant.txt中读取植物的基本信息,实现基于链表的顺序查找。
(4)基于顺序表的折半查找:从plant.txt中读取植物的基本信息,实现基于顺序表的折半查找。
(5)基于二叉排序树的查找:从plant.txt中读取植物的基本信息,实现基于二叉排序树的查找。
(6)基于开放地址法的散列查找:从plant.txt中读取植物的基本信息,实现基于开放地址法的散列查找。
(7)基于链地址法的散列查找:从plant.txt中读取植物的基本信息,实现基于链地址法的散列查找。
(8)基于BF算法的植物关键信息查询:编写一个基于字符串模式匹配算法的植物关键信息查询程序。
(9)基于KMP算法的植物关键信息查询:编写一个基于字符串模式匹配算法的植物关键信息查询程序。
(10)直接插入排序:从plant.txt中读取植物的基本信息,使用直接插入排序策略,将植物信息按植物学名的字典序进行排列。
(11)折半插入排序:从plant.txt中读取植物的基本信息,使用折半插入排序策略,将植物信息按植物学名的字典序进行排列。
(12)简单选择排序:从plant.txt中读取植物的基本信息,使用简单选择排序策略,将植物信息按植物学名的字典序进行排列。
(13)冒泡排序:从plant.txt中读取植物的基本信息,使用冒泡排序策略,将植物信息按植物学名的字典序进行排列。
(14)快速排序:从plant.txt中读取植物的基本信息,使用快速排序策略,将植物信息按植物学名的字典序进行排列。
(15)植物移植最短路径分析:当需要对植物进行跨省移植时,花费的成本与运载植物的路程长度息息相关(这里暂不考虑气候等环境因素对植物生长的影响)。用户可以通过输入植物名称和待移植的目的地,得到运输该植物需要花费的最短路径。其中,若移植的目的省份中已有该植物的分布,则输出“该省份已存在,无需移植”;否则,输出移植的出发地和抵达目的省份最短路径长度。
(16)可移植路径分析:当在某地发现一株新植物时,需要及时对其进行易地保护。易地移植的过程中,若路程过长,植物容易在运载途中死亡。用户输入新植物发现地、移植目的地及该植物能接受的最大路程,通过对省份图进行遍历,输出所有可行的运输路径。
(17)植物分类树构建:根据构建出的植物分类树和植物名称,得到该植物的属、科、目、纲、门、界信息
(18)同属植物信息检索:根据构建出的植物分类树和植物名称,得到与该植物同属的其它植物。
(19)下属植物信息检索:根据输入的植物类别(门、纲、目、科、属任何一个),输出隶属于该类别的所有植物。
2.BiTree结构(植物分类树) 3.数组的汉字存储问题 汉字存储占用 空间大小 与使用的 编码方式 有关。
常见的中文编码 GB2312(国标简体中文字符集)和 GBK(国标扩展)使用 2 个字节编码来表示一个汉字,不常用的 GB18030 使用 4 个字节编码来表示一个汉字,更通用的 UTF-8 编码使用 3 个字节编码来表示一个汉字。
CPU使用率 CPU使用率定义:
CPU 使用率是单位时间内 CPU 使用情况的统计,以百分比的方式展示。CPU 使用率是最常用来描述系统CPU 性能的指标。
Linux 作为一个多任务操作系统,将每个 CPU 的时间划分为很短的时间片,再通过调度器轮流分配给各个任务使用,因此造成多任务同时运行的错觉。
性能分析工具 下面介绍几种可用于分析CPU使用率的工具
top top是最常用的查看系统资源使用情况的工具,包括CPU、内存等等资源。
打开top,可以指定更新的周期。
输入H,打开隐藏的线程;输入1,可以显示单核CPU使用情况。
top -H -b -d 1 -n 200 > top.txt,每个1秒统计一次,共200次,显示线程细节,并保存到top.txt中。
top采样来源你还依赖于/proc/stat和/proc//stat两个,这两个的详细介绍参考:/proc/stat和/proc//stat。
以启动一个gazebo仿真环境为例
cpu的使用率情况如下:
可以看到 gazebo 的 gzserver 是非常占用cpu资源的,使用率高达86%
cpustat 通过下面指令进行安装
sudo apt install cpustat cpustat -T -D -x 结果如下
gazebo 的 gzserver 占用cpu资源的使用率达82%。
htop htop和top的功能类似,但是可读性比top更好。在界面按下F5,可以看到进程里面的线程,树形结构表示了父子关系。
同样gazebo 的 gzserver 占用cpu资源的使用率达85.8%。
atop atop是一个监控系统资源和进程的工具。它通过CPU使用率来对列表中的进程进行降序排列,而每一个进程则包含了CPU、内存、磁盘和网络状态等信息。它的功能与top和htop类似。
同样gazebo 的 gzserver 占用cpu资源的使用率达87%。
glances glances是一个由python编写的,与Nmon功能类似的报告工具,它能够报告统计cpu、内存、网络、磁盘和进程。除了报告统计,glances不支持任何其他特性或功能。当程序运行时点击“h”可以显示帮助页面。
同样gazebo 的 gzserver 占用cpu资源的使用率达84.9%。
nmon Nmon是一个非常容易使用,能够在一个屏幕上监视CPU、内存、网络、磁盘使用状况和进程列表的工具。除了无法管理进程和修改报告显示,Nmon与那些只用于报告的报告工具完全一样。另外,它可以将数据保存到电子表格文件。
概念:ajax是一种现有的技术集合,技术内容包括:HTML或XHTML,CSS,JavaScript,DOM,XML,XSLT,以及最重要的XMLHttpRequest。用于浏览器与服务器之间使用异步传输,做到局部请求以实现局部刷新。
作用: 不刷新页面就能更新网页(局部刷新)在页面加载后从服务器请求数据在页面加载后从服务器接收数据 在后台向服务器发送数据
如何使用ajax: 创建XMLHttpRequest对象使用open方法设置和服务器的交互信息设置requestHeader()request.setRequestHeader(属性名称,属性值)send()设置发送的数据,开始和服务器交互取得相应,注册事件
一、简介 1.1 哨兵的概述 哨兵(Sentinel)是 Redis 分布式系统中用于监控和管理多个 Redis 服务器的组件。它的主要目标是确保 Redis 系统的高可用性,通过实时监测主节点和从节点的状态,及时发现并自动处理故障,保证系统的稳定运行。
1.2 为什么需要哨兵? 引入Redis哨兵的原因主要与以下几个方面有关:
高可用性需求: 在生产环境中,确保Redis服务的高可用性是至关重要的。哨兵帮助监控Redis节点的状态,及时发现主节点的故障并进行自动故障转移,以保障系统的连续性和可用性。 故障自动处理: 通过哨兵,Redis能够实现自动故障转移,即在主节点发生故障时,哨兵会自动选择并提升一个从节点为新的主节点。这种自动处理机制大大减少了管理员手动干预的需求,加快了故障恢复速度。 实时监控和警报: 哨兵能够实时监控Redis节点的状态,并通过配置的方式提供实时的警报和通知。这使得管理员能够及时了解系统的健康状况,采取预防或紧急措施,从而提高对系统的监控和管理效率。 自动发现和配置更新: Redis哨兵通过周期性地与Redis服务器通信,能够自动发现新的节点,并且在系统拓扑结构发生变化时进行自动更新。这种自动发现和配置更新的机制简化了系统的扩展和维护过程,使得系统更加灵活和易于管理。 Quorum机制防脑裂: 哨兵采用Quorum(法定人数)机制来进行主节点切换的决策,确保在多数哨兵达成一致时才执行故障转移。这有助于防止由于网络分区等问题导致的脑裂(split-brain)情况,提高系统的可靠性。 配置和管理通知: 哨兵提供了配置和管理通知的机制,使得管理员能够及时获知节点的状态变化、故障转移的情况等重要信息。这有助于管理员在发生问题时迅速做出反应,采取必要的措施来修复或调整系统。 引入Redis哨兵是为了提高Redis分布式系统的稳定性、可用性和可维护性,确保系统在面对故障和变化时能够迅速、自动地做出适当的响应。
二、哨兵的工作原理 2.1 哨兵的运行模式 Redis Sentinel(哨兵)可以以单独模式或多哨兵模式运行,具体取决于你的系统架构和可用性需求。
单哨兵模式:
在单哨兵模式下,系统中只有一个哨兵实例监控 Redis 集群。这种简单的部署适用于小规模应用或测试环境,但不适用于对高可用性有更严格需求的生产环境。
特点和配置包括:
只有一个哨兵实例在监控 Redis 集群。故障检测和自动故障转移仍然有效,但是缺乏多节点监控的冗余性。配置文件中通常只包含一个监控的 Redis 集群的信息。 多哨兵模式:
在多哨兵模式下,系统中有多个哨兵实例同时监控 Redis 集群。这种模式提供了更高的可用性和冗余,确保在某个哨兵失效时仍然能够保持监控和维护功能。
特点和配置包括:
多个哨兵实例分布在不同的主机上,相互协同工作。配置文件中包含所有哨兵的信息,它们互相感知,并通过投票机制(Quorum)决策是否执行自动故障转移。多哨兵提供了更强大的故障检测和决策能力,降低了单点故障的风险。 在实际部署中,多哨兵模式更为常见,因为它能够提供更高的可用性和系统稳定性。在配置中,需要确保哨兵实例能够相互发现并形成一个工作群体,共同监控和维护 Redis 集群。
2.2 选举过程 Redis Sentinel 中的选举过程是在主节点(Master)不可用的情况下,由哨兵协作决策选择新的主节点的过程。以下是选举的基本过程:
主节点失效检测:
当哨兵检测到主节点不可用,可能是由于网络问题、进程崩溃或其他原因,哨兵会将主节点标记为不可用。 哨兵之间的通信:
在多哨兵模式中,失效的主节点信息会通过哨兵之间的通信进行传播。各个哨兵实例相互感知主节点的状态变化。 进行选举:
在哨兵集群中,进行主节点选举需要达成一定的共识,这就是 Quorum 机制的应用。Quorum 是指在多数哨兵达成一致时才执行选举操作,这有助于防止由于网络分区等问题导致的误操作。 Quorum 的计算:
哨兵进行选举时,需要得到超过半数的哨兵的支持才能执行选举。这确保了选举的合理性和可靠性。 选举的结果:
如果足够多的哨兵同意进行选举,它们会协作选择一个新的主节点。选举成功后,新的主节点会晋升为主,同时旧的主节点标记为从节点,确保数据的持久性。 系统状态更新:
Rust 的数值类型与其他语言并没有什么不同。
特定是:
整数类型,isize 和 usize 的大小取决于系统使用的是32位还是64位。NaN,当出现数学上未定义的结果时,就会返回 NaN。NaN,不能使用相等。但可以用 is_nan() 来判断一个值是否为 NaN。所有的转换必须是显式的,不存在隐式转换。数值类型可以自动推导,也可以手动指明。 fn main() { let x = 2.0; // f64 let y:i32 = 16; // i32 } 使用浮点数时需谨慎,不要使用浮点类型比较相等性。有理数和复数,不包含在标准库中。需要使用社区的库 num。在依赖中添加。
本内容是对 Rust开发干货集[1] 的实践与扩展.
iter() 不转移所有权 先简单解释下什么叫"转移所有权":
在 Rust 中,"转移所有权"(Ownership Transfer)是一种核心概念,它涉及变量和数据的所有权从一个实体转移到另一个实体。这种机制帮助 Rust 在编译时期管理内存安全,避免悬挂指针和内存泄漏等问题。
例如:
fn main() {
let s1 = String::from("hello");
let s2 = s1; // 所有权从 s1 转移到 s2
// println!("{}", s1); // 这行会引发编译错误,因为 s1 不再拥有数据的所有权. 报错: error[E0382]: borrow of moved value: `s1`
println!("{}", s2); // 正确,s2 现在拥有数据的所有权
}
当 s1 被赋值给 s2 时,s1 的所有权被转移给了 s2。这意味着 s1 不再有效,因此接下来如果使用 s1 将导致编译错误。
iter() 在 Rust 中用于创建集合的迭代器,比如在数组或向量上。iter() 不会转移集合的所有权。相反,它创建一个迭代器,该迭代器借用集合的内容:
fn main() {
let v = vec!
首先很高兴大家能够关注我,提前在2023年结束达到百粉!
然后这篇文章是使用虚幻UE 的网格体/顶点绘制模式来对Megascans材质进行混合的实验。
注意:以下材质都是指材质实例,网格体绘制和顶点绘制一个意思
文章目录 一、材料准备二、实验步骤1、Bridge混合材质2、顶点绘制参数3、混合材质实例参数 一、材料准备 1、顶点绘制模型:
需要模型的面数尽量多一点,官方的立方体面数不够,完成不了顶点绘制的工作(血泪史
博主准备了一个10m的立方体,646464的面数。(在资源里,估计
左边官方,右边博主准备的,在线框视图下我们可以对比出顶点的差距。
2、三个Megascans的材质
基础层材质:混合后为基底,混合后默认显示为此层,建议为砖块
中间层材质:混合后默认不显示,需要用网格体绘制模式来绘制,建议为干泥土
顶层材质:混合后默认不显示,也需要用网格体绘制模式来绘制,建议用湿泥土(博主选择的不太好
从Bridge导入的过程不再演示。
二、实验步骤 1、Bridge混合材质 用Bridge进行材质的混合,UE4使用Megascans:
1、按住ctrl顺序选定材质:基础层-》中间层-》顶层(最多三个材质进行混合 2、打开Bridge中任意一个模型右下角的滑动图标按钮 3、点击“创建材质混合”(可以自定义目录和命名 这样材质就已经混合完成,可以设置到我们准备好的模型中了
但是发现UV不对,所以我们进行调整UV。
由于我们的模型是10m
而材质分别是基础层22m、22m、2*2m
所以我们需要调整混合材质的TILE x、y为5
效果为图中展示
2、顶点绘制参数 选择已附上混合材质的模型,点击绘制
序号1中的选线都是绘制功能,没什么好讲的,重点在序号2。 序号2: 尺寸:画笔大小 强度:越大说明越强,越强随便刷一两下就可以刷满 衰减:边缘过度是否明显 绘制颜色和擦除颜色:哪个为黑色就说明处于哪个模式 通道:(究极重要!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!) 红:中间层绘制 绿:顶层绘制 蓝:水坑层绘制(默认没开 ps:到了这个模式无发对物体进行w、e、r进行位移旋转尺寸进行设置,需要设置回选项模式才行 通道红单独绘制:
通道绿单独绘制:
通道蓝单独绘制:
发现场景没有任何变化,是因为水坑层默认关闭,需要从混合材质实例中打卡。
那如果我们再在上面刷通道红,中间层会是什么效果呢。
中间层不会覆盖顶层,相应的基础层不会覆盖中间层,更不会覆盖顶层。
这样其实也没有达到一个真实效果,我们需要重新调整一下混合材质的参数,让他们更加逼真。
3、混合材质实例参数 混合控制
混合控制: 分为两个:顶层和中间层的控制 混合程度,越小就越往深处积累,像水往地砖缝隙渗透(有可能和我说的相反,需要自己评估 混合对比度:和混合程度一起配合 混合消散:边缘的过渡效果 反转混合:对混合程度的效果进行反转,先对高处进行材质生成,再向深度过渡 基础层、中间层、顶层
这里没什么好说的
全局:
勾了全局下面的某一层的调整,某一层中的原本材质实例中的参数就可以在此处调整了
比如粗糙度、高光等 水坑层也可以调整
可以设置水坑高度,透明度、粗糙度、最重要可以调整风吹的效果,在wave controls里面 水坑正常效果:
水坑加了Wave之后:
RIS 系列 See-Through-Text Grouping for Referring Image Segmentation 论文阅读笔记 一、Abstract二、引言三、相关工作3.1 Semantic Segmentation and Embeddings3.2 Referring Expression Comprehension3.3 Referring Image Segmentation 四、方法4.1 视觉表示4.2 文本表示4.3 See-through-Text Embedding4.4 Bottom-up STEP Heatmaps5.5 Top-down Heatmap Refinement细节 4.6 训练 五、实验5.1 消融研究5.2 与 SOTA 方法的比较5.3 定量分析 六、结论 写在前面
最近 Arxiv 没啥新东西了,找篇老的文章读读,看看它们之间的区别在哪里。
论文地址:See-Through-Text Grouping for Referring Image Segmentation代码地址:源文未提供收录于:ICCV 2019Ps:2023 年的最后一篇博文阅读笔记,我今年的 flag 也实现啦。主页 更多干货,欢迎关注呀,期待 6 千粉丝有你的参与呦~ 一、Abstract 基于传统的分组技术,本文提出一种方法来解决指代分割。提出的方法受循环卷积神经网络 convolutional-recurrent neural network (ConvRNN) 驱动,迭代地执行自顶向下的,对分割线索的自下而上的聚合过程。给定语言表达式,本文提出的方法学习去预测与其相关的每个像素,并驱动一个 See-through-Text Embedding Pixelwise (STEP) 热力图。通过学到的视觉-文本 co-embedding 得出像素水平的分割 masks。将热力图转化为一个精炼的热力图,ConvRNN 执行一个自上而下的近似。在精炼热力图辅助下,通过重新评估注意力分布来更新指代表达式的文本表示,然后计算一个新的 STEP 热力图作为 ConvRNN 的下一步输入。本文提出的方法泛化性强,无需来自其他 DNN 模型的目标检测结果,达到了 SOTA 的效果。
文章目录 一、SNAT和DNAT二、概念 一、SNAT和DNAT CDK:Container Deployment Kit
是一个基于华为云CCE服务的容器部署平台,内核是Kubernetes,CDK有SRE维护,专门作为云服务管理面的部署平台。
Hypervisor或者Virtual machine monitor(VMM)是创造并且运行虚拟机的软件、固件、或者硬件,通俗来讲Hypervisor是一种将操作系统与硬件抽象分离的方法,以达到host machine的硬件能够同时运行在一个至多个虚拟机作为guest machine的目的,这样能够使这些虚拟机高效地分享主机硬件资源。
弹性公网IP:可以直接访问Internet的IP地址,而私有IP地址为公有云内局域网络的IP地址,私有IP地址禁止出现在Internet中
SNAT功能:通过绑定弹性公网IP,实现私有IP向公有IP的转换,可实现VPC内跨可用区的多个云主机共享弹性公网IP,安全、高效地访问互联网。
DNAT功能:通过绑定弹性公网IP(IP映射或端口映射方式),实现VPC内跨可用区的多个云主机共享弹性公网IP,为互联网提供服务。
SNAT和DNAT区别:
云一切以自身为出发点:
1.SNAT源头是自身,访问云外;
2.DNAT目的地是自身,表示对外提供服务;
内部地址要访问公网上的服务时,内部地址会主动发起连接,将内部地址转换为公有IP,网关这个地址转换称为SNAT;
当内部需要对外提供服务时,外部发起主动连接,路由器或者防火墙的网关接收到这个连接,然后把连接转换到内部,此过程是由带公有IP的网关代替内部服务来接收外部的连接,然后再内部做地址转换,此过程称为DNAT,主要用于内部服务对外发布。
1、DNAT:目标网络地址转换Destination Network Address Translation
DNAT用于修改数据包的目标IP地址和端口号,将数据包从源地址转发到目标地址;
当数据包经过DNAT规则时,目标地址会被替换为指定的目标地址,端口号也可以被修改;
DNAT通常用于实现端口映射、负载均衡、虚拟服务器等功能;
举个例子,当你子啊路由器上设置了DANT规则,将外部的IP地址的某个端口映射到内部服务器的某个端口上时,外部用户访问路由器的该端口时,数据包会被转发到内部服务器上。
2、SNAT:源网络地址转换Source Network Address Translation
SNAT用于修改数据包的源IP地址和端口号,将数据包从源地址转发到目标地址;
当数据包经过SANT规则时,源地址会被替换为指定的源地址,端口号也可以被修改;
SNAT通常用于实现网络地址隐藏,多个内部主机共享一个公网IP地址等功能;
举个例子,当你在路由器上设置了SNAT规则,将内部服务器的数据源地址替换为路由器的公网IP地址时,外部服务器收到的数据包会以为是来自路由器的。
总结:
DNAT用于修改数据包的目标地址,将数据包转发到指定的目标地址;
SNAT用于修改数据包的源地址,将数据包转发出去时,源地址会被替换为指定的源地址;
DNAT常用于实现端口映射、负载均衡、虚拟服务器管理等功能;
SNAT常用于实现网络地址隐藏、多个内部主机共享一个公网IP地址等功能;
二、概念 HCS中
基础服务通常指IaaS基础服务,包括计算、存储、网络等
高阶服务通常指应用平台、EI、数据库
华为云stack(堆栈)和Cloud的区别
华为云stack和Cloud是两个不同的产品线,他们的主要区别在于应用场景和提供的服务特点
stack是面向企业应用的私有云解决方案,提供了一系列的基础设施服务,如计算、存储、网络等,适合更高定制化的企业用户。
而Cloud则是面向个人和小型企业的用户,提供了一系列的云计算服务,适合需要快速、便捷的公共云服务的个人和小型企业用户。
华为云安全体系-----冰山安全
普罗平台:CloudScope,华为云服务运维平台,提供统一软件开发和软件运维操作;在软件构建、集成、测试、发布到部署中提供自动化和监控。
SOP:Standard Operation Procedure标准操作流程
EDKM:Expand Develop ToolKit Manager 展开开发工具包管理器
剧本形式,底层封装的是Python
EDKM的使用方法,在CAC高阶变更菜单-高阶服务变更中上传插件包进行操作。所以EDKM其实依赖于普罗CAC,他其实是CAC的一个批量化操作功能。即通过上传一个按照一定规则编排的压缩包,一次性执行多个CAC功能。
EDKM封装了接口,并编排,所有的执行能力仍有服务方提供
压缩包(zip格式)即插件包,而为什么一个插件包可以一次性完成多个CAC功能,是因为华为云有一个叫原子能力的功能,它是CAC或者EDKM对“外”提供的一个类似访问入口的东西,类似于“计算机的访问端口”,可以对外部CAC进行命令传递。我们可以通过这个“端口”去命令CAC执行一些CAC的功能。比如它有一个原子能力叫创建虚拟机,那么我们通过这个原子能力就能去命令CAC执行“申请虚拟机”的功能,而该功能与原本在CAC手动执行“申请虚拟机”功能的效果是一致的。
SWR:SoftWAre Repository for Container容器镜像服务
优势:镜像下载加速、高可靠的存储:依托华为OBS专业存储,确保镜像的存储可靠性高达11个9、更安全的存储:细粒度的授权管理,让用户更精准的控制镜像访问权限。
目录
1.线程池是什么
2.标准库中的线程池
2.1ThreadPoolExecutor
2.2构造方法参数介绍
2.3拒绝策略(面试易考)
2.4Executor的使用
3.实现线程池
1.线程池是什么 线程池是一种用来管理线程的机制,它可以有效地控制线程的创建、复用和销毁,从而提高程序的性能和资源利用率。
想象这么⼀个场景:
在学校附近新开了⼀家快递店,老板很精明,想到⼀个与众不同的办法来经营。店里没有雇⼈,而是 每次有业务来了,就现场找⼀名同学过来把快递送了,然后解雇同学。这个类⽐我们平时来⼀个任 务,起⼀个线程进行处理的模式。
很快⽼板发现问题来了,每次招聘 + 解雇同学的成本还是非常高的。老板还是很善于变通的,知道 了为什么⼤家都要雇⼈了,所以指定了⼀个指标,公司业务⼈员会扩张到 3 个⼈,但还是随着业务 逐步雇⼈。于是再有业务来了,老板就看,如果现在公司还没 3 个⼈,就雇⼀个⼈去送快递,否则 只是把业务放到⼀个本本上,等着 3 个快递⼈员空闲的时候去处理。这个就是我们要带出的线程池的模式。
线程池最大的好处就是减少每次启动、销毁线程的损耗。
2.标准库中的线程池 2.1ThreadPoolExecutor 2.2构造方法参数介绍 以最后一个构造方法为例:
Java的 ThreadPoolExecutor 是一个线程池执行器,用于管理和调度线程的执行。它有以下几个参数:
1.corePoolSize:核心线程数
即线程池中保持活动状态的最小线程数。如果线程池中的线程数小于corePoolSize,则即使其他线程是空闲的,ThreadPoolExecutor也会创建新的线程来处理任务。
2.maximumPoolSize:最大线程数
即线程池中允许的最大线程数。当队列满了且当前线程数小于maximumPoolSize时,ThreadPoolExecutor会创建新的线程来处理任务。
3.keepAliveTime:线程保持活动的时间
即当线程池中的线程数量大于corePoolSize时,空闲线程被保留的最长时间。超过这个时间,空闲线程将被终止。
4.unit:线程保持活动时间的单位
可以是纳秒、微秒、毫秒、秒、分钟、小时或天。
5.workQueue:任务队列
用于保存等待执行的任务。ThreadPoolExecutor提供了多种类型的队列,如ArrayBlockingQueue、LinkedBlockingQueue、SynchronousQueue等。
6.threadFactory:线程工厂
用于创建新线程。可以通过实现ThreadFactory接口来自定义线程的创建过程。
7.handler:拒绝策略
用于处理无法添加到线程池的任务。拒绝策略可以ThreadPoolExecutor提供的几种默认策略,如AbortPolicy、CallerRunsPolicy、DiscardPolicy和DiscardOldestPolicy,也可以自定义实现RejectedExecutionHandler接口来定义自己的策略。
这些参数可以通过ThreadPoolExecutor的构造方法来设置,也可以通过相应的setter方法进行设置。根据具体的需求,可以调整这些参数来优化线程池的性能和行为。
2.3拒绝策略(面试易考) 在多线程编程中,当线程池无法接受新的任务时,就会触发拒绝策略(RejectedExecutionHandler)。拒绝策略是一个接口,用于定义当线程池无法接受新的任务时应该如何处理这些被拒绝的任务。
在Java中,有四种内置的拒绝策略:
1.AbortPolicy(默认):当线程池无法接受新的任务时,会抛出RejectedExecutionException异常。
2.CallerRunsPolicy:当线程池无法接受新的任务时,会由调用execute方法的线程来执行该任务。
3.DiscardOldestPolicy:当线程池无法接受新的任务时,会抛弃队列中最旧的任务,然后尝试再次提交新的任务。
4.DiscardPolicy:当线程池无法接受新的任务时,会直接抛弃被拒绝的任务。
除了以上四种内置的拒绝策略,我们还可以自定义拒绝策略,只需要实现RejectedExecutionHandler接口,并实现其唯一的方法rejectedExecution(Runnable r, ThreadPoolExecutor executor)。在该方法中,可以根据需求实现自定义的拒绝逻辑,如记录日志、发送通知等。然后,可以通过ThreadPoolExecutor的setRejectedExecutionHandler方法将自定义的拒绝策略设置给线程池。
ThreadPoolExecutor 本身用起来比较复杂, 因此标准库还提供了另一个版本, 把ThreadPoolExecutor封装了一下. 这个版本就是Executors类.
Executors类创建的线程池适用于一些简单的场景,不需要过多的自定义配置。而ThreadPoolExecutor适用于需要更多自定义配置的场景,可以根据需要灵活地配置线程池。
Executors中的方法:
2.4Executor的使用 import java.
ref有三种用法: 1、ref 加在普通元素上,用this.$refs.name 获取到的是dom元素
2、ref 加在子组件上,用this.$refs.name 获取到的是组件实例,可以使用组件的所有方法。
3、如何利用 v-for 和 ref 获取一组数组或者dom 节点
注意:
1、ref 需要在dom渲染完成后才会有,在使用的时候确保dom已经渲染完成。比如在生命周期 mounted(){} 钩子中调用,或者在 this.$nextTick(()=>{}) 中调用。
2、如果ref 是通过v-for 循环出来的,有多个重名,那么ref的值会是一个数组 ,此时要拿到单个的ref 只需要循环就可以了。
如下例子: 1、ref使用在外面的组件上 <div id="ref-outside-component" v-on:click="consoleRef">
<component-father ref="outsideComponentRef"></component-father>
<p>ref在外面的组件上</p>
</div>
var refoutsidecomponentTem={
template:"<div class='childComp'><h5>我是子组件</h5></div>"
};
var refoutsidecomponent=new Vue({
el:"#ref-outside-component",
components:{
"component-father":refoutsidecomponentTem
},
methods:{
consoleRef:function () {
console.log(this); // #ref-outside-component vue实例
console.log(this.$refs.outsideComponentRef); // div.childComp vue实例,组件实例
}
}
});
2、ref使用在外面元素上 <div id="ref-outside-dom" v-on:click="consoleRef" >
<component-father> </component-father>
<p ref="
一、概述 当我们查询所有数据时,如果缓存中没有,则去数据库查询,如果有,直接查缓存的数据就行。注意定期更新缓存数据。
二、主体代码 private static final String ROOM_SCHEDULES_HASH = "RoomSchedules"; @Override public List<RoomSchedule> getAllRoomSchedules() { BoundHashOperations<String, String, String> hashOps = stringRedisTemplate.boundHashOps(ROOM_SCHEDULES_HASH); if (hashOps.size() == 0) { List<RoomSchedule> roomSchedules = roomScheduleMapper.getAllRoomSchedules(); for (RoomSchedule roomSchedule : roomSchedules) { ObjectMapper objectMapper = new ObjectMapper(); try { String json = objectMapper.writeValueAsString(roomSchedule); hashOps.put(roomSchedule.getId().toString(), json); } catch (Exception e) { e.printStackTrace(); } } stringRedisTemplate.expire(ROOM_SCHEDULES_HASH, 3, TimeUnit.MINUTES); // 设置有效期为三分钟 return roomSchedules; } else { Map<String, String> entries = hashOps.
作为一名时刻想成为酷盖的人
谁的童年里没有一个当“黑客”的梦
尤其看着影视剧里
那英俊潇洒的身姿
哇塞!真帅~
从小学
哦不,从幼儿园开始
成为一名“黑客”
就成为了你远大的理想
不过老师说
你成为一名“黑“客的可能性为零
因为玩不好的人都进去了
直至上到大学
你才知道
原来你小时候说的”黑客“
学名叫——
网络安全工程师
今天,给大家总结一下
网络安全到底学什么?
一、你永远离不开的基础知识 当你以为你能瞬间学会黑进别人电脑时
现实总会给你迎头痛击
网络基础都掌握了?
Linux基础都熟悉了??
”没有“
没有还想上手高难度操作?
如果说控制别人服务器是珠穆朗玛峰
那么这些前置基础知识
就是组成珠穆朗玛峰的
一块块岩石
二、万花丛中过,还是入不了门 都说学习是要付出代价的
看着那些令人头大的
网络安全入门核心知识
信息安全基础
简直令人窒息
可能这就是你学习4年
还是小白的原因吧
三、选对工具就已经成功了一大半 曾经你也是一名实力派选手
所有难题一块上
你眼睛都不带眨一下的
可如今面对琳琅满目的渗透工具
你再也不能自信地说出
”我是这条gai上最靓的仔“
为了给自己能力锦上添花
这些渗透工具,成了你必学的内容
例如Burp、Nessus
再例如MSF、AWVS
当然最重要的,你还要了解Kali
四、是时候接触核心知识了 ”学网安核心知识,让网安无处可走”
长此以往,你就陷入了以下泥淖:
SQL注入漏洞、XSS漏洞
文件包含漏洞、文件上传漏洞
SSRF漏洞、越权漏洞
逻辑漏洞…
你猜还有什么要学?
这时候就有人哭着问了
难道真的没有人能学到进阶阶段吗?
五、各位久等了,我是进阶 遇到那些看起来高大的词
你就知道
进阶内容还是来了
后门分析?权限提升?
代码审计?等级保护?
风险评估?安全巡检?
应急响应?安全开发?
学会这些
04-VIP-Redis缓存设计与性能优化 文章目录 04-VIP-Redis缓存设计与性能优化正文多级缓存架构 缓存设计缓存穿透 缓存与数据库双写不一致明天我们说开发规范与性能优化! 正文 多级缓存架构 缓存设计 缓存穿透 缓存穿透是指查询一个根本不存在的数据, 缓存层和存储层都不会命中, 通常出于容错的考虑, 如果从存储层查不到数据则不写入缓存层。
缓存穿透将导致不存在的数据每次请求都要到存储层去查询, 失去了缓存保护后端存储的意义。
造成缓存穿透的基本原因有两个:
第一, 自身业务代码或者数据出现问题。
第二, 一些恶意攻击、 爬虫等造成大量空命中。
缓存穿透问题解决方案:
1、缓存空对象
1 String get(String key) { 2 // 从缓存中获取数据 3 String cacheValue = cache.get(key); 4 // 缓存为空 5 if (StringUtils.isBlank(cacheValue)) { 6 // 从存储中获取 7 String storageValue = storage.get(key); 8 cache.set(key, storageValue); 9 // 如果存储数据为空, 需要设置一个过期时间(300秒) 10 if (storageValue == null) { 11 cache.expire(key, 60 * 5); 12 } 13 return storageValue; 14 } else { 15 // 缓存非空 16 return cacheValue; 17 } 18 } 2、布隆过滤器
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>Document</title> <link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css" /> <script src="https://cdn.bootcdn.net/ajax/libs/vue/2.6.13/vue.js"></script> <script src="https://cdn.jsdelivr.net/npm/@unocss/runtime"></script> <script src="https://unpkg.com/element-ui/lib/index.js"></script> <!-- <link rel="stylesheet" href="./vue/element_ui.css" /> <script src="./vue/vue.js"></script> <script src="./vue/unocss.js"></script> <script src="./vue/element_ui.js"></script> --> <style> * { margin: 0; padding: 0; box-sizing: border-box; } .left_container { background: url('https://images8.alphacoders.com/132/thumbbig-1323361.webp') no-repeat center center; background-size: cover; border-radius: 15px; position: absolute; width: 50%; height: 100%; bottom: 0; left: 0; z-index: 999; transition: all 1s; transform: translateX(0); } .
一、登录友盟+官网,按照引导注册友盟+账号 二、在友盟平台新建小程序应用(建好之后会得到appkey) 进入小程序统计后台创建Appkey,按要求填写小程序名称及类型:
三、在微信小程序中接入SDK ---- 以下是npm 配置 1. 安装友盟微信sdk npm install umtrack-wx@latest --save 2. 配置 由于使用的是uniapp,所以不能按照官方给出的方式来配置
我们在 main.js 文件中加入以下代码
//接入友盟统计 import uma from "umtrack-wx"; uma.init({ appKey: '你在友盟创建的程序key', //由友盟分配的APP_KEY // 使用Openid进行统计,此项为false时将使用友盟+uuid进行用户统计。 // 使用Openid来统计微信小程序的用户,会使统计的指标更为准确,对系统准确性要求高的应用推荐使用Openid。 useOpenid: true, // 使用openid进行统计时,是否授权友盟自动获取Openid, // 如若需要,请到友盟后台"设置管理-应用信息"(https://mp.umeng.com/setting/appset)中设置appId及secret autoGetOpenid: true, debug: true, //是否打开调试模式 uploadUserInfo: true, // 自动上传用户信息,设为false取消上传,默认为false enableVerify: false, // 测试埋点,发布线上时改为false }); uma.install = function (Vue) { Vue.prototype.$uma = uma; }; Vue.use(uma); 3.使用 如何使用的话,就根据项目需求来进行操作就可以了。
我这边只需要给程序中的事件进行统计,所以就直接进入友盟的后台管理,添加自定义事件然后在小程序中对应的事件中加入以下代码就可以,比如监听点击了多少次。
onClick(){ this.$uma.trackEvent('eventID');//eventID是在友盟后台你自己创建的 } 友盟小程序SDK集成文档
文章目录 一、线程池二、线程安全的单例模式1.单例模式的特点2.饿汉实现方式和懒汉实现方式3.懒汉方式实现单例模式(线程安全版本) 三、STL,智能指针和线程安全四、常见的各种锁五、读者写者问题1.读写锁2.读写锁接口 一、线程池 线程池:一种线程使用模式。线程过多会带来调度开销,进而影响缓存局部性和整体性能。而线程池维护着多个线程,等待着监督管理者分配可并发执行的任务。这避免了在处理短时间任务时创建与销毁线程的代价。线程池不仅能够保证内核的充分利用,还能防止过分调度。可用线程数量应该取决于可用的并发处理器、处理器内核、内存、网络sockets等的数量。
线程池的应用场景:
1.需要大量的线程来完成任务,且完成任务的时间比较短。 WEB服务器完成网页请求这样的任务,使用线程池技术是非常合适的。因为单个任务小,而任务数量巨大,你可以想象一个热门网站的点击次数。 但对于长时间的任务,比如一个Telnet连接请求,线程池的优点就不明显了。因为Telnet会话时间比线程的创建时间大多了。
2.对性能要求苛刻的应用,比如要求服务器迅速响应客户请求。
3.接受突发性的大量请求,但不至于使服务器因此产生大量线程的应用。突发性大量客户请求,在没有线程池情况下,将产生大量线程,虽然理论上大部分操作系统线程数目最大值不是问题,短时间内产生大量线程可能使内存到达极限,出现错误.
线程池的种类:
线程池示例:
1.创建固定数量线程池,循环从任务队列中获取任务对象,
2.获取到任务对象后,执行任务对象中的任务接口
Thread.hpp
以下是自己封装实现的线程
#pragma once #include <iostream> #include <string> #include <functional> #include <cstring> #include <cassert> #include <pthread.h> namespace ThreadNs { typedef std::function<void *(void *)> func_t; const int num = 1024; class Thread { private: static void *start_routine(void *args) { Thread *td = static_cast<Thread *>(args); return td->callback(); } public: Thread() { char buffer[num]; snprintf(buffer, sizeof buffer, "
聚类是一种无监督学习方法,用于将数据集划分为几个不同的组或簇,使得同一组中的数据项具有相似性,而不同组之间的数据项具有差异性。MATLAB是一种广泛使用的编程语言和开发环境,可用于实现各种机器学习算法,包括聚类算法。
在MATLAB中,可以使用kmeans函数进行聚类。kmeans函数的基本语法如下:
matlab
[cluster_idx, cluster_center] = kmeans(data, k) 其中,data是输入数据,k是要划分的簇的数量。该函数返回两个输出:cluster_idx是一个n×1的向量,表示每个数据点的簇标签;cluster_center是一个k×p的矩阵,表示每个簇的中心点。
下面是一个简单的示例代码,演示如何在MATLAB中使用kmeans函数进行聚类,并为每行数据添加标签:
matlab % 读取数据 data = rand(84, 8); % 示例数据,您需要替换为您自己的数据 % 聚类数据 [cluster_idx, cluster_center] = kmeans(data, 2); % 显示聚类结果 figure; gscatter(data(:,1), data(:,2), cluster_idx); hold on; plot(cluster_center(:,1), cluster_center(:,2), 'kx'); % 聚类中心点 hold off; % 为每一行数据添加标签 labels = arrayfun(@(x) num2str(x), cluster_idx, 'UniformOutput', false); labels = cell2mat(labels'); 在上面的代码中,首先读取了一个84x8的随机数据集。然后使用kmeans函数进行聚类,将数据集划分为两个簇。接着使用gscatter函数显示聚类结果,并使用plot函数绘制聚类中心点。最后使用arrayfun和num2str函数为每一行数据添加标签。
目录
一、部署nginx01、nginx02
二、keepalived配置(抢占模式、master- backup模式)
三、测试
四、非抢占模式(backup-backup模式)
nginx01 11.0.1.31nginx0211.0.1.32虚拟IP(VIP)11.0.1.30 一、部署nginx01、nginx02 部署nginx:Nginx、keepalived安装详细步骤_keepalive 安装-CSDN博客
先部署一台,另一台直接克隆改ip就可以
二、keepalived配置(抢占模式、master- backup模式) keepalived配置文件路径 /etc/keepalived/keepalived.conf
主机 11.0.1.31 需要更改的参数:router_id、interface ens33、真实IP mcast_src_ip 、虚拟IP11.0.1.30、优先级priority(master需要比backup高)
global_defs { router_id nginx-01 #标识本节点的名称,通常为hostname } ## keepalived会定时执行脚本并对脚本执行的结果进行分析,动态调整vrrp_instance的优先级。 ##如果脚本执行结果为0,并且weight配置的值大于0,则优先级相应的增加。如果脚本执行结果非0, ##并且weight配置的值小于 0,则优先级相应的减少。其他情况,维持原本配置的优先级,即配置文件中priority对应的值。 vrrp_script chk_nginx { script "/etc/keepalived/nginx_check.sh" interval 2 #每2秒检测一次nginx的运行状态 weight -20 #失败一次,将自己的优先级-20 } vrrp_instance VI_1 { state MASTER # 状态,主节点为MASTER,备份节点为BACKUP interface ens33 # 绑定VIP的网络接口,通过ifconfig查看自己的网络接口 virtual_router_id 51 # 虚拟路由的ID号,两个节点设置必须一样,可选IP最后一段使用,相同的VRID为一个组,他将决定多播的MAC地址 mcast_src_ip 11.0.1.31 # 本机IP地址 priority 100 # 节点优先级,值范围0~254,MASTER要比BACKUP高 advert_int 1 # 组播信息发送时间间隔,两个节点必须设置一样,默认为1秒 # 设置验证信息,两个节点必须一致 authentication { auth_type PASS auth_pass 1111 } # 虚拟IP,两个节点设置必须一样。可以设置多个,一行写一个 virtual_ipaddress { 11.
文章目录 STL容器算法迭代器初识Vector存放自定义数据类型Vector容器嵌套容器string构造函数string赋值操作string字符串拼接string查找和替换string字符串比较string字符存取string插入和删除string子串 STL STL(Standard Template Library),即标准模板库。C++的面向对象和泛型编程思想,目的就是复用性的提升, 数据结构和算法都未能有一套标准,导致被迫从事大量重复工作,为了建立数据结构和算法的一套标准,诞生了STL,从而实现STL的一个重要特点是数据结构和算法的分离。
STL大体分为六大组件,分别是:容器、算法、迭代器、仿函数、适配器(配接器)、空间配置器
容器:各种数据结构,如vector、list、deque、set、map等,用来存放数据。算法:各种常用的算法,如sort、find、copy、for_each等迭代器:扮演了容器与算法之间的胶合剂。仿函数:行为类似函数,可作为算法的某种策略。适配器:一种用来修饰容器或者仿函数或迭代器接口的东西。空间配置器:负责空间的配置与管理。 1、容器:置物之所也
STL容器就是将运用最广泛的一些数据结构实现出来
常用的数据结构:数组, 链表,树, 栈, 队列, 集合, 映射表等。
这些容器分为序列式容器和关联式容器两种:
序列式容器:强调值的排序,序列式容器中的每个元素均有固定的位置。
关联式容器:二叉树结构,各元素之间没有严格的物理上的顺序关系。
2、算法:问题之解法也
有限的步骤,解决逻辑或数学上的问题,这一门学科我们叫做算法(Algorithms)。
算法分为:质变算法和非质变算法。
质变算法:是指运算过程中会更改区间内的元素的内容。例如拷贝,替换,删除等等。
非质变算法:是指运算过程中不会更改区间内的元素内容,例如查找、计数、遍历、寻找极值等等。
3、迭代器:容器和算法之间粘合剂。
提供一种方法,使之能够依序寻访某个容器所含的各个元素,而又无需暴露该容器的内部表示方式。
每个容器都有自己专属的迭代器。
迭代器使用非常类似于指针,初学阶段我们可以先理解迭代器为指针。
容器算法迭代器初识 容器: vector
算法: for_each
迭代器: vector<int>::iterator
#include <vector> #include <algorithm> //标准算法头文件 //vector容器存放内置数据类型 void myPrint(int val) { cout << val << endl; } void test01() { //创建了一个vector容器,数组 并且通过模板参数指定容器中存放的数据类型 vector<int> v; //向容器中插入数据 v.push_back(10); v.push_back(20); v.push_back(30); v.push_back(40); //通过迭代器访问容器中的数据 vector<int >::iterator itBegin = v.
一.题目 二.分析与思路 编写一个函数实现计算an,再遍历判断即可
三.代码实现 #include<bits/stdc++.h>//万能头 int f(int n){ if(n<=2)return n+1; else return (n-1)*(n-1)+3*(n-2)+1; }//an函数 int main() { int m,k; scanf("%d%d",&m,&k); int m1=0;//整除m个数 int m2=0;//余数等于一的个数 int m3=0;//余数大于一的个数 for(int i=0;i<k;i++){ if(f(i)%m==0)m1++;//判断是否整除 else if(f(i)%m==1)m2++;//判断余数是否为一 else if(f(i)%m>1)m3++;//判断余数是否大于一 } printf("%d %d %d",m1,m2,m3); return 0; } 四.评价 基础题,应该掌握!!