1、Redis为什么这么快 Redis有多快?单机可以支持约10w/s的QPS。
(1)纯内存操作
(2)5中数据类型选用的内部数据结构经过精心设计
(3)6.0以前采用单线程,省去了很多上下文切换的时间以及CPU消耗,不存在竞争条件,不用去考虑各种锁的问题
(4)基于非阻塞IO多路复用机制(select()、epoll())
通过一个线程监听多个socket的IO连接事件,从而实现在单个线程中处理多个连接的读写操作
这个线程是一个事件处理器(event loop);
该事件处理器会将每个连接对应的 文件描述符 注册到事件监听机制中,并在事件就绪时调用相应的读写函数来处理IO操作,这样就可以单线程处理多个连接IO操作
2、Redis的过期策略以及内存淘汰机制 redis采用的是定期删除+惰性删除策略。
2.1、为什么不用 定时删除 策略 定时删除,用一个定时器来负责监视key,过期则自动删除。虽然内存及时释放,但是十分消耗CPU资源。在大并发请求下尤其不适用。
2.2、定期删除+惰性删除是如何工作的 (1)定期删除,redis默认每个100ms检查,检查有过期key则删除。
需要说明的是,redis不是每隔100ms将所有的key检查一次,而是随机抽取进行检查(如果每隔100ms,全部key进行检查,redis岂不是卡死)。因此,如果只采用定期删除策略,会导致很多key到时间没有删除。
(2)于是,惰性删除派上用场。在获取某个key的时候,redis会检查一下,这个key如果设置了过期时间那么是否过期了,如果过期了此时就会删除(懒汉式)。
2.3、采用定期删除+惰性删除就没其他问题了么? 不是的,如果定期删除没删除key,也没即时去请求key,也就是说惰性删除也没生效。这样,redis的内存会越来越高。那么就应该采用内存淘汰机制。在redis.conf中配置。
2.4、Redis内存淘汰机制 当Redis的内存使用达到配置的最大内存限制时,会触发内存淘汰机制来释放部分内存空间
(1)allkeys-lru(推荐)
当内存不足以容纳新写入数据时,移除最近最少使用的key
(2)allkeys-random(不推荐)
随机移除某个key
(3)volatile-lru(不推荐)
在设置了过期时间的键空间中,移除最近最少使用的key
(4)volatile-random(不推荐)
在设置了过期时间的键空间中,随机移除某个key
(5)volatile-ttl(不推荐)
3、Redis并发环境下使用 3.1、如何解决redis的并发竞争key问题 (1)事务
通过使用MULTI、EXEC和WATCH命令,可以将多个操作作为一个事务进行执行,但是生产环境redis一般是集群的,不适用。
(2)乐观锁
使用版本号(Version)来实现乐观锁。每次对键进行修改时,都会更新该键的版本号;在读取时,先获取当前版本号,然后进行操作,最后再次验证版本号是否一致,如果版本号不一致,说明该键已被其他客户端修改,需要重新尝试。
(3)分布式锁(推荐)
是一种在分布式系统中解决并发竞争的常见机制,可使用Redisson
(4)队列Queue
将需要对同一个键进行操作的请求放入队列中,然后通过一个单独的线程或来处理队列中的请求。这样可以保证对同一个键的操作按序执行,避免并发竞争。
3.2、MySQL里有2000w数据,redis中只存20w的数据,如何保证redis中的数据都是热点数据 (1)缓存淘汰策略
redis 内存大小上升到一定大小时,就会施行数据淘汰策略,可选LRU最近最少使用淘汰策略;
(2)数据预热
在系统启动时,将热点数据预先加载到Redis中。可以使用jedis的管道(Pipeline )批量初始化加载到Redis。
Jedis jedis = JedisUtil.getJedis(); // 管道 Pipeline pipelined = jedis.pipelined(); for (int i = 0; i < 10000; i++) { pipelined.
PyTorch:关于Dataset,DataLoader 和 enumerate() 本博文主要参考了 Pytorch中DataLoader的使用方法详解 和 pytorch:关于enumerate,Dataset和Dataloader 两篇文章进行总结和归纳。
DataLoader 隶属 PyTorch 中 torch.utils.data 下的一个类,任何继承 torch.utils.data.Data 类的子类均需要重载__getitem__()及__len__()两个函数,且子类在__init__()函数产生的数据路径,将作为 DataLoader 参数 DataSets 的实参。该类将自定义的 Dataset 根据 batch size 大小、是否 shuffle 等封装成一个 Batch Size 大小的 Tensor,用于后面的训练。
Dataset 类构建 在构建数据集类时,除了__init__(self),还要有__len__(self)与__getitem__(self,item)两个方法,这三个是必不可少的,至于其它用于数据处理的函数,可以任意定义。这里的 Dateset 可以指整个数据集,也可以是训练集,测试集等。
class Dataset: def __init__(self,...): ... def __len__(self,...): return n def __getitem__(self,item): return data[item] 正常情况下,该数据集是要继承 Pytorch 中 Dataset 类的,但实际操作中,即使不继承,数据集类构建后仍可以用 Dataloader() 加载的。
在dataset类中,len(self)返回数据集中数据的总个数,getitem(self,item)表示每次返回第 item 条(个)数据。
①__init__:传入数据,或者像下面一样直接在函数里加载数据
②__len__:返回这个数据集一共有多少个 item
③__getitem__:返回一条(个)训练样本的数据,并将其转换成 tensor
在 dataset 实例化时一般要传入数据集的路径,一般在__init__() 函数中指定数据集路径等相关信息(可以通过相关路径读取包含图像名称、标签等相关信息的 json 或者 csv 等类型的文件);通过__getitem__(self,item) 得到对应的图像并将进行 transform 转换(缩放、裁剪、转换成 tensor 等操作),最终以 tensor 的形式返回。
1.概述 数据加载速度是评判数据库性能的重要指标,能否提高数据加载速度,对文件数据进行并行解析,直接影响数据库运维管理效率。基于此,AntDB分布式数据库提供了两种数据加载方式:
一是类似于PostgreSQL的Copy命令,二是通过AntDB提供的并行加载工具。Copy命令是大家都比较熟悉的,但Copy命令导入数据需要通过CN节点,制约了数据的导入性能,无法实现并行、高效的加载。而AntDB并行加载工具可以绕过CN节点,直连数据节点,大大提高了加载的速率。
2.实现原理 2.1并行加载工具整体流程 并行加载工具有两种线程,一种是文本处理线程,另外一种是数据处理线程。文本处理线程只有1个,用来读取文件,并按行进行拆分,拆分后将行数据发送到数据处理线程。数据处理线程是多个,并行分析行数据,并加载到相应数据节点。
图1 并行加载工具架构
2.2文本处理 并行加载工具支持Text和Csv两种格式的文件,下面简要说明下。Text和Csv文件都是以纯文本形式存储表格数据的,文件的每一行都是一个数据记录。每个记录由一个或多个字段组成,用分隔符分隔。文本处理线程的任务就是从文件中提取一行完整的记录,然后发送给数据处理线程。
文件中每一行数据以字符’\n’或者’\r\n’结尾。当是Csv文件是,由于Csv文件支持引用字符,当‘\n’、’\r\n’出现在引用字符中间时,作为普通字符处理,不能作为行结尾。Csv的引用字符为单字节字符,用户可以根据需要自己指定,未指定的话默认是双引号。
2.3行数据处理 数据处理线程用来分析文本处理线程发来的行数据,行数据由一个或多个字段组成,用分隔符分隔,分隔符可以指定。
数据处理线程从CN获取数据库及表相关信息,包括数据库编码方式,表分片方式,表的分片键等。
AntDB数据库中的表支持以下4中分布方式:
复制表Hash分片表取模分片表随机分片表 并行加载工具会根据表的分布方式生成相应的导入策略。以下以不同的表分布方式说明并行加载工具的导入策略。
复制表在每个DN数据节点都保留完整的数据,复制表的数据导入时,需要将行数据插入到所有DN节点。 图2 复制表数据加载流程
Hash分片表将表数据分散到各DN节点,通过对分片键进行Hash,确定行数据属于哪个DN节点。并行加载工具的行处理线程,通过CN节点获取Hash分片表的分片健,对其进行Hash,然后将该行数据插入对应的DN节点,并行加载工具中的Hash分片的算法需要和CN节点的Hash算法一致。 图3 hash分配表数据加载流程
取模分片表也是将表数据分散到各DN节点,通过对分片键进行取模确定行数据所属DN节点,并行加载工具导入的处理策略与Hash分片表相同,只是将Hash计算换成了取模的方式。随机分片表没有分片键,而是将数据根据随机分配到各DN节点。并行加载工具在每行数据导入前执行各随机函数,根据函数的返回值确定应该导入哪个节点。 图4 随机分片表数据加载流程
摘要 本篇技术博客将介绍如何使用克魔助手工具来查看iOS游戏的帧率(FPS)。通过克魔助手,开发者可以轻松监测游戏性能,以提升用户体验和游戏质量。
引言 在iOS游戏开发过程中,了解游戏的帧率对于优化游戏性能至关重要。克魔助手为开发者提供了一种简单可靠的方法来查看帧率,帮助他们监测游戏的运行数据,从而优化游戏性能。本文将详细介绍使用克魔助手来检查iOS游戏的帧率的步骤,并探讨其在游戏开发过程中的重要性。
克魔助手主页面 首先,为了使用克魔助手检查iOS游戏的帧率,需要在电脑上安装爱思助手或者iTunes驱动。随后,通过USB连接苹果手机到电脑,并启动克魔助手。
设备选择 第二步,在工具左侧菜单栏中,打开“设备”窗口。窗口中会显示你连接的所有苹果设备,选择要查询的设备,然后选中设备。
查看FPS和fps监测 第三步,点击“开始监听”,在右侧的“FPS曲线”查看当前应用程序的帧率。另外,在克魔助手中可以看到每秒图像
更新多少次,以及总图像更新次数,从而了解游戏性能如何。
CPU占比和应用追踪及特定APP数据 第四步,查看帧率是保证游戏顺畅性的重要因素,所以应用程序开发人员将会经常使用克魔助手检查苹果手机玩游戏的帧率。当然,游戏还有很多需要优化的地方,可以提高游戏整体性能,所以克魔助手不仅提供了监控帧率,还提供了可以分析内存占用,查看CPU实时活动数据,以及追踪特定app时等功能,让开发者可以更好地了解游戏运行情况。
通过克魔助手的帮助,开发者可以方便快捷地检查苹果手机玩游戏的帧率。了解帧率和游戏性能对增加游戏用户量,增强用户体验和游戏的质量都非常重要,所以在开发过程中不要忘记检查苹果手机的帧率。
文章目录 【 1. 系统管理 】1.1 查询系统版本1.2 查询硬件信息1.3 date 系统时间 【 2. IPC资源管理 】2.1 IPC 资源查询2.2 ulimit 检测和设置系统资源限制 【 1. 系统管理 】 1.1 查询系统版本 查询 Linux 系统版本 uname -a lsb_release -a 查询 Unix 系统版本 more /etc/release 1.2 查询硬件信息 命令作用sar -u 5 10查询 CPU 使用情况cat /proc/cpuinfo查询 CPU 信息cat /proc/cpuinfogrep processorcat /proc/meminfo查询内存信息pagesize显示内存page大小(以KByte为单位)arch显示架构 1.3 date 系统时间 全称作用date 日期显示或设置系统时间与日期 显示当前系统时间 # 直接输出当前 日期、周几、时间、时区 date # 格式化输出当前日期时间 date +%Y%m%d.%H%M%S 设置系统日期和时间格式(格式为2014-09-15 17:05:00)
设置系统时间需要 root 用户权限。 date -s 2014-09-15 17:05:00 date -s 2014-09-15 date -s 17:05:00 设置时区
1、创建编辑器
UE.getEditor('editor', {
initialFrameWidth:"100%" //初始化选项
})
精简版
UE.getEditor('editor')
2、删除编辑器
UE.getEditor('editor').destroy();
3、使编辑器获得焦点
UE.getEditor('editor').focus();
4、获取编辑器内容
UE.getEditor('editor').getContent()
5、编辑器是否有内容
UE.getEditor('editor').hasContents()
6、获取编辑器内容纯文本格式
UE.getEditor('editor').getContentTxt()
7、获取带格式的纯文本
UE.getEditor('editor').getPlainTxt()
8、启用编辑器
UE.getEditor('editor').setEnabled();
9、禁止编辑
UE.getEditor('editor').setDisabled('fullscreen');
10、获取整个html内容
UE.getEditor('editor').getAllHtml()
11、获取整个html内容
UE.getEditor('editor').setContent('欢迎使用ueditor', isAppendTo);
12、编辑器是否获得焦点
UE.getEditor('editor').isFocus();
13、编辑器失去焦点
UE.getEditor('editor').blur()
14、获取选区
UE.getEditor('editor').selection.getRange();
15、获取选中的文本
UE.getEditor('editor').selection.getText();
16、插入给定的内容
UE.getEditor('editor').execCommand('insertHtml', "插入你想插入的值")
17、设置可以编辑
UE.getEditor('editor').setEnabled();
18、设置禁止编辑
UE.getEditor('editor').setDisabled('fullscreen');
19、隐藏编辑器
UE.getEditor('editor').setHide()
19、显示编辑器
UE.getEditor('editor').setShow()
20、设置高度,为300默认关闭了自动长高
UE.getEditor('editor').setHeight(300)
常用设置
imageUrl:UEDITOR_HOME_URL + "../yunserver/yunImageUp.php", //图片上传接口
imagePath:"http://",
scrawlUrl:UEDITOR_HOME_URL + "../yunserver/yunScrawlUp.php",//涂鸦接口
scrawlPath:"http://",
fileUrl:UEDITOR_HOME_URL + "../yunserver/yunFileUp.php",//文件上传接口
filePath:"http://",
catcherUrl:UEDITOR_HOME_URL + "php/getRemoteImage.php",//获取远程图片接口
catcherPath:UEDITOR_HOME_URL + "
文章目录 前言一、Redis 分片集群介绍1.1 介绍:1.2 工作机制:1.2.1 节点:1.2.2 槽 slot:1.2.3 故障转移: 二、Redis 分片集群搭建:2.1 配置文件:2.2 redis 部署:2.3 redis 集群创建:2.4 redis 集群连接: 总结参考: 前言 对于平常的业务往往使用redis 的哨兵模式就可以了,虽然redis 单台服务可以提供10W 的并发,但是对于并发量非常大的服务来说可能还不够,所以此时就需要对redis 进行分片集群;
一、Redis 分片集群介绍 1.1 介绍: 如果说依靠哨兵可以实现redis的高可用,如果还想在支持高并发同时容纳海量的数据,那就需要 redis 集群。redis 集群是 redis 提供的分布式数据存储方案,集群通过数据分片sharding来进行数据的共享,同时提供复制和故障转移的功能。
1.2 工作机制: 1.2.1 节点: 一个 redis 集群由多个节点 node 组成,而多个 node 之间通过 cluster meet 命令来进行连接,节点的握手过程:
节点 A 收到客户端的 cluster meet 命令节点 A 根据收到的 IP 地址和端口号,向 B 发送一条 meet 消息节点 B 收到 meet 消息返回 pong节点 A 知道 B 收到了 meet 消息,返回一条 ping 消息,握手成功最后,节点 A 将会通过 gossip 协议把节点 B 的信息传播给集群中的其他节点,其他节点也将和 B 进行握手 1.
目录
1 概述
2 QStringListModel常用方法
3 使用QStringListModel的步骤 4 QStringListModel的使用
4.1 Model/View结构对象和组件初始化
4.2 编辑、添加、删除项的操作
4.3 以文本显示数据模型的内容
4.4 其他功能
1 概述 QStringListModel用于处理字符串列表的数据模型,它可以作为QListView的数据模型,在界 面上显示和编辑字符串列表。 QStringListModel的setStringList()函数可以初始化数据模型的字符串列表的内容,stringList() 函数返回数据模型内的字符串列表,在关联的 ListView 组件里编辑修改数据后,数据都会及时更 新到数据模型内的字符串列表里。 QStringListModel提供编辑和修改字符串列表数据的函数,如insertRows()、removeRows()、 setData() 等,这些操作直接影响数据模型内部的字符串列表,并且修改后的数据会自动在关联的 ListView 组件里刷新显示。 2 QStringListModel常用方法 1. QStringListModel(const QStringList &strings, QObject *parent = nullptr):构造函数,用于创建一个QStringListModel对象,并初始化它的数据为strings列表。 2. int rowCount(const QModelIndex &parent = QModelIndex()) const:返回模型中的行数。 3. QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const:返回模型中指定索引的数据。 4. bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole):设置模型中指定索引的数据为value。 5.
用户注册汇总表 需求分析 统计各窗口的注册用户数,写入Doris 思路分析 读取kafka用户注册主题数据转换数据结构 string -> JSONObject->javaBean使用user_info表中的数据代表用户注册设置水位线开窗聚合写入Doris 具体实现 创建用户注册统计类继承BaseApp,设置端口,并行度,kafka消费者组,kafka主题(Topic_user_register)启动zookeeper, HDFS, kafka, maxwell等框架测试能够收到数据stream.print()数据清洗过滤,并且转换数据结构为javaBean JSONObject.parseObject(value);转换格式json.getString();获取对应字段判断对应字段是否为空,不为空则out.collect()写出 添加水位线 assignTimestampsAndWatermark()使用WatermarkStrategy.<泛型>乱序流DateFormatUtil.dateTimeToTs(element.getCreateTime());提取数据中的时间 分组开窗聚合 reduce聚合 v1:累加值v2:需要累加进来的值 process获取窗口信息 启动doris, 在hadoop102:8030打开web页面在doris页面建立相应的表格创建对应的doris sink context.window()获取窗口windowwindow.getStart()和window.getEnd() 写出到doris, stream.sinkTo(doris sink); 用户加购汇总表 需求分析 统计各窗口加购独立用户数,写入Doris
思路分析 和上面一样
具体实现 数据的清洗过滤,判断user_id和ts不能为空 使用try-catch包裹转换判断代码修改ts的位数,原先是10位的秒级单位,*1000更改为毫秒级 添加水位线,获取数据中的ts 水位线可以保证数据是有序到达的 按照user_id进行分组判断是否为独立用户 创建独立用户加购类 CartAddUuBean在open方法中存储用户上次登录日期lastLoginDtState 设置状态的生存时间:lastLoginDtDesc.enableTimeToLive(StateTtlConfig.newBuilder(Time.days(1)).builder) 在processElement方法中,判断当前数据的时间和状态中的上次登录时间 如果上次登录时间为空或者上次登录时间不等于今天,就是独立用户lastLoginDtState.update(curDt);更新当前的状态如果是独立访客,才需要out.collect()写出 开窗聚合 v1.set(v1.get + v2.get)对度量值进行聚合TimeWindow window = context.window()获取窗口信息 测试开窗聚合信息是否完成写出到Doris, .map(转换为蛇形字符串) .sinkTo(doris sink); [gitee仓库地址:(https://gitee.com/langpaian/gmall2023-realtime)
文章目录 前言一、哨兵模式介绍:1.1 介绍:1.2 工作机制: 二、哨兵模式搭建:2. 1 redis 主从搭建:2.2 setinel 集群搭建:2.2.1 配置: sentinel.conf :2.2.2 运行容器:2.2.3 查看容器的信息:2.2.4 故障自动转移:2.2.5 slave 晋升maser:2.2.6 原主节点重新启动: 总结:参考: 前言 虽然有了Reids 的主从模式,但是我们发现它的故障转移能力非常弱,所以在主从模式的基础之上有衍生出了哨兵模式。
一、哨兵模式介绍: 1.1 介绍: 基于主从方案的缺点还是很明显的,假设 Master 宕机,那么就不能写入数据,那么 Slave 也就失去了作用,整个架构就不可用了,除非你手动切换,主要原因就是因为没有自动故障转移机制。
而哨兵(sentinel)的功能比单纯的主从架构全面的多了,哨兵模式是一种特殊的模式,首先 Redis 提供了哨兵的命令,哨兵是一个独立的进程,作为进程,它独立运行。其原理是哨兵通过发送命令,等待 Redis 服务器响应,从而监控运行的多个 Redis 实例。因此哨兵模式具备了自动故障转移、集群监控、消息通知等功能。
1.2 工作机制: 哨兵可以同时监视多个主从服务器,并且在被监视的 Master 下线时,自动将某个 Slave 提升为 Master,然后由新的 Master 继续接收命令。整个过程如下:
初始化 sentinel,将普通的 redis 代码替换成 sentinel 专用代码初始化 Masters 字典和服务器信息,服务器信息主要保存 ip:port,并记录实例的地址和 ID创建和 Master 的两个连接,命令连接和订阅连接,并且订阅 sentinel:hello 频道每隔 10 秒向 Master 发送 info 命令,获取 Master 和它下面所有 Slave 的当前信息
文章目录 前言Redis 主从部署:1.1 主从架构 介绍:1.2 主从架构 实现:1.2.1 redis 安装: 1.3 主从架构优缺点:1.4 故障转移: 总结 前言 显然在线上环境中 Redis 服务不能以单机的方式运行,必须有备份,来应对服务挂掉的情况,本文通过docker 完成 Redis 的主从模式部署;
Redis 主从部署: 1.1 主从架构 介绍: Redis主从架构是一种常见的数据复制和高可用性架构设计,它包括一个主节点和多个从节点。主节点负责接收写操作并将数据同步到所有从节点,而从节点则负责从主节点复制数据,并处理读请求。
主节点是可读可写的,所有的写操作都在主节点进行处理,主节点将写操作的结果同步到所有从节点上。从节点是只读的,它们通过与主节点进行复制同步来保持数据一致性。当客户端发起读请求时,可以在主节点或从节点上进行处理。
工作机制:
当save动后,主动向mastr发送SYNC命令,master接收到SYNC命令后在后合保存快照(RDB特久化) 和缓存保存快照这段时间的命令,然后将存的快照文件和缓存的命令发送给slave。slave接收到快照文件和命令后加载快照文件和缓存的执行命令.
复制初始化后,master每次接收到的写命令都会同步发送给slave,保证主从数据一致性。
1.2 主从架构 实现: 本文拉取到redis 最新的镜像 实际版本为:redis-cli 7.2.3
1.2.1 redis 安装: 1) 镜像下载:
docker search redis 选择星数最高的 进行镜像下载:
docke pull redis 2)容器安装:
在宿主机上创建redis.conf 配置文件,便于对redis 进行参数设置,创建data 文件夹对redis 的数据进行持久化:
其中redis.conf 可以参考如下:
#redis.conf # Redis configuration file example. # ./redis-server /path/to/redis.conf ################################## INCLUDES ################################### #这在你有标准配置模板但是每个redis服务器又需要个性设置的时候很有用。 # include /path/to/local.
背景:在上一篇文中,提到要写一篇openssl 配置文件详解的,这就来了~~~
find / -name openssl.cnf
/etc/pki/tls/openssl.cnf
/etc/pki/tls/openssl.cnf,该文件主要设置了证书请求、签名、crl相关的配置。主要相关的伪命令为ca和req。。
该文件从功能结构上分为4个段落:默认段、ca相关的段、req相关的段、tsa相关的段。每个段中都以name=value的格式定义.
以下是我将文件分段摘抄出来,并进行解释的:
默认段: #
# OpenSSL example configuration file.
# This is mostly being used for generation of certificate requests.
#
# This definition stops the following lines choking if HOME isn't
# defined. 定义当前目录变量,以及随机数的文件路径变量
HOME = .
RANDFILE = $ENV::HOME/.rnd
# Extra OBJECT IDENTIFIER info:
#oid_file = $ENV::HOME/.oid
oid_section = new_oids
# To use this configuration file with the "-extfile" option of the
IPsec(InternetProtocolSecurity)是为IP网络提供安全协议和服务的集合,是VPN(VirtualPrivateNetwork,一种常用于虚拟专用网络的技术。IP数据包在公共网络中传输,如Internet,可能面临被伪造、窃取或篡改的风险,因为IP报文本身没有集成任何安全特性。通信双方通过IPsec建立IPsec隧道,IP数据包通过IPsec隧道进行加密传输,有效保证了Internet等不安全网络环境下数据传输的安全性。
什么是IPsecVPN?
VPN(VirtualPrivateNetwork,虚拟专用网)是一种在公用网络上建立专用网络的技术。之所以称之为虚拟网络,主要是因为VPN的两个节点之间并没有像传统的特殊网络那样使用端到端的物理链接,而是构建在Internet等公共网络上的逻辑网络。用户数据通过逻辑链接传输。根据VPN协议,常见的VPN类型有:IPsec、SSL、GRE、PPTP和L2TP等。IPsec是一种通用性很强的VPN技术,适用于各种网络互访场景。IPsecVPN是指利用IPsec实现远程接入的VPN技术,通过在公共网络上建立两个或两个以上私有网络之间的IPsec隧道,并通过加密和验证算法确保VPN连接的安全。
IPsecVPN
IPsecVPN保护点对点之间的通信。通过IPsecVPN,可以在主机、主机、网络安全网关之间或网络安全网关之间建立安全隧道连接(如路由器、防火墙)。其协议主要工作在IP层,在IP层对数据包进行加密和验证。IPsecVPN与其它VPN技术相比,安全性更高,数据在IPsec隧道中被加密传输,但是相应的IPsecVPN在配置和组网部署上更加复杂。
IPsec是如何工作的?
IPsec的工作原理大致可分为四个阶段:识别“感兴趣流”。网络设备收到报文后,通常会将报文的五元组等信息与IPsec策略相匹配,判断报文是否要通过IPsec隧道传输。需要通过IPsec隧道传输的流量通常被称为“感兴趣流”。协商安全联盟(SecurityAssociation,以下简称SA)。SA是通信双方对某些协商要素的协议,如双方使用的安全协议、数据传输的包装方式、协议使用的加密验证算法、数据传输的密钥等。只有SA建立在通信双方之间,才能进行安全的数据传输。识别出感兴趣流后,本端网络设备会向对端网络设备发起SA协商。在这一阶段,通信双方之间通过IKE协议先协商建立IKESA(用于身份验证和密钥信息交换),然后在IKESA的基础上协商建立IPsecSA(用于数据安全传输)。数据传输。IPsecSA建立成功后,双方就可以通过IPsec隧道传输数据了。IPsec为了保证数据传输的安全性,在这一阶段需要通过AH或ESP协议对数据进行加密和验证。加密机制保证了数据的机密性,防止数据在传输过程中被窃取;验证机制保证了数据的真实性和可靠性,防止了数据在传输过程中被模仿和篡改。如图所示,IPsec发送方会使用加密算法和加密密钥对报文进行加密,即将原始数据“乔装打扮”封装起来。然后发送方和接收方分别通过相同的验证算法和验证密钥对加密后的报文进行处理得到完整性校验值ICV。如果两端计算的ICV相同则表示该报文在传输过程中没有被篡改,接收方对验证通过的报文进行解密处理;如果ICV不相同则直接丢弃报文。IPsec加密验证过程,隧道拆除。通常,通信双方之间的对话老化(连接断开)意味着通信双方的数据交换已经完成。因此,为了节省系统资源,当空闲时间达到一定值时,通信双方之间的隧道将自动删除。
IPsec的3个重要协议-IKE/AH/ESP
IKE(InternetKeyExchange,因特网密钥交换),IKE协议是一种基于UDP的应用层协议,它主要用于SA协商和密钥管理。IKE协议分IKEv1和IKEv2两个版本,IKEv2与IKEv1相比,修复了多处公认的密码学方面的安全漏洞,提高了安全性能,同时简化了安全联盟的协商过程,提高了协商效率。IKE协议属于一种混合型协议,它综合了ISAKMP(InternetSecurityAssociationandKeyManagementProtocol)、Oakley协议和SKEME协议这三个协议。其中,ISAKMP定义了IKESA的建立过程,Oakley和SKEME协议的核心是DH(Diffie-Hellman)算法,主要用于在Internet上安全地分发密钥、验证身份,以保证数据传输的安全性。IKESA和IPSecSA需要的加密密钥和验证密钥都是通过DH算法生成的,它还支持密钥动态刷新。
AH(AuthenticationHeader,认证头)
AH协议用来对IP报文进行数据源认证和完整性校验,即用来保证传输的IP报文的来源可信和数据不被篡改,但它并不提供加密功能。AH协议在每个数据包的标准IP报文头后面添加一个AH报文头,AH协议对报文的完整性校验的范围是整个IP报文。
ESP(EncapsulatingSecurityPayload,封装安全载荷)
ESP协议除了对IP报文进行数据源认证和完整性校验以外,还能对数据进行加密。ESP协议在每一个数据包的标准IP报头后方添加一个ESP报文头,并在数据包后方追加一个ESP尾(ESPTrailer和ESPAuthdata)。ESP协议在传输模式下的数据完整性校验范围不包括IP头,因此它不能保证IP报文头不被篡改。AH和ESP可以单独使用,也可以同时使用。AH和ESP同时使用时,报文会先进行ESP封装,再进行AH封装;IPsec解封装时,先进行AH解封装,再进行ESP解封装。
IPsec使用的端口
IPsec中IKE协议采用UDP500端口发起和响应协商,因此为了使IKE协商报文顺利通过网关设备,通常要在网关设备上配置安全策略放开UDP500端口。另外,在IPsecNAT穿越场景下,还需要放开UDP4500端口。而AH和ESP属于网络层协议,不涉及端口。为了使IPsec隧道能正常建立,通常还要在网关设备上配置安全策略放开AH(IP协议号是51)和ESP(IP协议号是50)服务。
IPsecVPN和SSLVPN对比
IPsec和SSL是部署VPN时最常用的两种技术,它们都有加密和验证机制保证用户远程接入的安全性。从以下几个方面对IPsecVPN和SSLVPN进行对比:OSI参考模型工作层级OSI定义了网络互连的七层框架:物理层、数据链路层、网络层、传输层、会话层、表示层、应用层。IPsec工作在网络层,它直接运行在IP(InternetProtocol,互联网协议)之上。在应用层中,SSL工作是一种应用层协议,它对HTTP流量进行加密,而不是对IP数据包进行直接加密。
IPsec和SSL的工作层级
IPsecVPN的配置部署通常适用于SitetoSite(网站到网站)的组网,要求网站分别部署VPN网关或远程用户安装专用VPN客户端,因此配置部署的复杂性和维护成本都比较高。但SSLVPN通常适用于ClientoSite(客户端到站点)的组网,只要求远程用户使用支持SSL的标准浏览器安装指定插件即可进行访问,通过数据中心部署VPN网关进行集中管理和维护,因此配置部署更简单,维护成本相对较低。
SSLVPN
安全性IPSec工作在网络层,对站点间传输的所有数据进行保护。IPSecVPN要求远程用户安装专用的VPN客户端或在网站上部署VPN网关设备,用户访问将受到用户认证规则、安全策略规则或内容安全过滤方面的检查,因此安全性较高。而SSLVPN不要求安装专用客户端或接入站点部署网关设备,更容易受到安全威胁的影响。访问控制IPsec工作在网络层,不能基于应用进行细粒度的访问控制。而且SSLVPN在精细化访问控制方面更加灵活,网络管理员可以根据不同的应用类型将网络资源划分为不同的资源类型,每一类资源的访问权限都不一样。
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
文章目录 前言一、力扣990. 等式方程的可满足性 前言 并查集(Union-Find)算法是一个专门针对「动态连通性」的算法,我之前写过两次,因为这个算法的考察频率高,而且它也是最小生成树算法的前置知识,所以我整合了本文,争取一篇文章把这个算法讲明白
一、力扣990. 等式方程的可满足性 class Solution { public boolean equationsPossible(String[] equations) { if(equations == null || equations.length == 0){ return true; } int n = equations.length; Uf uf = new Uf(27); for(int i = 0; i < n; i ++){ char c1 = equations[i].charAt(1); if(c1 == '='){ int x = equations[i].charAt(0) - 'a'; int y = equations[i].charAt(3) - 'a'; uf.union(x,y); } } for(int i = 0; i < n; i ++){ if(equations[i].
正常我们 adb push xxxx /sdcard/即可
但如果有中文则要加上双引号
adb push "c:\\这是中文.jpg" "/sdcard/这是中文.jpg"
同样 adb pull也是一样的 adb pull "/sdcard/这是中文.jpg" "c:\\这是中文.jpg"
不用大费周章的去同改adb 的代码,加上双引号就好了!
c# 在执行中增加
psi.StandardOutputEncoding = Encoding.UTF8;
psi.StandardErrorEncoding = Encoding.UTF8;
可对中文进行捕获
public static String run_process_without_window(String path, String arg, int time_wait_for_exit = 10000, bool forceDisconnect = false) { string output = ""; try { if (forceDisconnect == false) { if (arg.IndexOf("disconnect") != -1) { return arg; } } System.Diagnostics.ProcessStartInfo psi = new System.Diagnostics.ProcessStartInfo(@path, @arg); psi.
(1) el-table刷新要求绑定el-table的key要发生变化才会刷新
(2) 单元格双击事件 cell-dblclick
(3) 往row里面添加一个属性来唯一标识某一行的数据,双击时使这特殊属性为true,输入框失去焦点时则设置特殊属性为false,并且输入框的显示与隐藏通过v-if与特殊属性绑定。
(4) 回车事件 @keyup.enter.native
<el-table border class="mt20" :data="data" style="width: 100%" row-key="id" :key="key" @cell-dblclick="dblclick"> <el-table-column type="index" label="序号" width="50"> <template slot-scope="scope"> <span>{{ (search.page -1) * search.size + scope.$index+1 }}</span> </template> </el-table-column> <el-table-column prop="id" label="ID" width="width"> </el-table-column> <el-table-column prop="name" label="名称" width="width"> </el-table-column> <el-table-column prop="lwkx" label="论文扩写" width="width"> <template scope="scope"> <div v-if="scope.row[scope.column.property+'Show']" class="input-box"> <el-input size="small" @keyup.enter.native="handleInputlwkx(scope.row,scope.column)" v-model="scope.row.lwkx"></el-input> </div> <span v-else>{{scope.row.lwkx}}</span> </template> </el-table-column> </el-table> <script> export default { data() { return { key: "
视频
Shell概述 本次课程主要包含内容:
Shell脚本入门Shell变量Shell内置命令Shell运算符与执行运算命令流程控制语句Shell函数Shell重定向Shell好用的工具, cut sed awk sort大厂常见企业面试题 Shell脚本入门 疑问 linux系统是如何操作计算机硬件CPU,内存,磁盘,显示器等?
答: 使用linux的内核操作计算机的硬件
Shell介绍 通过编写Shell命令发送给linux内核去执行, 操作就是计算机硬件. 所以Shell命令是用户操作计算机硬件的桥梁,
Shell是命令, 类似于windows系统Dos命令
Shell是一个门程序设计语言, Shell里面含有变量, 函数, 逻辑控制语句等等
Shell脚本 通过Shell命令或程序编程语言编写的Shell文本文件, 这就是Shell脚本 , 也叫Shell程序
为什么学习Shell脚本? 通过Shell命令与编程语言来提高linux系统的管理工作效率
Shell的运行过程 当用户下达指令给该操作系统的时候,实际上是把指令告诉shell,经过shell解释,处理后让内核做出相应的动作。 系统的回应和输出的信息也由shell处理,然后显示在用户的屏幕上。
Shell解析器 查看linux系统centos支持的shell解析器
cat /etc/shells 效果
介绍解析器类型
解析器类型介绍/bin/shBourne Shell,是UNIX最初使用的shell;/bin/bashBourne Again Shell它是Bourne Shell的扩展,简称bash,是LinuxOS默认shell,有灵活和强大的编辑接口,同时又很友好的用户界面,交互性很强;/sbin/nologin未登录解析器, shell设置为/sbin/nologin 是用于控制用户禁止登陆系统的, 有时候有些服务,比如邮件服务,大部分都是用来接收主机的邮件而已,并不需要登陆/bin/dashdash(Debian Almquist Shell),也是一种 Unix shell。它比 Bash 小,只需要较少的磁盘空间,但是它的对话性功能也较少,交互性较差。/bin/cshC Shell是C语言风格Shell/bin/tcsh是C Shell的一个扩展版本。 Centos默认的解析器是bash 语法
echo $SHELL 含义: 打印输出当前系统环境使用的Shell解析器类型
echo 用于打印输出数据到终端
$SHELL 是全局共享的读取解析器类型环境变量, 全局环境变量时所有的Shell程序都可以读取的变量,
效果
Shell脚本文件编写规范 脚本文件后缀名规范 shell脚本文件就是一个文本文件, 后缀名建议使用 .
论文地址:VERY DEEP CONVOLUTIONAL NETWORKS FOR LARGE-SCALE IMAGE RECOGNITION
论文学习 1. 摘要 这篇论文探讨了在大规模图像识别任务中,卷积神经网络(ConvNets)深度对其准确性的影响。作者的主要贡献是对不断增加深度的网络进行了全面评估,这些网络使用了非常小的(3x3)卷积滤波器。研究发现,通过将网络深度增加到16到19层,可以显著提高性能,超越了之前的艺术水平配置。(通过卷积神经网络的加深可以显著提高性能)这些发现是作者在2014年ImageNet挑战中提交作品的基础,他们的团队在定位和分类跟踪中分别获得了第一和第二名。此外,作者还展示了他们的表示(网络学到的特征)在其他数据集上也能很好地泛化,并取得了最先进的结果。为了促进深度视觉表示在计算机视觉领域的进一步研究,作者公开了他们表现最好的两个ConvNet模型。(验证通过卷积神经网络结构上的加深可以提高性能这个猜想) 2. 引言 卷积网络的成功应用 引言部分首先强调了卷积网络(ConvNets)在大规模图像和视频识别领域的成功应用。特别提到了一些关键的研究,如Krizhevsky等人在2012年的工作,这些研究标志着深度学习在视觉识别任务中的重要突破。 公共图像库和高性能计算系统的作用 论文提到了大型公共图像库(如ImageNet)和高性能计算系统(如GPU或大规模分布式集群)在推动深度视觉识别架构发展中的作用。 ImageNet挑战赛的影响 引言中还讨论了ImageNet大规模视觉识别挑战(ILSVRC)对于几代大规模图像分类系统的影响,从高维浅层特征编码到深度卷积网络。 卷积网络架构的改进尝试 论文回顾了在Krizhevsky等人的原始架构基础上,为了提高准确性而进行的各种改进尝试,包括调整卷积层的接收窗口大小和步幅,以及在整个图像和多个尺度上密集训练和测试网络。 深度在卷积网络设计中的重要性 引言部分特别强调了深度在卷积网络架构设计中的重要性。论文的主要目标是通过增加更多的卷积层来探索深度的极限,并使用非常小的(3x3)卷积滤波器。 研究动机和目标 论文的动机是验证通过增加网络深度是否能显著提高图像识别的性能。目标是开发出能够在ILSVRC分类和定位任务上取得最先进性能的深度卷积网络架构。 3. ConvNet配置 统一的ConvNet架构设计 论文中所有的ConvNet配置都遵循了一套统一的设计原则。这些原则受到了之前研究的启发,特别是Ciresan等人(2011年)和Krizhevsky等人(2012年)的工作。 架构细节 训练时,ConvNets的输入是固定大小的224x224 RGB图像。唯一的预处理步骤是从每个像素中减去在训练集上计算得到的平均RGB值。图像通过一系列卷积层进行处理,这些层使用非常小的3x3的感受野。在某些配置中,还使用了1x1的卷积滤波器,作为输入通道的线性变换。卷积层之后是一系列最大池化层,但并不是每个卷积层后都跟有池化层。网络的最后是三个全连接层,前两个各有4096个通道,第三个用于1000类ILSVRC分类,因此有1000个通道。 深度和宽度的平衡 论文中的网络深度从11层(网络A)到19层(网络E)不等。卷积层的宽度(通道数)从第一层的64开始,每经过一个最大池化层就翻倍,直到达到512。 网络配置的变体 论文详细描述了几种不同的网络配置(标记为A到E),每种配置都在通用设计的基础上增加了更多的层。这些配置的主要区别在于网络的深度,即卷积层和全连接层的数量。 配置与先前工作的比较 作者讨论了他们的ConvNet配置与之前在ILSVRC-2012和ILSVRC-2013比赛中表现最佳的模型之间的区别。与先前模型相比,本文的网络使用了更小的感受野,并在整个网络中保持了较小的步幅和较多的卷积层。 4. 分类框架 训练细节 训练过程基本遵循了Krizhevsky等人(2012年)的方法,但在从多尺度训练图像中采样输入裁剪方面有所不同。使用小批量梯度下降法进行优化,批量大小设为256,动量为0.9。采用L2权重衰减(权重衰减系数设为5e-4)和前两个全连接层的dropout(dropout比率为0.5)进行正则化。初始学习率设为1e-2,当验证集准确率不再提高时,学习率减少10倍,总共减少3次,学习过程在大约370K次迭代(74个epoch)后停止。 网络初始化 网络权重的初始化非常重要,因为不良的初始化可能导致深度网络中梯度的不稳定。作者首先训练了较浅的网络A,然后使用它来初始化更深网络的部分层。对于随机初始化的层,权重从均值为0、方差为1e-2的正态分布中采样,偏置项初始化为0。 训练图像的尺寸和增强 训练图像首先被等比例缩放,然后从中随机裁剪出224x224的图像作为网络输入。进行了图像水平翻转和随机RGB颜色偏移的数据增强。 多尺度训练 论文考虑了两种设置训练尺度S的方法:固定S和多尺度训练,后者通过从一定范围内随机采样S来模拟不同大小的对象。 5. 分类实验 实验数据集 实验主要在ImageNet Large Scale Visual Recognition Challenge (ILSVRC) 2012数据集上进行,该数据集包含1000个类别,超过120万张训练图像、5万张验证图像和15万张测试图像。 单尺度评估 对不同深度的ConvNet模型在单一尺度上进行评估。测试图像的尺寸被固定,与训练时相同。
实验结果显示,随着网络深度的增加,分类错误率显著下降。特别是,更深的网络(如配置D和E)比浅层网络有更好的性能。 多尺度评估 在测试时考虑了多个尺度,以提高性能。这包括在不同尺寸的图像上运行模型,并将结果进行平均。使用多尺度评估可以进一步提高分类准确率。 多裁剪评估 除了全图评估外,还使用了多裁剪方法来提高准确率。这种方法包括在图像的不同位置进行裁剪,并对结果进行平均。 ConvNet融合 通过结合多个不同配置的ConvNet模型的输出来提高性能。这种融合方法利用了不同模型的互补性。 与最先进技术的比较 将实验结果与当时的最先进技术进行了比较。论文中的深度ConvNet模型在分类任务上达到了新的最佳性能。 实验结论 实验结果强调了网络深度对于提高大规模图像分类性能的重要性。更深的网络能够学习到更丰富和更具判别性的特征表示。 6.
系列文章目录 提示:这里可以添加系列文章的所有文章的目录,目录需要自己手动添加
MyBatis之关联查询
提示:写完文章后,目录可以自动生成,如何生成可参考右边的帮助文档
文章目录 系列文章目录前言一、一对一关联查询二、一对多关联查询三、多对多关联查询总结 前言 提示:这里可以添加本文要记录的大概内容:
在使用MyBatis进行数据库操作时,关联查询是一种重要的查询方式。它能够在一个查询中同时检索多个表中的数据,从而提高查询效率和性能。在开始学习和使用MyBatis的关联查询之前,我们需要先了解一些基础概念和知识,包括数据库表、实体类、Mapper接口和Mapper.xml文件等。
在接下来的博客文章中,我们将逐步学习如何使用MyBatis进行关联查询,并通过示例代码演示如何实现多对一和一对多的关联查询。希望通过这些介绍,你能够掌握MyBatis关联查询的基本知识和技能,并能够在实际项目中应用这些知识。
提示:以下是本篇文章正文内容,下面案例可供参考
一、一对一关联查询 在 MyBatis 中,一对一关联查询是指通过在查询语句中使用连接(JOIN)操作,从多个表中获取相关联的数据。这样可以一次性获取到涉及多个表的数据,避免了多次查询和手动关联的麻烦。
一对一关联查询通常涉及到两个表,其中一个表包含主要数据,称为“主表”,另一个表包含与主表关联的数据,称为“从表”。在关联查询中,通过在主表和从表之间建立连接条件,可以将相关的数据关联起来。
在 MyBatis 的映射文件中,可以使用标签来配置一对一关联查询。以下是一个简单的示例:
<resultMap id="studentMapper" type="com.zhangsan.pojo.Student"> <!-- 主键列 --> <id property="sid" column="sid"></id> <!-- 普通列 --> <result property="name" column="name"></result> <result property="age" column="age"></result> <result property="sex" column="sex"></result> <!-- 一对一对象列 property:属性名 column:关联列名 javaType:对象类型--> <association property="classes" column="classId" javaType="com.zhangsan.pojo.Classes"> <!-- 关联对象主键列 --> <id property="cid" column="cid"></id> <!-- 关联对象普通列 --> <result property="className" column="className"></result> </association> </resultMap> <!-- 多表查询,级联查询学生和其班级 --> <select id="findAll" resultMap="studentMapper"> select * from student left join classes on student.
反弹shell升级全交互式shell 1、获取反弹shell(过程略)2、升级到半交互式shell3、升级到全交互式shell4、重复上面的步骤,获取全交互式shell 1、获取反弹shell(过程略) 2、升级到半交互式shell python -c 'import pty;pty.spawn("/bin/bash")' 半交互式shell问题:1、vi编辑文件不方便;2、命令行上下左右乱码;3、不能补全等
3、升级到全交互式shell echo $TERM Ctrl+Z stty raw -echo fg reset tmux-256color 此时有个问题,输入reset之后回车会乱码^M。查看系统使用的shell解析器,需要改为bash并重启系统。
echo $SHELL chsh -s /bin/bash reboot 4、重复上面的步骤,获取全交互式shell python -c 'import pty;pty.spawn("/bin/bash")' Ctrl+Z stty raw -echo fg reset tmux-256color Mark 一下
记录一个方法用于移动端横屏画布的旋转图片功能。
核心代码:
rotateBase64(data) { return new Promise((resolve) => { const imgView = new Image(); imgView.src = data; const canvas = document.createElement('canvas'); const context = canvas.getContext('2d'); const cutCoor = { sx: 0, sy: 0, ex: 0, ey: 0 }; // 裁剪坐标 imgView.onload = () => { const imgW = imgView.width; const imgH = imgView.height; const size = imgH; canvas.width = size * 2; canvas.height = size * 2; cutCoor.sx = size; cutCoor.
1. 请解释TCP和UDP的主要区别。 TCP和UDP都是位于传输层的协议,具有不同的特点和应用场景。以下是它们的主要区别:
连接方式:TCP是面向连接的协议,这意味着在数据传输之前需要先建立连接。这通常通过三次握手来建立连接,以确保通信双方都已准备好。而UDP是无连接的,即在发送数据之前不需要建立连接。
可靠性:TCP提供了可靠的数据传输服务。它通过使用确认、重传和流量控制等机制来确保数据的完整性和正确性。与此相反,UDP是不可靠的,它不保证数据的完整性或正确性。
传输速度:由于TCP需要进行各种检查和确认,其传输速度可能相对较慢。而UDP由于没有这些额外的机制,因此在传输速度上通常更快。
应用场景:TCP通常用于需要高可靠性的应用,如Web服务器、电子邮件和文件传输等。而UDP则常用于对实时性要求较高的应用,如视频流、在线游戏和VoIP通话等。
数据流量控制:TCP有流量控制机制,可以避免数据传输过快导致的问题。而UDP没有流量控制功能,因此可能会导致数据丢失或网络拥塞。
数据包顺序:TCP保证数据包的顺序,即数据包会按照发送的顺序到达接收端。而UDP则不保证数据包的顺序,数据包可能会乱序到达接收端。
头部开销:TCP的头部开销较大,因为它需要携带更多的信息来保证可靠性。而UDP的头部开销较小,这使得其在传输小数据包时更为高效。
2. TCP协议是如何保证数据的可靠性的? TCP协议保证数据传输可靠性的方式主要有以下几种:
校验和:TCP在数据传输过程中,将每个发送的数据包进行校验和计算,并将结果添加到数据包头部。接收方在接收到数据包后,会对数据包进行校验和的验证,如果发现校验和不匹配,就会向发送方发送错误报告。
序列号确认应答:TCP为每个字节分配一个序列号,接收方会对序列号进行检查并确认应答,以此来确保数据的完整性和正确性。
超时重传:如果发送方在规定时间内没有收到接收方的确认应答,就会认为该数据包已丢失或损坏,进而进行超时重传。
连接管理:TCP通过三次握手来建立连接,并采用四次挥手来终止连接,这种方式可以确保连接的可靠性。
流量控制和拥塞控制:TCP通过流量控制机制来避免数据传输过快导致的问题,同时,通过拥塞控制机制来避免网络拥塞,这两者都有助于保障数据的可靠传输。
3. TCP协议是如何实现流量控制的? TCP协议实现流量控制的主要机制是滑动窗口。在TCP的数据传输过程中,发送方会持续地维护一个叫做“窗口”的数据结构,而接收方也会维护一个类似的数据结构。这两个“窗口”分别代表了发送方和接收方可以接收或发送的数据量。
当发送方需要向接收方发送数据时,它会先查看自己的窗口。如果窗口允许,那么它就会将一部分数据发出去。一旦这些数据被发送出去,窗口就会相应地缩小。
同时,接收方会根据自己的处理能力来动态调整其窗口的大小。如果接收方发现自己处理不过来了,那么它就会通过TCP协议告诉发送方,让自己的窗口变小一些。
此外,网络中的拥塞状况也会影响到发送方一次可以向接收方发送的TCP报文段的大小和数量。具体来说,无论处于流量控制还是拥塞控制的目的,发送方的发送速率总是受到两者中较小一者的限制。
总的来说,TCP协议通过这种动态调整窗口大小的方式,实现了对数据传输速度和流量的有效控制,从而避免了因网络拥塞而导致的数据包丢失和网络堵塞的现象。
4. TCP协议是如何实现拥塞控制的? TCP协议实现拥塞控制的主要方法是通过"拥塞窗口"变量来动态调整发送速率。在TCP的发送端,所有未收到确认的数据段必须落在这个窗口内。当网络出现拥塞时,TCP程序会减小拥塞窗口的大小,从而降低数据的发送速率;反之,当网络状况好转时,TCP程序会增大拥塞窗口的大小,提高数据的发送速率。
此外,TCP协议还设计了四种拥塞控制算法:慢开始、拥塞避免、快重传和快恢复。这些算法结合使用,可以有效地防止过多的数据注入到网络中,避免出现网络负载过大的情况。
慢开始:发送方在开始发送数据时,会先探测一下网络的状况,如果网络状况良好,则逐渐增大拥塞窗口的大小;否则,会按照一定的规则逐渐增大拥塞窗口的大小。拥塞避免:当拥塞窗口的大小达到一个阈值时,就会进入拥塞避免阶段。在这个阶段,拥塞窗口的大小会按照线性增长的规则逐渐增大。快重传:当发送方连续收到三个重复的确认报文时,就会直接重传数据包,而不用等待超时重传定时器的时间到了再重传。快恢复:当发送方连续收到三个重复的确认报文时,它会把慢开始门限设置为当前拥塞窗口大小的一半,然后把拥塞窗口的大小设定为慢开始门限加上3个报文段的大小。 5. 请解释TCP三次握手和四次挥手的过程。 TCP三次握手和四次挥手是TCP协议中建立连接和断开连接的两个重要过程。
三次握手:
第一次握手:客户端向服务器发送一个SYN(同步)报文,表示请求建立连接。第二次握手:服务器接收到SYN报文后,会发送一个SYN+ACK(同步确认)报文给客户端,表示同意建立连接。第三次握手:客户端接收到SYN+ACK报文后,会发送一个ACK(确认)报文给服务器,表示已经准备好建立连接了。
通过三次握手,客户端和服务器之间建立了可靠的连接,并确定了双方的序列号。 四次挥手:
第一次挥手:客户端发送一个FIN(结束)报文给服务器,表示即将关闭连接。第二次挥手:服务器接收到FIN报文后,会发送一个ACK(确认)报文给客户端,表示已经收到了客户端的结束信号。第三次挥手:客户端接收到ACK报文后,会发送一个FIN(结束)报文给服务器,表示已经关闭了连接。第四次挥手:服务器接收到FIN报文后,会发送一个ACK(确认)报文给客户端,表示已经收到了客户端的结束信号,并且也准备关闭连接了。
通过四次挥手,客户端和服务器之间的连接被彻底关闭。 总之,TCP三次握手和四次挥手的过程确保了数据传输的可靠性和安全性,避免了网络中的资源浪费和数据丢失。
6. 请解释TCP的慢启动、拥塞避免、快速重传和快速恢复算法。 TCP的慢启动、拥塞避免、快速重传和快速恢复算法是TCP协议中用于控制数据传输速率和处理网络拥塞的重要机制。
慢启动(Slow Start):在TCP连接建立后,发送方的初始窗口大小为1个MSS(最大段大小)。当接收方确认一个数据段时,发送方会将窗口大小翻倍。但是,如果在一定时间内没有收到任何确认信息,发送方会将窗口大小减半,并等待一段时间后再尝试翻倍。这个过程被称为“慢启动”。
拥塞避免(Congestion Avoidance):当网络出现拥塞时,TCP协议会通过降低发送速率来减少拥塞的程度。发送方会逐渐减小其发送速率,直到网络状况得到改善。这个过程被称为“拥塞避免”。
快速重传(Fast Retransmit):当发送方在规定的时间内未收到接收方的确认信息时,它会认为数据包丢失或出错,并要求重新发送该数据包。这个过程被称为“快速重传”。
快速恢复(Fast Recovery):当接收方检测到网络状况已得到改善时,它会通知发送方可以恢复其发送速率。发送方会逐渐增加其发送速率,直到达到原来的值。这个过程被称为“快速恢复”。
这些算法共同作用,确保了TCP协议在面对网络拥塞时能够有效地调整数据传输速率,从而保证了数据传输的可靠性和效率。
7. UDP协议的特点是什么?为什么它比TCP更快? UDP协议的特点包括以下几个方面:
无连接:UDP协议不需要建立连接,也不需要维护连接状态。数据报文直接发送到目标地址,不会等待确认应答。
不可靠:UDP协议没有提供可靠性保证,数据报文在传输过程中可能会出现丢失、重复或乱序的情况。
无流量控制:UDP协议没有内置的流量控制机制,发送方可以以任意速率发送数据,接收方无法控制数据的接收速度。
无拥塞控制:UDP协议没有内置的拥塞控制机制,网络拥塞时无法进行自适应调整。
面向数据报文:UDP协议采用面向数据报文的方式传输数据,每个数据报文都是独立的,包含完整的信息。
相比于TCP协议,UDP协议更快的原因主要有以下几点:
无需建立连接和维持连接状态:TCP协议需要进行三次握手来建立连接,而UDP协议可以直接发送数据报文,省去了连接建立和断开的时间开销。
无需等待确认应答:TCP协议在发送数据后需要等待接收方的确认应答,而UDP协议不需要等待确认应答,可以连续发送多个数据报文。
无流量控制和拥塞控制:TCP协议通过滑动窗口机制进行流量控制和拥塞控制,而UDP协议没有这些机制,可以更快速地传输数据。
需要注意的是,由于UDP协议的不可靠性,它适用于对实时性要求较高但允许一定数据丢失的场景,如音视频传输、网络游戏等。而对于对数据传输可靠性要求较高的场景,如文件传输、电子邮件等,通常使用TCP协议。
8. 请解释UDP如何实现数据包的顺序传输。 UDP协议本身并不保证数据包的顺序传输。因为UDP是无连接的,每个数据包都是独立发送的,并且没有序列号和确认机制来保证数据包的顺序。因此,如果多个数据包在网络上同时传输,到达接收端的顺序可能与发送端的顺序不同。
然而,在应用层,可以通过一些手段来实现UDP数据包的顺序传输。以下是几种常见的方法:
在C#中,异常处理是一种处理程序运行时可能出现的错误或异常情况的重要机制。通过异常处理,我们可以捕获并处理程序中的错误,从而避免程序崩溃或产生不可预测的行为。
C#中的异常处理主要通过try-catch语句块来实现。以下是C#中异常处理的基础语法:
try { // 代码块,可能会抛出异常 } catch (ExceptionType1 ex) { // 处理ExceptionType1异常的代码块 } catch (ExceptionType2 ex) { // 处理ExceptionType2异常的代码块 } finally { // 无论是否发生异常,最后都会执行的代码块 } try块包含可能会抛出异常的代码。catch块用于捕获并处理异常。你可以有多个catch块来处理不同类型的异常。ExceptionType表示要捕获的异常类型,如System.DivideByZeroException、System.NullReferenceException等。ex是catch块中定义的变量,它存储了被捕获的异常对象。finally块包含的代码无论是否发生异常都会执行。通常用于释放资源或进行清理工作。 下面是一个简单的例子:
try { int a = 0; int b = 1; int result = b / a; // 这将抛出一个DivideByZeroException异常 } catch (DivideByZeroException ex) { Console.WriteLine("发生除以零的异常: " + ex.Message); } catch (NullReferenceException ex) // 这个catch块永远不会执行,因为前面的catch已经捕获了异常 { Console.WriteLine("发生空引用异常: " + ex.Message); } finally { Console.
服务端如何防止订单重复支付? 概述为了防止掉单,这里可以这样处理:为了防止订单重复提交,可以这样处理:附上微信支付最佳实践: 概述 如图是一个简化的下单流程,首先是提交订单,然后是支付。
支付的话,一般是走支付网关(支付中心),然后支付中心与第三方支付渠道(微信、支付宝、银联)交互。
支付成功以后,异步通知支付中心,支付中心更新自身支付订单状态,再通知业务应用,各业务再更新各自订单状态。
这个过程中经常可能遇到的问题是掉单,无论是超时未收到回调通知也好,还是程序自身报错也好。
总之由于各种各样的原因,没有如期收到通知并正确的处理后续逻辑等等,都会造成用户支付成功了,但是服务端这边订单状态没更新。
这个时候有可能产生投诉,或者用户重复支付。
由于③⑤造成的掉单称之为外部掉单,由④⑥造成的掉单我们称之为内部掉单
为了防止掉单,这里可以这样处理: 1、支付订单增加一个中间状态“支付中”,当同一个订单去支付的时候,先检查有没有状态为“支付中”的支付流水,当然支付(prepay)的时候要加个锁。支付完成以后更新支付流水状态的时候再讲其改成“支付成功”状态。
2、支付中心这边要自己定义一个超时时间(比如:30秒),在此时间范围内如果没有收到支付成功回调,则应调用接口主动查询支付结果,比如10s、20s、30s查一次,如果在最大查询次数内没有查到结果,应做异常处理
3、支付中心收到支付结果以后,将结果同步给业务系统,可以发MQ,也可以直接调用,直接调用的话要加重试(比如:SpringBoot Retry)
4、无论是支付中心,还是业务应用,在接收支付结果通知时都要考虑接口幂等性,消息只处理一次,其余的忽略
5、业务应用也应做超时主动查询支付结果
对于上面说的超时主动查询可以在发起支付的时候将这些支付订单放到一张表中,用定时任务去扫
为了防止订单重复提交,可以这样处理: 1、创建订单的时候,用订单信息计算一个哈希值,判断redis中是否有key,有则不允许重复提交,没有则生成一个新key,放到redis中设置个过期时间,然后创建订单。
其实就是在一段时间内不可重复相同的操作
附上微信支付最佳实践: title: 服务端如何防止订单重复支付!date: 2021-03-18 tags: categories: 精进 permalink: Fight/Server-how-to-prevent-double-payment-of-orders! author: 狂乱的贵公子 from_url: cnblogs.com/cjsblog/p/14516909.html wechat_url:
概述 如图是一个简化的下单流程,首先是提交订单,然后是支付。
支付的话,一般是走支付网关(支付中心),然后支付中心与第三方支付渠道(微信、支付宝、银联)交互。
支付成功以后,异步通知支付中心,支付中心更新自身支付订单状态,再通知业务应用,各业务再更新各自订单状态。
这个过程中经常可能遇到的问题是掉单,无论是超时未收到回调通知也好,还是程序自身报错也好。
总之由于各种各样的原因,没有如期收到通知并正确的处理后续逻辑等等,都会造成用户支付成功了,但是服务端这边订单状态没更新。
这个时候有可能产生投诉,或者用户重复支付。
由于③⑤造成的掉单称之为外部掉单,由④⑥造成的掉单我们称之为内部掉单
为了防止掉单,这里可以这样处理: 1、支付订单增加一个中间状态“支付中”,当同一个订单去支付的时候,先检查有没有状态为“支付中”的支付流水,当然支付(prepay)的时候要加个锁。支付完成以后更新支付流水状态的时候再讲其改成“支付成功”状态。
2、支付中心这边要自己定义一个超时时间(比如:30秒),在此时间范围内如果没有收到支付成功回调,则应调用接口主动查询支付结果,比如10s、20s、30s查一次,如果在最大查询次数内没有查到结果,应做异常处理
3、支付中心收到支付结果以后,将结果同步给业务系统,可以发MQ,也可以直接调用,直接调用的话要加重试(比如:SpringBoot Retry)
4、无论是支付中心,还是业务应用,在接收支付结果通知时都要考虑接口幂等性,消息只处理一次,其余的忽略
5、业务应用也应做超时主动查询支付结果
对于上面说的超时主动查询可以在发起支付的时候将这些支付订单放到一张表中,用定时任务去扫
为了防止订单重复提交,可以这样处理: 1、创建订单的时候,用订单信息计算一个哈希值,判断redis中是否有key,有则不允许重复提交,没有则生成一个新key,放到redis中设置个过期时间,然后创建订单。
1、创建订单的时候,用订单信息计算一个哈希值,判断redis中是否有key,有则不允许重复提交,没有则生成一个新key,放到redis中设置个过期时间,然后创建订单。
其实就是在一段时间内不可重复相同的操作。
1.docker build -t imgname . 镜像制作(依赖DockerFile)
2.docker images 查看镜像
3.docker run -d -p 58080(外部端口):8080(内部端口) imgname 运行docker暴露端口在宿主机上
4.docker exec -it <container_id> bin/bash 进入运行中的docker容器内
4.docker ps -a 查看运行和不运行的容器
5.docker stop 302544e0d7a4(容器id) 停止正在运行的容器
6.docker run 302544e0d7a4(容器id) 停止后重新运行容器
7.docker save -o savefilename imgname
8.docker load imgname
9.docker logs <container_id> 查看运行日志
Oracle低版本实现UTC格式转换 文章目录 Oracle低版本实现UTC格式转换前言一、创建 FUNCTION(GET_UTC_DATE)二、使用步骤1.跨年日期2.跨月日期(判断 闰年 or 平年、用于计算2月天数,正常大小月)3.跨日日期3.正常日期 总结 前言 现在Oracle版本过低是不能直接转UTC格式时间的,那么我们低版本用户可以以下这样做
一、创建 FUNCTION(GET_UTC_DATE) CREATE OR REPLACE FUNCTION GET_UTC_DATE (V_DATE IN DATE) RETURN VARCHAR2 IS V_DATA VARCHAR2 (50); BEGIN SELECT CASE --跨年 WHEN TO_CHAR (V_DATE, 'MM') = 01 AND TO_CHAR (V_DATE, 'DD') = 01 AND TO_CHAR (V_DATE, 'HH24') < 08 THEN TO_NUMBER (TO_CHAR (V_DATE, 'YYYY')) - 1 || '-' || LPAD (TO_NUMBER (TO_CHAR (V_DATE, 'MM')) + 11, 2, 0) || '-' || LPAD (TO_NUMBER (TO_CHAR (V_DATE, 'DD')) + 29, 2, 0) || 'T' || LPAD (TO_NUMBER (TO_CHAR (V_DATE, 'HH24')) + 16, 2, 0) || TO_CHAR (V_DATE, ':MI:SS') || '+08:00' --闰年跨月 WHEN TO_CHAR (V_DATE, 'DD') = 01 AND TO_CHAR (V_DATE, 'HH24') < 08 AND LPAD (TO_NUMBER (TO_CHAR (V_DATE, 'MM')), 2, 0) = 03 AND MOD (TO_CHAR (V_DATE, 'YYYY'), 4) = 0 AND MOD (TO_CHAR (V_DATE, 'YYYY'), 100) !
Trunc 在oracle中,可利用 trunc函数 查询当天数据,该函数可用于截取时间或者数值,将该函数与 select 语句配合使用可查询时间段数据
查询当天数据 --sysdate是获取系统当前时间函数 --TRUNC函数用于截取时间或者数值,返回指定的值 select * from 表名 where trunc(时间字段名)=trunc(sysdate) 日期处理 --date 为必要参数,是输入的一个date日期值 --fmt 参数可忽略,是日期格式,缺省是表示指定日期的0点,00:00:00 trunc(date,[fmt]) SQL 如下 --日 select * from 表名 where trunc(时间字段名)=trunc(sysdate) --周 select trunc(sysdate, 'd') '本周第一天,周日起' from dual; select trunc(sysdate, 'day') '本周第一天,周日起' from dual; select next_day(trunc(sysdate), 'TUESDAY')+12/24 '下个星期中午12点' from dual; select trunc(least(next_day(sysdate,'saturday'),next_day(sysdate,'sunday')))+(6*60+10)/(24*60) '下个星期早上6点10分' from dual; --月 select trunc(sysdate, 'mm') '当月第一天' from dual; select trunc(sysdate, 'month') '当月第一天' from dual; select trunc(last_day(sysdate)+1) '下个月第一天的0点' from dual; --季度 select trunc(sysdate, 'q') '当前季度的第一天' from dual; select trunc(add_months(sysdate,3), 'Q') -1/24 '当年第一天' from dual; --年 select trunc(sysdate, 'yy') '当年第一天' from dual; select trunc(sysdate, 'yyyy') '当年第一天' from dual; select trunc(sysdate, 'year') '当年第一天' from dual; 扩展知识 --将小数点右边指定位数后面的截去; select trunc(123.
背景 flink 在1.15版本后开始提供generic log-based incremental checkpoints的检查点方案,目的在于减少checkpoint的耗时,尽量缩短端到端的数据处理延迟,本文就来看下这种新类型的checkpoint的设计
generic log-based incremental checkpoints 设计 generic log-based incremental checkpoints的设计主要是参考事务数据库的设计方案,总体来说就是insert、update、delete操作先记录到事务日志文件中,然后应用到DB数据文件中,通过这样的设计,相当于每时每刻状态操作都已经持久化到了事务日志中,遇到checkpoint barrier的时候也是只要确保barrier之前的修改操作已经记录到事务日志中即可,这样的话,整个checkpoint操作就会非常快,当然缺点也是显而易见,包括双写会导致状态操作的时延增加,状态的大小空间占用庞大,crash崩溃后恢复耗时增加等
文章目录 1 前言1.1 背景 2 数据集3 实现过程4 CNN网络实现5 模型训练部分6 模型评估7 预测结果8 最后 1 前言 🔥 优质竞赛项目系列,今天要分享的是
基于CNN实现谣言检测
该项目较为新颖,适合作为竞赛课题方向,学长非常推荐!
🧿 更多资料, 项目分享:
https://gitee.com/dancheng-senior/postgraduate
1.1 背景 社交媒体的发展在加速信息传播的同时,也带来了虚假谣言信息的泛滥,往往会引发诸多不安定因素,并对经济和社会产生巨大的影响。
2 数据集 本项目所使用的数据是从新浪微博不实信息举报平台抓取的中文谣言数据,数据集中共包含1538条谣言和1849条非谣言。
如下图所示,每条数据均为json格式,其中text字段代表微博原文的文字内容。
每个文件夹里又有很多新闻文本。
每个文本又是json格式,具体内容如下:
3 实现过程 步骤入下:
*(1)解压数据,读取并解析数据,生成all_data.txt
*(2)生成数据字典,即dict.txt
*(3)生成数据列表,并进行训练集与验证集的划分,train_list.txt 、eval_list.txt
*(4)定义训练数据集提供器train_reader和验证数据集提供器eval_reader
import zipfile import os import io import random import json import matplotlib.pyplot as plt import numpy as np import paddle import paddle.fluid as fluid from paddle.fluid.dygraph.nn import Conv2D, Linear, Embedding from paddle.
概述 Oracle SQL 提供了用于执行特定操作的专用函数。这些函数大大增强了 SQL 语言的功能。函数可以接受零个或者多个输入参数,并返回一个输出结果。 Oracle 数据库中主要使用两种类型的函数:
1. 单行函数:对每一个函数应用在表的记录中时,只能输入一行结果,返回一个结果,
比如:MOD(x,y)返回 x 除以 y 的余数(x 和 y 可以是两个整数,也可以是表中的整
数列)。常用的单行函数有:
Ø 字符函数:对字符串操作。
Ø 数字函数:对数字进行计算,返回一个数字。
Ø 转换函数:可以将一种数据类型转换为另外一种数据类型。
Ø 日期函数:对日期和时间进行处理。
2. 聚合函数:聚合函数同时可以对多行数据进行操作,并返回一个结果。比如 SUM(x)
返回结果集中 x 列的总合。
一、字符函数
字符函数接受字符参数,这些参数可以是表中的列,也可以是一个字符串表达式。
常用的字符函数:
函数
说明
ASCII(X)
返回字符X的ASCII码
CONCAT(X,Y)
连接字符串X和Y
INSTR(X,STR[,START][,N)
从X中查找str,可以指定从start开始,也可以指定从n开始
LENGTH(X)
返回X的长度
LOWER(X)
X转换成小写
UPPER(X)
X转换成大写
LTRIM(X[,TRIM_STR])
把X的左边截去trim_str字符串,缺省截去空格
RTRIM(X[,TRIM_STR])
把X的右边截去trim_str字符串,缺省截去空格
TRIM([TRIM_STR FROM]X)
把X的两边截去trim_str字符串,缺省截去空格
REPLACE(X,old,new)
在X中查找old,并替换成new
SUBSTR(X,start[,length])
返回X的字串,从start处开始,截取length个字符,缺省length,默认到结尾
上面各函数的例子:
示例
示例结果
SELECT ASCII('a') FROM dual;
97
Package base version 4.2.0
Parameters names(x) names(x) <- value 参数【x】:一个 R 对象。
参数【value】:与参数【x】长度相同的字符向量,或者 NULL。
Details names 是一个通用访问函数,而 names<- 是一个通用替换函数。默认方法用于获取和设置向量(包括列表)或配对表的 "names" 属性。
对于环境 env,names(env) 会给出相应列表的名称,即 names(as.list(env, all.names = TRUE)),ls(env, all.names = TRUE, sorted = FALSE) 也会给出这些名称。如果环境被用作哈希表,names(env) 就是它的 "键"。
如果参数【value】比参数【x】短,则用字符 NA 扩展到参数【x】的长度。
可以通过一般规则只更新名称属性的一部分。这样做是可行的,因为表达式的求值方式是 z <- "names<-"(z, "[<-"(names(z), 3, "c2"))。
Spring: 优点:
Spring是一个开源的免费框架(容器)!Spring是一个轻量级的,非入侵的框架!控制反转(IOC),面向切面编程(AOP)支持事务的处理,对框架整合的支持! 弊端:
发展太久之后违背了原来的理念!配置十分繁琐。 Spring Boot: 一个快速开发的脚手架;基于SpringBoot 可以快速开发单个微服务;约定大于配置; Spring Cloud: 基于Spring Boot实现的 发大多数公司都在使用SpringBoot进行快速开发,学习SpringBoot的前提是完全掌握Spring 和SpringMVC;
学习路线:
1.Spring
2.SpringMVC
3.SpringBoot
4.Spring Cloud
JoySSL是一家专业的SSL证书服务提供商,致力于为网站和在线业务提供最佳的安全加密解决方案。以下是JoySSL的一些优点:
提供多种类型的SSL证书选择:JoySSL提供单域名、多域名、通配符等不同类型的SSL证书,以满足不同网站的需求。证书品牌可信度高:JoySSL与全球多家知名的SSL证书品牌厂商合作,如Sectigo、Digicert、Geotrust等,提供的证书具备可信度和安全性。用户友好的控制面板:JoySSL通过提供直观的界面,帮助用户快速生成CSR、验证域名所有权,并获取所需的证书文件。此外,还提供技术支持和指导,确保用户能够正确地安装和配置SSL证书。强大的技术支持:JoySSL拥有专业的技术支持团队,可以为用户提供及时的技术支持和帮助,解决用户在安装和使用SSL证书过程中遇到的问题。并且JoySSL证书的兼容性能达到99.99%,这一点遥遥领先于其他品牌。 综上所述,JoySSL作为一家专业的SSL证书服务提供商,提供了多种类型的SSL证书选择、用户友好的控制面板、强大的技术支持等优点。如果您需要为网站提供安全加密解决方案,可以考虑使用JoySSL的服务。
Selenium框架 Selenium是一个用于Web应用程序测试的强大工具,它提供了一系列的API,可以模拟用户在浏览器中的操作,包括点击、填写表单、导航等。在进行网络提取数据时,https网站的数据提取一直是一个技术难点。Selenium作为一个自动化测试工具,也可以用于数据提取,但默认情况下并不支持https网站的数据提取。本文将介绍如何配置Selenium项目以添加CONNECT支持,从而实现https网站的数据摘要。
HTTPS问题 首先,让我们了解一下为什么在抽取HTTPS网站时会遇到问题。HTTPS是一种通过了解传输层安全协议(TLS)进行加密的HTTP通信协议。这意味着网站使用SSL证书对通信进行加密,以确保数据的安全性和缺陷。然而,这也意味着在使用Selenium时,需要我们确保它能够正确处理这种加密连接。
为了解决这个问题,我们可以使用Selenium的Desired Capability来添加CONNECT选项。Desired Capability是一个键值对,用于配置Selenium WebDriver实例的行为。通过设置CONNECT选项,我们可以告诉Selenium建立安全连接的方式。
如何在Selenium中添加CONNECT支持? 现在让我们来讨论如何在Selenium中添加CONNECT支持。为了实现这个功能,我们可以使用Selenium的Desired Capability来配置代理服务器,并通过代理服务器来建立连接。以下是一个示例代码,演示了如何在Selenium中添加CONNECT支持:
from selenium import webdriver from selenium.webdriver.common.desired_capabilities import DesiredCapabilities # 设置代理服务器信息 proxyHost = "www.16yun.cn" proxyPort = "5445" proxyUser = "16QMSOML" proxyPass = "280651" # 创建代理对象 proxy = f"{proxyUser}:{proxyPass}@{proxyHost}:{proxyPort}" capabilities = DesiredCapabilities.CHROME capabilities['proxy'] = { "httpProxy": proxy, "ftpProxy": proxy, "sslProxy": proxy, "proxyType": "MANUAL", } # 添加CONNECT支持 capabilities['acceptSslCerts'] = True # 启动浏览器 driver = webdriver.Chrome(desired_capabilities=capabilities) # 访问https网站 driver.get("https://example.com") # 进行其他操作 # .
目标:希望根据一个给定的excel模版,生成多个Sheet页面,比如模版:
示例程序 import openpyxl excel_workbook = openpyxl.load_workbook("模版.xlsx") for _i in range(3): # 比如填充3个页面 # 复制模版sheet页,之后对input_sheet的操作等同于对模版的复制体操作 input_sheet = excel_workbook.copy_worksheet(excel_workbook["模版sheet"]) input_sheet.title = f"sheet_{_i}" # 这个是sheet的名称 input_sheet.cell(row=2, column=1).value = _i # 这个是对具体的单元格赋值 input_sheet.cell(row=2, column=2).value = f"{_i}%" input_sheet.cell(row=2, column=3).value = "2023-12-29" excel_workbook.remove(excel_workbook['模版sheet']) # 过河拆桥,删除原有的sheet模版页 excel_workbook.save("导出结果.xlsx") # 保存结果 得到结果:
第一步:准备工作 在开始之前,确保已经创建了一个Spring Boot项目,并且已经配置了基本的依赖项。
第二步:配置多数据源 首先,我们需要配置多个数据源。在Spring Boot中,可以使用@Configuration类来定义数据源,并使用@Primary注解指定默认数据源。
@Configuration public class DataSourceConfig { @Bean(name = "firstDataSource") @ConfigurationProperties(prefix = "spring.datasource.first") public DataSource firstDataSource() { return DataSourceBuilder.create().build(); } @Bean(name = "secondDataSource") @ConfigurationProperties(prefix = "spring.datasource.second") public DataSource secondDataSource() { return DataSourceBuilder.create().build(); } // 可以配置更多数据源... } 在application.properties(或application.yml)文件中配置数据源的详细信息,例如:
spring: datasource: first: url: jdbc:mysql://localhost:3306/first_db username: username password: password # 其他配置... second: url: jdbc:mysql://localhost:3306/second_db username: username password: password # 其他配置... 第三步:实现动态数据源切换 接下来,我们将创建一个类来动态选择要使用的数据源。我们可以使用ThreadLocal来保存当前数据源的上下文,并在需要时切换数据源。
public class DataSourceContext { private static final ThreadLocal<String> contextHolder = new ThreadLocal<>(); public static void setDataSource(String dataSourceName) { contextHolder.
因为需要在window10上安装.NET Framework 3.5 SP1,下载了脱机包,安装时发现还是要联机更新,并报错:0x800F0954,网上说的方法都无效。
后来在微软官网发现脱机包只适用于 Windows 10 之前的 Windows 版本(见:在 Windows 11、Windows 10、Windows 8.1 和 Windows 8 上安装 .NET Framework 3.5)。
于是决定使用官网《使用部署映像服务和管理 (DISM) 部署 .NET Framework 3.5》介绍的方 ,用DISM命令行来进行安装,一开始错误的以为安装媒体就是下载的脱机安装包,出现了错误:0x800F081F,没找到安装源,最后通过认真阅读官网文字,发现安装媒体指的是windows安装光盘(并不是脱机安装包),用安装光盘终于解决完成了安装。
安装源就是上面的包。
整体的vim的设置是在 /etc/vim/vimrc 文件中。如果想设置所有用户的配置,在里面设置就可以了,配置和.vimrc是一样的,在最后面添加下面2中的语句。
不建议修改/etc/vimrc 文件,每个用户可以在用户根目录中设置vim,新建.vimrc。命令如下:
vim ~/.vimrc 在终端下使用vim进行编辑时,默认情况下,编辑的界面上是没有显示行号、语法高亮度显示、智能缩进等功能的。为了更好的在vim下进行工作,需要手动设置一个配置文件:.vimrc。
需要通过安装很多插件来完成功能,这里直接将~/.vimrc文件发给大家,大家直接替换就可以了。
我的vim配置主要有以下优点:
1.按F5可以直接编译并执行C、C++、java代码以及执行shell脚本,按“F8”可进行C、C++代码的调试 2.自动插入文件头 ,新建C、C++源文件时自动插入表头:包括文件名、作者、联系方式、建立时间等,读者可根据需求自行更改 3.映射“Ctrl + A”为全选并复制快捷键,方便复制代码 4.按“F2”可以直接消除代码中的空行 5.“F3”可列出当前目录文件,打开树状文件目录 6.支持鼠标选择、方向键移动 7.代码高亮,自动缩进,显示行号,显示状态行 8.按“Ctrl + P”可自动补全 9.[]、{}、()、”“、’ ‘等都自动补全 10.其他功能读者可以研究以下文件 map <F9> :call SaveInputData()<CR> func! SaveInputData() exec "tabnew" exec 'normal "+gP' exec "w! /tmp/input_data" endfunc "colorscheme torte "colorscheme murphy "colorscheme desert "colorscheme desert "colorscheme elflord colorscheme ron "set fencs=utf-8,ucs-bom,shift-jis,gb18030,gbk,gb2312,cp936 "set termencoding=utf-8 "set encoding=utf-8 "set fileencodings=ucs-bom,utf-8,cp936 "set fileencoding=utf-8 """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" " 显示相关 """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" "set shortmess=atI "
简介 本文主要介绍了一下js和ts的基础语法,为前端开发zuo
JavaScript 更详细的 JavaScript 学习资料:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript
简介 定位 : JavaScript 是一种动态语言,它包含类型、运算符、标准内置( built-in)对象和方法。在基本语法方面,JavaScript 有很多和 C/C++相似的地方,经常在浏览器开发中使用
依附宿主 : 与大多数编程语言不同,JavaScript 没有输入或输出的概念。它是一个在宿主环境(host environment)下运行的脚本语言,任何与外界沟通的机制都是由宿主环境提供的。浏览器是最常见的宿主环境,但在非常多的其他程序中也包含 JavaScript 解释器,如 Adobe Acrobat、Adobe Photoshop、SVG 图像、Yahoo! 的 Widget 引擎,Node.js之类的服务器端环境。
标准 : 我们有时候也会看到 ECMAScript 或者 ES6 之类的称呼,ECMA 是 JavaScript 的标准化组织,ECMAScript 是针对 JavaScript 语言制定的标准,之所以不叫 JavaScript,是因为 Java 和 JavaScript 的商标都被注册了。因此 ECMAScript 和 JavaScript 的关系是,前者是后者的规格,后者是前者的一种实现(另外的 ECMAScript 方言还有 JScript 和 ActionScript)
运行环境 安装js解释器node.js,终端输入npm -v检查是否安装成功
安装vscode插件code runner便于运行js代码
然后就可以ctrl+alt+N或者点击顶部有个三角形的图标就可以运行js代码了,另外js也可以直接F5运行
console.log("Hello World") 或者终端输入
node js/learn.js 数据类型 Number(数字)
3/2=1.5(默认浮点运算)特殊的值 NaN(Not a Number 的缩写),如果把 NaN 作为参数进行任何数学运算,结果也会是 NaN。NaN如果通过 == 、 !
介绍 Java Agent技术 Java Agent技术是JDK提供的用来编写Java工具的技术,使用这种技术生成一种特殊的jar包,这种jar包可以让Java程序
运行其中的代码。
Java Agent技术的两种模式 Java Agent技术实现了让Java程序执行独立的Java Agent程序中的代码,执行方式有两种:
⚫ 静态加载模式
⚫ 动态加载模式
Java Agent技术的两种模式 - 静态加载模式 静态加载模式可以在程序启动的一开始就执行我们需要执行的代码,适合用APM等性能监测系统从一开始就监控程序
的执行性能。静态加载模式需要在Java Agent的项目中编写一个premain的方法,并打包成jar包。
接下来使用以下命令启动Java程序,此时Java虚拟机将会加载agent中的代码并执行
premain方法会在主线程中执行:
Java Agent技术的两种模式 – 动态加载模式 动态加载模式可以随时让java agent代码执行,适用于Arthas等诊断系统。动态加载模式需要在Java Agent的项目中编
写一个agentmain的方法,并打包成jar包
接下来使用以下代码就可以让java agent代码在指定的java进程中执行了。
agentmain方法会在独立线程中执行:
搭建java agent静态加载模式的环境 步骤: 1、创建maven项目,添加maven-assembly-plugin插件,此插件可以打包出java agent的jar包。
2、编写类和premain方法,premain方法中打印一行信息。
3、编写MANIFEST.MF文件,此文件主要用于描述java agent的配置属性,比如使用哪一个类的
premain方法。
4、使用maven-assembly-plugin进行打包。
5、创建spring boot应用,并静态加载上一步打包完的java agent。
步骤1-4
代码(使用jdk17编辑):
目录结构:
maven 项目 pom.xml 文件(关注代码点插件位置)
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>org.example</groupId> <artifactId>itheima-agent</artifactId> <version>1.0-SNAPSHOT</version> <properties> <maven.compiler.source>17</maven.compiler.source> <maven.
mac上使用的编译器是Clang,但是没有万能头文件bits/stdc++.h\,本文介绍如何添加万能头文件
Xcode 版本:15.1
- 打开应用程序-Xcode-右键显示包内容
Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include
低版本: Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include/c++/v1 - 在该文件夹下创建文件名为 bits 文件夹
- 创建stdc++.h头文件 代码如下,也可直接下载导入,资源置顶免费下载
// C++ includes used for precompiling -*- C++ -*- // Copyright (C) 2003-2014 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 3, or (at your option) // any later version.
React设计思想是什么? 回答思路:react的组件化-->react的数据驱动-->react的虚拟DOMreact的组件化数据驱动视图虚拟DOM 回答思路:react的组件化–>react的数据驱动–>react的虚拟DOM react的组件化 每个组件都符合开放封闭原则,封闭是针对渲染工作来说的,指的是组件内部的状态都由自身维护,只处理自身内部的渲染逻辑。开放是针对通信来说的,指不同组件之间可以通过props等进行数据交互
数据驱动视图 UI = function(data),通过这个公式得出,如果要渲染界面,不应该直接操作DOM,而是通过修改state或props来驱动视图更新
虚拟DOM 由浏览器的渲染可知DOM操作是一个很耗性能的一个操作,因此产生了虚拟DOM,虚拟DOM是对真实DOM的映射,React通过新旧DOM的对比,得出需要更新数据的部分,实现数据的增量更新
一个简单的Sniffer程序,可以用来捕获和打印接收到的IP数据包。
实现多IP报文、ARP、TCP和UDP的简单打印,
IP报文0800
ARP报文0806
TCP:6
UDP:17
ICMP:1
#include <stdio.h> #include <stdlib.h> #include <stdint.h> #include <unistd.h> #include <sys/socket.h> #include <sys/types.h> #include <linux/if_ether.h> #include <linux/in.h> //#include <arpa/inet.h> #define BUFFER_MAX 2048 struct my_ethhdr { unsigned char h_dest[ETH_ALEN]; unsigned char h_source[ETH_ALEN]; unsigned short h_proto; }; struct my_arphdr { unsigned short ar_hrd; unsigned short ar_pro; unsigned char ar_hln; unsigned char ar_pln; unsigned short ar_op; unsigned char ar_sha[ETH_ALEN]; unsigned char ar_sip[4]; unsigned char ar_tha[ETH_ALEN]; unsigned char ar_tip[4]; }; struct my_iphdr { unsigned char ihl:4, version:4; unsigned char tos; unsigned short tot_len; unsigned short id; unsigned short frag_off; unsigned char ttl; unsigned char protocol; unsigned short check; unsigned int saddr; unsigned int daddr; }; struct my_tcphdr { unsigned short source; unsigned short dest; unsigned int seq; unsigned int ack_seq; unsigned short res1:4, doff:4, fin:1, syn:1, rst:1, psh:1, ack:1, urg:1, res2:2; unsigned short window; unsigned short check; unsigned short urg_ptr; }; struct my_udphdr { unsigned short source; unsigned short dest; unsigned short len; unsigned short check; }; struct my_icmphdr { uint8_t type; uint8_t code; uint16_t checksum; uint32_t data; }; void uint32_ip_2_str_ip(uint32_t ip,char *str_ip) { unsigned char bytes[4]; bytes[0] = (ip >> 24) & 0xFF; bytes[1] = (ip >> 16) & 0xFF; bytes[2] = (ip >> 8) & 0xFF; bytes[3] = ip & 0xFF; sprintf(str_ip,"
Tensorflow和pytorch、PaddlePaddle都是非常优秀的深度学习框架,它们各自有着独特的优势和特点。下面是它们之间的一些比较:
易用性: PyTorch:以简洁、直观的设计思想著称,易于学习和使用。它采用动态图模式,更加灵活,允许用户动态构建计算图,便于调试和开发。PaddlePaddle:注重易用性和高性能,并提供了灵活的动态图和高效的静态图两种模式,用户可以根据需求选择适合的模式。PaddlePaddle的中文文档写的非常清楚,上手比较简单。TensorFlow:设计上更加复杂,学习曲线相对较陡。它采用静态图模式,先构建计算图,然后再进行执行。静态图在执行前需要经过编译优化,性能相对较高。
性能:
在相同的硬件条件下,TensorFlow 的运算速度要远远快于其他框架。
PyTorch通常具有更快的运算速度,但占用的内存空间要比 TensorFlow 小。
PaddlePaddle 在 CPU 上运行速度快、占用内存少,GPU 上运行速度更快、占用内存更少。 社区活跃度: TensorFlow 有著名的研究团队支持,有丰富的官方教程和文档。PyTorch 的开发者很活跃,GitHub 库中有众多的项目可供参考。PaddlePaddle 没有太强大的研究团队支持,但已经成为中国深度学习领域的主流框架之一。 功能和扩展性: PyTorch:功能与PaddlePaddle相似,更加灵活和易用,支持动态图和静态图两种方式,并且可以在移动设备上运行。TensorFlow:功能非常强大,提供了丰富的工具和库,支持分布式训练、高性能计算等功能,但也有较为复杂的API和使用门槛。PaddlePaddle:功能比较全面,支持分布式训练、模型压缩、自动求导等高级功能,同时也提供了较为简单易用的API。 综上所述,Tensorflow和pytorch、PaddlePaddle都是优秀的深度学习框架,选择哪个框架取决于你的具体需求和使用场景。如果你需要一个简单易用、灵活的框架,可以考虑使用PyTorch或PaddlePaddle;如果你需要一个功能强大、性能优越的框架,可以考虑使用TensorFlow。
Android发展历史
开发工具
Android Studio
安装工具
下载页面:下载 Android Studio 和应用工具 - Android 开发者 | Android Developers
安装步骤
要求代理,关闭就可以
下载SDK
完成后创建新项目
工程目录结构
编译配置文件
界面与逻辑处理
利用XML标记描绘应用界面,使用java代码书写程序逻辑
上图的LinearLayout相当于父节点,TextView相当于叶子节点。
LinearLayout中的:
orientation:布局
vertical:线性布局
gravity="center":居中
TextView中的:
id:为这个标签的id
layout_width:长度
layout_height:宽度
wrap_content:自适应大小
text:文本内容
Acticity创建与跳转
1.在res下的layout文件夹下创建一个xml文件 2.在res下的values文件夹下的strings.xml写入代码
3.在创建java类与MainActivity同济即可编写代码
4.在清单文件AndroidManifest.xml中写入代码
也可以通过工具快速的创建
跳转
1.在xml加入button标签
2.在java类中编写代码
演示效果
努力学习中~
作者丨JerryYin777@知乎
来源丨https://zhuanlan.zhihu.com/p/670185945
编辑丨极市平台
我的科研工具链分享 CS/AI方向为主,所有软件支持Windows和MacOS双端
我的Github:JerryYin777 - Overview
https//github.com/JerryYin777
本知乎文章同步Github仓库(未来同步更新),如果对你有用,可以点个Star:GitHub - JerryYin777/Cr_Research_Toolchain: 我的科研工具链分享
https//github.com/JerryYin777/Cr_Research_Toolchain
文献阅读器 常规PDF:Adobe Acrobat
https//www.adobe.com/acrobat.html
好处:PDF格式发明公司Adobe的工具软件,阅读体验好,能够编辑,分割,合并PDF(网页平替工具 IlovePDF:https//www.ilovepdf.com/
坏处:不能内置翻译工具,对于英语不好的人会有一定的压力
文献阅读器:Zotero:https//www.zotero.org/
好处:便捷的文献管理工具,多端云同步(iPad,iPhone,电脑),可自带 翻译工具(https//github.com/windingwind/zotero-pdf-translate) ,自带文献导出功能,自带网页端文献一键保存(Zotero Connector),可集成ChatPaper(https//github.com/MuiseDestiny/zotero-gpt) 功能
坏处:云环境存储容量免费只有300M,多了要付费(只能保存在本地)
笔记管理 Notion(https//www.notion.so/product)
好处:多端云同步,Database格式数据存储,教育版无存储上限,集成NotionAI
An Example
Typora
适合写点小东西,排版优美,markdown富文本编辑,数学公式友好,可以很方便改Theme
Hackmd.io(https//hackmd.io/%3Fnav%3Doverview)
在线Markdown,方便分享
论文在哪找 Google Scholar(https//scholar.google.com/)
Arxiv(https//arxiv.org/) 【每日学术推荐:https://arxivdaily.com】
SCIHub(https//sci-hub.ren/) (免费白嫖SCI,知识共产)
ReadPaper(https//readpaper.com/) (国产Paper阅读平台)
Zlibrary:世界上最大的图书资料网站
Paper With Code:带Code的论文,更适用于AI
Github带Awesome的仓库(例如:https://github.com/youngfish42/Awesome-FL(https//github.com/youngfish42/Awesome-FL )
科研信息源 Twitter/X 、LinkedIn:掌握一线最新科研成果,认识很多PhD & AP
ConnectedPaper(https//www.connectedpapers.com/)
Inoreader
RSS阅读器,排除推荐算法的干扰
配合 RSSHub(https//docs.rsshub.app/) 使用更香,Everything is RSSible(赞美DIYGOD大佬)
AI三大顶会(新智元、机器之心、量子位):最前沿的AI讯息,不过带了很多吹水的成分,小白可以看看,方便了解行业讯息
如何找科研机会(陶瓷,但是前提是你最好做好一个学术个人主页,中英文简历各做一份)
知乎
一亩三分地、某些群聊(境外)
在出海的大环境中,企业数字化转型的趋势之一就是上云。然而,上云也带来了新的挑战,特别是对企业的 IT 建设和管理提出了更高的要求。为了构建一个安全合规的云上信息系统环境,满足企业中不同用户的快速增长、资源访问可控、成本可控以及与本地数据中心安全网络连接的需求,并且能够满足审计需求并以较低的管理成本来达成管理要求,企业的IT管理部门需要考虑在云上建立安全着陆区(Security Landing Zone),以此来构建一个安全合规、能满足各种业务要求的安全云环境,下面九河云为大家展开介绍AWS Landing Zone解决方案:
AWS Landing Zone是一种基于AWS云服务的解决方案,旨在帮助企业快速、安全地构建和管理多账号、多区域的云基础设施环境。它提供了一套预定义的最佳实践和自动化工具,帮助企业在AWS上快速创建安全合规的基础设施,以及确保整个云环境的可控性、可扩展性和高可用性。
AWS Landing Zone的实现主要包括以下几个关键步骤:
1. 架构设计:根据企业的需求和最佳实践,设计AWS Landing Zone的架构。这包括定义账号结构、网络架构、安全策略等。
2. 自动化部署:利用AWS CloudFormation等自动化工具,快速创建和部署AWS Landing Zone环境。通过模板定义代码的方式,实现基础架构的自动化部署和配置。
3. 安全设置:配置AWS Identity and Access Management(IAM)策略、网络访问控制列表(Network ACL)、安全组等,确保资源的安全访问和控制。
4. 连接和集成:配置AWS Direct Connect、Amazon Virtual Private Cloud(VPC)对等连接等,实现AWS云环境与本地数据中心的连接和集成。
5. 运维和监控:利用AWS CloudWatch等服务,进行运维和监控,实现资源的自动化管理、日志记录、事件响应等。
AWS Landing Zone的业务价值主要体现在以下几个方面:
1. 加速上云:通过AWS Landing Zone,企业可以快速构建和部署安全合规的云基础设施环境,减少IT基础设施的构建时间和复杂性。
2. 提高可控性和安全性:AWS Landing Zone提供了一套最佳实践和自动化工具,帮助企业确保资源的可控性和安全性。通过标准化和自动化的方式,降低了人为错误的风险。
3. 支持扩展性和弹性:AWS Landing Zone的架构设计可以支持企业快速扩展和灵活调整资源,满足业务的快速增长需求。
4. 降低管理成本:通过自动化部署和管理,AWS Landing Zone可以降低IT管理的复杂性和工作量,减少人力和时间成本。
总之,AWS Landing Zone提供了一种基于最佳实践和自动化工具的解决方案,帮助企业快速、安全地构建和管理AWS云基础设施环境。它不仅提供了快速上云的能力,还提高了可控性、安全性和扩展性,并降低了管理成本,为企业的数字化转型提供了强大的支持和业务价值。
项目框架 jdk1.8、springboot2.5.10
情况一 项目中未使用(权限认证框架:Sa-Token)
application.yml文件内增加配置
server.servlet.session.cookie.http-only=trueserver.servlet.session.cookie.secure=true (此条配置建议也加上) 情况二 项目中使用(权限认证框架:Sa-Token)
使用Sa-Token会使“server.servlet.session.cookie.http-only=true”配置失效,因为框架会重写cookie。
application.yml文件内增加配置
# Sa-Token 配置 sa-token: # Cookie 相关配置 cookie: secure: true httpOnly: true 成功截图
单纯形是 n 维空间 n+1 个仿射无关的点的集合的凸包。在几何意义上:
1维单纯形是一个线段2维单纯形是一个三角形3维单纯形是一个四面体(tetrahedron)
前些天发现了一个人工智能学习网站,通俗易懂,风趣幽默,最重要的屌图甚多,忍不住分享一下给大家。点击跳转到网站。
我们先看一下展示:
代码展示:
<form action=""> <div class="form-group"> <label for="password">Password</label> <input id="password" type="password" required /> <button type="button" title="Reveal Password" aria-pressed="false"> <svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> <defs> <mask id="eye-open"> <path d="M1 12C1 12 5 4 12 4C19 4 23 12 23 12V20H12H1V12Z" fill="#D9D9D9" stroke="black" stroke-width="1.5" stroke-linejoin="round" /> </mask> <mask id="eye-closed"> <path d="M1 12C1 12 5 20 12 20C19 20 23 12 23 12V20H12H1V12Z" fill="#D9D9D9" /> </mask> </defs> <path class="lid lid--upper"