这篇文章是用来讲解Resnet(残差网络)代码的,结合代码理解残差网络结构。
目录
Bottleneck类
Conv3×3
Conv1×1 BasicBlock ResNet
_make_layer代码解析
完整的ResNet代码:
可以直接调用torch内置的resnet官方代码。
from torchvision.models import resnet50 model = resnet50() print("model:", model) 不论是调用resnet50还是resnet101,这些模型都是调用的Resnet模型。因此我们仅需要看这个类就可以。
在ResNet这个类中又由Bottleneck(瓶颈层)、3×3卷积层、1×1卷积层、BasicBlock组成。接下来将逐步解释。
Bottleneck类 拼劲层这个类在resnet50及之后的系列用这个,resnet18、resnet34用BasicBlock
参数说明:
expansion=4:Bottleneck的输出通道数是输入通道数的4背
inplanes:输入通道数
planes:输出通道数
stride:步长
downsample:下采样
groups:分组卷积
base_width:卷积块宽度
dilation:空洞卷积
nor_layer:是否传入norm_layer
class Bottleneck(nn.Module): # Bottleneck in torchvision places the stride for downsampling at 3x3 convolution(self.conv2) # while original implementation places the stride at the first 1x1 convolution(self.conv1) # according to "Deep residual learning for image recognition"https://arxiv.org/abs/1512.03385. # This variant is also known as ResNet V1.
7-3 定义接口(Biology、Animal)、类(Person)、子类(Pupil)(分数 30)
(1)定义Biology(生物)、Animal(动物)2个接口,其中Biology声明了抽象方法breathe( ),Animal声明了抽象方法eat( ) 和 sleep( )。
(2)定义一个类Person(人)实现上述2个接口,实现了所有的抽象方法,同时自己还有一个方法think( )。breathe()、eat()、sleep()、think()四个方法分别输出:
我喜欢呼吸新鲜空气
我会按时吃饭
早睡早起身体好
我喜欢思考
(3)定义Person类的子类Pupil(小学生),有私有的成员变量school(学校),公有的成员方法setSchool( )、getSchool( ) 分别用于设置、获取学校信息。
(4)在测试类Main中,用Pupil类创建一个对象zhangsan。尝试从键盘输入学校信息给zhangsan,获取到该信息后输出该学校信息,格式为“我的学校是XXX”;依次调用zhangsan的breathe()、eat()、sleep()、think()方法。
输入格式:
从键盘输入一个学校名称(字符串格式)
输出格式:
第一行输出:我的学校是XXX(XXX为输入的学校名称)
第二行是breathe()方法的输出
第三行是eat()方法的输出
第四行是sleep()方法的输出
第五行是think()方法的输出
输入样例:
在这里给出一组输入。例如:
新余市逸夫小学
输出样例:
在这里给出相应的输出。例如:
我的学校是新余市逸夫小学
我喜欢呼吸新鲜空气
我会按时吃饭
早睡早起身体好
我喜欢思考
import java.util.Scanner; //定义两个接口 interface Biology { void breathe(); //定义一个抽象方法 } interface Animal { void eat(); //定义两个抽象方法 void sleep(); } class Person implements Biology,Animal { //实现上述接口 public Person() { } //实现所有抽象方法 public void breathe() { System.
1.缘起: 为啥想学习es,主要是在工作中会用到,但是因为不了解原理,所以用起来畏手畏脚的,就想了解下es是怎么存储数据,以及es是怎么搜索数据的,我们平时应该如何使用es,以及使用时候需要注意的方面。
es:https://github.com/elastic/elasticsearch
lucene:https://github.com/apache/lucene.git
2.es的一些基础概念 es是一个基于lucence的分布式的搜索引擎,它使用java编写,并提供了一套RESTful api,是一款流行的企业级搜索引擎
2.1 es的特点 横向可扩展性: 作为大型分布式集群, 很容易就能扩展新的服务器到ES集群中; 也可运行在单机上作为轻量级搜索引擎使用.更丰富的功能: 与传统关系型数据库相比, ES提供了全文检索、同义词处理、相关度排名、复杂数据分析、海量数据的近实时处理等功能.分片机制提供更好地分布性: 同一个索引被分为多个分片(Shard), 利用分而治之的思想提升处理效率.高可用: 提供副本(Replica)机制, 一个分片可以设置多个副本, 即使在某些服务器宕机后, 集群仍能正常工作.开箱即用: 提供简单易用的API, 服务的搭建、部署和使用都很容易操作. 2.2 es的重要概念 1.cluster(集群)
可以通过为多个节点配置同一个集群名来创建集群,通过elasticsearch.yml文件配置。
2.node(节点)
运行了单个es实例的主机被成为节点,一个集群里会包含一个或者多个节点。可以用来存储数据,搜索数据,操作数据。有三个主节点,三个数据节点。
3.shard(分片)
一个索引会分成多个分片,并存储在不同的节点中。每个shard都是一个最小工作单元,承载部分数据,对应一个lucene实例,具有完整的建立索引和处理请求的能力。shard分为primary shard和replica shard,其中replica shard 负责容错,以及承担读请求负载。一个document只会存在一个primary shard及其replica shard中,而不会存在于多个primary shard中。shards:5*2,表示有五个primary shard 以及五个replica shard。一旦创建完成,其primary shard的数量将不可更改。
4.index(索引)
一堆类型数据结构相同的document的集合。类似于数据库中的表
5.document( 文档)
es中的最小数据单元。比如一条纠纷单的数据,存在es中就是一个document。但是存储格式为json。类似于数据库中的一行数据。
6.type
类型,一个索引会存在一个或者多个 type,一个type下的document有相同的field。7.x后废弃
7.field
一个field就是一个数据字段
8.term
field的内容在经过analyze后,会被分词为term,是数据中最小的存储单位
9.数据库和es概念类比Elasticsearch 关系型数据库
3.es是如何存储数据的 3.1 es写入数据过程 用户发送的请求会随机打到某一node,此时这个node为coordinate nodecoordinate node通过路由策略找到对应的主分片 shard = hash(routing) % number_of_primary_shards,其中routing为docId,如果docId不存在,es会生成一个id来实现路由。主分片也会把请求转发到副本分片,实现数据备份。索引的primary shards在索引创建后不可更改也是因为路由策略,举个例子,对于同一个docId,原本存在primary shard 0 中,但是primary shard num修改后,就被路由到primary shard 3,这样就出现数据查不到的情况了。主分片&副本分片会构建索引以及将索引落盘 3.
目录
10、查询学过编号为"01"但是没有学过编号为"02"的课程的同学的信息:
11、查询没有学全所有课程的同学的信息:
12、查询至少有一门课与学号为"01"的同学所学相同的同学的信息:
13、查询和"01"号的同学学习的课程完全相同的其他同学的信息:
14、查询没学过"张三"老师讲授的任一门课程的学生姓名:
15、查询两门及其以上不及格课程的同学的学号,姓名及其平均成绩:
16、检索"01"课程分数小于60,按分数降序排列的学生信息:
17、按平均成绩从高到低显示所有学生的所有课程的成绩以及平均成绩:
18、查询各科成绩最高分、最低分和平均分:以如下形式显示:课程ID,课程name,最高分,最低分,平均分,及格率,中等率,优良率,优秀率:
19、按各科成绩进行排序,并显示排名(实现不完全):
10、查询学过编号为"01"但是没有学过编号为"02"的课程的同学的信息: SELECT student.s_id, s_name, s_birth, s_sex FROM student, score sc1 WHERE student.s_id = sc1.s_id AND sc1.c_id = '01' AND NOT EXISTS (SELECT * FROM score sc2 WHERE student.s_id = sc2.s_id AND sc2.c_id = '02'); 11、查询没有学全所有课程的同学的信息: SELECT * FROM student WHERE EXISTS (SELECT * FROM course WHERE NOT EXISTS (SELECT * FROM score WHERE score.s_id = student.s_id AND score.c_id = course.
目录
题目描述:
分析:
链式前向星:
预处理lg数组:
DFS求解深度depth和fa数组:
LCA:
完整代码:
样例:
题目描述: 如题,给定一棵有根多叉树,请求出指定两个点直接最近的公共祖先。
输入格式
第一行包含三个正整数 N, M, S,分别表示树的结点个数、询问的个数和树根结点的序号。
接下来 N - 1 行每行包含两个正整数 x, y,表示 x 结点和 y 结点之间有一条直接连接的边(数据保证可以构成树)。
接下来 M 行每行包含两个正整数 a, b,表示询问 a 结点和 b 结点的最近公共祖先。
输出格式
输出包含 M 行,每行包含一个正整数,依次为每一个询问的结果。
分析: 使用暴力循环判断的方法一定会超时,故可使用倍增LCA,即一次性可以跳 2 ^ i 个,而不是一个一个向上跳,减少了时间空间开销。
链式前向星: void add(int x, int y) { //存储与x相连的下一个节点 e[++tot].t = y; //存储以x为首的上一条边 e[tot].next = head[x]; //记录编号,这是第几条边 head[x] = tot; } 预处理lg数组: //若(1 << lg[i - 1]) == i,则使得lg[i] + 1 //否则,lg[i] = lg[i - 1] //eg.
路漫漫其修远兮,吾将上下而求索
文章目录 一、TCP报头结构
二、TCP确认应答机制 那么网络中为什么会出现先发后至的情况呢?
三、超时重传 四、连接管理 1.TCP三次握手(建立连接)
2.TCP四次挥手(断开连接)
五、滑动窗口 1.返回的ACK丢了 数据到达了 2.发送的数据丢了 自然也不会有ACK
六、流量控制
七、拥塞控制
八、延迟应答
九、捎带应答
十、面向自字节流
十一、异常情况
一、TCP报头结构 二、TCP确认应答机制 我们知道TCP的特点:
有连接传输
面相字节流
提供可靠传输
全双工
有接收缓冲区和发送缓冲器
那么TCP中是如何保证数据的可靠性呢??(尽可能的传过去 不管成功不成功都有个应答)
核心机制就在 接收方收到或者没收到 都会有个应答 这就是TCP 的确认应答机制
为了解决上述的先发后至的这种问题 TCP中使用确认序号来保证数据传输的前后顺序
TCP会针对每一个字节来编号 比如说 这里发送的在不在? 占有1000字节 那么前1000字节就是数据 那么你前面发来的数据就必须是<1001序列号的数据 以此类推
那么网络中为什么会出现先发后至的情况呢? 因为网络中的数据 不一定都是直接到达目的地的 往往要经过很多的设备进行转发 这就好比结婚时候的车队 比如说这个车队有1000辆车 一整个车队就是你的数据 当开始的时候 所有的婚车都开了 他们不能保证还是按照原来的顺序挨个排列到我的目的地 往往是一出发 就各走各的 到了目的地再整合一下队伍 TCP上的数据也是这样传输的 我们不管数据是怎么传输的 只要到接受缓冲器后 按照我们的序列号进行1-1000的排序 等到所有数据都到了之后 才是正式到达
三、超时重传 当我们的前面的传输没有问题之后 ,如果遇到了丢包?那我的客户端或者服务器就有一方收不到ack或者是数据 这时候就造成了数据丢失 这样就叫做丢包
那么TCP是如何解决丢包问题的呢?? TCP使用超时重传来解决丢包问题
🔵前提引入 :
1如果一个类中什么成员都没有,称为空类,但空类并非什么都没有,在我们没有写任何东西时,编译器会自动生成6个默认成员函数。
2.默认成员函数 : 用户没有显式实现,编译器会自动生成的函数,称为默认成员函数。
🔴构造函数:
在编写代码时,通常遇到需要初始化的变量,对象等。若每次都初始化,是不是太麻烦了,我想在对象创建时就初始化,所以提出了构造函数这一特殊的成员函数。
🔺构造函数是一个特殊的成员函数,名字与类名相同,创建类类型对象时由编译器自动调用,以保证每个数据成员都有 一个合适的初始值,并且在对象整个生命周期内只调用一次
构造函数是特殊的成员函数,需要注意的是,构造函数虽然名称叫构造,但是构造函数的主要任务并不是开空间创建对象,而是初始化对象。
🔻其特征如下:
1. 函数名与类名相同。
2. 无返回值。
3. 对象实例化时编译器自动调用对应的构造函数。
4. 构造函数可以重载。
#include<iostream> using namespace std; class time { public: { time() { h=0; m=0; s=0; } } private://内置类型 int h; int m; int s; } class date { public: date()//不带参的构造函数 { ; } date(int year, int month, int day)//带参的构造函数 { _year = year; _month = month; _day = day; } private://内置类型 int _year; int _month; int _day; time _t;//自定义类型 }; int main() { date T1();//调用无参构造函数 date T2(2023 , 4, 15);//调用有参构造函数 } 如果类中没有显式定义构造函数,则C++编译器会自动生成一个无参的默认构造函数,一旦用户显式定义编译器将不再生成。
文章目录 简介代码运行效果备注 简介 用python代码画出汤姆劈树名场面,仅使用turtle库。如下:
绘画过程可以在下列平台查看:
抖音:汤姆这个名场面太搞笑了,画出来!
b站:汤姆劈树名场面太搞笑了,35秒画出来!_哔哩哔哩_bilibili
代码 # coding=gbk import turtle def plotLine(points, pencolor=None, width=None, speed=None): ''' 功能:画折线 参数: - points : 一系列点,用列表或元组表示 - pencolor : 画笔颜色,默认不变 - width : 画笔宽度,默认不变 - speed : 绘制速度,默认不变 ''' # 记录旧参数 oldpencolor = turtle.pencolor() oldwidth = turtle.width() oldspeed = turtle.speed() # 修改新参数 if pencolor is not None: turtle.pencolor(pencolor) if width is not None: turtle.width(width) if speed is not None: turtle.speed(speed) # 绘制折线 turtle.
文章目录 简介代码运行效果备注 简介 用python代码画出麻衣学姐,仅使用turtle库。如下:
绘画过程可以在下列平台查看:
抖音:只需35秒!就可代码画出麻衣学姐!
b站:只需35秒!就可代码画出麻衣学姐!_哔哩哔哩_bilibili
代码 # coding=gbk import turtle def plotLine(points, pencolor=None, width=None, speed=None): ''' 功能:画折线 参数: - points : 一系列点,用列表或元组表示 - pencolor : 画笔颜色,默认不变 - width : 画笔宽度,默认不变 - speed : 绘制速度,默认不变 ''' # 记录旧参数 oldpencolor = turtle.pencolor() oldwidth = turtle.width() oldspeed = turtle.speed() # 修改新参数 if pencolor is not None: turtle.pencolor(pencolor) if width is not None: turtle.width(width) if speed is not None: turtle.speed(speed) # 绘制折线 turtle.
文章目录 SpringBoot实现热部署手动开启热部署自动开启热部署热部署相关配置 SpringBoot实现热部署 什么是热部署?
所谓热部署,就是在应用正在运行的时候升级软件,却不需要重新启动应用。对于Java应用程序来说,热部署就是在运行时更新Java类文件。
热部署有什么用?
节约时间,热部署只需要重新更新一下改动过的class文件,不需要全部再编译一遍提高开发效率,热部署对于静态资源能够实现实时更新,不需要再重启项目 手动开启热部署 之前在SSM中我们热部署,是通过勾选两个选项就实现了:
而在SpringBoot首先我们需要通过热部署依赖实现热部署:(Step1)
<!--热部署依赖--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> </dependency> <!-- 配置插件,让热部署依赖spring-boot-devtools生效 备注:一般这个插件在我们创建SpringBoot项目时就自带了,不需要手动引入,所以我们只需要导入热部署依赖就行了 --> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <configuration> <!-- 设置为true,让热部署devtools生效 --> <fork>true</fork> <addResources>true</addResources> </configuration> </plugin> 然后每次当我们修改了代码(Step2)后,我们需要点击构建项目:(Step3)
这样就不需要重启项目了
知识拓展:重启和重载
重启(Restart):自定义开发代码,包含类、页面、配置文件等,加载位置restart类加载器重载(ReLoad):jar包,加载位置base类加载器 重新运行项目也就是重启项目包括了Restart过程和ReLoad过程,而热部署只包含Restart过程,所以热部署要比重启要快得多
自动开启热部署 前面我们学习了手动开启热部署,每次都需要手动点击,这显得很麻烦,这里我们将学习如何让IDEA自动启动热部署(也就是定时热部署,一般是鼠标停止五秒中就会热部署一次)
注意:自动开启热部署,也是需要引入热部署依赖的
Step1:勾选自动构建项目
Step2:勾选热部署配置项
温馨提示:如果使用的是IDEA 2021.2之前版本的话还是使用快捷键Shift+Ctrl+Alt+/,选择Registry...,将compiler.automake.allow.when.app.running选项勾上(这里我使用的是2022版的IDEA,与2021版IDEA的配置不同)
注意:汉化后的IDEA这个选项的位置发生了变化
Step3:
IDEA鼠标悬停5秒不动,IDEA就会自动开启热部署
热部署相关配置 通过修改项目中的文件,你可以发现其实并不是所有的文件修改都会激活热部署的,原因在于在开发者工具中有一组配置,当满足了配置中的条件后,才会启动热部署,配置中默认不参与热部署的目录信息如下:
/META-INF/maven/META-INF/resources/resources/static/public/templates 以上目录中的文件如果发生变化,是不参与热部署的。如果想修改配置,可以通过application.yml文件进行设定哪些文件不参与热部署操作,如果想添加不参与热部署的文件或文件夹,可以通过下面的配置:
spring: devtools: restart: # 设置不参与热部署的文件或文件夹 exclude: static/**,public/**,config/application.yml # 关闭或开启热部署(false表示关闭) enable: false 知识拓展: 配置文件优先级
在resource下的配置文件中选择关闭热部署,可以会在其它地方打开,比如在 resource/config/ 下的配置文件中开启了热部署,又或者在file下的配置文件,又或者是file下config下的配置文件中开启了热部署,这是由于其它三个配置文件的优先级要高于resource下的配置文件,我们可以通过设置临时属性来提高优先级,也可以通过设置Java系统属性值,相关知识详情可以参考:SpringBoot运维篇学习笔记
文章目录 简介代码运行效果备注 简介 今天写一个Python代码,绘制喜羊羊,仅使用Python的turtle库。如下:
绘画过程可以在下列平台查看:
抖音:懒羊羊心目中的男神
b站:懒羊羊心目中的男神_哔哩哔哩_bilibili
代码 # coding=gbk import turtle def plotLine(points, pencolor=None, width=None, speed=None): ''' 功能:画折线 参数: - points : 一系列点,用列表或元组表示 - pencolor : 画笔颜色,默认不变 - width : 画笔宽度,默认不变 - speed : 绘制速度,默认不变 ''' # 记录旧参数 oldpencolor = turtle.pencolor() oldwidth = turtle.width() oldspeed = turtle.speed() # 修改新参数 if pencolor is not None: turtle.pencolor(pencolor) if width is not None: turtle.width(width) if speed is not None: turtle.speed(speed) # 绘制折线 turtle.
大家好,我是三叔,很高兴这期又和大家见面了,一个奋斗在互联网的打工人。
在 Java 开发中,经常需要对 List 中的对象进行一些操作,例如对某个字段进行过滤、排序等。而 Java 8 中引入的 Stream API 提供了一种更加便捷的方式来处理 List 中的对象,使得代码更加简洁、优雅。本篇博客将介绍如何使用 Stream 将对象 List 中的某个字段放到新 List 中,以及相关的代码示例。
Stream API 有两个主要的类:Stream 和 Collectors。Stream 表示一个数据流,可以对其进行操作,而 Collectors 可以将 Stream 转换为其他类型的集合,如 List、Set、Map 等。
需要操作的对象类:
@Data public class ApplicationVO { // 项目id(唯一) private String appId; // 项目名 private String name; // 业务字段 ... public ApplicationVO() { } public ApplicationVO(String appId, String name) { this.appId = appId; this.name = name; } } 我们想要将 ApplicationVO对象的 name 字段提取出来,放到一个新的 List 中。使用 Stream API 可以轻松实现这个功能:
【Spring源码系列- IOC】
1
【Spring源码】0.安装Gradle环境
2
【Spring源码】1.下载与编译_pom relocation to an other version number is not f
3
【Spring源码】2.试个水先~Debug找到传说中的三级缓存(图解向,堆图预警)
4
【Spring源码】3. xml文件如何转换成BeanDefinition(主要涉及prepareRefresh()+ obtainFreshBeanFactory()两个函数,图解向,堆图预警)_spring xml转bean
5
【Spring源码】4. 自己搞个标签?~自定义标签保姆级全过程(图解向,堆图预警)
6
【Spring源码】5.spring的bean工厂准备工作(prepareBeanFactory(beanFactory)
7
【Spring源码】6. Spring扩展自定义属性编辑器保姆级教程
8
【Spring源码】7. 如何添加自定义的BeanFactoryPostProcessor
9
【Spring源码】8. 捋下invokeBeanFactoryPostProcessors()主要处理流程
10
【Spring源码】9. 超级重要的ConfigurationClassPostProcessor
11
【Spring源码】10. 递归调用的processConfigurationClass()方法
12
【Spring源码】11. 我是注解类不?checkConfigurationClassCandidate()注解类判断方法详解
13
【Spring源码】12. 注册bean处理器registerBeanPostProcessors()
14
【Spring源码】13. 国际化处理initMessageSource()源码解析
【补充内容】【保姆级】SpringBoot项目中的i18n国际化
15
【Spring源码】14. 消息多播器(观察者模式)
【补充内容】【保姆级示例向】观察者模式
16
【Spring源码】15. Bean的创建过程(1.概述篇)
17
【Spring源码】16. Bean的创建过程(2)
18
【Spring源码】17.创建Bean这篇认真的@(・●・)@
【补充内容】
【保姆级·创建对象】如何通过Supplier创建对象
【保姆级·创建对象】如何通过factory-method创建对象
【保姆级·创建对象】如何利用resolveBeforeInstantiation()在预处理阶段返回一个Bean的实例对象
19
Visual Studio Code,或者称作VS Code,是一个广为人知且评价很高的代码编辑器,它有许多特性和扩展功能,以增强开发体验。使用VS Code的主要好处之一是它的灵活性,允许开发人员根据自己的特定需求进行自定义。
此外,VS Code还非常轻便快速,适合处理大型项目或者资源有限的情况,它包含了调试工具、终端和Git集成等功能,使其成为开发人员的全能选择。
不仅如此,在Visual Studio Marketplace中还有众多VS Code扩展可供选择,这使它成为开发者社区中的领先IDE。这些扩展可以帮助开发人员编写整洁且无bug的代码,让开发人员的生活更加愉悦。
下面我们将按照以下类别列出顶级的Visual Studio Code扩展:
增加工作效率的VS Code扩展
代码片段的颜色扩展
版本控制的VS Code扩展
代码格式化和linting的VS Code扩展
调试和故障排除的VS Code扩展
针对javascript、react、java、html和css的VS Code扩展
让我们开始吧!
一、以下是针对提高生产力的VS Code扩展
1、GraphQL GraphQL Visual Studio Code 扩展提供了一系列工具,帮助您编写、验证和测试 GraphQL 代码。GraphQL 扩展包括自动完成功能,建议您在输入时使用的字段和参数,使编写有效的 GraphQL 代码更加容易。这个功能可以节省时间,减少语法错误的可能性。
该扩展还带有内置的linter,可以检查您的代码中的错误并建议修复方法。使用此扩展可以避免 GraphQL 错误,提高效率。
2、Remote-SSH 您可以使用VS Code扩展从安全的角度连接到远程服务器,而不需要额外的软件或终端窗口。Remote-SSH 允许您在熟悉的 Visual Studio Code 界面内轻松访问、编辑和传输文件到和从远程服务器。您可以充分利用 Visual Studio Code 的能力,而不受本地设置的限制,能够在远程机器上运行命令、调试代码,甚至使用扩展功能。
Remote-SSH是一个必不可少的VS Code扩展。尝试使用它来发现使用VS Code扩展远程工作的强大和方便。这不仅可以简化您的工作流程,还可以提高您的整体生产力。
3、Settings Sync 开发人员经常使用文本编辑器创建 Web 应用程序。手动在多个设备之间维护相同的设置非常不方便。手动同步设置也可能耗费大量时间,并且在多个设备上提供不一致的体验。
使用Settings Sync VS Code扩展,您可以轻松地在多个设备之间同步设置,减少配置时间,甚至与他人共享设置。
4、Auto Rename Tag VS Code可以自动突出显示匹配的标签,并在使用开标签时添加闭标签。Auto Rename Tag扩展可以在您编写代码时重命名更改的标签。例如:
目录
1.统一用户的的登录权限校验
最开始的用户登录
Spring拦截器
2.统一数据返回格式
统一数据的返回格式意义
统一数据返回格式的实现
3.统一异常处理
在上篇博客中我介绍了Spring AOP的基础知识,这篇博客则是AOP的实践练习,通过借助AOP实现三个目标
1.统一用户登录权限的校验
2.统一数据的返回格式
3.统一异常处理
接下来我们一个一个来实现
1.统一用户的的登录权限校验 最开始的用户登录 在实现统一用户登录之前先回顾一下之前如何判断用户登录的
@RestController @RequestMapping("/user") public class UserController { /** * 某⽅法 1 */ @RequestMapping("/m1") public Object method(HttpServletRequest request) { // 有 session 就获取,没有不会创建 HttpSession session = request.getSession(false); if (session != null && session.getAttribute("userinfo") != null) { // 说明已经登录,业务处理 return true; } else { // 未登录 return false; } } } 可以看到为完成登录校验判断就需要在方法中单独写判断方法,封装成公共方法也需要进行调用,如果校验方法修改那么所有调用都需要修改,这将大大增加代码的维护成本,并且这些登录校验代码与所要写的业务代码并无关系但还是需要写出来,所以就需要提供AOP来解决这个问题
当想使用Spring AOP的环绕方法解决问题时我们发现无法获取到HttpSession对象并且有一些方法是不需要拦截的,此时无法准确使用切点定义拦截规则,如何接解决问题呢?可以使用Spring拦截器
Spring拦截器 Spring提供了拦截器:HandlerInterceptor,拦截器实现分为两个步骤
本地使用Vagrant搭建开发环境 搭建虚拟机开发环境软件安装安装VirtualBox安装Vagrant 软件配置配置VirtualBox虚拟机存放位置 配置Vagrant虚拟机镜像文件存放位置下载虚机镜像CentOSUbuntu添加Box Vagrant 基本操作新建虚拟机启动虚机查看虚拟机状态连接虚机停止虚拟机暂停虚机恢复虚机重载虚机删除虚机 搭建虚拟机开发环境 在不使用docker开发环境的场景下,如果想在个人电脑上安装虚拟机来搭建开发/测试环境,Vagrant 是一个不错的选择。
软件安装 由于Vagrant是使用VirtualBox的基本环境,所以也需要安装VirtualBox
安装VirtualBox 进入 VirtualBox 的主页,点击大大的下载按钮,即可进入下载页面。
VirtualBox 是一个跨平台的虚拟化工具,支持多个操作系统,根据自己的情况选择对应的版本下载即可。
注意,除了主程序,还要把对应的扩展包程序也一并下载了。有些高级特性,比如 USB 3.0 等需要扩展包的支持。
在安装完主程序后,直接双击扩展包文件即可安装扩展包。
安装Vagrant 在 Vagant 网站下载最新的版本,根据自己的操作系统选择对应的版本下载即可。
注意,Vagrant 是没有图形界面的,所以安装完成后也没有桌面快捷方式。具体使用方法,接下来会详细说明。
Vagrant 的安装程序会自动把安装路径加入到 PATH 环境变量,所以,这时候可以通过命令行执行 vagrant version 检查是否安装成功:
C:\Users\Administrator>vagrant version Installed Version: 2.3.4 Latest Version: 2.3.4 You're running an up-to-date version of Vagrant! 软件配置 配置VirtualBox 虚拟机存放位置 VirtualBox安装之后需要打开软件,配置虚机的存放位置,尽量放在一个空间较大的位置
配置Vagrant 虚拟机镜像文件存放位置 通过 Vagrant 创建虚机需要先导入镜像文件,也就是 box,它们默认存储的位置在用户目录下的 .vagrant.d 目录下,对于 Windows 系统来说,就是 C:\Users\用户名.vagrant.d。
如果后续可能会用到较多镜像,或者你的 C 盘空间比较紧缺,可以通过设置环境变量 VAGRANT_HOME 来设置该目录。
介绍 unity更改帧率的方法
方法一 通过编辑器更改帧率:
a. 在Unity编辑器中,选择“Edit”(编辑)菜单,然后选择“Project Settings”(项目设置)。
b. 在“Project Settings”中选择“Time”(时间)选项卡。
c. 在“Time”选项卡中,将“Fixed Timestep”(固定时间步)选项设置为所需的帧率。默认值为0.02秒,即每秒50帧。
方法2 脚本设置帧率
public float globalFrameRate = 100f; void Update() { Application.targetFrameRate = globalFrameRate; }
求三维坐标系的旋转矩阵通常需要求分别沿3个坐标轴的二维坐标系下的旋转矩阵,二维坐标系下的旋转矩阵的推导过程通常以某一点逆时针旋转 θ \theta θ角度进行推理。以下将通过此例来详细讲解二维坐标系下的旋转矩阵推导过程,并进一步给出其他方式的旋转矩阵。
一、二维坐标中点的旋转变换 点的旋转矩阵(逆时针旋转) 已知点 P ( x , y ) P(x, y) P(x,y),将该点以逆时针方向旋转 θ \theta θ角度后得到点 P ′ ( x ′ , y ′ ) P^{\prime}(x^{\prime}, y^{\prime}) P′(x′,y′),如下图所示。求由点 P P P到点 P ′ P^{\prime} P′的旋转矩阵。
设半径为 r r r,由图可以分别得到以下三角公式:
对于点 P ( x , y ) P(x, y) P(x,y)
x = r cos α y = r sin α (1) \begin{aligned} & x=r \cos \alpha \\ & y=r \sin \alpha \end{aligned} \tag{1} x=rcosαy=rsinα(1)对于点 P ′ ( x ′ , y ′ ) P^{\prime}(x^{\prime}, y^{\prime}) P′(x′,y′)
# pip install tensorflow==2.12.0 numpy==1.24.2 matplotlib==3.7.1 -i https://mirrors.aliyun.com/pypi/simple/ # 此笔记本(notebook)使用评论文本将影评分为积极(positive)或消极(nagetive)两类。 # 这是一个二元(binary)或者二分类问题,一种重要且应用广泛的机器学习问题。 # 我们将使用来源于网络电影数据库(Internet Movie Database)的 IMDB # 数据集(IMDB dataset),其包含 50,000 条影评文本。从该数据集切割出的25,000条评论用作训练, # 另外 25,000 条用作测试。训练集与测试集是平衡的(balanced),意味着它们包含相等数量的积极和消极评论。 # 此笔记本(notebook)使用了 tf.keras,它是一个 Tensorflow 中用于构建和训练模型的高级API。 # 有关使用 tf.keras 进行文本分类的更高级教程,请参阅 MLCC文本分类指南 # (MLCC Text Classification Guide)。 import tensorflow as tf from tensorflow import keras # import numpy as np print("tensorflow verion: ",tf.__version__) print("tensorflow verion: ",tf.__version__) # 下载 IMDB 数据集 # IMDB 数据集已经打包在 Tensorflow 中。该数据集已经经过预处理, # 评论(单词序列)已经被转换为整数序列,其中每个整数表示字典中的特定单词。 # 以下代码将下载 IMDB 数据集到您的机器上(如果您已经下载过将从缓存中复制): imdb = keras.
Linux服务器怎么修改系统时间
linux服务器的系统时间,有的时候会产生误差,导致我们的程序出现一些延迟,或者其他的一些错误,那么怎么修改linux的系统时间呢?
我是艾西,今天又是跟linux小白分享小知识的时间
具体操作:
我们一般使用“date -s”命令来修改Linux系统时间。
比如将系统时间设定成为2019年11月12日的命令:
首先在linux下输入命令“ date ”查看当前时间:
date
删除当前时间 命令:
rm -rf /etc/localtime #删除当前默认时区
将当前时区修改为上海时区命令:
ln -s /usr/share/zoneinfo/Asia/Shanghai /etc/localtime #修改默认时区为上海
输入“ date ”查看当前时间,设置完毕
三、修改时间
当前时间:
date
修改时间:
date -s "20140225 20:16:00" #yyyymmdd hh:mm:ss
查看当前系统时间:
date
设置系统时间:
date -s "时间"
查看硬件的时间:
hwclock --show
设置硬件时间:
hwclock --set --date="10/28/2020 10:15:15“
设置系统时间和硬件时间同步:
hwclock --hctosys
保存时间(一定要保存设置,否则下次重新启动时,设置会失效):
clock -w
演示:输入date的时候,系统输出的是linux的当前时间
date -s 11/12/19
修改系统当前的日期为19年11月12日,注意这个命令会让你的时分秒置为00:00:00
一些其他例子以及格式
在系统启动时,Linux操作系统将时间从CMOS中读到系统时间变量中,以后修改时间通过修改系统时间实现。为了保持系统时间与CMOS时间的一致性, Linux每隔一段时间会将系统时间写入CMOS。由于该同步是每隔一段时间(大约是11分钟)进行的,在我们执行date -s后,如果马上重启服务器,修改时间就有可能没有被写入CMOS,这就是问题的原因。如果要确保修改生效可以执行如下命令。
#hwclock -w 这个命令强制把系统时间写入CMOS
由于Linux时钟和Windows时钟从概念的分类、使用到设置都有很大的不同,所以,搞清楚Linux时钟的工作方式与设置操作,不仅对于Linux初学者有着重大意义,而且对于使用Linux服务器的用户来说尤为重要。
1.我们可能会遇到安装时显示缺少配置文件的错误。 解决方法:打开我们解压的QTP解压包
就可以正常进行安装了,按照网上安装教程,一步一步安装,祝大家安装顺利!
2.我们还会遇到以下问题 安装完成后,打不开,而且会在这个界面卡死。
原因:
1.在安装时目录里面有中文
2.你电脑的账户名为中文
解决方法:
愿因1:卸载qtp重下,确保安装目录里没有中文
愿因2:网上有教程改变你的电脑账户名,大家可以自行查看,但操作不慎的话,电脑就得重装系统,我按网上的教程,任务栏假死,而且也没有解决问题。
然后我在电脑上重新创建了一个临时账户,之后就可以打开了。
如何创建临时帐户: 1、打开“开始”菜单,在里面选择“设置”按钮。打开“设置”面板;
2、在“设置"面板中选择“账户”。进入“账户"设置窗口,如下图所示:
3.在账户设置窗口,切换到”其他用户栏“里。
4.点击将”其他人添加到这台电脑“
5.弹出”为这台电脑创建哟个账户”的对话框 。
6、输入用户名,必须是英文,密码可以设置,也可以不输入密码。点击下一步即可。
7.可以看到账户已经添加成功
8.更改他的帐户类型为管理员
9.之后我们重启电脑会在左下角显示你新创建的临时账户,我们选择它就行了。
如下图:
之后我们再次打开QTP就可以进入了。 江湖路远,让我们顶峰相见!
What is cloud computing? Cloud computing is the on-demand delivery of IT resources over the Internet/network with pay-as-you-go pricing. Instead of buying, owning, and maintaining physical data centers and servers, you can access technology services, such as computing power, storage, and databases, on an as-needed basis from a cloud provider. (from https://aws.amazon.com/what-is-cloud-computing/?nc1=h_ls)
What is private cloud? It is dedicated to a single user/organization.It is provided over the Internet or a private network.
What is deep learning?
It is subset of machine learning,It uses Artificial Neural Network with three or more hidden layers.The ANNs attempt to simulate the behavior of human brain allowing it to learn from large amount of data What are the advantages of DL?
It makes clever use of unstructured data.It outperforms other methos if the data set is large.It enables machines to process data with a nonlinear approach.It is effective at identifying hidden patterns that are too complex.
目录
GItlab配置邮箱
绑定邮箱
创建群组
添加人员
创建一个项目
添加文件
新建分支
如何拉取代码
Git bash 演示
Git GUI演示
安装jenkins
更改插件镜像源
配置jenkins使用gitlab更新代码
安装jekins插件
配置jenkins免密拉取gatlab代码
jenkins创建项目
将代码发布到web服务器
测试
给不同的用户分配权限
开启role
设置角色
给lyh用户分配角色
创建角色
分配角色
分支回滚
项目合并
回滚操作
GItlab配置邮箱 #修改配置文件 vim /etc/gitlab/gitlab.rb #去掉注释并修改内容 gitlab_rails['smtp_enable'] = true gitlab_rails['smtp_address'] = "smtp.163.com" gitlab_rails['smtp_port'] = 465 gitlab_rails['smtp_user_name'] = "17633164083@163.com" gitlab_rails['smtp_password'] = "BMEOXDBBMJGWOIHT" #这是邮箱域名(可写可不写) #gitlab_rails['smtp_domain'] = "example.com" gitlab_rails['smtp_authentication'] = "login" gitlab_rails['smtp_enable_starttls_auto'] = true gitlab_rails['smtp_tls'] = true gitlab_rails['smtp_pool'] = true #手动添加 gitlab_rails['gitlab_email_from'] = '17633164083@163.
目录
一、序列化和反序列化
序列化
用途
二、Java反序列化漏洞
数据出现
函数接口
漏洞发现
漏洞利用
三、Java序列化反序列化演示
四、靶场演示
一、序列化和反序列化 序列化 把 Java 对象转换为字节序列(字节流)的过程。
反序列化
把字节序列(字节流)恢复为 Java 对象的过程。
用途 把对象的字节序列永久地保存到硬盘上,通常存放在一个文件中(持久化对象)。在网络上传送对象的字节序列(网络传输对象) 二、Java反序列化漏洞 数据出现 1、功能特性: 反序列化操作一般应用在导入模板文件、网络通信、数据传输、日志格式化存储、对象数 据落磁盘、或 DB 存储等业务场景。因此审计过程中重点关注这些功能板块。 2、数据特性: 一段数据以 rO0AB 开头,你基本可以确定这串就是 JAVA 序列化 base64 加密的数据; 或者如果以 ACED 开头,那么他就是这一段 java 序列化的 16 进制。 3、出现具体: http 参数, cookie , sesion ,存储方式可能是 base64(rO0 ),压缩后的base64(H4s),MII 等 Servlets http,Sockets,Session 管理器,包含的协议就包括: JMX、RMI、JMS、JND1等。(/xac/Xed) xm IXstream/XmldEcoder等(http Body:Content-type: application/xml)json(jackson,fastjson)http请求中包含。 函数接口 1、Java: Serializable Externalizable 接口、 fastjson 、 jackson 、 gson 、ObjectInputStream.
文章目录 前言 课题1 : 基于SSM与VUE的房屋出租出售系统 <br /> 课题2 :基于SSM与VUE的租房信息管理系统 <br /> 课题3 : 基于SSM与VUE的个人健康信息管理系统 <br /> 课题4 : 基于SSM与VUE的共享充电宝管理系统 <br /> 课题5 : 基于SSM的健身运动平台管理系统 <br /> 前言 🔥 这两年开始毕业设计和毕业答辩的要求和难度不断提升,传统的java web缺少创新和亮点,往往达不到毕业答辩的要求,这两年不断有学弟学妹告诉学长自己做的java web管理系统达不到老师的要求。
为了大家能够顺利以及最少的精力通过毕设,学长分享5个优质java web毕业设计项目,需要的自取。
课题1 : 基于SSM与VUE的房屋出租出售系统 🥇 题目综合评分(每项满分5分)
难度系数:3分工作量:5分创新点:3分界面美化:5分 🥇 相关技术和工具 :
开发语言:Java框架:ssmJDK版本:JDK1.8服务器:tomcat7数据库:mysql 5.7(一定要5.7版本)数据库工具:Navicat11开发软件:eclipse/myeclipse/ideaMaven包:Maven3.3.9 🥇 功能模块
管理员:首页、个人中心、用户管理,房型信息管理,房屋租售管理,出租订单管理、购买订单管理、租售合同管理、留言板管理、系统管理前台首页:首页、房屋租售、系统公告、留言反馈、个人中心、后台管理、在线客服用户:首页、个人中心、出租订单管理、购买订单管理、租售合同管理、我的收藏管理 🥇 项目详细描述地址:
https://gitee.com/sinonfin/L-javaWebSha/tree/master
课题2 :基于SSM与VUE的租房信息管理系统 🥇 题目综合评分(每项满分5分)
难度系数:3分工作量:5分创新点:3分界面美化:5分 🥇 相关技术和工具 :
开发语言:Java框架:ssmJDK版本:JDK1.8服务器:tomcat7数据库:mysql 5.7(一定要5.7版本)数据库工具:Navicat11开发软件:eclipse/myeclipse/ideaMaven包:Maven3.3.9 🥇 功能模块
管理员:个人中心、租户管理、房源信息管理、房屋户型管理、租赁订单管理、租赁合同管理、留言板管理、求租信息、我的收藏管理、系统管理租户:个人中心、租赁合同管理、求租信息前台:首页、房源信息、论坛信息、新闻资讯、留言反馈、我的、跳转到后台 🥇 项目详细描述地址:
https://gitee.com/sinonfin/L-javaWebSha/tree/master
课题3 : 基于SSM与VUE的个人健康信息管理系统 🥇 题目综合评分(每项满分5分)
目录
A T325481 时效「月岩笠的诅咒」
B T296566 藤原「灭罪寺院伤」
C T324977 不死「徐福时空」
D T296568 灭罪「正直者之死」
E T309251 蓬莱「凯风快晴 −富士火山−」
F T296569 「不死鸟附体」
A T325481 时效「月岩笠的诅咒」 #include<stdio.h> #include<stdlib.h> int main(int argc,char *argv[]) { char a[100],b[100]; int i,flag=1,index1,index2; scanf("%s%s",a,b); for(i=0; i<100; i++) { if(a[i]=='.') { index1=i; break; } } for(i=0; i<100; i++) { if(b[i]=='.') { index2=i; break; } } for(i=0; i<12; i++) { if(a[++index1]!=b[++index2]) { flag=0; break; } } if(flag==1){ printf("YES"); }else{ printf("NO"); } return 0; } B T296566 藤原「灭罪寺院伤」 #include<stdio.
【题目链接】 ybt 1352 【例4-13】奖金
【题目考点】 1. 图论:拓扑排序 【解题思路】 解法1:拓扑排序 每个人是一个顶点。
如果a奖金比b高,应该先确定b的奖金数,再确定a的奖金。
因此可以这样定义边:如果b的奖金比a高,那么存在有向边<a, b>。
设数组money,顶点i的奖金为money[i]。
图中入度为0的顶点的奖金为100。
使用Kahn算法进行拓扑排序:
拓扑排序的过程中,顶点u访问邻接点v,存在弧<u, v>,v的奖金应该比u的奖金至少高1,应该用money[u]+1更新money[v],即moeny[v] = max(money[v], moeny[u]+1)。
统计算法进行过程中入度变为0的顶点数量num
如果num < n,则未完成拓扑排序,有向图中存在环,无法安排奖金,输出"Poor Xed"。如果num == n,则完成了拓扑排序,有向图无环。输出所有顶点的奖金加和。 【题解代码】 #include<bits/stdc++.h> using namespace std; #define N 10005 int n, m, degIn[N], money[N];//money[i]:员工i获得的钱数 vector<int> edge[N]; bool topoSort()//返回是否有环 { int num = 0; queue<int> que; for(int v = 1; v <= n; ++v) if(degIn[v] == 0) { que.push(v); money[v] = 100; } while(que.
文章目录 Spring事务Spring快速入门事务相关配置 Spring事务 Spring快速入门 事务作用:在数据层保障一系列的数据库操作同成功同失败
Spring事务作用:在数据层或业务层保障一系列的数据库操作同成功同失败
Spring提供了一个接口PlatformTransactionManager用来处理事务
public interface PlatformTransactionManager{ void commit(TransactionStatus status) throws TransactionException; void rollback(TransactionStatus status) throws TransactionException; } PlatformTransactionManager接口最基本的事务管理实现类DataSourceTransactionManager
public class DataSourceTransactionManager { …… } 案例学习: 模拟银行账户间转账业务
需求:实现任意两个账户间转账操作
需求微缩:A账户减钱,B账户加钱
分析:
①:数据层提供基础操作,指定账户减钱(outMoney),指定账户加钱(inMoney)
②:业务层提供转账操作(transfer),调用减钱与加钱的操作
③:提供2个账号和操作金额执行转账操作
④:基于Spring整合MyBatis环境搭建上述操作
结果分析:
①:程序正常执行时,账户金额A减B加,没有问题
②:账户金额A减执行完成后, 程序出现异常后,转账失败,但是异常之前账户金额A减操作成功,异常之后账户金额B加操作失败,这是有非常大的安全隐患的
实现步骤:
首先创建一个数据库, 有id, name, money三个字段, 以及两条数据
create table tb_account( id int primary key auto_increment, name varchar(10), money varchar(10) ) insert into tb_account (name, money) values ("chenyq", 1000), ("zhangsan", 1000); 基于整合Mybatis和Junit环境(不会的可以看前面文章), 创建一个service层接口AccountService
文章目录 clcflowmeter介绍1.简介2.特征含义3.工作流程cicflowmeter的用法 clcflowmeter介绍 1.简介 CICflowmeter是一款流量特征提取工具,该工具输入pcap文件,输出pcap文件中包含的数据包的特征信息,共80多维,以csv表格的形式输出。
2.特征含义 提取的都是传输层的一些统计信息,以一个TCP流或一个UDP流为一个单位。TCP流以FIN标志为结束,UDP以设置的flowtimeout时间为限制,超过时间就判为结束。在一个TCP流中有很多个数据包,先三次握手而后传输信息再四次挥手。统计一个流中的统计信息作为提取的特征。统计的特征都分前后向,规定由源地址到目的地址为正向,目的地址到源地址为反向。为每个流构建一个标志叫Flow ID:192.168.31.100-183.232.231.174-46927-443-6,由源地址、目的地址、协议号组成。 特征描述fl_dur流动持续时间tot_fw_pk正向总包数tot_bw_pk反向总包数tot_l_fw_pkt正向数据包的总大小fw_pkt_l_max正向数据包的最大大小fw_pkt_l_min正向包的最小大小fw_pkt_l_avg正向数据包的平均大小fw_pkt_l_std正向数据包的标准偏差大小Bw_pkt_l_max反向包的最大大小Bw_pkt_l_min反向包的最小大小Bw_pkt_l_avg反向包的平均大小Bw_pkt_l_std反向包的标准偏差大小fl_byt_s流字节率,即每秒传输的数据包数fl_pkt_s流包速率,即每秒传输的包数fl_iat_avg两个流之间的平均时间fl_iat_std两个流的标准差时间fl_iat_max两个流之间的最长时间fl_iat_min两个流之间的最短时间fw_iat_tot前向发送的两个数据包之间的总时间fw_iat_avg前向发送的两个数据包之间的平均时间fw_iat_std前向发送的两个数据包之间的标准偏差时间fw_iat_max前向发送的两个数据包之间的最大时间fw_iat_min前向发送的两个数据包之间的最短时间bw_iat_tot反向发送的两个数据包之间的总时间bw_iat_avg反向发送的两个数据包之间的平均时间bw_iat_std反向发送的两个数据包之间的标准偏差时间bw_iat_max反向发送的两个数据包之间的最大时间bw_iat_min反向发送的两个数据包之间的最短时间fw_psh_flag在正向传输的数据包中设置 PSH 标志的次数(UDP 为 0)bw_psh_flag在反向传输的数据包中设置 PSH 标志的次数(UDP 为 0)fw_urg_flag在正向传输的数据包中设置 URG 标志的次数(UDP 为 0)bw_urg_flag在反向传输的数据包中设置 URG 标志的次数(UDP 为 0)fw_hdr_len用于前向数据包头部的总字节数bw_hdr_len用于反向数据包头部的总字节数fw_pkt_s每秒前向数据包数bw_pkt_s每秒反向数据包数pkt_len_min流的最小长度pkt_len_max流的最大长度pkt_len_avg流的平均长度pkt_len_std流的标准偏差长度pkt_len_va数据包最小到达间隔时间fin_cnt带FIN的数据包数syn_cnt带有 SYN 的数据包数rst_cnt带有 RST 的数据包数pst_cntPUSH的数据包数ack_cnt带有 ACK 的数据包数urg_cnt带有 URG 的数据包数量cwe_cnt带有 CWE 的数据包数ece_cnt带有 ECE 的数据包数down_up_ratio下载上传比例pkt_size_avg数据包平均大小fw_seg_avg前向的平均尺寸bw_seg_avg反向的平均尺寸fw_byt_blk_avg前向平均字节数批量速率fw_pkt_blk_avg前向平均包块率fw_blk_rate_avg前向平均散货率bw_byt_blk_avg反向平均字节数批量速率bw_pkt_blk_avg反向平均包块率bw_blk_rate_avg反向平均散货率subfl_fw_pk前向子流中的平均数据包数subfl_fw_byt前向子流的平均字节数subfl_bw_pkt反向子流中的平均数据包数subfl_bw_byt反向子流的平均字节数fw_win_byt前向初始窗口中发送的字节数bw_win_byt反向初始窗口中发送的字节数Fw_act_pkt前向具有至少 1 字节 TCP 数据有效载荷的数据包的数量fw_seg_min前向观察到的最小段大小atv_avg流在变为空闲之前处于活动状态的平均时间atv_std流在空闲之前处于活动状态的标准偏差时间atv_max流在变为空闲之前处于活动状态的最长时间atv_min流在变为空闲之前处于活动状态的最短时间idl_avg流在变为活动之前处于空闲状态的平均时间idl_std流在变为活动之前空闲的标准偏差时间idl_max流在变为活动之前空闲的最长时间idl_min流在变为活动之前空闲的最短时间 3.工作流程 cicflowmeter的用法 参考:
cicflowmeter安装(安装方法)cicflowmeter环境配置(注意:要使用这上面给定的maven、jdk、gradle版本)
我修完产假回来上班了,被分到了割草机项目组,机遇与挑战并存,我啥也不会,但是这次扛下来也许就蜕变了呢,也许我是想多了,管他呢,有问题咱就解决,有活咱就干,态度摆端正,结果就不会太差。上班第一天开会安排任务,有个双目测距的任务,领导问我之前做过吗,我心想,我在SLAM里用过双目,这算做过吗?现在想想,当时应该说没做过,但是我可以做好。同事有双目测距SGBM代码,是自己根据双目立体匹配原理重新实现的,还有SIMD加速版本的,还有,,我运行起来调整一下参数,再交叉编译搞到板子上去,应该不成问题。
领导问我双目出深度的精度,我想着等我这个同事周一回来了再跟他讨论,不过问题貌似比较急,我不得不给我这同事打电话吗,他说这个精度跟很多因素有关系的,得实际测的,我想我这怎么跟领导汇报来,只能靠自己了,我就在网上搜索相关的资料,就是如何计算双目测距的精度问题,我就找到了下面这篇文章
双目视觉误差与距离关系_双目fov计算_这个不开车的老司机的博客-CSDN博客
我马上查阅了我们使用相机的资料,把参数都填上去,计算了一下,给领导一个直观的反馈。
B = 60; %mm,两个相机之间的距离,也叫基线 fs = 1.6; %mm,相机的物理焦距 ss = 1.968; %mm ,芯片的宽 %1.968 wid = 640; %pix,相机的分辨率 宽 pp = ss/wid %um 像元尺寸 dd = 0.25; %pix,视差的精度,检测的精度,亚像素 f = fs/(pp); minZ = 1000; %离相机最近的距离 maxZ = 3000; %最远距离 theta = atan((wid/2)/f); fov = 2*theta *180/pi minDepth = 0.5*B/((wid/2)/f) vdD = []; for D = minZ:maxZ d = B*f/D; dD = B*f*(1/d - 1/(d+dd)); vdD = [vdD;dD]; end plot([minZ:maxZ],vdD);grid on; xlabel("
个人博客
授人以鱼不如授人以渔.
所谓“一流的企业制定标准,二流的企业申请专利,三流的企业兜售产品”,这种说法虽不中亦不远。
追求专业精神的 IT 从业者不能只埋首于眼前的一亩三分地,被动承受变化,而要溯流而上,主动出击,从源头上理解自己手头使用的技术,增强自己对技术的理解和应变能力,再进一步未尝不能影响标准制定。
作为工程实践性较强的行业,IT 被许多具有世界级影响力的标准化组织所规范,这些标准化组织制定了若干标准来引领、指导和约束行业实践。
IETF ⭐⭐⭐⭐⭐ IETF(The Internet Engineering Task Force),互联网工程任务组,负责制定互联网相关的技术规范——也就是最常提到的 RFC,目前已累积了 9000+ 规范,几乎囊括了网络相关的所有内容。TCP 协议、UDP 协议、HTTP 协议都由 RFC 定义,有了 RFC 以后,各种操作系统、编程语言里的实现就遵守 RFC 的规范要求来做:
RFC 9293,TCP;RFC 768,UDP;RFC 9112,HTTP 1.1;RFC 9113,HTTP 2;RFC 9114,HTTP 3; …
几年前译过一篇 如何阅读 RFC,可供进一步了解。
通过阅读 RFC,追随大师们的脚步学习世界级的工程技术思路。
W3C ⭐⭐⭐⭐ W3C(The World Wide Web Consortium),万维网联盟,专注于 Web 相关技术标准,如:
Web 安全Web 认证Web 加密Web 可访问性Web 隐私HTMLCSSXMLJavaScript Web APIi18nMobile Web …
推荐上 MDN 网站学习更加细节的 Web 相关技术,该网站由各大浏览器厂商共同维护。
IEEE ⭐⭐ IEEE(The Institute of Electrical and Electronics Engineers),电子电气工程师学会,负责制定通信层面的协议,如著名的 IEEE 802 系列:
文章目录 1. 对文件夹进行操作1.1 ls:对路径进行访问1.2 mkdir:对路径进行创建1.3 rm:对路径进行删除 2.对文件进行操作2.1在文件系统中创建空文件2.2上传本地文件到hdfs上2.3 从hdfs上下载文件到本地路径2.4 查看hdfs 上的文件内容2.5 对hdfs上的文件进行复制2.6 追加本地文件内容到hdfs文件中2.7 将hdfs上的多个文件合并成一个文件2.8 修改文件的权限 3. 判断操作3.1 使用test命令进行判断 1. 对文件夹进行操作 1.1 ls:对路径进行访问 使用ls命令可以查看文件系统中的目录和文件
hadoop fs -ls 需要被查看的目录
-- 查看hdfs上的根目录 hadoop fs -ls / -R 代表递归查询 hadoop fs -ls -R / 1.2 mkdir:对路径进行创建 使用mkdir命令可以在文件系统中创建目录
hadoop fs -mkdir 需要创建的目录
-- 在hdfs根路径下创建test01目录 hadoop fs -mkdir /test01 -p 代表递归创建目录 hadoop fs -mkdir -p /study/test 1.3 rm:对路径进行删除 使用rm命令可以在文件系统中删除目录或者文件
hadoop fs -rm 需要删除的文件 -r 递归删除目录 -- 删除/test01目录 hadoop fs -rm -r /test01 2.
我们以两道力扣原题作为例子来讲解如何用迭代法来实现深度优先搜索:
112. 路径总和
113. 路径总和 II
对于[112. 路径总和],我们可以很容易写出以下递归版的深度优先搜索代码:
class Solution { public boolean hasPathSum(TreeNode root, int targetSum) { if (root == null) { // 1.边界条件 return false; } if (targetSum - root.val == 0 && root.left == null && root.right == null) { // 3.边界条件及条件判断,符合条件的叶节点 return true; } // 2.状态转移 // 只要子递归有一个返回 true,由于 || 的运算逻辑,将直接返回 true (短路运算特性,如果是前面的返回 true,后面的递归将不会调用) return hasPathSum(root.left, targetSum - root.val) || hasPathSum(root.right, targetSum - root.val); // targetSum - root.
Android Studio默认会在C:\Users\用户名\ .xxx 缓存一些数据。当使用Android Studio时间越来越长时,会发现C盘存储空间越来越小。
存储空间增加的主要原因是:
经常导入第三方工程,会从远程下载大量第三方依赖,gradle相关插件,且不同编译版本需要下载对应support依赖经常编译会产生大量日志文件模拟器镜像文件占用大小,有时候删除模拟器不彻底导致残留 当然你可以修改AS配置默认路径,.gradle缓存路径
1.gradle 版本 位置:
插件版本位置:
2.Gradle瘦身处理: 删除C:\Users\用户名\.android\avd目录下不要的模拟器镜像删除C:\Users\用户名\.gradle\wrapper\dists不要的gradle版本,保留常用版本(本人3.0以下的gradle版本已经全部清理,当导入的工程基于gradle3.0以下编译时,可以先修改本地支持的gradle版本和插件版本再导入工程)删除C:\Users\用户名\.gradle\caches不要的gradle版本缓存,跟第2点对应删除(依赖可以选择性删除)删除C:\Users\用户名\.gradle\daemon下每个gradle版本的.log日志文件(长期gradle构建编译,会产生大量日志文件,可达几个GB)
3.gradle下载 Gradle Distributions
解决Ubuntu软件更新命令:sudo apt-get update的“N: 无法安全地用该源进行更新,所以默认禁用该源”错误并安装gcc 解决方法:换源(1)先确定Ubuntu的版本号(2)确定镜像源(3)添加镜像源(4)最后再在命令行下执行命令就可以更新软件,之后可以安装gcc,vim等包 解决方法:换源 (1)先确定Ubuntu的版本号 使用快捷键:Ctrl+Alt+T打开终端进入命令行
使用命令确认Ubuntu版本:
cat /etc/issue (2)确定镜像源 镜像源网址:
https://mirror.tuna.tsinghua.edu.cn/help/ubuntu/
打开之后如图所示,因为没有找到完全对应的Ubuntu版本号,尝试选择了Ubuntu版本:22.10,亲测可行
(3)添加镜像源 因为初始的Ubuntu不自带vim工具,所以这里用vi进行编辑文件
sudo mv /etc/apt/sources.list /etc/apt/sources.list_bak sudo vi /etc/apt/sources.list 将镜像源复制粘贴进文件,执行效果如下(打开的sources.list先是空的)
键盘输入指令:
进入编辑 i
退出编辑 Esc
退出并保存文件 q:
(4)最后再在命令行下执行命令就可以更新软件,之后可以安装gcc,vim等包 sudo apt-get update 安装gcc
sudo apt install gcc
根据不同网络环境可以使用不同的docker-compose写法。
写法一:docker-compose 可以根据基础镜像包创建并按参数启动容器。可以离线方式部署使用。比较快。
写法二:docker-compose 可以根据dockerfile文件拉取镜像创建并按参数启动容器。可以外网开发环境时使用,方便开发调试。比较慢。
基础镜像打包部分可以参考博主的以往博客内容。
1 环境 # 软件版本 npm 6.14.15 centos 7.6 docker 20.10.8 docker-compose v2.6.1 node 14.17.6 vue 2.9.6 nginx 1.23.4 django 3.2.5 2 项目结构介绍 路径没有硬要求,后续打包时填写目录正确即可。
project ├── docker-compose.yml # docker-compose 配置文件 ├── docker_env │ ├── django │ │ ├── DockerfileBuild # server docker 基础镜像包配置 │ ├── nginx │ │ └── my.conf # nginx 配置 │ └── web │ └── DockerfileBuild # web docker 基础镜像包配置 ├── hippo │ ├── docker_start.
目录 前言一、将所有依赖和模块代码打包为一个jar二、只将模块代码打包为一个jar三、其他方法打包1.使用 spring-boot-maven-plugin 插件打包2.其他插件打包 前言 假设我有如下简单 maven 项目
点击 File ==> Project Structure ==> Artifacts ==> 点击加号 ==> 选择JAR ==> 选择From modules with dependencies
一、将所有依赖和模块代码打包为一个jar 如果你想把所有项目依赖的其他库和代码打成一个 jar,可以选择extract to the target JAR 。比如如果你项目里依赖了 fastjson.jar 等第三方 jar,可以把这些第三方 jar 也打到最终生成的 jar 里面。
1.先选择你要打包的模块和启动类,然后选择extract to the target JAR ,点击ok
2.确认要生成的 jar 名称(默认是项目或模块名),确认 jar 包的输出的目录,确认最终输出的 jar 里包含的依赖(我这里包含了14个其他依赖和项目代码,如果不想包含第三方依赖可以选中相关依赖点击减号进行排除),点击 Apply 和 Ok
3 . 点击 Build ==> Build Artifacts
先点击 clear 进行清除,然后再点击 Build 进行构建,就可以打成一个jar包了
(如果不点击 clear 进行清理上次的构建,直接点击Build 进行构建的话,可能会把上次构建的东西打进去导致 jar 包变得比较大)
终端打开Jupyter, 内部服务报错500:Internal Server Error
终端返回报错内容:
ImportError: cannot import name 'contextfilter' from 'jinja2' (/home/user/anaconda3/envs/myenv/lib/python3.7/site-packages/jinja2/__init__.py) 报错原因:
jupyter和当前安装的jinja2版本不兼容
可以用conda search jinja2查看 当前jupyter支持的jinja2版本只支持到3.0.3
解决方法:首先卸载当前的jinja2,再安装降版本的jinja2
conda uninstall jinja2 conda install jinja2==3.0.3 然后重新打开jupyter即可
系统:Ubuntu 20.04
终端输入:
nvidia-smi 出现报错:
NVIDIA-SMI has failed because it couldn't communicate with the NVIDIA driver. Make sure that the latest NVIDIA driver is installed and running. 错误原因:驱动掉了
解决办法:重新打驱动
终端cd到下载的nvidia驱动的文件夹输入:
sudo ./N(tab) --no-x-check --no-opengl-files 备注:(tab)指输入N后敲Tab键补全
然后再终端输入nvidia-smi就显示正常了
补充指令:
终端输入nvcc -V查看cuda是否返回版本号确定cuda是否正常
终端输入cuda list 确认已经安装的cuda版本
1、背景说明: OpenResty是一个基于 Nginx 与 Lua 的高性能 Web 平台,其内部集成了大量精良的 Lua 库、第三方模块以及大多数的依赖项。用于方便地搭建能够处理超高并发、扩展性极高的动态 Web 应用、Web 服务和动态网关。
简单地说OpenResty 的目标是让你的Web服务直接跑在 Nginx 服务内部,充分利用 Nginx 的非阻塞 I/O 模型,不仅仅对 HTTP 客户端请求,甚至于对远程后端诸如 MySQL、PostgreSQL、Memcached 以及 Redis 等都进行一致的高性能响应
本次教学操作是在rpm已安装openresty1.21的前提下(dockerfile安装),动态加入第三方模块nginx_upstream_check_module因此我们选择安装OpenResty1.21(目前最新版本)。
nginx_upstream_check_module是阿里的检测后端relaserver 真实状态的模块,使用前端负载均衡器nginx做到后端服务出错时,自动将出错的节点路踢掉,使得正常请求不发往出错的后端节点,当出错的后端节点恢复后,又能将节点自动加入集群中。nginx自身虽然带有简单的健康检测,但并不有效。因此我们选择单独安装nginx_upstream_check_module更好的做健康检查
首先根据rpm安装openresty1.21后发现三方模块无法在dockerfile加入,所以本次安装为手动动态添加
2、下载最新 openresty1.21(此版本要和你rpm安装的版本相同,必须相同) https://openresty.org/download/openresty-1.21.4.1.tar.gz
从GitHub下载三方zip 包
https://github.com/yaoweibin/nginx_upstream_check_module.git
3、nginx_upstream_check_module-master打补丁 cd /root
tar -zxvf openresty-1.21.4.1.tar.gz
unzip nginx_upstream_check_module-master.zip
打nginx_upstream_check_module补丁:
因为我们nginx是1.21版本,因此需要选择check_1.20.1+.patch进行打补丁,这个地方版本需要对应好,不然会报错
打补丁过程中,因为安装的不是默认Nginx,是openresty,因此需要手工指定安装文件的路径和名称
打补丁过程中共需要手工录入5个文件的路径信息,其实就是要更新这5个文件的内容,使其兼容nginx_upstream_check_module-master的功能:
test# cd openresty-1.21.4.1 test# patch -p1 < /root/nginx_upstream_check_module-master/check_1.21.1+.patch file to patch:/root/openresty-1.21.4.1/bundle/nginx-1.21.4.1/src/http/modules/ngx_http_upstream_hash_module.c file to patch:/root/openresty-1.21.4.1/bundle/nginx-1.21.4.1/src/http/modules/ngx_http_upstream_ip_hash_module.c file to patch:/root/openresty-1.21.4.1/bundle/nginx-1.21.4.1/src/http/modules/ngx_http_upstream_least_conn_module.c file to patch:/root/openresty-1.21.4.1/bundle/nginx-1.21.4.1/src/http/ngx_http_upstream_round_robin.c file to patch:/root/openresty-1.
1、idea设置缩进符为空格 Java 代码
golang 代码
2、设置提交仓库时的空格处理,否则 golang 代码为了减少文件大小,可能会把空格缩进改为制表符。 设置当前仓库配置
git config core.whitespace "-trailing-space,space-before-tab"
设置当前用户配置
git config --global core.whitespace "-trailing-space,space-before-tab"
core.whitespace 可选值:
trailing-space: 删除行末的空格space-before-tab: 保留空格缩进indent-with-non-tab: 是否应该将非 tab 字符作为缩进字符cr-at-eol: 是否在文件的行末添加回车符 3、查看 git config
查看当前仓库配置
git config --local --list
当前当前用户仓库配置
git config --global --list
查看系统配置
git config --system --list
本周AI圈”最红炸子鸡“诞生——AutoGPT。
不仅如此,这款软件系统的横空出世,一举将AI进程推向了新高度——
自主人工智能。
顾名思义,它所具备的能力主打的就是一个“自主”,完全不用人类插手的那种!
例如一位网友就要求AutoGPT开发一个网站,结果不到3分钟,AI自己就用React和Tailwind CSS“唰唰唰”地搞定了。
AI自己上网、自己使用第三方工具、自己思考、自己操作你的电脑。
这一套打法,算得上是把“行动→观察结果→思考→决定下一步行动”这条路子给打通并循环了起来。
就连前特斯拉AI总监Andrej Karpathy对此都评价道:
AutoGPT是提示工程的下一个前沿。
而且不只是AutoGPT,最近还陆陆续续地衍生出了各种自主人工智能工具,例如AgentGPT、BabyAGI等等。
然后网友们对面此景也坐不住了,惊叹于AI发展的日新月异:
这俩月,一睁眼就出新东西,太累了。
无需人类插手的AutoGPT们 那么这个当红的AutoGPT,和之前ChatGPT那波AI又有何区别?
微博博主“木遥”便下场亲测了一下。
△图源:微博博主“木遥”
他测试所用的题目是“给我解释LangChain怎么用”(LangChain是大型语言模型的一种应用框架)。
这个问题若是交给传统的GPT,由于LangChain这个概念太新,AI就会出现不知道怎么回答的情况。
若是交给“GPT+插件”这个组合来回答,那结果就会有点像Bing或者Bard。
但AutoGPT上手就不一样了,来欣赏一下它的执行过程:
首先试着直接去LangChain官网爬信息。
被官网拒绝了,可能因为有屏蔽。
发现失败了之后想了想,说要不Google一下?
Google出了很多结果。
读了半天这些结果,说「现在我们已经搜集了不少有用的信息了,接下来让我们安装它玩一下」
然后就开始动手在我的电脑上安装LangChain……
而博主“木遥”在这整个过程中所做的事情就是“坐在屏幕前看着这一切自动在我眼前发生”……
△图源:微博博主“木遥”
然后这位博主不禁发出了感慨:
我要是有它这个行动力,三个PhD都念完了。
有类似自主能力的AI,还有最近同样火爆的AgentGPT。
也是只需要给个任务,剩下的都交给它来完成:
用100美元的资金创建一个新的创业公司。
AgentGPT在接到这项任务之后,便开始了他的展示:
思考中……
添加任务:研究需要最少资金的低成本商业模式。
添加任务:确定潜在的目标市场及其需求。
添加任务:开发一个精简的MVP(最小可行产品),并在目标市场进行测试以验证需求。
思考中……
然后AgentGPT先是输出执行“研究需要最少资金的低成本商业模式”的结果:
根据我的研究,一些需要最少资金的低成本商业模式包括:
1、Dropshipping:通过Dropshipping,你可以在网上销售产品而无需持有库存。您只需通过第三方供应商完成订单,第三方供应商将产品直接运送给您的客户。你可以从50美元开始支付网站托管和域名注册费。
2、 社交媒体营销:如果你有社交媒体营销的天赋,你可以通过帮助企业接触他们的目标受众来创办自己的代理公司。你所需要的只是一台电脑,互联网连接,以及一些社交媒体营销的经验和技能,而你的起价只有50美元或更少。
3、活动策划:如果你对组织活动有热情,你可以开始自己的活动策划业务。你可以从策划一些小活动开始,比如生日派对、婚礼等等。你可以从100美元开始,创建一个简单的网站,名片,并通过社交媒体营销自己。
4、自由写作:如果你有写作天赋,你可以开始自己的自由写作事业。你可以通过在线平台,如Upwork、Fiver和其他求职网站找到客户。只需50美元,你就可以创建一个投资组合网站,并通过社交媒体营销自己。
这些只是一些低成本的商业模式,你只需要100美元的资金就可以考虑。选择一个符合你的技能和兴趣的商业模式是很重要的。
到这还没有完,AgentGPT会继续开始它的工作:
思考中……
添加任务:针对每种已确定的低成本商业模式,对潜在的产品或服务想法进行头脑风暴。
添加任务:评估每个想法的潜在盈利能力和可扩展性。
添加任务:选择最有希望的想法,并开发精益MVP,用于目标市场的测试。
而后便是继续地再思考、执行。
再如BabyAGI,也只需给个目标和任务迭代次数,AI“唰唰唰”地便自己搞了起来:
而且已经有博主开始把AutoGPT当做自己的生产力工具了——做视频!
不少网友在看到AI们的如此表现之后,表示整个人都通透了:
怎么玩? 这么强的工具,真的不想亲自玩一下?
操作一点也不麻烦。
首先,准备好OpenAI API和PINECONE API的密钥(后者是专为AI长期内存开发的一个数据库,使用前者则会消耗你OpenAI帐户中的余额,免费版本送18美元)。
Python要求3.8版本及以上。
如果你需要语音输出,你也可以准备一个ElevenLabs API的。
Ps. 获取地址都放在文末链接中了。
关于漫反射 光打到凹凸不平的平面上,光线会被反射到四面八方,被称为漫反射
关于这种模型,由于光线由于分散,所以进入人眼的光线强度和观察角度没有区别
在A点和B点接收到的光线强度是一样的
在漫反射下,光线强度只和光的入射角度有关
关于法线和叉乘 法线,是指始终垂直于某平面的虚线,这是在二维平面下的法线
叉乘是求一条垂直于平面的向量
可以用叉乘求出物体的法线
关于点乘 点乘表示A在B方向上的投影与B方向的乘机,反映了两个向量在方向上的相似度
计算公式为:
兰伯特光照模型(Lambert Lighting) diffuse = I*cosθ
其中I为入射光强度
cosθ为光源方向和顶点法线的余弦,也就是两者的点乘,这个值越大,则cosθ越大
但是如果光在物体背面,则这个值为负数,于是就归为0就可以了
然后再乘上材质的颜色就是最后的颜色值了,也就是下面的完全公式
Diffuse = 直射光颜色 *材质颜色 * max(0,cos夹角(光和法线的夹角))
在辐射度量学之前,图形学一直处于一个想当然的境地
这个公式是在1760年提出来的,这个公式完全是经验公式,看起来像那么回事就可以了
但是兰伯特光照模型有个弊端,就是在物体打不着光的一面完全是黑色的,会“不那么好看”
于是就有了半兰伯特光照模型
半兰伯特光照模型(Half-Lanbert) 在1998的《半条命》的游戏引擎中,使用了半兰伯特的光照模型
这是Valve官方开发者文档上的原句
"Half Lambert" lighting is a technique first developed in the original Half-Life.
Half Lambert - Valve Developer Community (valvesoftware.com) 在半兰伯特光照模型公式中
Diffuse = 直射光颜色 * 材质颜色 * (dot(光源方向, 法线方向) * 0.5 + 0.5)
在光在物体的背面的时候,最后的计算结果也会有明暗变化
这样物体就会”好看多了“
目录
7-1 群发邮件
输入格式:
输出格式:
输入样例:
输出样例:
7-2 学号识别
输入格式:
输出格式:
输入样例:
输出样例:
输入样例1:
输出样例1:
7-3 jmu-Java-02基本语法-03-身份证排序
输入样例:
输出样例:
7-4 单词替换
输入格式:
输出格式:
输入样例:
输出样例:
7-5 jmu-Java-02基本语法-02-StringBuilder
输入样例:
输出样例:
7-6 图书价格汇总
输出格式:
输入样例:
输出样例:
7-7 编写程序,实现字符串大小写的转换并倒序输出。
输入格式:
输出格式:
输入样例:
输出样例:
7-8 字符串加密
输入格式:
输出格式:
输入样例1:
输出样例1:
输入样例2:
输出样例2:
7-1 群发邮件 作为一个职业HR,要给某个项目组的所有职员群发邮件,已经知道HR有所有人的姓名、电话以及邮箱,请编写程序,取出所有人的邮箱,合并为一个邮箱列表,邮箱之间以“;”隔开,使其可以群发邮件。
输入格式: 在一行中给出所有人的姓名、电话以及邮箱,例如:丽丽/13539870198/lili@qq.com,天梯/13408791122/tiant@qq.com
输出格式: 一行中邮箱列表,以分号隔开。
输入样例: 在这里给出一组输入。例如:
丽丽/13539870198/lili@qq.com,天梯/13408791122/tiant@qq.com,楠楠/13112034567/nn@qq.com 输出样例: 在这里给出相应的输出。例如:
lili@qq.com;tiant@qq.com;nn@qq.com; import java.util.Comparator; import java.util.Arrays; import java.util.Scanner; import java.util.Objects; public class Main { public static void main(String[] args) { Scanner scan = new Scanner(System.
依赖
npm install --save html2canvas npm install --save jspdf 模板 <div class="container"> ... 页面内用 </div> <button @click="getPdf('文件名')">下载PDF文件</div> utils创建 htmlToPdf.js /* 调用getPdf() 打印class类名 'container'中所有样式 */ import html2Canvas from 'html2canvas' import JsPDF from 'jspdf' export default { install(Vue, options) { Vue.prototype.getPdf = function (htmlTitle) { html2Canvas(document.querySelector('.container'), { allowTaint: true, taintTest: false, useCORS: true, y: 0, // 对Y轴进行裁切 // width:1200, // height:5000, dpi: window.devicePixelRatio * 4, //将分辨率提高到特定的DPI 提高四倍 scale: 4 //按比例增加分辨率 }).then(function (canvas) { let contentWidth = canvas.
Java中内部类是一种嵌套在其他类中的类。根据内部类的声明方式,Java内部类可以分为静态内部类和普通内部类。本文将深入探讨Java内部类的两种类型,并比较它们之间的异同点。
什么是Java内部类 在Java中,内部类是指嵌套在其他类中的类。与外部类不同,内部类可以访问外部类的私有变量和方法,并且可以对外部类进行更细粒度的封装。Java内部类可以分为静态内部类和普通内部类。
静态内部类 静态内部类是指被static修饰的内部类。静态内部类和外部类之间的关系类似于普通类和外部类之间的关系。静态内部类的实例化不依赖于外部类的实例,因此可以直接使用new关键字创建对象。
下面是一个静态内部类的例子:
public class OuterClass { private static int outerData = 1; private int innerData = 2; public static class InnerClass { public void print() { System.out.println("Outer data: " + outerData); } } } 在上面的例子中,OuterClass是外部类,InnerClass是静态内部类。我们可以看到,InnerClass可以访问OuterClass的静态变量outerData。
下面是一个使用静态内部类的例子:
public class StaticInnerClassExample { public static void main(String[] args) { OuterClass.InnerClass inner = new OuterClass.InnerClass(); inner.print(); } } 在上面的例子中,我们使用new关键字创建了InnerClass的实例,并调用了它的print()方法。由于InnerClass是静态内部类,所以可以直接使用OuterClass.InnerClass来引用它。
普通内部类 普通内部类是指没有被static修饰的内部类。普通内部类的实例化依赖于外部类的实例。因此,在创建普通内部类的实例之前,必须先创建外部类的实例。
下面是一个普通内部类的例子:
public class OuterClass { private int outerData = 1; public class InnerClass { private int innerData = 2; public void print() { System.
1. 要删除 /****/这种块注释: 直接匹配 /\*(.|[\r\n])*?\*/ 即可。 转自:简书:利用正则表达式去掉注释/****/
2. 要删除 // 开头的注释:直接 匹配 //.*即可。 转自:csdn: Notepad++删除代码中的注释,可删除//单行注释和/**/多行注释
3. 要删除 <!-- xxxx --> 这种html块注释,直接 匹配 <!--(.|[\r\n])*?--> 即可。
4. 删除 java 注释 /* */:/\*{1,2}[\s\S]*?\*/
5. 删除 java 注释 //://[\s\S]*?\n
6. 删除xml注释:<!-[\s\S]*?-->
7. 删除空白行:^\s*\n
项目地址 github : GitHub - wuchuanpeng/no-vue3-cron: 这是一个 cron 表达式生成插件,基于 vue3.0 与 element-plus 实现
安装方式 :
pnpm install no-vue3-cron && npm install no-vue3-cron 引入方式:
//当前使用的页面引入 import { noVue3Cron } from 'no-vue3-cron' import 'no-vue3-cron/lib/noVue3Cron.css' // 引入样式 示例:
<template> <div class="cron"> <h1>no-vue3-cron</h1> <el-input v-model="state.cron" placeholder="cron表达式..."> <template #append> <el-popover v-model:visible="state.cronPopover" width="700px" trigger="manual"> <noVue3Cron :cron-value="state.cron" @change="changeCron" @close="state.cronPopover=false" max-height="400px" i18n="cn" ></noVue3Cron> <template #reference> <el-button @click="state.cronPopover = !state.cronPopover">设置</el-button> </template> </el-popover> </template> </el-input> </div> </template> <script> import { reactive,defineComponent } from 'vue' import { noVue3Cron } from 'no-vue3-cron' import 'no-vue3-cron/lib/noVue3Cron.
在做数学建模比赛中遇到的一个小问题。
已知一个大量离散的数据的excel表,为了简化计算,我们需要将同列项相加。
如下图所示(注意,这里的数据量多达2万行,肯定不能手工计算)
因此,我们利用python的panda对数据进行分组合并相加,代码如下。
import pandas as pd # 读取Excel表格 df = pd.read_excel('Tu.xlsx', sheet_name='Sheet1') # 根据前两列分组并求和第三列数据 result = df.groupby(['start', 'end'])['weight'].sum().reset_index() # 将结果导出到Excel表格 result.to_excel('result.xlsx', index=False) # 输出完成提示 print('导出完成!') 将新的数据导出到名为“result.xlsx”的新表中,最终简化成一千多行。
钉钉微应用启动的时候,默认是使用内嵌浏览器进行打开的。
那如果是希望在外部进行打开呢?
1.官方示例 当然,官方已经给出了相应的API:【biz.util.openLink】
具体使用如下:
dd.biz.util.openLink({ url:"https://open.dingtalk.com/",//要打开链接的地址 onSuccess : function(result) { /**/ }, onFail : function(err) {} }) 2. 我的实操 <template> <div class="full tips-center">{{tips}}</div> </template> <script> export default { data() { return { tips: "正在打开外部浏览器..." }; }, mounted() { const _this = this; dd.biz.util.openLink({ url: "https://open.dingtalk.com", //要打开链接的地址 onSuccess: function(result) { _this.tips = "已打开外部浏览器"; }, onFail: function(err) { _this.tips = "打开外部浏览器失败"; } }); } }; </script> <style lang="scss" scoped> .tips-center { line-height: 100vh; text-align: center; } </style> 3.
Python 是一门非常流行的编程语言,应用广泛。以下是一些学习 Python 的建议:
1. 先了解 Python 的基础语法,掌握变量、数据类型、条件语句、循环语句等基本概念。
2. 学习 Python 的核心模块,如 math、random、datetime、os、sys 等,这些模块可以帮助你完成更复杂的任务。
3. 练习编写 Python 程序。可以从简单的任务入手,例如打印“Hello, world”、计算两个数的和等。
4. 参考 Python 的官方文档和教程,例如 Python 官方文档、Python 官方教程、Python 100 天从新手到大师等。
5. 参加 Python 的在线课程和社群,例如 Coursera、edX、Udemy、PyCon 等,这些课程和社群可以提供你更多的学习资源和实践机会。
自律性较差该如何
如果你发现自己的自律性比较差,可以尝试以下方法来提高自律性:
1. 制定明确的目标。设定具体的目标并将其写下来,可以让你更加明确自己想要实现什么,从而提高自律性。
2. 制定详细的计划。将目标分解成具体的任务,制定详细的计划,可以让你更加清晰地知道自己需要做什么,从而更容易坚持下去。
3. 建立习惯。将学习 Python 等任务变成习惯,例如每天固定的时间段学习,可以让你更加容易坚持下去。
4. 寻求外部支持。让朋友或家人成为你的支持者,并告诉他们你的目标和计划,可以让你更有动力去实现目标。
5. 奖励自己。在完成任务之后,给自己一些小奖励,例如看一集电视剧、吃一块巧克力等,可以让你更有动力去完成任务。
希望这些方法能对你有所帮助。记住,越努力越幸运,只要你坚持努力,就一定能够成功。
官网:python-ldap — python-ldap 3.4.3 documentation
下面是一个简单的 Python LDAP 代码示例,用于连接到 LDAP 服务器并检索用户信息:
import ldap # Set the LDAP server URI and bind credentials LDAP_URI = 'ldap://ldap.example.com' LDAP_USERNAME = 'cn=admin,dc=example,dc=com' LDAP_PASSWORD = 'adminpassword' # Connect to the LDAP server ldap_conn = ldap.initialize(LDAP_URI) ldap_conn.simple_bind_s(LDAP_USERNAME, LDAP_PASSWORD) # Search for a user by their email address search_filter = '(mail=user@example.com)' search_base = 'ou=people,dc=example,dc=com' attrs = ['uid', 'givenName', 'sn', 'mail'] result = ldap_conn.search_s(search_base, ldap.SCOPE_SUBTREE, search_filter, attrs) # Print the user information if result: dn, entry = result[0] uid = entry.
前提条件 确认资源会一起打包到打包文件里
若无法打包到打包文件里,则需要在项目设置里面添加额外打包附加目录
两种方式通过路径获取资源信息 蓝图(简单) c++(稍复杂) 添加依赖模块
加入引用路径
加载资源信息 (TArray)
蓝图调用,并设置
FunLib_GetStaticMeshByContentPath 方法其实是通过输入文件路径,在c++端加载静态资源的方法
// TEXT("/Game/StarterContent/Shapes/Shape_Cylinder.Shape_Cylinder") bool UJGF_FunLib::FunLib_GetStaticMeshByContentPath( const FString& contentPath, UStaticMesh* & mesh) { mesh = LoadObject<UStaticMesh>(nullptr, *contentPath); if (mesh) { return true; } return false; }
lc-fab-touch的贴边隐藏原理 悬浮按钮的贴边原理简单来说就是用屏幕的宽度或高度减去球的一半的宽度或高度,从而实现隐藏效果。
也就如上图所示,悬浮按钮和屏幕的宽度和高度表示。
上图指向的就是对于悬浮按钮的初始位置计算
// that.safeArea.minLeft 代表靠左
// that.safeArea.maxLeft 代表靠右
// that.safeArea.minTop 代表靠下
// that.safeArea.maxTop 代表靠上
这是箭头指向位置,即是靠边隐藏的实现代码。想要取消就不能将用悬浮按钮的宽和高除以2去计算,即直接减去整个按钮的宽或高,从而使按钮完全展露出来。
解决办法:
// 计算悬浮球初始位置 initDragBall(){ console.log('initDragBall'); let that = this; try { uni.createSelectorQuery().in(this).select('#drag-ball').fields({ size: true }, dragBallSize => { // dragBallSize就是球的大小, // 球的宽 that.width = dragBallSize.width; // 球的高 that.height = dragBallSize.height; uni.getSystemInfo({ success: function(res) { that.safeArea.windowWidth = res.windowWidth; that.safeArea.windowHeight = res.windowHeight; if (that.orientation === 'landscape') { // dragBallSize.height / 2就是贴边(也就是显示一半) // that.safeArea.minTop = -parseInt(dragBallSize.
可以设置轮询时间 鼠标移入停止轮询 鼠标移出自动开始轮询 可以设置渐变颜色 <template> <div class="line_chart h-full w-full"> <div id="main" style="width: 300px; height: 300px; position: relative; float: left"></div> </div> </template> <script lang="ts" setup> import { ref, nextTick } from 'vue'; import * as echarts from 'echarts'; nextTick(() => { const getInfo = () => { let chartDom: any = document.getElementById('main'); let myChart = echarts.init(chartDom); const option = ref<any>({ series: [ { name: 'Access From', type: 'pie', radius: ['45%', '64%'], // 通过设置内径与外径将饼图变为圆环饼图 itemStyle: { borderRadius: 0, // 设置圆环的圆角弧度 //此处注释放开可以设置饼图渐变色 // color: (list) => { // 这里的渐进色数组一定要大于等于data的长度,不然会找不到对应得颜色而报错 // var colorList = [ // { // colorStart: '#1F7EFF', // colorEnd: '#B0D2FF', // }, // { // colorStart: '#FF65D3', // colorEnd: '#FFD1F2', // }, // { // colorStart: '#00AFFF', // colorEnd: '#9ADFFF', // }, // { // colorStart: '#7FF0FF', // colorEnd: '#00E1FF', // }, // { // colorStart: '#FFB0B0', // colorEnd: '#FF5454', // }, // { // colorStart: '#FFEFBE', // colorEnd: '#FFD961', // }, // { // colorStart: '#FF9946', // colorEnd: '#FFE4CD', // }, // { // colorStart: '#678AF7', // colorEnd: '#C2D1FF', // }, // ]; // return new echarts.
收集网站信息的时候子域名收集是非常重要的一部分,通常在一个主站进行防护完善的情况下找不到渗透点的话,我们可以考虑在子站点进行渗透爆破,通过旁站C段进行渗透,子域名收集是渗透测试中,前期信息收集必不可少的一个阶段。
Python子域名代码块 可自行添加代理: import requests import time import threading def get_info(domain,header): try: url=f"https://{domain}.daw.cn" #自定义目标跑格 第一处需要修改的地方 如果是http 那就改为f"https://{domain}.主域名.后缀" 列入 f"https://{domain}.baidu.com" response=requests.get(url=url,headers=header) if response.status_code == 200: print(url+"\t200") except: print(url+"\t不存在") return "不存在" def start(): f = open("自定义字典", "r", encoding="utf-8") #第二处需要修改的位置 f = f.readlines() header = { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" } print("开始判断:===========================") for domain in f: time.sleep(0.5) #第三处需要修改的地方 .可自定义更改短暂停止时间 domain = domain.strip() ret = get_info(domain, header) if ret == "
原因:服务器开了防火墙,nginx无法访问。
打开防火墙:
systemctl start firewalld 查看防火墙可允许的端口列表:
firewall-cmd --permanent --list-port 设置新的端口可允许通过防火墙:
firewall-cmd --zone=public --add-port=8001-8030/tcp --permanent 重启防火墙:
firewall-cmd --reload
文章目录 一、SEO优化1、什么是 SEO2、搜索引擎的原理3、SEO需要什么?4、SEO 为什么对于单页面应用不友好5、vue解觉SEO方案预渲染 prerender-spa-plugin存在问题使用 一、SEO优化 1、什么是 SEO 搜索引擎优化,提高网站的搜索关键词排名以及公司产品的曝光度。
2、搜索引擎的原理 从 meta 标签中读取 keywords、description 的内容从HTML标签爬取和分析内容(h1-h6、strong、em等标签)读取a标签里的链接,通过a标签的链接再跳转到别的网站(深度优先:先跳转回头再爬取;广度优先:先爬取然后再依次跳转) 3、SEO需要什么? 多页面需要动态改变网页的 title、描述、关键字网站内容 注意: 这里网站内容从哪里来是一个关键点,如果页面的数据是通过请求来的,在页面加载的时候是先有DOM结构,然后才有数据,也就是说此时的网站内容,是无法被蜘蛛抓取的,所以会导致无法被百度收录。 4、SEO 为什么对于单页面应用不友好 vue是通过js控制路由,然后渲染出对应页面,因此所有隐藏在js中的跳转或者数据都获取不到,蜘蛛抓取中不会执行js,导致搜索引擎只能收录 index.html,而无法搜到其相关的子页面的内容。浏览器加载页面时,首先会对页面进行渲染(dom生成、css构建、javascript解析、布局、绘制),当解析到js的时候,才会去触发vue的渲染,将元素挂载到id为app的div上,这时候我们才能看到页面的内容。因此被搜索引擎收录的index页面,可能也毫无价值,因为没有任何数据。 5、vue解觉SEO方案 预渲染 prerender-spa-plugin 存在问题 动态路由解决不了 【比如详情页】无法动态改变title、描述、关键字。 使用 安装插件
cnpm install --save prerender-spa-plugin //解决打包多个页面 cnpm install --save vue-meta-info //设置title、描述、关键字,解决SEO的问题 配置 vue.config.js:
const path = require('path'); const PrerenderSPAPlugin = require('prerender-spa-plugin'); module.exports = { publicPath: './', configureWebpack: { plugins: [ new PrerenderSPAPlugin({ staticDir: path.join(__dirname, 'dist'), routes: [ // 需要预渲染的路由地址(需要打包成几个页面就配置几个路由) '/', '/about', '/contact', ], }), ], }, }; 在组件中使用 vue-meta-info :
效果图:
景深透视图
html代码:
<div class="container"> <!-- 这里使用的图片均为png格式,因为png格式带有alpha通道,也就是透明图层 --> <!-- html渲染是从上到下的,所以最上层的图片需要放在最下面 --> <img src="./src/30c91359b0877ef038be685c8081501ed34c3089.png" width="800"> <img src="./src/30c91359b0877ef038be685c8081501ed34c30891.png" width="800"> <img src="./src/30c91359b0877ef038be685c8081501ed34c30892.png" width="800"> </div> css代码:
/* 我们需要用到css的全局变量 ,每层图片各需要2个变量*/ :root{ --bottom-left:0; --mid-left:0; --top-left:0; --bottom-top:0; --mid-top:0; --top-top:0 } /* 将图片多余的部分不显示,并且容器是相对定位 */ .container{ width: 800px; height: 400px; background-color: gray; margin:0 auto; overflow: hidden; position: relative; } .container img{ position: absolute; top:0; left: 0; } /* 因为我们图片是需要偏移的,我们就需要设置图片的缩放比例 */ /* 这里通过修改图片的定位来实现景深透视效果 */ .container img:nth-child(1){ left: var(--bottom-left); top: var(--bottom-top); transform: scale(1.
索引从0开始,并且存放相同结构元素的集合叫数组
数组常用的API
②,shift 从数组中删除第一个元素, 返回值为 删除的元素的值。 此方法会更改数组的长度
描述
③,pop : 从数组中删除最后一个元素,并返回该元素,该方法会更改数组的长度。
④,push : 将一个或多个元素添加到数组的末尾,并返回该数组的新长度
⑤,splice 通过删除 或者 替换 现有元素 或者 原地添加新的元素 来修改数组, 并以 数组形式 返回被修改的内容 。 此方法会改变 原数组。
⑥, concat 用于合并两个或多个数组 。该方法不会更改现有的的数组, 而返回一个新数组。
⑦,sort : 对数组的元素按照码表进行排序, 并返回数组 (排列后的数组)。 默认排列顺序是 将元素转换为字符串 ,然后再按照码表进行排序。
⑧,reverse : 数组的反转 ,将数组的元素位置颠倒,并返回该数组。 会改变原来的数组。
⑨,join : 将一个数组(或者一个类数组对象) 的所有元素连成一个字符串,并返回这个字符串。
⑩,slice : 截取一段数组,该方法会返回一个新数组, 这个数组有 开始下标 和 结束下标 决定的, 为原数组的浅拷贝, ( 包括开始下标,但是不包括结束的下标) 。 原数组也不会更变。
目录 安规设计01、安规简介1.定义2.安规所涉及的要求3.世界主要安规体系4.安规认证 02安规认证的申请流程03电子产品的安规基本要求04电子产品在制作过程中的安规要求1.耐压2.绝缘电阻-主要考量产品的绝缘性能3.泄漏电流4.接地电阻5.安全距离6.电磁兼容7.耐火阻燃8.机械结构伤害和热伤害9.电子产品常见的安规零部件 安规设计 01、安规简介 1.定义 为了保证人身安全,财产,环境等不受伤害和损失,所做出的规定。
2.安规所涉及的要求 a.电击
b.火灾
c.电磁辐射
d.环境污染
e.化学辐射
f.能量冲击
g.化学腐蚀
h.机械伤害和热伤害
3.世界主要安规体系 a.IEC体系----以欧盟为代表
b.UL体系----以美国为代表
尽管这两个体系各自独立,但现在有互相承认,走向一致的趋势。
4.安规认证 安规认证其实是一种技术壁垒,世界各国为了限制别国的产品进入本国,都对安规有不同要求,而且是带有强制性的。
常见的安规认证:
a.UL-美国
b.TUV,VDE,GS-德国
c.CCC-中国
d.PSE-日本
e.CE-欧盟
f.KETI-韩国
g. --丹麦
h. --挪威
i. --芬兰
j. --瑞典
另外,还有澳大利亚,新西兰,新加坡等国。
02安规认证的申请流程 1.向安规机构递交申请资料。
2.安规认证机构会在承诺的时间内给予是否接受申请的答覆。
3.安规机构接受申请後,申请人开始送样接受安规测试。
4.如果样品通过安规测试,安规认证机构安排工厂检查(UL叫IPI),如果未通过测试,则退回申请人,申请人对未通过测试的项目进行改善,然後再重新送样测试,如果第二次未通过,则需要重新申请。
5.工厂检查通过,安规认证机构颁发认证证书或安规标志使用授权书,申请人可以在获得认证的产品使用认证机构的标志。如果工厂检查未通过,认证机构会给申请人一段时间进行整改,整改结束後进行复查,复查若未通过,则须重新申请。
6.以後认证机构对获得认证的产品转入跟踪检查,UL一般是一年四次,CCC是每年一次,其他认证机构的周期也大都为1年1次.跟踪检查主要检查产品的一致性,但象CCC,TUV等还对品质系统进行审查。
03电子产品的安规基本要求 1.耐压(抗电强度)-防止电击伤害
2.绝缘电阻-防止电击伤害
3.接地电阻-防止电击伤害
4.泄漏电流-防止电击伤害
5.电磁兼容-抗电磁干扰能力和对其他电子产品的影响
6.耐火阻然-防止火灾危险
7.机械结构-防止机械结构缺陷引起的损伤,灼伤等
8.能源冲击-防止因为大电流引起火灾或电弧灼伤
04电子产品在制作过程中的安规要求 1.耐压 -主要考量产品在异常高压下,绝缘系统的承受能力.工作电压低於50V,一般不进行耐压测试。
a.耐压一般与产品的工作电压有关。
通常用的计算公式:
1)交流:1000 2*额定工作电压
2)直流(1000 2*额定工作电压)*1.4
以上是普通绝缘用的试验电压,如果是双重绝缘,则试验电压为普通的2倍.
如果计算出来的结果不是100的整数倍,则取大不取小.
例:额定工作电压为220V,普通绝缘的试验电压为:
交流:1000 2*220=1440V,此时试验电压应当取1500V,而不是采用四舍五入.
b.泄漏电流的设定
docker 安装准备 官方网址: https://www.docker.com/
GitHub网址:https://github.com/docker/docker-install
OS系统版本选择 Docker 目前已经支持多种操作系统的安装运行,比如Ubuntu、CentOS、Redhat、Debian、Fedora,甚至是还支持了Mac和Windows,在linux系统上需要内核版本在3.10或以上
安装和删除方法 官方文档: https://docs.docker.com/engine/install/
阿里云文档:
https://developer.aliyun.com/mirror/docker-ce?spm=a2c6h.13651102.0.0.3e221b11gu
HCWE
ubuntu安装和删除docker 官方文档: https://docs.docker.com/install/linux/docker-ce/ubuntu/
Ubuntu 14.04/16.04/18.04/20.04 安装docker
# step 1: 安装必要的一些系统工具 sudo apt-get update sudo apt-get -y install apt-transport-https ca-certificates curl softwareproperties-common # step 2: 安装GPG证书 curl -fsSL https://mirrors.aliyun.com/docker-ce/linux/ubuntu/gpg | sudo apt-key add - # Step 3: 写入软件源信息 sudo add-apt-repository "deb [arch=amd64] https://mirrors.aliyun.com/dockerce/linux/ubuntu $(lsb_release -cs) stable" # Step 4: 更新并安装Docker-CE sudo apt-get -y update sudo apt-get -y install docker-ce 删除docker [root@ubuntu ~]#apt purge docker-ce [root@ubuntu ~]#rm -rf /var/lib/docker Centos 安装和删除Docker 官方文档: https://docs.
若一个查询同时涉及两个或两个以上的表, 则称之为连接查询(在FROM子句中体现)。 参与连接的表可有多个,但连接操作在两个表之间进行,即两两连接。
连接查询包括:
内连接 等值连接:用“=”比较被连接列的列值非等值连接:用“>、>=、<、<=、<>”号进行比较运算自连接:特殊的内连接,一张表看成两张表,自己连接自己,必须给表取别名外连接 左外右外前外交叉连接 1 内连接 执行连接操作的过程:
先取表1中的第1个元组,然后从头开始扫描表2,逐一查找满足连接条件的元组;
找到后就将表1中的第1个元组与该元组拼接起来,形成结果表中的一个元组。
表2全部查找完毕后,再取表1中的第2个元组,然后再从头开始扫描表2, …
重复这个过程,直到表1中的全部元组都处理完毕为止。
select ... from tablename [inner] join 被连接表 on 连接条件 ...... ——举例(引用已有数据库:bjpowernode.sql)
dept:部门表emp:员工表salgrade :工资等级表 deptno:部门编号
empno:员工编号
grade:等级dname:部门名称ename:员工名字losal:最低薪资loc:部门位置job:工作岗位hisal:最高薪资mgr:上级领导编号hiredate:入职时间sal:月薪comm:补助/津贴deptno:部门编号 1.1 等值连接 查询每个员工的部门名称,显示员工名和部门名。
select ename,dname from emp e join dept d on e.deptno=d.deptno; 1.2 非等值连接 查询每个员工的工资等级,显示员工名、工资、工资等级。
select ename,sal,grade from emp e join salgrade s on e.sal between s.losal and s.hisal; 1.3 自连接 特殊的内连接——相互连接的表物理上为同一张表。
必须为两个表取别名,使之在逻辑上成两个表(一个是查询结果表,一个查询条件表)。 注:为表指定别名时,在查询语句中其它地方, 所有用到表名处均要用别名,不能再用原表名。 <表名> [AS] <表别名> (注意与列别名的区别,group by 后不能用列别名)
注:本文主要介绍六大排序中的快排
文章目录 前言一、三大法则1.1 Hoare法1.2 挖坑法1.3 双指针法(更加便捷)1.4 三种方法时间复杂度计算 二、快排栈问题优化方式2.1 三数取中2.2 小区间优化 三、非递归快排 前言 快速排序是Hoare于1962年提出的一种二叉树结构的交换排序方法,其基本思想为:任取待排序元素序列中的某元素作为基准值,按照该排序码将待排序集合分割成两子序列,左子序列中所有元素均小于基准值,右子序列中所有元素均大于基准值,然后最左右子序列重复该过程,直到所有元素都排列在相应位置上为止。
一、三大法则 1.1 Hoare法 什么是Hoare法则呢?
Hoare法是指在对数组进行排序时,定义两个变量,与一个在单子循环中不变的key值,右值先动找比key小的数字,找到后左值动,找比key大的数字,后进行交换以完成对数组的排序。
初始状态
right先进行寻找,找到5<key3
left进行寻找找到7>key,进行交换
继续进行刚才的工作交换9/4
当左值与右值相等时,一次循环结束,left与right所在位置与初始的key位置进行Swap交换,进入递归循环。
1.Hoare法代码 void PartSort1(vector<int>& v, int begin, int end) { //出递归判断 if (begin >= end) { return; } int key = begin; int left = begin, right = end; while (left < right) { //寻找小于key的左值 while (right > left && v[right] >= v[key]) { right--; } //寻找大于key的右值 while (right > left && v[left] <= v[key]) { left++; } Swap(v[left], v[right]); } Swap(v[key], v[left]); //key左边都是小于key的数,key右边都是大于key的数字 key = left; //进入递归,先递归左半部分小于key的区间,后递归右半部分大于key的区间 QuickSort(v, begin, key - 1); QuickSort(v, key + 1, end); } int main() { vector<int> v = { 8,12,5,3,6,4,7,91,5,16,35,21,52,2,1 }; QuickSort(v, 0, v.
前言 一般来说,一个应用至少有一个进程,一个进程至少有一个线程。线程是CPU调度的基本单位,进程是系统资源分配的基本单位。
进程拥有独占的内存资源,一个进程可以看作一个JVM一个进程崩溃后,一般不会影响保护模式下的其他进程。同一进程中的线程共享内存资源,一个线程的死亡导致整个进程的死亡。
Android开发四种常用的多线程实现方式:
AsyncTask异步消息机制IntentServiceThreadPoolExcutor 1.AsyncTask
Android AsyncTask 类,它是封装好的线程池,操作 UI 线程极其方便。
AsyncTask 的三个泛型参数:
public abstract class AsyncTask<Params, Progress, Result> Params ,传入参数类型,即 doInBackground() 方法中的参数类型;Progress,异步任务执行过程中返回的任务执行进度类型, 即 publishProgress() 和onProgressUpdate() 方法中传入的参数类型;
Result,异步任务执行完返回的结果类型\,即 doInBackground() 方法中返回值的类型。 四个回调方法:
onPreExecute(),在主线程执行,做一些准备工作。doInBackground(),在线程池中执行,该方法是抽象方法,在此方法中可以调用 publishProgress() 更新任务进度。onProgressUpdate(),在主线程中执行,在 publishProgress() 调用之后被回调,展示任务进度。onPostExecute(),在主线程中执行,异步任务结束后,回调此方法,处理返回结果。 注意:
当AsyncTask 任务被取消时,回调 onCanceled(obj) ,此时onPostExecute(),不会被调用,AsyncTask 中的 cancel()方法并不是真正去取消任务,只是设置这个任务为取消状态,需要在 doInBackground() 中通过 isCancelled()判断终止任务。AsyncTask 必须在主线程中创建实例,execute() 方法也必须在主线程中调用。每个 AsyncTask实例只能执行一execute() ,多次执行会报错,如需执行多次,则需创建多个实例。Android 3.0 之后,AsyncTask 对象默认执行多任务是串行执行,即 mAsyncTask.execute() ,并发执行的话需要使用executeOnExecutor()。AsyncTask 用的是线程池机制和异步消息机制(基于 ThreadPoolExecutor和 Handler )。Android 2.3 以前,AsyncTask 线程池容量是 128 ,全局线程池只有 5 个工作线程,如果运用 AsyncTask 对象来执行多个并发异步任务,那么同一时间最多只能有 5 个线程同时运行,其他线程将被阻塞。Android 3.
CentOS是一种流行的Linux操作系统,它可以用于各种用途,包括Web服务器、数据库服务器、邮件服务器等。在某些情况下,您可能需要禁止某个国家之外的IP地址访问您的服务器。这可以通过使用防火墙规则来实现。在本教程中,我们将介绍如何使用CentOS的防火墙来禁止某个国家之外的IP地址访问您的服务器。
安装GeoIP支持库: yum install -y geoip-devel 下载GeoIP数据库文件: wget -N https://geolite.maxmind.com/download/geoip/database/GeoLiteCountry/GeoIP.dat.gz gunzip GeoIP.dat.gz 安装iptables模块: yum install -y iptables iptables-devel yum install -y xtables-addons xtables-addons-geoip 使用xt_geoip命令生成国家IP段列表: /usr/libexec/xtables-addons/xt_geoip_build -D /usr/share/xt_geoip GeoIP.dat 编写iptables规则: 假设我们要禁止中国以外的所有国家访问,可以使用如下iptables规则:
iptables -I INPUT -m geoip ! --src-cc CN -j DROP iptables-save > /etc/sysconfig/iptables systemctl restart iptables.service 这条规则表示:如果来源地不是中国(CN)就拒绝连接。
验证是否生效 可以使用以下指令验证是否禁止了中国以外的所有国家访问:
curl ip.cn # 查看当前机器 IP 地址,然后将此地址输入到下面指令中。 curl http://api.ipstack.com/<YOUR_IP>?access_key=<YOUR_ACCESS_KEY> # 获取当前 IP 所在国家名称和代码(需要注册ipstack API并获取access_key) 如果验证结果显示当前IP所在的国家不是中国,则说明规则已经生效。
以上就是禁止某个国家之外的IP访问的步骤和示例代码。需要注意的是,这种方式只能起到一定程度上的防御作用,并不能完全保证系统安全。因此,在实际应用中还需综合考虑其他措施。
当前环境的keycloak地址:http://ovirt.engine.com/ovirt-engine-auth/
在使用keycloak的REST API的时候,一定要在path路径后面添加上auth/admin/realms,然后再跟上对应的API,下面是获取相关信息的几个实例
一、获取token
执行rest api的时候需要先获取token,获取token的方式如下,其中client_id固定为admin-cli,username和password为登录keycloak的用户名和密码,grant_type为固定的password类型
curl -d "client_id=admin-cli" -d "username=admin" -d "password=rootroot" -d "grant_type=password" "http://ovirt.engine.com/ovirt-engine-auth/realms/master/protocol/openid-connect/token"
输出结果如下,其中access_token是我们需要的部分:
{"access_token":"eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJTOVc2ZUktS2hjVldBRjVxRFF3MmZONGFhbFBQZE1BM0VYNXB5Nk84a2JVIn0.eyJleHAiOjE2ODEzOTI3NzEsImlhdCI6MTY4MTM4NTU3MSwianRpIjoiYTc3NjQxODUtMWI3Zi00YzVmLTg1ZGQtMzc2MGYzZWEzN2Y0IiwiaXNzIjoiaHR0cDovL292aXJ0LmVuZ2luZS5jb20vb3ZpcnQtZW5naW5lLWF1dGgvcmVhbG1zL21hc3RlciIsInN1YiI6IjVlYWU0Nzc2LTJkZTgtNDAzOS04NzY4LTk5NTUyMzdlZDQyNCIsInR5cCI6IkJlYXJlciIsImF6cCI6ImFkbWluLWNsaSIsInNlc3Npb25fc3RhdGUiOiI0MmY1NWIzYy03YzgwLTRiMGItODc1MC02ZDNlNTFjZWE3MzQiLCJhY3IiOiIxIiwic2NvcGUiOiJlbWFpbCBwcm9maWxlIiwic2lkIjoiNDJmNTViM2MtN2M4MC00YjBiLTg3NTAtNmQzZTUxY2VhNzM0IiwiZW1haWxfdmVyaWZpZWQiOmZhbHNlLCJwcmVmZXJyZWRfdXNlcm5hbWUiOiJhZG1pbiJ9.dXNVQx6odx_usICvkIwdx298wCFqiJYuDRN3rygCEaR-fWlUZra_zdqbI875Xku6PNuNhlLmUP9zV14SEA66BcyjSyhxgjB_j4fNcqgwQ5k8BnojG1Grv_mcOVTkoV1-cGcxLc7qYk_9s_muiHsp5NvBQimsi_Pt4vt2DzNEOYaRMB4mq53--yEhJiLaxZT2e-4L8xLrJDaNsIdSQVFZ5x2aONZFMrV47Wga7KtA4Ek3hzNiNQwgTc7pzssZx-v38WIeTijnIs697vYFryA3lwPQpApfecsKsmzI-U58FNwiuhoXU4THX3mGPYfXrk3T32_cptLpTPbIBmPPYUeA8g","expires_in":7200,"refresh_expires_in":1800,"refresh_token":"eyJhbGciOiJIUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICIzOGE3ODMyNy1lNzQ1LTQwYTktYjU1NC1jYWEyZDZhOTYzOWEifQ.eyJleHAiOjE2ODEzODczNzEsImlhdCI6MTY4MTM4NTU3MSwianRpIjoiYWQ4MDFjZDctZDE2OS00YTdkLWEyZTgtOTlkM2M2ODU2ZDY3IiwiaXNzIjoiaHR0cDovL292aXJ0LmVuZ2luZS5jb20vb3ZpcnQtZW5naW5lLWF1dGgvcmVhbG1zL21hc3RlciIsImF1ZCI6Imh0dHA6Ly9vdmlydC5lbmdpbmUuY29tL292aXJ0LWVuZ2luZS1hdXRoL3JlYWxtcy9tYXN0ZXIiLCJzdWIiOiI1ZWFlNDc3Ni0yZGU4LTQwMzktODc2OC05OTU1MjM3ZWQ0MjQiLCJ0eXAiOiJSZWZyZXNoIiwiYXpwIjoiYWRtaW4tY2xpIiwic2Vzc2lvbl9zdGF0ZSI6IjQyZjU1YjNjLTdjODAtNGIwYi04NzUwLTZkM2U1MWNlYTczNCIsInNjb3BlIjoiZW1haWwgcHJvZmlsZSIsInNpZCI6IjQyZjU1YjNjLTdjODAtNGIwYi04NzUwLTZkM2U1MWNlYTczNCJ9.e1FWQJhljBES602SDo7CROfDVd5vr2Gp1MZ51_iVBQk","token_type":"Bearer","not-before-policy":0,"session_state":"42f55b3c-7c80-4b0b-8750-6d3e51cea734","scope":"email profile"}
有了上述的token之后,我们可以根据keycloak的rest api获取很多信息,下面介绍一些常用的信息
二、获取userinfo信息
使用第一步获取的token信息,获取当前登录用户的userinfo信息,具体命令如下,其中${ACCESS_TOKEN}替换为第一步获取的token值
curl -H "Authorization: Bearer ${ACCESS_TOKEN}" -H "Content-Type: application/json" "http://ovirt.engine.com/ovirt-engine-auth/realms/master/protocol/openid-connect/userinfo"
输出结果如下:
{"sub":"5eae4776-2de8-4039-8768-9955237ed424","email_verified":false,"preferred_username":"admin"}
三、获取realm的所有roles
curl -H "Authorization: Bearer ${ACCESS_TOKEN}" -H "Content-Type: application/json" "http://ovirt.engine.com/ovir-engine-auth/admin/realms/master/roles"
获取输出如下:
[{"id":"60edcf42-188a-43a7-9d44-7bd00a598c8c","name":"default-roles-master","description":"${role_default-roles}","composite":true,"clientRole":false,"containerId":"master"},{"id":"5f6fe0a9-51ae-41d9-9eed-3a64edab3085","name":"create-realm","description":"${role_create-realm}","composite":false,"clientRole":false,"containerId":"master"},{"id":"afa35046-b7a9-4a5d-97be-ff91d9d339b4","name":"offline_access","description":"${role_offline-access}","composite":false,"clientRole":false,"containerId":"master"},{"id":"e427622c-1e13-4314-b333-2d4592a88ff9","name":"admin","description":"${role_admin}","composite":true,"clientRole":false,"containerId":"master"},{"id":"efc6ed50-daa1-4956-bba1-78fa0b92935f","name":"uma_authorization","description":"${role_uma_authorization}","composite":false,"clientRole":false,"containerId":"master"}]
三、获取所有groups信息
由于默认的master realm中没有group,所以我们获取ovirt-internal这个realm中的group
命令如下:
curl -H "Authorization: Bearer ${ACCESS_TOKEN}" -H "Content-Type: application/json" "http://ovirt.engine.com/ovirt-engine-auth/admin/realms/ovirt-internal/groups"
获取的输出如下:
[{"id":"3ac9f9fb-95f7-4ef7-8f2c-bbbfd955655f","name":"ovirt-administrator","path":"/ovirt-administrator","subGroups":[]}]
四、获取users信息
命令:
curl -H "Authorization: Bearer ${ACCESS_TOKEN}" -H "
文章目录 前言一、jQuery隐藏显示二、jQuery淡入淡出三、jQuery滑动四、jQuery自定义动画五、stop方法六、回调函数总结 前言 jQuery 给我们封装了很多动画效果,其中最为常见的就是显示隐藏、滑动、淡入淡出和自定义动画。下面来看一下这些效果的使用方法。
一、jQuery隐藏显示 可以使用hide() 和show() 方法来隐藏和显示HTML元素。
//隐藏元素 $("#hide").click(function(){ $("p").hide(); }); //显示元素 $("#show").click(function(){ $("p").show(); }); 也可以使用toggle() 方法来切换hide()和show()方法。
$("button").click(function(){ $("p").toggle(); }); 二、jQuery淡入淡出 fadeIn() 用于淡入已隐藏的元素
fadeOut() 用于淡出已隐藏的元素
$("button").click(function(){ //淡入元素 $("#div1").fadeIn(); //可以添加参数 $("#div2").fadeIn("slow"); //淡出元素 $("#div3").fadeOut(3000); }); fadeToggle() 方法可以在fadeIn()与fadeOut()方法之间进行切换。
$("button").click(function(){ $("#div2").fadeToggle("fast"); }); fadeTo() 方法允许渐变为给定的不透明度(值介于0与1之间)。
$("button").click(function(){ $("#div1").fadeTo("slow",0.15); }); 三、jQuery滑动 slideDown() 方法用于向下滑动元素。
slideUp() 方法用于向上滑动元素。
$("#flip").click(function(){ $("#div1").slideDown(); $("#div1").slideUp(); }); slideToggle() 方法slideDown()与slideUp()方法之间进行切换。
$("#flip").click(function(){ $("#panel").slideToggle(); }); 四、jQuery自定义动画 animate() 方法用于创建自定义动画。可选的speed参数规定效果的时长。
它可以取以下值:“slow”、"fast"或毫秒。可选的callback参数是动画完成后所执行的函数名称。
$("button").click(function(){ $("div").animate({ left:'250px', opacity:'0.5', height:'150px', width:'150px' }); }); 五、stop方法 jQuerystop() 方法用于停止动画或效果,在它们完成之前,适用于所有jQuery效果函数,包括滑动、淡入淡出和自定义动画。
postman 的使用心得
最近新换了一家公司是前后分离的项目 之前写的都是测试页面,现在写纯接口
就得用测试工具 我看postman别人用得挺好得 我也用了
其实测试就是增删改查 其实都挺好用就是上传图片不好测试
上图
第一步就是选择你得请求方法一般提交我用的是post得请求 写自己得地址信息 ,
第二步就是选择 点击进入 Body 选择 form-data ,
第三步就是选择你自己的请求头得信息 ,key值是自己得请求信息 ,点击可以选择 有file 和txt ,一般上传文件图片都是用 file ,然后如果你有json对象一起提交得话就选txt
第四步是关键得 你得找到 Content type 选择自己对应得类型 ,我图片传得是png,我选择得png,也可以选择其他得 ,最关键得就是你传json的对象时候,你的指定你的json对象的类型不然测试会报错 ,那个类型也是可以选择的,你输入application/会自动有提示你传的是什么就写什么
第五步 点击测试 就ok了
注 :: 本人技术一般 希望大佬不要介意一个对技术有执着追求的,也希望这能帮到新人 ,也给自己一个提示
0.下载MySQL和Navicat 注册MySQL的账户密码,后面会用到的。
1.检查Qt支持的数据库驱动 qDebug()<<QSqlDatabase::drivers(); 2.检查Qt的位数和MySQL的位数要对应,32位对应32位的 将MySQL的驱动libmysql.dll库复制一份到对应的debug目录或者release目录下
//添加一个数据库 QSqlDatabase db=QSqlDatabase::addDatabase("QMYSQL"); //括号内要写出数据库的类型 //设置数据库 db.setHostName("127.0.0.1"); //设置数据库的主机ip,localhost也可以 //设置端口,mysql的端口默认是3306 db.setPort(3306); //设置数据库的用户名 db.setUserName("root"); //设置数据库的密码 db.setPassword("123456"); //这个就是安装MySQL时设置的密码 //设置数据库的名字 db.setDatabaseName("aaa2"); //打开数据库(已经安装过mysql驱动了) if(db.open()==false){ QMessageBox::warning(this,"waring",db.lastError().text()); } else QMessageBox::about(this,"success","数据库打开成功"); 运行成功 主外键的级联操作 在Navicat中新建两张表,我建的是student的学生表和classinfo的班级信息表,在班级信息表中将classID设置为主键,类型为int,学生表中添加一个字段和班级信息表中的字段classID,名字不一定要相同,按自己的习惯来,方便区分就可以了。
、
、
、
在学生表中插入外键,名字自己取,字段选择学生表中的classID,被引用的模式就是你当前的数据库,被引用的父表就是你要关联的主表,被引用的字段就是父表中的某一个字段,删除时和更新时选择CASCADE(级联模式),当父表中关联的字段更新时从表中对应的字段也会更新。
在插入外键时,一定要仔细检查主表和从表中关联的字段是否匹配,比如说类型,长度,小数点,不是null,虚拟都要一一匹配,不然会报错,无法建立外键。
、
向表中添加一些数据后进行操作
删除主表中关联的字段记录后,从表中的数据会更新。这里我们删除了classID中1的记录,刷新student表中发现classID的记录也被删除了,这就是基础的级联操作,当然还可以关联多个表,可能会复杂一点。
时间轮算法是一种高效的时间管理算法,可以用来解决定时任务的调度问题。它可以将任务根据其时间戳放入不同的槽位中,然后通过定时扫描槽位中的任务,来执行任务的调度。在Java中,时间轮算法有着广泛的应用,比如定时任务调度、网络IO等方面。
本文将介绍Java时间轮算法的实现和优点,包括多级时间轮的实现、时间轮的详解和优点。我们将会深入探讨时间轮算法的实现原理、优化方法,以及如何在Java中使用时间轮算法。
时间轮算法的基本原理 时间轮算法是一种基于数组的时间管理算法。它将一个固定时间间隔的时间线分成若干个槽位,每个槽位代表一个时间间隔。时间轮算法中有两个关键的概念:槽位和刻度。
一个时间轮中包含多个槽位,每个槽位中包含多个任务。时间轮有一个固定的大小,也就是时间轮的槽数。当一个任务到达时间轮时,它会被放入到对应的槽位中。时间轮会定时扫描每个槽位,来执行其中的任务。
时间轮中的每个槽位代表的是一个时间间隔,也就是刻度。时间轮的大小和刻度的大小决定了时间轮的精度和时间间隔。比如,如果时间轮的大小为10,刻度为1秒,那么时间轮可以处理的最小时间间隔就是10秒。当一个任务的时间间隔小于10秒时,它会被放入到时间轮的下一个槽位中。
时间轮算法的核心就是槽位的管理。当时间轮的指针指向一个槽位时,时间轮就会执行这个槽位中的所有任务。然后时间轮的指针会指向下一个槽位,直到回到起点。这样,时间轮就可以循环执行任务,实现定时任务的调度。
多级时间轮的实现 多级时间轮是一种时间轮的扩展,它可以提高时间轮的精度和可扩展性。一个多级时间轮包含多个子时间轮,每个子时间轮代表一个时间间隔。每个子时间轮都包含多个槽位,每个槽位中包含多个任务。
多级时间轮的实现方式很简单,就是将多个时间轮串联在一起。每个子时间轮中的任务到达时,会被放入到子时间轮的对应槽位中,然后子时间轮会定时扫描每个槽位,执行其中的任务。同时,子时间轮的指针也会按照一定的规则,指向下一个子时间轮的对应槽位。
多级时间轮的实现可以提高时间轮的精度和可扩展性。它可以将时间轮的刻度细分到更小的时间间隔,同时还可以支持更长的时间间隔。例如,我们可以将一个小时分成60分钟,然后将每个分钟再分成60秒,这样就可以实现更精确的时间管理。
下面是一个Java多级时间轮的示例代码:
import java.util.Date; import java.util.concurrent.DelayQueue; import java.util.concurrent.Delayed; import java.util.concurrent.TimeUnit; public class MultiLevelTimeWheel { // 时间轮大小,每一格代表1秒 private final int WHEEL_SIZE = 60; // 时间轮的每一格,用来存储定时任务 private TimeSlot[] timeSlots; // 当前指针指向的时间槽 private int currentSlotIndex = 0; // 下一级时间轮 private MultiLevelTimeWheel nextLevelWheel; // 延迟队列,用来存储需要延迟执行的任务 private DelayQueue<Task> delayQueue = new DelayQueue<>(); public MultiLevelTimeWheel() { this.timeSlots = new TimeSlot[WHEEL_SIZE]; for (int i = 0; i < WHEEL_SIZE; i++) { this.
文章目录 一、XSS攻击1、什么是XSS攻击2、XSS攻击的两种方式反射型攻击持久性攻击 3、如何防止XSS攻击4、XSS攻击要做什么坏事5、预防xss攻击方法 二、CSRF攻击1、什么是CSRF攻击2、CSRF攻击方式示例 3、如何防御CSRF?验证码验证Referercookie设置sameSite添加token验证 三、SQL注入1、什么是SQL注入示例 2、原因总结3、防止方法 一、XSS攻击 1、什么是XSS攻击 XSS攻击(跨站点脚本攻击),就是黑客恶意篡改你网页的前端代码,在里面注入一些恶意的 html+javascript的脚本,并在你的浏览器内运行,获取你的信息,或者进行一些恶意操作。
2、XSS攻击的两种方式 反射型攻击 黑客在钓鱼网站设置其URL链接,URL链接可为色情动图、诱惑小视频,此URL链接内嵌有其恶意脚本,你点后 ,恶意脚本被返回至你的浏览器里。此时脚本就会运行,一旦控制了浏览器可得到大量东西,浏览器内包含cookie,可利用cookie伪造你的用户登录的session 状态,去以你这个用户的名义干一些事儿。
持久性攻击 持久型攻击,论坛、社交网站之类的系统,可发布一些帖子,评论。黑客可在里面写一段恶意脚本, 然后把恶意脚本混杂在评论内容里提交到网站的数据库里去 。然后其他用户在社交网站里浏览到了黑客的这个评论,评论内容会被返回到其浏览器里去,此时评论内容是包含恶意js脚本的,马上恶意脚本运行,可利用cookie伪造你的用户登录的session 状态,去以你这个用户的名义干一些事儿。
3、如何防止XSS攻击 包含恶意URL链接的图片、视频、动图、flash动画,少点,尽量使用正规的网站 ;
消毒机制,代码里必须对内容进行消毒,就是进行一些转义,比 如说把>转义为>之类的,这样就可以把恶意脚本里的html标签、js代码之类的东西,都给转义掉,让这些恶意脚本失效 -> ,这种东西在浏览器里是不会运行的 这样的话,转义以后的脚本被其他用户看到的时候也不会在浏览器里运行了;
HttpOnly方式,这个意思是说如果你在浏览器里存放cookie的时候,可以设置一个HttpOnly属性,比如说存放用户加密认证信息的 cookie,这样的话,在浏览器里运行的js脚本是被禁止访问这些HttpOnly cookie的,他就无法窃取你在浏览器里存储的cookie了。
4、XSS攻击要做什么坏事 窃取cookie,然后借刀杀人,借用户的身份伪造数据请求;劫持流量,后导流到他的私域网站上去;插入广告;置入木马;获取用户信息; 5、预防xss攻击方法 二、CSRF攻击 1、什么是CSRF攻击 CSRF,即 Cross Site Request Forgery,是指跨站请求伪造,是一种劫持受信任用户向服务器发送非预期请求的攻击方式。
与XSS不同,XSS攻击是向受攻击网站进行脚本注入攻击,而CSRF攻击是其他网站对受攻击网站进行伪造请求。
2、CSRF攻击方式 CSRF 攻击是借助被攻击者的 Cookie 骗取服务器的信任,以被攻击者名义伪造请求发送给受攻击服务器,从而在并未授权的情况下执行在权限保护之下的操作。
示例 银行网站A,它以GET请求来完成银行转账的操作,如:http://www.mybank.com/Transfer.php?toBankId=11&money=1000
危险网站B,它里面有一段HTML的代码如下:
< img src =http://www.mybank.com/Transfer.php?toBankId=11&money=1000 >
首先,你登录了银行网站A,然后访问危险网站B,噢,这时你会发现你的银行账户少了1000块…
为什么会这样呢?原因是银行网站A违反了HTTP规范,使用GET请求更新资源。在访问危险网站B的之前,你已经登录了银行网站A,而B中的以GET的方式请求第三方资源(这里的第三方就是指银行网站了,原本这是一个合法的请求,但这里被不法分子利用了),所以你的浏览器会带上你的银行网站A的Cookie发出Get请求,去获取资源“http://www.mybank.com/Transfer.php?toBankId=11&money=1000”,结果银行网站服务器收到请求后,认为这是一个更新资源操作(转账操作),所以就立刻进行转账操作…
3、如何防御CSRF? 验证码 由于CSRF攻击伪造请求不会经过受攻击的网站,所以我们可以在网站加入验证码,这样必须通过验证码之后才能进行请求,有效的遏制了CSRF请求。
但是,这种方式不是万能的,并不是每个请求都加验证码,那样用户体验会非常不好,只能在部分请求添加,作为一种辅助的防御手段。
验证Referer 在HTTP协议中,头部有个Referer字段,他记录了该HTTP请求的来源地址,在服务端设置该字段的检验,通过检查该字段,就可以知道该请求是否合法。
cookie设置sameSite cookies设置sameSite属性的值为strict,这样只有同源网站的请求才会带上cookie。这样cookies就不能被其他域名网站使用,达到了防御的目的。
添加token验证 这是一种相对成熟的解决方案。要抵御 CSRF,关键在于在请求中放入攻击者所不能伪造的信息,并且该信息不存在于 Cookie 之中。在服务端随机生成token,在 HTTP 请求中以参数的形式加入这个 token,并在服务器端建立一个拦截器来验证这个 token,如果请求中没有 token 或者 token 内容不正确,则认为可能是 CSRF 攻击而拒绝该请求。
目录
B2002 Hello,World!
题目描述
输入格式
输出格式
输入输出样例
B2025 输出字符菱形
题目描述
输入格式
输出格式
输入输出样例
P1000 超级玛丽游戏
题目背景
题目描述
输入格式
输出格式
输入输出样例
P1001 A+B Problem
B2005 字符三角形
题目描述
输入格式
输出格式
输入输出样例
说明/提示
P5703 【深基2.例5】苹果采购
题目描述
输入格式
输出格式
输入输出样例
题目描述
输入格式
输出格式
输入输出样例
P5705 【深基2.例7】数字反转
题目描述
输入格式
输出格式
输入输出样例
P5706 【深基2.例8】再分肥宅水
题目描述
输入格式
输出格式
输入输出样例
说明/提示
P5708 【深基2.习2】三角形面积
题目描述
输入格式
输出格式
输入输出样例
说明/提示
P5707 【深基2.例12】上学迟到
题目描述
输入格式
输出格式
输入输出样例
说明/提示
B2029 大象喝水
定义 Internet控制消息协议ICMP (Internet Control Message Protocol)是IP协议的辅助协议
ICMP协议用来在网络设备间传递各种差错和控制信息,对于收集各种网络信息、诊断和排除各种网络故障等方面起着至关重要的作用。
icmp的作用 检测网络的双向联通性
功能:ping Ping是网络设备、Windows、Unix和Linux平台上的一个命令,其实是一个小巧而实用的应用程序,该应用基于ICMP协议。
Ping常用于探测到达目的节点的网络可达性。
ping 选项: 显示自己 IP地址 ipconfig ping --help 显示帮助命令 -t 长ping -l size 发送缓冲区大小。 -w 超时等待时间 -n 指定ping 几次 ping -t ip地址 长ping ctrl+c 停止 ping -l 指定包的大小(1600 2000) ip地址 ping -w 指定等待时间(默认是秒:2 ) ip 地址 ping -n 指定的次数(5) ip 地址 tip: ping的通一定通 ping不通不一定网络不通 tracert 也是 icmp协议 192.168.1.144 192.168.1.152 tracert IP地址 tracert 192.168.1.152 经过几个路由设备 追踪 广播域 = 一个网段 排除网络故障的方法及常见故障 一 排错思路 排错思路,当你的 服务出了问题,网络不通
Spring Boot 技术文档 简介 Spring Boot 是一个快速构建 Java 应用程序的框架,它基于 Spring Framework,并通过自动配置和简化的开发流程来简化应用程序的开发。Spring Boot 可以帮助开发者快速创建独立的、生产级别的 Spring 应用程序,并减少了开发者配置应用程序所需的时间和精力。Spring Boot 最大的优势是提供了一种快速开发体验,可以实现零配置启动。
文章目录 Spring Boot 技术文档简介@[toc]主要特点快速上手应用场景 主要特点 简化配置:Spring Boot 采用约定大于配置的原则,可以在不修改配置文件的情况下启动 Web 应用或其他应用。内嵌服务器:集成了 Tomcat、Jetty 等内嵌容器,不需要安装额外的 Web 服务器。自动配置:Spring Boot 自动根据项目所引入的依赖自动配置相关参数,大部分应用可以零配置启动。独立运行:使用 Spring Boot 创建独立可运行的 Java 应用程序,无需打包成 WAR 文件。 快速上手 使用 Spring Boot 可以非常方便地创建一个 Web 应用程序。只需几步操作即可完成:
创建一个 Maven 项目,添加以下依赖: <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> 在主类中添加注解 @SpringBootApplication ,这个注解会自动扫描所有 Bean 并启动 Web 服务。 @SpringBootApplication public class Application { public static void main(String[] args) { SpringApplication.
相关文章:jenkins部署vue/react项目_jenkins部署react_不求甚解bc的博客-CSDN博客
准备工作 1、新建一个流水线任务
2、配置git参数,选择指定分支部署流水线
3、在流水线配置对应步骤代码
不知道如何写流水线代码,可清空内容,选择右上角的示例,会自动填充示例代码
点击底部“流水线语法”,可以打开语法实例,选择对应的操作,生成代码,拷贝到steps中
比如,clone远程代码并指定分支,填写好git地址和用户,选择对应分支,点击生成流水线脚本即可,将结果拷贝到steps中
类似的还有配置node版本、shell脚本等,都可以在流水线语法页面生成
4、备份上述脚本
pipeline { agent any stages { stage('Clone') { steps { // Get some code from a GitHub repository checkout([$class: 'GitSCM', branches: [[name: '${branch}']], extensions: [], userRemoteConfigs: [[credentialsId: '65574a37-15dd-4021-9bb0-01d432da81aa', url: 'https://gitlab.com/bucong/vue-demo.git']]]) } } stage('Build') { steps { nodejs('nodejs14') { sh '''npm install rm -rf ./dist/* npm run build''' } } } stage ("Deply") { steps { sh '''rm -rf /usr/share/nginx/html/vue-demo/* cp -rf .
bytes_to_long()函数:
原理:长度为n的字节串,从最低位向最高位每挪动一位,乘数倍增2^8,因为一个字节是8位bits。
bytes_to_long():将字符串变为一串数。逆:long_to_bytes()(将一串数字变为字符串)
用法:在后端传给我们数据的时候,有时候数据并不是我们想要的,我们需要将它转换为我们所使用的格式
例子如下:
方法1:
<el-table :data="tabledata">
<el-table-column label="性别" prop="sex">
<template slot-scope="scope">
<span v-if="scope.row.sex==="1">男</span>
<span v-else-if="scope.row.sex==="2">女</span>
<span v-else="scope.row.sex==="3">其它</span>
</template>
<el-table-column>
<el-table>
方法2:
<el-table :data="tabledata>
<el-table-column :formatter="sexFormatter" prop="sex">
<el-table-column>
<el-table>
const sexFormatter = row = >{
return getSexStatus(row.sex)
}
const getSexStatus = sex = >{
switch(sex){
case '1':
return '男';
case '2':
return '女';
default:
return "其它";
}
}
数据库基础知识 1、ACID: mysql相关日志:
逻辑备份日志:binlog
(物理)重做日志:redolog
回滚日志:undolog
锁技术+MVCC
原子性(atomicity): 强调单个事务不可分割,
全部commit,否则全部rollback
undolog实现异常回滚
每条数据变更:INSERT UPDATE DELETE REPLACE产生一条undolog日志,sql执行前优先于数据持久化到磁盘 insert: rollback时执行delete delete:回滚时会执行insert; update: 回滚时会执行相反的update,把数据改回来 记录事务开始前老版本数据,用于实现回滚,保证了原子性,实现MVCC,将数据修改前的旧版本保存在undolog,行记录有隐藏字段回滚指针指向老版本 一致性(Consistency): 数据库总是从一个一致性的状态转换到另外一个一致性的状态过程中系统崩溃,事务未提交,不影响结果通过aid来确认数据的最终一致性 隔离性(isolation): 多个事务,操作隔离避免并发事务产生影响读写锁+MVCC 持久性:(durability) 一旦提交,其所做的修改就会永久保存到数据库中即使后面出现故障,也不会影响原来的结果binlog+redolog实现表数据持久化到磁盘,为了保证在并发持久化的情况下不影响效率,引用了缓存池(包含了磁盘中部分数据页的映射,可以当作缓存使用)当修改表数据时,将操作记录先写到buffer pool中,标记事务已完成,等mysql空闲时,再将更新操作持久化到磁盘,从而缓解MySQL并发压力 redolog:记录事务开启之后对数据做的修改(crash-safe) 介绍: WAL技术:全称是Write-Ahead Logging,关键点:先写日志,再写磁盘、特性:空间一定,写完后会循环写,有两个指针write pos指向当前记录位置,checkpoint指向将擦除的位置,redolog相当于是个取货小车,货物太多时来不及一件一件入库太慢了这样,就先将货物放入小车,等到货物不多或则小车满了或则店里空闲时再将小车货物送到库房。用于crash-safe,数据库异常断电等情况可用redo log恢复。 写入流程: 先写redo log bufferwrite到文件系统的page cachefsync持久化到磁盘 写入策略: 根据innodb_flush_log_at_trx_commit参数控制(innodb以事务的什么提交方式刷新日志
0:事务提交时只把redo log 留在redo log buffer1:将redo log直接持久化到磁盘(所以有个双“1”配置,后面会讲)2:只是把redo log写到page cache 2、并发事务产生的问题以及对应隔离级别 InnoDB在实现MVCC时用到的一致性读视图,即consistent read view,用于支持RC(Read Committed,读提交)和RR(Repeatable Read,可重复读)隔离级别的实现。
2.1、产生的问题: 脏读:(dirty read) 事务A读到事务B未提交的数据 丢失修改:(lost to modify) 两事务A和B同时操作某一数据,最先执行完的事务的修改被丢失例如:事务1读取某表中的数据A=20,事务2也读取A=20,事务1修改A=A-1,事务2也修改A=A-2,最终结果A=18,事务1的修改被丢失。 不可重复读(Unrepeatableread) 一个事务里多次读同一个数据,在这个事务还没有结束,有另一个事务修改了数据,导致多次读取数据不一致并发事务修改 幻读(Phantom read) 并发事务新增或者删除一个事务里多次读同一个数据,在这个事务还没有结束,有另一个事务新增或者删除了数据,导致多次读取数据行数不一致 2.2、事务隔离级别: Mysql8以前:SELECT @@GLOBAL.
# 界面 def menu(): print("1.添加名片") print("2.删除名片") print("3.修改名片") print("4.查询名片") print("5.获取所有名片名片") print("6.推出系统") # # 添加 def add(list): print("添加") map={"name":"","age":"","id":"","address":""} print("输入姓名:") name=input() print("输入年龄:") age=input() print("输入id:") id=input() print("输入住址") address=input() map['name']=name map['age']=age map['id']=id map['address']=address list.append(map) print("添加成功!") return list # # 删除 def delete(name,list): print("删除") n=0 for i in list: if name==i['name']: del list[n] print("删除成功!") n=n+1 # # 修改 def updata(name,list): print("修改") for i in list: if name==i['name']: print("输入要修改的元素") print("1.年龄") print("2.id") print("3.地址") n=int(input()) if n==1: print("
ubuntu(wsl2)访问windows 方式一:ubuntu中查看 ubuntu终端中输入
cat /etc/resolv.conf 显示结果
# 显示结果 # This file was automatically generated by WSL. To stop automatic generation of this file, add the following entry to /etc/wsl.conf: # [network] # generateResolvConf = false nameserver 172.17.32.1 nameserver 后的ip即为wsl可访问的 windows的IP地址
2. 方式2:windows中查看 打开windows命令行窗口,即 运行 cmd。
输入如下命令
ipconfig 结果中找到“以太网适配器 vEthernet (WSL):"下的IPv4地址即为wsl可访问的windows IP地址
windows 访问ubuntu(WSL2) ubuntu终端中输入
# 以下命令2选1均可 ifconfig # 或者也可以使用如下命令 ip addr | grep eth0 结果中eth0下的inet后面的IPv4格式地址即windows可访问的wsl2的IP地址
参考 Wsl与Windows互相访问_讓丄帝愛伱的博客-CSDN博客_wsl访问windows
wsl2 固定地址访问windows服务 - 简书 (jianshu.
随着计算机性能的不断提升,应用程序的并发处理需求也越来越大。传统的线程模型虽然能够解决并发编程问题,但是线程的创建和切换成本较高,容易导致系统资源的浪费和性能的下降。Java协程(Coroutine)则是一种更加高效的异步编程方式,它可以轻松地实现并发编程,并且相比于传统的线程模型,具有更加高效的性能和更加优雅的编程方式。本文将详细介绍Java协程的概念、优势以及实现方式。
协程的概念 协程是一种用户态线程,可以在单个线程中实现多个协程之间的切换,从而达到异步编程的目的。协程的实现方式与传统的线程模型有所不同,它并不需要额外的线程来实现并发处理,而是将线程的执行权交给协程调度器(Coroutine Scheduler),由调度器来决定在何时切换执行的协程。
协程具有以下几个特点:
协程是一种用户态线程,不需要额外的系统资源(如线程、进程)来创建和管理。
协程可以在单个线程中实现多个协程之间的切换,从而达到异步编程的目的。
协程的切换由协程调度器决定,在运行时可以动态调整协程的优先级和调度策略。
协程之间的切换可以实现非阻塞式的协作式多任务处理,避免了线程切换的开销和锁竞争的问题。
协程的优势 相比于传统的线程模型,协程具有以下几个优势:
高效性能:协程的创建和销毁开销很小,可以在单个线程中实现多个协程之间的切换,避免了线程切换的开销和锁竞争的问题,提高了系统的并发处理能力和性能。更优的编程方式:协程可以实现非阻塞式的协作式多任务处理,避免了传统的线程模型中需要使用锁和线程间通信的复杂编程方式,代码更加简洁易读。更好的资源利用率:协程可以在单个线程中实现多个协程之间的切换,从而避免了创建过多的线程所带来的系统资源占用问题,提高了系统的资源利用率。 Java协程的实现方式 Java协程的实现方式可以分为两种:JDK 17引入的协程实现虚拟线程和第三方库实现。
JDK 17引入的协程实现虚拟线程 在JDK 17中,Java引入了协程实现虚拟线程(Fiber),它是一种用户态线程,由Java虚拟机直接管理,不需要额外的系统资源来创建和管理。虚拟线程的创建和销毁开销很小,可以在单个线程中实现多个虚拟线程之间的切换,避免了线程切换的开销和锁竞争的问题,提高了系统的并发处理能力和性能。
虚拟线程的实现方式与传统的线程模型有所不同。虚拟线程的切换由协程调度器决定,在运行时可以动态调整协程的优先级和调度策略。在Java中,可以使用Java Fiber API来创建和管理虚拟线程。
以下是Java Fiber API的示例代码:
import java.util.concurrent.CompletableFuture; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; import java.lang.invoke.MethodHandles; import java.lang.invoke.VarHandle; import jdk.incubator.foreign.MemoryAddress; import jdk.incubator.foreign.MemoryHandles; public class FiberExample { public static void main(String[] args) { ExecutorService executor = Executors.newSingleThreadExecutor(); // 创建一个虚拟线程 CompletableFuture<String> future = new CompletableFuture<>(); executor.submit(() -> { try { FiberScope.scope(fiberScope -> { Fiber fiber = Fiber.
Intro 1 GCC 官方文档 GCC 官方文档网站:https://gcc.gnu.org/onlinedocs/
官方文档是最权威的,网上所有的答案都来自官方文档适应英语阅读,中文是母语,很多词我们自己有根深蒂固的含义和概念,再重新赋予新含义非常不容易理解或有歧义英语用词、逻辑比较严谨,网上的翻译水平参差不齐,坑很多国内论坛找到好答案全凭运气,好的答案可以节省时间,没有好的答案还是得花时间看官方文档,所以还是自己靠谱一点,锻炼一下英语能力 2 GCC的介绍 GCC 是 GNU项目的一个产品。
GCC(GNU Compiler Collection,GNU编译程序集合)是最重要的开放源码软件。其他所有开放源码软件都在某种层次上依赖于它。甚至其他语言,例如 Python,都是由 C 语言开发的,由 GNU 编译程序编译的。
这个软件对于整个自由软件运动而言具有根本性的意义。如果没有它或类似的软件,就不可能有自由软件运动。GCC 为 Linux 的出现提供了可能性。
GCC 是由许多组件组成的,但它们也并不总是出现的。有些部分是和语言相关的,所以如果没有安装某种特定语言,系统中就不会出现相关的文件。
2.1 GCC常见的组成部分 c++: gcc 的一个版本,默认语言设置为 C++,而且在链接的时候自动包含标准 C++ 库。这和 g++ 一样
configure: GCC 源代码树根目录中的一个脚本。用于设置配置值和创建 GCC 编译程序必需的 make 程序文件
g++: gcc 的一个版本,默认语言设置为 C++,而且在链接的时候自动包含标准 C++库。这和 c++ 一样
gcc: 该驱动程序等同于执行编译程序和连接程序以产生需要的输出
libgcc: 该库包含的例程被作为编译程序的一部分,是因为它们可被链接到实际的可执行程序中。它们是特殊的例程,链接到可执行程序,来执行基本的任务,例如浮点运算。这些库中的例程通常都是平台相关的
libstdc++: 运行时库,包括定义为标准语言一部分的所有的 C++类和函数
2.2 GCC包含的常见的软件 ar: 这是一个程序,可通过从文档中增加、删除和析取文件来维护库文件。通常使用该工具是为了创建和管理连接程序使用的目标库文档。该程序是 binutils 包的一部分
as: GNU 汇编器。实际上它是一族汇编器,因为它可以被编译或能够在各种不同平台上工作。该程序是 binutjls 包的一部分
autoconf:产生的 shell 脚本自动配置源代码包去编译某个特定版本的 UNIX
在之前在工作中遇到在富文本编辑器中粘贴图片不能展示的问题,于是各种网上扒拉,终于找到解决方案,在这里感谢一下知乎中众大神以及TheViper。
通过知乎提供的思路找到粘贴的原理,通过TheViper找到粘贴图片的方法。
其原理为一下步骤:
监听粘贴事件;【用于插入图片】
获取光标位置;【记录图片插入位置】
获取剪切板内容;【主要是获取文件】
上传剪切板图片;
在指定光标位置插入图片。
以下是代码部分:
1.获取光标代码部分,大部分都是直接利用TheViper的代码,只是做了简单的修改,在获取光标的位置添加了插件子集document对象,因为直接使用document对象获取不到光标位置
var isSupportRange = typeof document.createRange == 'function';
var currentRange,
_parentElement;
// 获取当前光标多在位置
function getCurrentRange(target) {
var selection,
range;
if (isSupportRange) {
selection = target.getSelection();
if (selection.getRangeAt && selection.rangeCount) {
range = selection.getRangeAt(0);
_parentElement = range.commonAncestorContainer;
}
} else {
range = target.selection.createRange();
_parentElement = range.parentElement();
}
return range;
}
function saveSelection(target) {
currentRange = getCurrentRange(target);
}
function _restoreSelection() {
**
运用说明: 为了加强数据库的安全性,我们需要限制指定用户访问数据库的权限,让指定用户只能查看、操作个别需要用到的表**
设置步骤:1、登录管理员账号,新建用户
2、将需要访问的数据库权限映射给该用户
3、登录管理员账号,给该用户分配指定表、视图、存储过程的操作权限。以视图为例,表和存储过程和该步骤一致。
4、权限设置完成。
目录
spark概述
spark集群搭建
1.Spark安装
2.环境变量配置
3.Spark集群配置
4.启动Spark集群
存在问题及解决方案
请参考以下文章 spark概述 Spark是一个开源的大数据处理框架,它可以在分布式计算集群上进行高效的数据处理和分析。Spark的特点是速度快、易用性高、支持多种编程语言和数据源。Spark的核心是基于内存的计算模型,可以在内存中快速地处理大规模数据。Spark支持多种数据处理方式,包括批处理、流处理、机器学习和图计算等。Spark的生态系统非常丰富,包括Spark SQL、Spark Streaming、MLlit
GraphX等组件,可以满足不同场景下的数据处理需求。
spark集群搭建 在部署spark集群时,我们知道有三种:
一种是本地模式,一种是Standalone 集群,还有一种是云端。
1.Spark安装 首先我们需要在master节点上进行Spark的安装。
其中1台机器(节点)作为Master节点,主机名为hadoop1,另外两台机器(节点)作为Slave节点(即作为Worker节点),主机名分别为hadoop2和hadoop3。
在Master节点机器上,访问Spark官方下载地址Downloads | Apache Spark,按照如下图下载:
我们选择2.1.0的版本,也可以选择其他的版本,但是需要注意的是,如果你选择的Spark版本过高,可能导致无法与你的hadoop版本适配。
完成下载后,进行如下的命令行操作,和hadoop安装时十分类似。
$ tar -zxvf scala.2.11.8.tgz #解压到当前路径
$ cd /usr/local
$ sudo mv ./spark-2.1.0-bin-without-hadoop/ ./spark #重命名
spark安装与上述Scala步骤一致
2.环境变量配置 同样在master机器上,打开bashrc文件进行环境变量配置。
$ vim ~/.bashrc
在文件中添加如下内容
export PATH=$PATH:/usr/local/scala/bin并使其生效。
保存文件并退出vim编辑器,执行如下命令让改环境变量生效:
$ source ~/.bashrc
设置好后,可以使用Scala命令来检验一下是否设置正确:
$ scala
输入scala命令以后,屏幕上会显示Scala和java版本信息,并进入“scala>”提示符状态,这时就可以开始使用Scala解释器了,可以输入scala语句来调试scala代码。
3.Spark集群配置 进入到/usr/local/spark的conf路径下,进行以下文件的配置。
a)配置slaves文件
但是由于其开始并没有这个文件,而只有slaves.template文件,所以我们需要先拷贝重命名一下。
$ cd /usr/local/spark/conf/
$ cp ./slaves.template ./slaves
目录:
1.连接redis服务命令
2.redis数据类型
3.keys命令
4.string(字符串命令)
5.hash命令
6.list(列表)
7.set集合
8.zset(sorted set:有序集合)
1.连接redis服务命令: 1.连接本地redis服务命令:redis-cli
2.远程连接redis服务命令:redis-clo -h host -p port -a password
2.redis数据类型 Redis支持五种数据类型:string(字符串),hash(哈希),list(列表),set(集合)及zset(sorted set:有序集合)。
string 是 redis 最基本的类型,string 类型是二进制安全的。意思是 redis 的 string 可以包含任何数据。比如jpg图片或者序列化的对象。
Redis hash 是一个键值(key=>value)对集合。
Redis hash 是一个 string 类型的 field 和 value 的映射表,hash 特别适合用于存储对象。
List(列表)简单的字符串列表,按照插入顺序排序。你可以添加一个元素到列表的头部(左边)或者尾部(右边)。
Set 是 string 类型的无序集合。是通过哈希表实现的,所以添加,删除,查找的复杂度都是 O(1)。
zset(有序集合)是 string 类型的有序集合。zset的成员是唯一的,但分数(score)却可以重复。
3.keys命令: del key key存在时删除key
exists key 检查key是否存在
expire key seconds(秒) 为key设置过期时间,以秒计算
expire key timestamp(毫秒) 设置key的过期时间以毫秒计算
persist key 移除key的过期时间,key将持久保持
一、方法 点击浏览器的三点->点击设置 点击系统->计算机代理设置 将这些代理都关掉
Word、Excel、PPT作为大家日常办公的使用最频繁的办公软件。对于一些涉及个人隐私或者涉及企业机密性的文档文件,我们经常会给自己的文档加上密码。
但有时候文档时间比较久了、或者密码太多了,有时候我们会把文档的密码给忘记了,如果密码忘记了怎么办,能找回来吗?
今天小编给大家分享这个非常好用的Office文档密码找回工具Advanced Office Password Recovery(本文简称“AOPR”)。下面小编给大家介绍一使用AOPR解除Office文档密码的教程。
方式一、字典模式破解 1.打开AOPR软件
首先打开安装好的AOPR软,软件打开后的主界面如下图所示,该软件默认采用的是“字典破解”方式进行文档密码清除。
AOPR软件主界面
2.打开要解除文档密码的文档
然后我们鼠标单击软件左上角的“打开文件”按钮,在弹出的文件对话框找到需要忘记文档密码的文件,点击确定后即可打开需要破解密码的文件。
图2:打开待破解的文件
3.自动开始用字典模式破解(软件已经录入的一些常规密码,逐个尝试)。
同时该软件会自动执行查找匹配文档密码,它先执行初步破解,如果密码设置简单,那么你很幸运,一般都可以很快找到密码。如果你的文档密码设置的很复杂的话,一般采用这种方式很难找回密码的。
图3:执行初步破解
方式二、暴力破解方式 1.进入暴力破解界面。
如果上面的字典破解没有成功获得文档密码,我们可以尝试采用暴力破解方式,鼠标单击选择“暴力”选项,同时我们可以对密码长度、包含的字符集和起始密码进行设置,从而缩小文档密码范围,减少密码获取的时间。
图4:设置暴力选项
2.开始破解。
需要的设置完成后,我们点击“开始”按钮,继续开始破解文件密码。经过这样的设置后,成功获取文档密码的机会就非常高了。
图5:开始暴力破解
方式三、自定义字符范围 1.如果以上方法都没有成功,我们可以大致确定密码的字符范围,自定义字符集。单击“定义自定义字符集”按钮,在弹出的对话框设置文本中的字符。
图6:定义字符集
2.然后单击“开始”按钮,在开始在指定范围内破解,这样成功率更高,速度更快。比如下图就是定义字符集后成功破解的Word文件密码。
图7:密码已恢复对话框
以上就是给大家介绍的使用AOPR获取Word、Excel、PPT等Office文档密码的技巧,如果初步破解没有成功,则可以尝试下面的第二步、第三步,直至密码被恢复为止。
下载地址
1,算符优先文法 算符优先分析过程是自下而上的归约过程,但未必是严格的最左归约。也就是说,算符优先分析法不是一种规范归约法。所谓【算符优先分析法】就是定义算符之间的某种优先关系,借助于这种关系寻找“可归约串”进行归约的一种方法。
【算符文法】一个文法,如果它的任一产生式的右部都不含两个相继(并列)的非终结符,即不含如下形式的产生式右部: ,则我们称该文法为算符文法。
约定:
代表任意终结符。 代表任意非终结符号。 代表由终结符和非终结符组成的任意序列,包括空字。 假定 是一个不含 产生式的算符文法。对于任意一对终结符 ,我们说:
,当且仅当文法 中含有形如 或 的产生式。,当且仅当文法 中含有形如 的产生式,而 或 。,当且仅当文法 中含有形如 的产生式,而 或 。 如果一个算法文法 中的任何终结符对 至多满足下述三关系之一:
则称 是一个算符优先文法。
FIRSTVT推出的第一个终结符集合:
若产生式 或 ,则 若 ,且有产生式 ,则 。 LASTVT: 可用下面规则构造集合 :
若有产生式 ,则 ;若 ,且有产生式 ,则 。 2,优先表构造 优先关系表的构造算法:
检查 的每个候选式,若有 或 的产生式,则置 。若 中有形如 的候选项,则对于所有的 ,有 。若 中有形如 的候选式,则对于所有的 ,有 。 先行后列
3,算符优先文法 素短语:至少含有一个终结符的短语(且不能拆分成最小)
移进:当栈顶终结符 < 或 = 当前输入符号时。归约:当栈顶终结符 > 当前输入符号时,在栈中寻找最左素短语进行归约。接受:当栈顶终结符 = 当前输入符号=‘#’ 时,分析成功结束。出错:当栈顶终结符与当前输入符号没有优先关系时。 【例子】
目录
1. Batch Normalization的基本思想
2. BN层的作用 3. 训练阶段和测试阶段的BN层
4. BN、LN、IN、GN与SN
1. Batch Normalization的基本思想 BN解决的问题:深度神经网络随着网络深度加深,训练越困难,收敛越来越慢
问题出现的原因:深度神经网络涉及到很多层的叠加,而每一层的参数更新会导致上层的输入数据分布发生变化,通过层层叠加,高层的输入分布变化会非常剧烈,这就使得高层需要不断去重新适应底层的参数更新——BatchNorm就是在深度神经网络训练过程中使得每一层神经网络的输入保持相同分布
BN的基本思想:
训练过程中整体分布逐渐往非线性函数的取值区间的上下限两端靠近,导致反向传播时低层神经网络的梯度消失,训练收敛慢BN把每层神经网络任意神经元输出的分布强行拉回到均值为0方差为1的标准正态分布,使得激活输入值落在非线性函数对输入比较敏感的区域,可以得到比较大的梯度,避免梯度消失,梯度变大意味着学习收敛速度快,能大大加快训练速度 2. BN层的作用 加快网络的训练和收敛的速度 深度神经网络中,每层的数据分布不一样会导致网络非常难收敛和训练,BN将每层数据分布转化为一致的标准正态分布,更容易收敛控制梯度爆炸,防止梯度消失 梯度消失:深度神经网络中,如果网络的激活输出很大,其对应梯度会很小,甚至梯度消失,导致网络的学习速率慢,使用BN层归一化后,网络的输出不会很大,梯度就不会很小梯度爆炸:第一层偏移量的梯度=激活层斜率1x权值1x激活层斜率2x…激活层斜率(n-1)x权值(n-1)x激活层斜率n,假如激活层斜率均为最大值0.25,所有层的权值为100,这样梯度就会指数增加,但使用BN层后权值的更新也不会很大防止过拟合 在网络的训练中,BN的使用使得一个minibatch中所有样本都被关联在一起,因此网络不会从某一个训练样本中生成确定的结果,即同样一个样本的输出不再仅仅取决于样本的本身,也取决于跟这个样本同属一个batch的其他样本,而每次网络都是随机取batch,这样就会使得整个网络不会朝这一个方向使劲学习,一定程度上避免了过拟合Allows higher learning rates, faster convergence and networks become more robust to initialization -- Fei-Fei Li 注意⚠️:为什么BN层一般用在线性层和卷积层后面,而不是放在非线性单元后?
非线性单元的输出分布形状会在训练过程中变化,归一化无法消除它的方差偏移,相反的,全连接和卷积层的输出一般是一个对称、非稀疏的分布,更加类似高斯分布,对它们进行归一化会产生更加稳定的分布 例如Relu激活函数,输入的数据是一个高斯分布,变换后数据小于0的被抑制了(分布小于0的部分直接变成0) 3. 训练阶段和测试阶段的BN层 训练阶段:
例如batchsize为32,某层的某个神经元会输出32个响应值对这32个响应求均值和标准差,再做归一化归一化的响应值乘以γ,加上β每个神经元都训练一组γ、β 测试阶段:
测试阶段均值、方差、γ、β都用训练阶段全局求出 在测试阶段Batch Normalization相当于做线性变换 注意⚠️:Dropout和BN都有防止过拟合的作用,单独使用,都带来一定的性能改进,为什么一起用反而性能下降?
原因:
当网络的状态从训练转移到测试时,Dropout转移了特定神经单元的方差。但是,在测试阶段,BN保持了它的统计方差,这是在整个学习过程中积累的。Dropout和BN中方差的不一致性(“方差偏移”),导致推断中不稳定的数值行为,最终导致错误的预测 如下图,Dropout在训练阶段以p的概率进行失活,而在测试阶段,对每个神经元进行尺度放缩(乘p)。另一种等价的表现形式,在训练阶段乘1/p,而测试阶段不需要做任何改动,所以,训练:X=a*(1/p)*X,测试:X=X,存在方差偏移 解决方案:总体思路是降低方差偏移
在所有BN层后使用Dropout修改Dropout公式(如使用高斯Dropout)使得它对方差不是那么敏感 4. BN、LN、IN、GN与SN BN、LN、IN和GN这四个归一化的计算流程几乎一样,输入的图像shape记为[N, C, H, W],区别在于:
BatchNorm:在batch上,对NHW做归一化,把每个通道的NHW单独拿出来归一化处理,针对每个channel都有一组γ,β,可学习的参数为2*C,当batch size越小,BN的表现效果也越不好,因为计算过程中所得到的均值和方差不能代表全局
LayerNorm:在通道方向上,对CHW归一化,把每个CHW单独拿出来归一化处理,不受batchsize 的影响,主要对RNN作用明显,常用在RNN网络,但如果输入的特征区别很大,那么就不建议使用它做归一化处理
InstanceNorm:在图像像素上,对HW做归一化,把每个HW单独拿出来归一化处理,不受通道和batchsize 的影响,常用在风格化迁移,但如果特征图可以用到通道之间的相关性,那么就不建议使用它做归一化处理
GroupNorm:将channel分组再做归一化,把先把通道C分成G组,然后把每个gHW单独拿出来归一化处理,最后把G组归一化之后的数据合并成CHW,GN介于LN和IN之间,LN(G=C)和IN(G=1)是GN的特例
SwitchableNorm:将BN、LN、IN结合,赋予权重,让网络自己去学习归一化层应该使用什么方法,集万千宠爱于一身,但训练复杂
目录
(一)介绍什么是VTP
(二)VTP的原理
(1)VTP的构成
(2)VTP模式简介
(三)VTP的配置
(1)网络拓扑图
(2)配置代码
(四)VTP的验证
(一)介绍什么是VTP VTP(VLAN Trunk Protocol)VLAN中继协议:是一种应用在思科交换机上的管理VLAN的方法,同时也是思科的私有协议,在大型的项目中,往往需要用到很多交换机,那么为了管理者更好的统一配置和管理各个交换机上的VLAN,我们就可以用到VTP这个协议。
(二)VTP的原理 (1)VTP的构成 VTP域(domain):在同一个VTP域中的交换机可以同步VLAN配置信息
VTP密码(password):给在VTP域中的交换机配置密码
VTP模式(mode):一共有三种模式分别是服务端(Server)、客户端(Client)和透明模式(Transparent)
VTP通告:以组播帧的形式发送,思科模拟器在默认情况下每5分钟进行一次VTP通告,对交换机上的VLAN信息进行更新
(2)VTP模式简介 ①服务模式(server):在VTP服务端上可以创建、修改和删除VLAN,并且可以把这些信息通告出去
②客户模式(client):在客户端上不可以创建、修改和删除VLAN,并且同样可以把这些信息在trunk链路上进行通告
③透明模式(transparent):这种模式下的交换机是可以进行VLAN的创建、删除和修改,但并不会将这些信息通告出去,也并不会参与到VTP域中的VLAN信息修改和创建,他不会因为接收其他交换机的VLAN信息而去修改自己的VLAN信息,但是它会将接收到的信息通过trunk链路转发出去,其实可以理解为一个中转站,但在整个VTP中,这类的交换机不容易“被注意”,所以叫做透明模式
(三)VTP的配置 (1)网络拓扑图 (2)配置代码 第一步:在服务端(server)上配置
Switch>enable
Switch#conf t
Switch(config)#hostname SERVER ----改名
SERVER(config)#vtp mode server ----模式为服务模式
SERVER(config)#vtp domain 123 ----VTP域名为123
SERVER(config)#vtp password 123 ----配置密码
SERVER(config)#int range e0/0-1
SERVER(config-if-range)#switchport trunk encapsulation dot1q ----三层交换机要打标签
SERVER(config-if-range)#switchport mode trunk ----设置接口为trunk口
SERVER(config-if-range)#exit
SERVER(config)#
第二步:在客户端(client)配置
Switch>en
Switch#conf
Switch(config)#hostname CLIENT ----改名
CLIENT(config)#vtp mode client ----设置模式为客户模式
stata变量引用–潘登同学的stata笔记 文章目录 stata变量引用--潘登同学的stata笔记 变量生成gen命令通配符:*, ?, -因子变量时间序列 变量命名、前缀与标签变量命名、添加前缀通配符与批量重命名变量标签数字-文字对应表CSMAR数据处理 查看、查找变量单值、暂元单值暂元利用暂元写循环语句 变量生成 gen命令 sysuse nlsw88, clear gen lnwage = ln(wage) gen yes_white = (race==1) // [=exp] tabstat lnwage hours married age, by(yes_white) s(mean) f(%3.2f) 通配符:*, ?, - sysuse nlsw88, clear sum age race married never_married grade sum age-grade // 顺序出现的变量,列出头尾两个变量即可 sum s* // "*" 是孙悟空,可以表示`任何'长度的字母或数字 sum *arr* // 可以用在任何位置 sum ?a?e // "?" 是猪八戒,只能替代`一个'长度的字母或数字 因子变量 i: 表示将变量转换为虚拟变量c: 表示变量为连续型变量(只有加上c或i才能参与后续交乘项平方项的运算)#: 相当于乘号##: 能同时具有更低阶的交乘项 sysuse nlsw88, clear tab race // 类别变量 reg wage tenure hours i.
stata数据处理–潘登同学的stata笔记 文章目录 stata数据处理--潘登同学的stata笔记 数据导入、导出使表格第一行成为变量标注(label) 数据合并横向与纵向合并一对多与多对一横向合并 缺失值处理查看缺失值替换缺失值缺失值填充 离群值处理取对数的方法截尾处理、缩尾处理 分组统计列表统计分组回归 egen函数做数据处理其他egen函数 文字日期变量的处理将季度数据调整为月度数据 抽样不放回抽样有放回抽样 数据导入、导出 数据导入:
import excel auto.xls, firstrow sheet(Sheet1) clear br foreign encode foreign, gen(Cartype2) label(foreign) br Cartype2 label list foreign save myauto.dta, replace //保存为 Stata 格式数据文件 firstrow 表示把 Excel 的第一行视为变量名称sheet() 中填入 Excel 中的 sheet 名称Excel2003 文件后缀为 .xls, Excel2007 文件后缀为 .xlsx 数据导出:
sysuse auto.dta, clear export excel auto.xls, firstrow(variables) replace //首行为变量名称 shellout auto.xls // 打开 excel 文档 export excel auto.xlsx, firstrow(varlabels) replace //首行为变量标签 shellout auto.
【论文翻译】- Segment Anything / Model / SAM论文 论文链接:
https://arxiv.org/pdf/2304.02643.pdfhttps://ai.facebook.com/research/publications/segment-anything/ 代码连接:https://github.com/facebookresearch/segment-anything
论文翻译:
http://t.csdn.cn/nnqs8https://blog.csdn.net/leiduifan6944/article/details/130080159 文章目录 【论文翻译】- Segment Anything / Model / SAM论文摘要1、简介2、分割任何物体任务3、分割任意物体模型4、分割任何数据引擎5、数据集6、RAI分析7、零样本迁移实验7.1、零样本单点有效掩码评估7.2、零样本边缘检测7.3、零样本目标建议7.4、零样本实例分割7.5、Zero-Shot Text-to-Mask7.6、消融研究 8、讨论参考引用链接: 摘要 本文提出Segment Anything (SA)项目:一个用于图像分割的新任务、模型和数据集。在数据收集循环中使用我们的高效模型,我们构建了迄今为止(到目前为止)最大的分割数据集,在1100万张授权和尊重隐私的图像上有超过10亿个掩码。该模型被设计和训练为可提示的,因此它可以将零样本迁移到新的图像分布和任务。评估了其在许多任务上的能力,发现其零样本性能令人印象深刻——通常与之前的完全监督结果竞争,甚至优于。我们将在https://segment-anything.com"上发布Segment Anything模型(SAM)和相应的数据集(SA-1B),其中包含1B个掩码和1100万张图像,以促进对计算机视觉基础模型的研究。
1、简介 在网络规模的数据集上预训练的大型语言模型正在以强大的零样本和少样本泛化[10]彻底改变NLP。这些“基础模型”[8]可以泛化到训练期间看到的任务和数据分布之外。这种能力通常通过提示工程实现,其中使用手工制作的文本来提示语言模型为手头的任务生成有效的文本响应。当使用来自web的丰富文本语料库进行缩放和训练时,这些模型的零次和少次性能与微调模型(在某些情况下甚至匹配)相比惊人地好[10,21]。经验趋势表明,这种行为随着模型规模、数据集大小和总训练计算量的增加而改善[56,10,21,51]。
计算机视觉领域也对基础模型进行了探索,尽管程度较低。也许最突出的插图对齐了来自网络的成对文本和图像。例如,CLIP[82]和ALIGN[55]使用对比学习来训练对齐两种模态的文本和图像编码器。经过训练,工程文本提示可以零样本泛化到新的视觉概念和数据分布。这种编码器还可以与其他模块有效组合,以实现下游任务,如图像生成(如DALL·E[83])。虽然在视觉和语言编码器方面已经取得了很大进展,但计算机视觉包括了超出这个范围的广泛问题,对于其中许多问题,并不存在丰富的训练数据。
本文的目标是建立一个图像分割的基础模型。也就是说,本文试图开发一个可提示的模型,并使用一个能实现强大泛化的任务在广泛的数据集上对其进行预训练。使用该模型,旨在使用prompt工程解决新数据分布上的一系列下游分割问题。
这个计划的成功取决于三个部分:任务、模型和数据。为发展它们,本文解决有关图像分割的以下问题。
1.什么任务将实现零样本泛化?
2.对应的模型架构是什么?
3.什么数据可以支持这个任务和模型?
这些问题错综复杂,需要一个全面的解决方案。首先定义一个可提示的分割任务,足够通用,可以提供一个强大的预训练目标,并实现广泛的下游应用。此任务需要一个支持灵活提示的模型,并可以在提示时实时输出分割掩码,以允许交互使用。为了训练我们的模型,我们需要一个多样化的、大规模的数据源。不幸的是,没有web规模的分割数据源;为了解决这个问题,我们构建了一个“数据引擎”,也就是说,我们在使用高效的模型来帮助收集数据和使用新收集的数据来改进模型之间进行迭代。接下来介绍每个相互关联的组件,然后是创建的数据集和证明方法有效性的实验。
任务(§2)。在NLP和最近的计算机视觉中,基础模型是一个有希望的发展,可以通过使用"提示"技术对新数据集和任务进行零样本和少样本学习。受这一行工作的启发,本文提出了promptable分割任务,目标是在给定任何分割提示时返回有效的分割掩码(见图1a)。提示符只是指定要在图像中分割的内容,例如,提示符可以包括识别对象的空间或文本信息。有效输出掩码的要求意味着,即使提示是模糊的,并且可能指向多个对象(例如,衬衫上的一个点可能表示衬衫或穿着它的人),输出也应该是其中至少一个对象的合理掩码。将提示分割任务作为预训练目标,并通过提示工程解决一般的下游分割任务。
模型(§3)。可提示的分割任务和现实世界使用的目标对模型架构施加了约束。特别是,该模型必须支持灵活的提示,需要实时摊销计算掩码以允许交互使用,并且必须能够感知歧义。一个简单的设计满足了所有三个约束:一个强大的图像编码器计算图像嵌入,一个提示编码器嵌入提示,然后将两个信息源组合在一个预测分割掩码的轻量级掩码解码器中。我们把这个模型称为Segment Anything模型,简称SAM(见图1b)。通过将SAM分离为图像编码器和提示符快速编码器/掩码解码器,相同的图像嵌入可以在不同的提示符中重用(及其成本分摊)。给定图像嵌入,提示编码器和掩码解码器在web浏览器中从提示符预测掩码的时间为50ms。重点关注点、框和掩码提示,还用自由形式的文本提示呈现初步结果。为使SAM具有歧义性,设计了它来为单个提示预测多个面具,使SAM能够自然地处理歧义,如衬衫和人的例子。
数据引擎(§4)。为了对新的数据分布实现强大的泛化,有必要在一个大型和多样化的掩码集上训练SAM,而不是现有的任何分割数据集。虽然基础模型的典型方法是在线获取数据[82],但掩码本身并不丰富,因此我们需要另一种策略。我们的解决方案是建立一个“数据引擎”,即我们与在环模型数据集注释共同开发我们的模型(见图1c)。我们的数据引擎有3个阶段:辅助手动、半自动和全自动。在第一阶段,SAM帮助标注者注释掩码,类似于经典的交互式分割设置。在第二阶段,SAM可以通过提示它可能的对象位置,自动为一个对象子集生成掩码,注释器专注于注释剩余的对象,帮助增加掩码多样性。在最后阶段,用规则的前景点网格提示SAM,平均每张图像产生100个高质量掩模。
数据集(§5)。最终数据集SA-1B包括来自11M授权和保护隐私图像的超过1B个掩码(见图2)。使用数据引擎的最后阶段完全自动收集的SA-1B的掩码比任何现有的分割数据集[66,44,117,60]多400倍,并且经过广泛验证,掩码具有高质量和多样性。除了用于训练SAM使其健壮和通用外,我们希望SA-1B成为旨在建立新的基础模型的研究的宝贵资源。
负责任的AI(§6)。研究和报告了使用SA-1B和SAM时潜在的公平问题和偏见。SA-1B中的图像涵盖了一组地理和经济上不同的国家,我们发现SAM在不同人群中的表现相似。总之,我们希望这将使我们的工作对现实世界的用例更加公平。我们在附录中提供了模型卡和数据集卡。
实验(§7)。我们对SAM进行了广泛的评估。首先,使用一套不同的23个分割数据集,SAM从单个前景点产生高质量的掩码,通常只略低于手动标注的地面真实值。在使用prompt工程的零样本迁移协议下,对各种下游任务取得了一致强大的定量和定性结果,包括边缘检测、目标建议框生成、实例分割,以及对文本到掩码预测的初步探索。这些结果表明,SAM可以与prompt engineering一起开箱即用,以解决涉及SAM训练数据之外的物体和图像分布的各种任务。然而,正如我们在§8中所讨论的,改进的空间仍然存在。
Release。为了研究目的,我们发布了SA-1B数据集,并使SAM在一个许可的开放许可证(Apache 2.0)下可在https://segment-anything.com上使用。我们还通过一个在线演示展示了SAM的功能。
2、分割任何物体任务 从NLP中获得灵感,下一个token预测任务用于基础模型预训练,并通过提示工程[10]解决各种下游任务。为了建立一个分割的基础模型,本文旨在定义一个具有类似能力的任务。
任务。首先,我们将提示的想法从NLP转换为分割,其中提示可以是一组前景/背景点,一个粗略的框或掩码,自由形式的文本,或者一般来说,任何表示图像中要分割的信息。那么,promptable切分任务就是在给定任何提示时返回一个有效的切分掩码。“有效”掩模的要求只是意味着,即使提示是模糊的,并且可能指向多个对象(例如,回想一下衬衫和人的例子,参见图3),输出也应该是这些对象中的至少一个的合理掩模。这个要求类似于期望语言模型对有歧义的提示输出连贯的响应。选择这项任务,是因为它导致了一种自然的预训练算法和一种通过提示将零样本迁移到下游分割任务的通用方法。
预训练。promptable segmentation任务提出了一种自然的预训练算法,为每个训练样本模拟一系列提示(例如,点、框、掩码),并将模型的掩码预测与基本事实进行比较。本文从交互式分割[109,70]中采用这种方法,尽管与交互式分割的目的是在足够的用户输入后最终预测有效掩码不同,本文的目标是始终为任何提示预测有效掩码,即使提示是模糊的。这确保了预训练模型在涉及歧义的用例中是有效的,包括我们的数据引擎要求的自动注释§4。我们注意到,在这项任务中表现良好具有挑战性,需要专门的建模和训练损失选择,我们在§3中讨论。
Zero-shot迁移。预训练任务赋予了模型在推理时适当响应任何提示的能力,因此下游任务可以通过工程适当的提示来解决。例如,如果有一个猫的边界框检测器,则可以通过提供检测器的框输出作为我们模型的提示来解决猫实例分割。一般来说,一系列实际的分割任务都可以作为提示。除了自动数据集标注,在§7的实验中探索了五个不同的示例任务。
相关的任务。分割是一个广泛的领域:有交互式分割[57,109]、边缘检测[3]、超像素化[85]、目标建议生成[2]、前景分割[94]、语义分割[90]、实例分割[66]、全景分割[59]等。提示分割任务的目标是产生一个功能广泛的模型,通过提示工程可以适应许多(尽管不是全部)现有的和新的分割任务。这种能力是任务泛化[26]的一种形式。请注意,这与之前在多任务分割系统上的工作不同。在多任务系统中,单个模型执行一组固定的任务,例如联合语义、实例和全景分割[114,19,54],但训练和测试任务是相同的。本文工作中的一个重要区别是,为提示分割训练的模型可以作为更大系统中的一个组件,在推理时执行新的、不同的任务,例如,为了执行实例分割,将提示分割模型与现有的目标检测器相结合。
讨论。提示和组合是强大的工具,使单个模型能够以可扩展的方式使用,可能完成模型设计时未知的任务。这种方法类似于其他基础模型的使用方式,例如CLIP[82]是DALL·E[83]图像生成系统的文本-图像对齐组件。我们预计,由prompt engineering等技术驱动的可组合系统设计,将比专门为固定任务集训练的系统实现更广泛的应用。通过组合的角度来比较提示分割和交互分割也是很有趣的:虽然交互分割模型是为人类用户设计的,但为提示分割训练的模型也可以组合成一个更大的算法系统,我们将演示。
3、分割任意物体模型 接下来,我们描述了分段任意模型(SAM),以实现快速分割。SAM有三个组件,如图4所示:图像编码器,灵活的提示编码器和快速掩码解码器。建立了Transformer视觉模型[14,33,20,62],并对(平摊)实时性能进行了特定的权衡。我们在这里高层次地描述这些组件,详情见§A。
图像编码器。受可扩展性和强大的预训练方法的激励,本文使用MAE[47]预训练视觉Transformer (ViT)[33]最小适应于处理高分辨率输入[62]。图像编码器对每张图像运行一次,可以在提示模型之前应用。
提示编码器。考虑两组提示:稀疏(点、框、文本)和密集(掩码)。我们通过位置编码[95]表示点和框,并对每种提示类型的学习嵌入和自由形式的文本使用CLIP[82]的现成文本编码器进行求和。密集提示(即掩码)使用卷积嵌入,并与图像嵌入元素相加。
掩码译码器。掩码解码器有效地将图像嵌入、提示嵌入和输出标记映射到掩码。该设计受[14,20]的启发,采用了对Transformer解码器块[103]的修改,然后是动态掩码预测头。修改后的解码器块使用两个方向上的提示自注意力和交叉注意力(提示到图像嵌入,反之亦然)来更新所有嵌入。在运行两个块后,我们对图像嵌入进行上采样,MLP将输出标记映射到动态线性分类器,然后计算每个图像位置的掩码前景概率。
解决歧义。使用一个输出,如果给出模糊的提示,模型将平均多个有效掩码。为解决这个问题,我们修改了模型,以为单个提示预测多个输出掩码(见图3)。我们发现3个掩码输出足以解决大多数常见的情况(嵌套掩码通常最多有3个深度:整体、部分和子部分)。在训练过程中,我们只对掩模的最小损失[15,45,64]进行反向传播。为了对口罩进行排名,该模型预测每个口罩的置信度分数(即估计的IoU)。
效率。整体模型设计很大程度上是由效率驱动的。给定一个预先计算的图像嵌入,prompt编码器和mask解码器在web浏览器上运行,在CPU上,大约需要50毫秒。这种运行时性能使我们的模型能够无缝、实时的交互提示。
损失和训练。我们用[14]中使用的focal loss[65]和dice loss[73]的线性组合来监督掩膜预测。使用几何提示的混合来训练可提示的分割任务(关于文本提示,见§7.5)。在[92,37]之后,通过在每个掩码中11轮随机采样提示来模拟交互式设置,允许SAM无缝集成到我们的数据引擎中。
4、分割任何数据引擎 由于分割掩码在互联网上并不丰富,我们构建了一个数据引擎,以收集我们的11 b掩码数据集SA-1B。该数据引擎有三个阶段:(1)模型辅助的手动标注阶段,(2)半自动阶段,其中混合了自动预测的掩码和模型辅助的标注,以及(3)全自动阶段,在该阶段中,我们的模型在没有标注者输入的情况下生成掩码。我们接下来会详细介绍每一种。
环境:centos7,双网卡
ens18: 192.168.6.51
ens19: 192.168.2.111
client:192.168.6.41访问192.168.6.51正常,
client:192.168.6.41访问192.168.2.111不正常,
路由如下:
[root@localhost ~]# route -n Destination Gateway Genmask Flags Metric Ref Use Iface 0.0.0.0 192.168.6.1 0.0.0.0 UG 102 0 0 ens18 192.168.2.0 0.0.0.0 255.255.255.0 U 101 0 0 ens19 192.168.6.0 0.0.0.0 255.255.255.0 U 102 0 0 ens18 服务器收到数据包之后,如果是自己的包,就会往上层协议栈转发处理,而如果不是自己的,就会根据路由表进行转发。
当服务器接收到来自192.168.6.41访问192.168.6.51的包后,查询路由表最优路径匹配到192.168.6.0,0表示匹配任意,Iface表示网卡,所以会从ens18网口进入,
回包,反向源地址和目的地址互换,目标地址变为192.168.6.41,查询路由表只能匹配到0.0.0.0,Iface表示网卡,所以会从ens18网口出去,
进口和出口都是ens18网卡,所以能正常转发。
当服务器接收到来自192.168.6.41访问192.168.2.111的包后,查询路由表最优路径匹配到192.168.2.0,0表示匹配任意,Iface表示网卡,所以会从ens19网口进入,
回包,反向源地址和目的地址互换,目标地址变为192.168.6.41,查询路由表只能匹配到0.0.0.0,Iface表示网卡,所以会从ens18网口出去,
回包会从ens18发出,这就导致了异步路由问题。
linux内核针对这个问题,有一个安全机制,反向路由检测机制。
Linux的反向路由检测机制,该机制的目的有多个:
– 避免出现意料之外的结果(从一个网卡进,从另一个网卡出),形成循环
– 安全考虑,避免出现IP单播数据包的欺骗
– 避免在较复杂的网络拓扑环境下,因为路由器错误的路径规划,造成反向路径过于复杂,降低网络性能。
rp_filter (Reverse Path Filtering)参数定义了网卡对接收到的数据包进行反向路由验证的规则。他有三个值,0、1、2,具体含意如下:
0:关闭反向路由校验
1:开启严格的反向路由校验。对每个进来的数据包,校验其反向路由是否是最佳路由。如果反向路由不是最佳路由,则直接丢弃该数据包。
2:开启松散的反向路由校验。对每个进来的数据包,校验其源地址是否可达,即反向路由是否能通(通过任意网口),如果反向路径不通,则直接丢弃该数据包。
修改方式如下:
sysctl -w net.
nvm是node的一款版本管理工具,可以简单操作node版本的切换、安装、查看。常规来说,开发中安装一个node版本就够了,但是最近在开发中有的老项目或者一些特定的项目需要来回切换node的版本,不可能手动去卸载掉之前的node版本,又去下载需要的node版本来安装在使用,这样效率太低下了。所以nvm的作用就体现了,nvm-windows是专门针对windows系统的应用。
自己之前也一直没有使用过nvm-windows这个工具,不知道怎么安装、使用,所以百度了安装以及使用方法,发现很多博主分享的都是比较片面的,要么不合符自己的需求,要么有的是自己实际操作后根本无法使用,所以这里介绍下我踩过的坑
下载 下载地址如下:
https://github.com/coreybutler/nvm-windows/releases
选择自己需要的下载就是了。这里说明一下,有的博主说要下载1.1.7的版本终端才不会出现乱码字符,亲测乱码字符不是版本的缘故,所以这里大家可以根据自己需要的版本下载
安装 安装有点小讲究,不过还好
1. 这一步是让你选择nvm安装的盘符,建议非系统盘
2. 这一步是让你选择后面node的下载存放地址,这一步比较关键,后面的node版本切换不成功、npm无法使用等原因都跟这里的选择有较大的关系,上面图片的地址是默认的存放地址,这里建议大家都选中跟上面安装nvm的盘符一样,我上面装在D盘,这里我也选择D盘放置下载的node
那么这里选择D盘就完了嘛,不~ 坑就在这里,很多博主直接说选择D盘就完了,然后一路next下去,然后安装完成之后发现node版本切换不成功,最后就是去各种环境变量的配置修改。其实这里根本不用后面的环境的配置,如果修改了环境变量的配置,后面你还需要使用npm去下载yarm、pnpm等其他包管理工具的时候,你会发现可能导致pnpm yarm的安装失败,失败原因大致就是环境变量那套东西导致的,这里正确的做法是选择D盘之后,再在路径后面键入存放node的文件夹,我这里取的nodejs的名称
这样你后面下载的node就会存储在D盘下面的nodejs文件夹里,这样是最方便,最省事的,后面不用修改环境变量什么的。
另外这里还有博主写的是选择跟上面安装nvm的文件夹一样,也就是D:\nvm,这里大家注意,不要选择把下载的node存放在安装nvm的nvm文件夹下,也就是下图这样的路径,这样也会导致后面需要配置环境变量
安装完成之后建议配置下node下载的国内镜像
在nvm的安装路径下找到 setting.txt,新增如下信息
node_mirror: https://npm.taobao.org/mirrors/node/ npm_mirror: https://npm.taobao.org/mirrors/npm/ 每行的意思分别表示:
第一行是nvm安装路径
第二行是nodejs路径
第三行是node下载镜像
第四行是npm下载镜像
然后就可以去使用nvm了,很多博主建议cmd以管理员身份打开,在cmd中去操作nvm。但是我们平时开发都是在vscode的终端中去操作的,你还要关闭vscode的窗口,去打开cmd着实麻烦,其实可以直接在vscode的终端中去操作的,给vscode管理员身份就行了
1. vscode右键点击,选择属性
2.选择高级
3. 勾选 管理员运行
这样vscode终端中输入的命令就是以管理员身份执行的了
使用 vscode终端中使用 nvm -v 命令查看版本
可以看到版本,表示安装成功
这样就可以下载 切换 node版本了,具体怎么下载 切换的命令,大家自己可以看看nvm的常规使用命令
如果还有要使用pnpm yarn 的 ,自己在安装下就是了,例如安装pnpm:
前提是你已经安装了并且切换了你要使用的node版本,npm已经可以正常使用
像往常一样安装其他工具一样的命令 这样操作之后,ok,可以正常使用。可以看到刚才选择的存放node的文件夹nodejs里面已经有node的相关文件了
并且安装的包管理工具也在node_modules中可以看到了,一切都OK
这样操作下来,不用修改环境变量,不会出现无法切换node版本, 也没有出现 nvm use xxx 失败的情况
一、textarea文本域标签 常见属性:
cols文本域可见宽度rows文本域可见行数 注:右下角可拖拽改变文本大小。实际开发针对样式效果:
<textarea name="文本" cols="30" rows="10"></textarea> 推荐CSS设置。
二、label标签 1,使用label标签把内容如文本包裹起来。
2,在表单标签上添加id属性。
3,在label标签的for属性中设置对应id属性值
使用方法:
1,直接使用label标签把内容如文本和表单标签一起包裹起来。
2,需要把label标签的for属性删除即可。
三、语义化标签 ①没有语义布局标签(div、span)
div标签:一行只显示一个(独占一行)
span:一行可以显示多个(双标签)
②有语义的布局标签
标签名语义header网页头部hav网页导航footer网页底部aside网页侧边栏section网页区块article网页文章
jenkins安装请参考上一篇文章:centOS安装jenkins_centos an安装jkens_不求甚解bc的博客-CSDN博客
准备工作 1、安装参数化部署插件
Git Parameter Plug-In git参数化构建,可选择分支、标签构建Extended Choice Parameter Plug-In 自定义参数化构建,可根据需要任意添加参数NodeJS Plugin Node环境,打包vue项目 2、安装好插件后,配置Nodejs环境
打开全局工具配置
找到NodeJS,填写别名,选择需要安装的node版本
创建项目 1、创建一个job,选择构建一个自由风格的软件项目
2、选择根据分支选项构建项目,也可以根据刚才安装的Extended Choice Parameter Plug-In插件选择自定义参数,已选值建议使用TOP,即第一个
3、添加Git仓库,校验填写Git账号和密码,指定分支使用第2步的参数名,用${}包裹
4、构建环境添加node
5、添加执行shell脚本
shell脚本注解
// 安装依赖包 npm install // 删除原有dist目录 rm -rf ./dist/* // 打包 npm run build // 删除nginx服务前端资源目录 rm -rf /usr/share/nginx/html/vue-demo/* // 将打包后的新资源添加到nginx服务前端目录 cp -rf ./dist/* /usr/share/nginx/html/vue-demo/ 上传到外部服务器
// 通过ssh-keygen命令生成公钥 ssh-keygen -t rsa // 在/root/.ssh/目录下会生成一个'id_isa.pub'的文件,将其拷贝到目标主机 // 部署到外部服务器shell脚本 scp -r ./dist/* root@47.100.51.191:/usr/share/nginx/html/vue-demo/ 6、build过程中,经常会出现没有权限写入文件的情况
因为jenkins默认的用户是jenkins,可以通过给jenkins用户添加文件夹操作权限解决
chown -R jenkins /usr/share/nginx/html 7、构建成功后自动打tag,方便找到对应部署版本。tag内容可根据需求自己填写,我使用时间加分支形式,${BUILD_TIMESTAMP}为当前时间,${GIT_BRANCH}为分支