凸多边形的划分(区间dp)

给定一个具有 N 个顶点的凸多边形,将顶点从 1 至 N 标号,每个顶点的权值都是一个正整数。 将这个凸多边形划分成 N−2 个互不相交的三角形,对于每个三角形,其三个顶点的权值相乘都可得到一个权值乘积,试求所有三角形的顶点权值乘积之和至少为多少。 输入格式 第一行包含整数 N,表示顶点数量。 第二行包含 N 个整数,依次为顶点 1 至顶点 N 的权值。 输出格式 输出仅一行,为所有三角形的顶点权值乘积之和的最小值。 数据范围 N≤50, 数据保证所有顶点的权值都小于1e9 输入样例: 5 121 122 123 245 231 输出样例: 12214884 三个点相乘最为 10 ^ 27, 最终答案最大为 5 * 10 ^ 28 long long存不下但是 __int128 可以存可以避免写高精度 #include<bits/stdc++.h> using namespace std; using ll = long long; int dir[4][2] = { 1, 0, -1, 0, 0, 1, 0, -1 }; using lll = __int128; template <class T> istream& read(T& x, istream& cin = std::cin) { T num = 0; bool f = 0; char ch = 0; while (!

SQLSERVER,MySQL JSON字段解析

1.SQLSERVER JSON解析 背景: 最近在维护一个老的项目,发现数据库中某字段存储的JSON字符串,有些失败信息JSON格式还存在不一致,经常会查询这部分数据提供给下游,但是下游只需要错误描述信息,由于数据都是临时查询的,每次都不固定,所以在数据库中直接用函数进行进行JSON格式 并返回详细的描述信息。增加2个函数并调用 1.解析字符串函数 CREATE FUNCTION [dbo].[fn_split](@p_str VARCHAR(8000), @p_split VARCHAR(10)) RETURNS @tab TABLE(tid VARCHAR(2000)) AS BEGIN DECLARE @idx INT DECLARE @len INT SELECT @len = LEN(@p_split), @idx = CHARINDEX(@p_split, @p_str, 1) WHILE(@idx >= 1) BEGIN INSERT INTO @tab SELECT LEFT(@p_str, @idx - 1) SELECT @p_str = RIGHT(@p_str, LEN(@p_str) - @idx - @len + 1), @idx = CHARINDEX(@p_split, @p_str, 1) END if(@p_str <> '') INSERT INTO @tab SELECT @p_str RETURN END; 2.

软考知识点汇总

本篇文章为22年上半年软件设计师备考笔记 个人总结笔记,如有错误望包涵指正 计算机组成和结构 海明校验码 n个数据位,设k个校验位 2 k > = n + k + 1 2^{k}>=n+k+1 2k>=n+k+1 整个编码系统中任意两个码字的最小距离就是该编码系统的码距。为了使一个系统能检查和纠错一个差错,码间最小距离必须至少是==3==(2n+1)海明码是一种可以纠正一位差错的编码,是利用奇偶性来检错和纠错的校验方法循环冗余校验码(CRC)编码方法是在k位信息码后再拼接r位的校验码,形成长度为n位的编码,其特点是检错能力极强且开销小,易于用编码器及检测电路实现。 奇偶校验 对于奇偶校验,是由若干位有效信息,再加上一个二进制位(校验位)组成校验码,其中 奇校验"1"的个数为奇数,而偶校验"1"的个数为偶数, 只有奇数个数据位发生错误,才能发现错误。同时,奇偶校验只能查错不能纠错 采用模二出发运算的只有循环冗余检验CRC CPU 指令周期:取指令,分析指令,执行指令 CPU控制单元部件 指令寄存器 IR:用来保存当前正在执行的指令 输出是指令译码器的输入 对用户完全透明 程序计数器 PC:存储的总是将要执行的下一条指令的地址 程序员可以访问 指令译码器 ID:对操作码进行测试,以便识别所要求的的操作(对现行指令进行分析,确定指令类型和指令所要完成的操作以及寻址方式,并将相应的控制命令发往相关部件) 状态字寄存器 PSW用于保存指令执行完成后产生的条件码,例如运算是否有溢出,结果为正还是为负,是否有进位等,此外,PSSW还保存中端和系统工作状态等信息。 地址寄存器 AR:用来保存当前CPU所访问的内存单元的地址 数据寄存器 MDR:主要用来保存操作数和运算结果,目的为了节省读取操作数所需占用的总总线和访问储存器的时间 地址寄存器 MAR:用来保存当前CPU所访问的内存单元地址,以便对内存的读写操作 累加器 AC:专门存放算术或逻辑运算的一个操作数和运算结果的寄存器 加法器:cpu中算术逻辑运算部件 ALU:CPU的执行单元,主要负责运算工作 控制器:控制整个计算机的各个部件有条不紊的工作,基本功能就是从内存去指令和执行指令 CPU依据指令周期的不同阶段来区分在内存中以二进制编码形式存放的指令和数据 输入输出控制 程序控制:由CPU执行程序控制数据的输入输出过程中断控制:外设准备好输入数据或接受数据时向CPU发出中断信号,CPU响应则中断DMA控制:CPU只需向DMA控制器下达指令,让DMA控制器来处理数据的传送,传送完毕再把信息反馈给CPU,减轻CPU负担节省系统资源 DMA(直接主存存取)是指数据在主存与I/O设备间(即主存与外设之间)直接成块传输;CPU只需在开始和结束时作少量处理,而无需干预数据传送过程 总线结构 三总线结构:数据总线、地址总线和控制总线CPU是在一个总线周期结束时响应DMA请求的优点:简化系统结构,便于系统设计制造;大大减少连线数目,便于布线,减小体积,提高系统的可靠性;便于接口设计,所有与总线连接的设备均采用类似的接口;便于系统扩充、更新与灵活配置。易于实现系统的模块化;便于设备的软件设计,所有接口的软件就是对不同的口地址进行操作;便于故障诊断和维修,同时也减低了成本 内存 主存地址与Cache地址之间的转换工作由硬件完成Cache的设计思想工作是在合理的成本下提高命中率虚拟存储体系由两级存储器构成:主存——辅存多级高速缓存cache,目的是提高CPU访问主存数据或指令的效率随机访问存储器(RAM)有两类:静态的(SRAM)和动态的(DRAM) SRAM比DRAM速度更快,SRAM用来作为高速缓冲存储器(Cache),SRAM将每个位存储在一个双稳态的存储器单元中DRAM用来作为主存及图像系统的帧缓冲区,DRAM将每个位存储为对一个电容的充电由于电容非常小,在10~100ms时间内会失去电荷,所以需要周期性地刷新充电以保持信息 EEPROM是电可擦除可编程只读存储器 CISC和RISC CISC:复杂指令集计算机,进一步增强原有指令的功能,用更为复杂的新指令取代原先由软件子程序完成的功能,实现软件功能的硬件化RISC:精简指令集计算机,通过减少指令总数和简化指令功能,降低硬件设计的复杂度,使指令能单周期执行,并通过优化编译提高指令的执行速度,采用硬布线控制逻辑优化编译程序RISC和CISC在架构上的不同主要有: 在指令集的设计上,RISC指令格式和长度通常是固定的、且寻址方式少而简单、大多数指令在一个周期内就可以执行完;CISC构架下的指令长度通常是可变的、指令类型也很多、一条指令通常要若干周期才可以执行完。由于指令集多少与复杂度上的差异,使RISC的处理器可以利用简单的硬件电路设计出指令解码功能,这样易于流水线的实现。相对的CISC则需要通过只读存储器里的微码来进行解码,CISC因为指令功能与指令参数变化较大,,执行流水线作业时有较多的限制RISC架构中只有载入和存储指令可以访问存储器,数据处理指令只对寄存器的内容进行操作。为了加速程序的运算,RISC会设定多组的寄存器,并且指定特殊用途的寄存器。CISC构架则允许数据处理指令对存储器进行操作,对寄存器的要求相对不高 指令系统的不同寻址方式 寻址方式是指寻找操作数或操作数地址的方式。 指令系统中采用不同寻址方式的目的是为了在效率和方便性上找一个平衡。 立即寻址和寄存器寻址在效率上是最快的。 但是寄存器数目少,不可能将操作数都存入其中等待使用,立即寻址的使用场合也非常有限,这样就需要将数据保存在内存中,然后使用直接寻址、寄存器间接寻址、寄存器相对寻址、基址加变址寻址、相对基址基变址寻址等寻址方式将内存中的数据移入寄存器中 常用的寻址方式 立即寻址:操作数就包含在指令中直接寻址:操作数存放在内存单元中,指令中直接给出操作数所在存储单元的地址寄存器寻址:操作数存放在某一寄存器中,指令中给出存放操作数的寄存器名寄存器间接寻址:操作数存放在内存单元中,操作数所在存储单元的地址在某个寄存器中间接寻址:指令中给出操作数地址的地址相对寻址:指令地址码给出的是一个偏移量(可正可负),操作数地址等于本条指令地址加上该偏移量变址寻址:操作数地址等于变址寄存器的内容加偏移量 主存与Cache的映射方式 全相联地址映射:主存的任意一块可以映象到cache中的任意一块 发生块冲突次数最小直接相联映射:主存中一块只能映象到cache的一个特定的块中 发生块冲突次数最多组相联的映射:各区中某一块只能存入缓存的同组号的空间内,但组内个各块地址之间则可以任意存放。即从主存的组到cache的组之间采用直接映象方式,在两个对应的组内部采用全相联映象方式Cache与主存之间的映射由硬件实现,主存与辅存之间的交互是硬件与软件结合起来实现的 浮点数 [运算]对阶:将小阶向大阶对齐,同时将尾数右移n位 N=2E*F(E阶码,F尾数)规格化,即规定尾数的最高数位必须是一个有效值,即0.

gitlab 生成ssh密匙

文章链接 SSH代表用于管理网络,操作系统和配置的Secure Shell或Secure Socket Shell,并且每次都不需要使用用户名和密码即可验证GitLab服务器。 您可以设置SSH密钥以提供计算机与GitLab之间的可靠连接。 在生成ssh keygen之前,您需要在系统中安装Git。 创建SSH密钥 步骤(1): 要创建SSH密钥,请打开Git Bash命令提示符并输入命令, ssh-keygen Shell 它会提示’输入保存密钥的文件(//.ssh/id_rsa):’,只需键入文件名并按回车。 接下来提示输入密码显示“输入密码(空密码)”。 输入一些密码并按回车。 您将看到生成的SSH密钥, 步骤(2): 现在登录到您的GitLab帐户,然后单击[Settings] 选项。 步骤(3): 要创建SSH密钥,请单击菜单左侧的 SSH Key 选项卡。 步骤(4): 现在转到您的电脑C盘驱动器,您将看到第一步中生成的.pub扩展名的文件(在目录:C:\Users\Administrator.ssh)。 步骤(5): 接下来打开 id_rsa.pub 文件,复制SSH密钥并将其粘贴到高亮显示的密钥框中。 步骤(6): 单击添加密钥(Add key)按钮,将SSH密钥添加到您的GitLab。 您将看到SSH密钥的简短版本,标题和创建日期。 如果多次生成的还是报错 且 错误如图 就看看是不是又known_host文件 把这个文件删了 重新拉去代码即可

一个常用的gpio驱动

分享一个gpio驱动,其中使用了gpio、pinctrl、irq、workqueue、input等知识,代码中有较详细的注释,不时可以来瞅一瞅! 首先设备树中如下配置: &pio { touchsensor_pins_tp_int10: eint@10 { pins_cmd_dat { pins = <MT8163_PIN_32_EINT10__FUNC_GPIO32>; slew-rate = <0>; bias-disable; }; }; touchsensor_pins_tp_int11: eint@11 { pins_cmd_dat { pins = <MT8163_PIN_43_EINT11__FUNC_GPIO43>; slew-rate = <0>; bias-disable; }; }; }; &touch { interrupt-parent = <&pio>; interrupts = <10 IRQ_TYPE_EDGE_FALLING>, <11 IRQ_TYPE_EDGE_FALLING>, eint-debounce = <256>; pinctrl-names = "tp_int10","tp_int11"; pinctrl-0 = <&touchsensor_pins_tp_int10>; pinctrl-1 = <&touchsensor_pins_tp_int11>; int10_gpio32 = <&pio 32 0>; int11_gpio43 = <&pio 43 0>; status = "okay"; }; 源码如下:

python:引用其他不同目录下的python文件

目录 前言 引用方式 同级目录 引用上下级目录 引用不同级目录 引用深层目录 推送 结语 前言 初入python的时候对python的引用过程有诸多不解,留一篇文章做记录吧,本篇主要记录使用__init__来引用python脚本 引用方式 同级目录 import py_2 import py_2 as p2 如上图所示,在同级目录下,py_1.py想要引用py_2.py只需要如上述代码所示,直接import就可以了,如果想引用后重新定义,则加个as 引用上下级目录 import file1.py_2 如上图所示,py_1.py和file1同级目录,在py_1.py内,如果想引用py_2.py,需要在file1文件下创建一个__init__.py,文件,这样就可以如上述所示引用了 import py_1 如上图所示,作为下级文件的py_2.py,如果想引用py_1.py,则不需要添加__init__.py文件,直接import就可以 引用不同级目录 import file2.py_2 如上图所示,py_1.py和py_2.py处于不同级目录下,py_1.py想要引用2,那么在file2下添加__init__后,如上述所示的引用就可以了 引用深层目录 import src.file2.py_2 如上图所示,如果想要引用深层次的目录文件,要确保自己能够一路通过__init__文件连接到另一个文件,py_1.py先通过src下的__init__链接到根目录src,在一路向下找到py_2 推送 Github:https://github.com/KingSun5 结语 希望看到最后的同学有所收获,若是觉得博主的文章写的不错,不妨关注一下博主,点赞一下x博文,另博主能力有限,若文中有出现什么错误的地方,欢迎各位评论指摘。 QQ交流群:806091680(Chinar) 该群为CSDN博主Chinar所创,推荐一下!我也在群里! 本文属于原创文章,转载请著名作者出处并置顶!!!!

服务器宝塔是什么意思?

服务器宝塔是什么意思? 服务器宝塔面板是一款简单好用的服务器运维面板,简单说来就是一个可视化的面板管理工具,支持一键LAMP/LNMP/集群/监控/网站/FTP/数据库/JAVA等100多项服务器管理功能。出错少而且安全,由于宝塔面板既有windows版本也有linux版本,尤其是Linux服务器很多用户不会操作,宝塔是为了让那些不会linux的人使用的,使用宝塔,操作linux更简单,更方便,这里要提醒一下虽然宝塔面板可以安装在物理服务器或者云服务器,虚拟主机无法安装的,但是云服务器基本都是可以安装的。 宝塔面板的环境要求整理如下: Linux面板环境要求 操作系统:全新系统(支持CentOS、Ubuntu、Debian、Fedora、Deepin), 确保是干净的操作系统,没有安装过其它环境带的Apache/Nginx/php/MySQL 宝塔Linux6.0版本是基于centos7开发的,强烈建议使用centos7.x 系统 内存要求:内存要求最低512MB,推荐768MB以上,纯面板约占系统60MB内存 windows面板环境要求 操作系统:支持2003(x86)/2008(x64)/2012/2016 环境需求:Microsoft .NET Framework 2.0 内存要求:内存要求最低1G,推荐1G以上内存。

java中动态脚本

1. ScriptEngine JavaSE6中自带了JavaScript语言的脚本引擎,基于Mozilla的Rhino实现,可以通过三种方式查找脚本引擎: ① 通过脚本名称获取: ScriptEngine engine = new ScriptEngineManager().getEngineByName("JavaScript"); ② 通过文件扩展名获取: ScriptEngine engine = new ScriptEngineManager().getEngineByExtension("js"); ③ 通过MIME类型来获取: ScriptEngine engine = new ScriptEngineManager().getEngineByMimeType("text/javascript"); JavaScript脚本中的println是Rhino引擎额外提供的打印控制台方法 JSEngineUtil import java.io.BufferedReader; import java.io.InputStream; import java.io.InputStreamReader; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.regex.Matcher; import java.util.regex.Pattern; import javax.script.Invocable; import javax.script.ScriptEngine; import javax.script.ScriptEngineManager; import javax.script.ScriptException; import javax.script.SimpleBindings; public class JSEngineUtil { /** * 获取js引擎 */ public static ScriptEngine getJavaScriptEngine() { ScriptEngineManager manager = new ScriptEngineManager(); // ScriptEngine engine = new ScriptEngineManager().

zigbee 使用串口来开关来控制灯

#include <ioCC2530.h> #define uint unsigned int #define uchar unsigned char #define LED1 P0_4 //定义P1_0为LED1的控制引脚 void Init_LED(); //声明LED初始化函数 void Init_Uart0(); //声明串口0初始化函数 void Init_Cfg_32M(); //声明初始化32M时钟初始化函数 void UR0SendByte(unsigned char Byte);//声明发送一个字节初始化函数 void UR0SendString(unsigned char *str);//声明发送字符串初始化函数 void Execute_CMD(); //声明执行上位机命令初始化函数 char RxBuf; //定义接收缓冲区 char Rx_flag; //定义串口接收标志位 /*====================主函数入口====================*/ void main() { Init_Uart0(); //初始化串口0 Init_LED(); //初始化LED端口 Init_Cfg_32M(); //初始化32M晶振 UR0SendString(" Hello ZigBee!\r\n"); while(1) { if(Rx_flag == 1) //是否接收到上位机指令 { Execute_CMD(); //判断并执行上位机指令 } } } /*===================LED初始化函数==================*/ void Init_LED() {

SpringBoot邮件发送

SpringBoot邮件发送 邮件发送是一个非常常见的功能,注册时的身份认证、重要通知发送等都会用到邮件发送。Sun公司提供了JavaMail用来实现邮件发送,但是配置烦琐,Spring 中提供了JavaMailSender 用来简化邮件配置,Spring Boot则提供了MailSenderAutoConfiguration 对邮件的发送做了进一步简化。 1. 发送前的准备 本节以QQ邮箱为例向读者介绍邮件的发送过程。使用QQ邮箱发送邮件,首先要申请开通POP3/SMTP服务或者IMAP/SMTP服务。SMTP全称为Simple Mail Transfer Protocol,译作简单邮件传输协议,它定义了邮件客户端软件与SMTP服务器之间,以及SMTP服务器与SMTP服务器之间的通信规则。也就是说,aaa@qq.com 用户先将邮件投递到腾讯的SMTP服务器,这个过程就使用了SMTP协议,然后腾讯的SMTP服务器将邮件投递到网易的SMTP服务器,这个过程依然使用了SMTP协议,SMTP服务器就是用来接收邮件的。而POP3全称为Post Office Protocol3,译作邮局协议,它定义了邮件客户端与POP3服务器之间的通信规则。该协议在什么场景下会用到呢?当邮件到达网易的SMTP服务器之后,111@163.com 用户需要登录服务器查看邮件,这个时候就用上该协议了:邮件服务商会为每一个用户提供专门的邮件存储空间,SMTP服务器收到邮件之后,将邮件保存到相应用户的邮件存储空间中,如果用户要读取邮件,就需要通过邮件服务商的POP3邮件服务器来完成。至于IMAP协议,则是对POP3协议的扩展,功能更强,作用类似。下面介绍QQ邮箱开通POP3/SMTP服务或者IMAP/SMTP服务的步骤。 步骤01 登录QQ邮箱,依次单击顶部的设置按钮和账户按钮如图所示。 步骤02 在账户选项卡 下方找到POP3/SMTP服务,单击后方的“开启”按钮,如图所示。 单击“开启”按钮后,按照引导步骤发送短信,操作成功后,会获取一个授权码,将授权码保存下来过后使用。 拿到授权码后,准备工作就完成了。 2. 发送 2.1 环境搭建 使用Spring Boot发送邮件,环境搭建非常容易,首先在创建项目时添加邮件依赖,代码如下: <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-mail</artifactId> </dependency> 项目创建成功后,在application.properties中完成邮件基本信息配置,代码如下: # 配置邮件服务器的地址 spring.mail.host=smtp.qq.com # 配置邮件服务器的端口(465或587) spring.mail.port=465 # 配置用户的账号 spring.mail.username=123@qq.com # 配置用户的密码(即上面我们申请到的授权码) spring.mail.password=qgczjydhuqytabcd # 配置默认编码 spring.mail.default-encoding=UTF-8 # SSL 连接配置 spring.mail.properties.mail.smtp.socketFactory.class=javax.net.ssl.SSLSocketFactory # 开启 debug,这样方便开发者查看邮件发送日志 spring.mail.properties.mail.debug=true 这里配置了邮件服务器的地址、端口(可以是465或者587)、用户的账号和密码以及默认编码、SSL连接配置等,最后开启debug,这样方便开发者查看邮件发送日志。注意,SSL的配置可以在QQ邮箱帮助中心看到相关文档,如图所示。 完成这些配置之后,基本的邮件发送环境就搭建成功了,接下来就可以发送邮件了。邮件从简单到复杂有多种类型,下面分别予以介绍。 2.2 发送简单邮件 创建一个MailService用来封装邮件的发送,代码如下: @Component public class MailService { // JavaMailSender 在Mail 自动配置类 MailSenderAutoConfiguration 中已经导入,这里直接注入使用即可 @Autowired JavaMailSender javaMailSender; //方法5个参数分别表示:邮件发送者、收件人、抄送人、邮件主题以及邮件内容 public void sendSimpleMail(String from, String to, String cc, String subject, String content) { // 简单邮件直接构建一个 SimpleMailMessage 对象进行配置并发送即可 SimpleMailMessage simpMsg = new SimpleMailMessage(); simpMsg.

通过vue cli命令打包发布组件

功能描述 把某个系统中的几个vue页面需要供给多个系统使用,所以需要对公共的vue页面进行打包发布到npm仓库,其他系统工程通过npm install导入进行使用 工程示例 |-- src | |-- App.vue # 根组件 | |-- main.js # 入口js文件 | |-- api # 接口请求api | |-- assets # 资源目录 | |-- components # 公共组件 | |-- route # 路由 | |-- store # store module | |-- views # vue页面视图 | |-- utils | | |-- request.js # axios请求 | | |-- auth.js # 获取cookie 关键代码 在package.json中的关键代码,关键是使用vue-cli-service的target lib命令进行打包 官方文档说明:vue cli的库打包说明 "name": "库的名称", "

中介模式(python实现2)

相较前一个中介模式(python实现)来说,本例子实现了多个中介者的情况 from abc import ABCMeta, abstractmethod from enum import Enum class InteractiveObject: """进行交互的对象""" class InteractiveObjectImplA: """实现类A""" class InteractiveObjectImplB: """实现类B""" class Mediator: """中介类""" def __init__(self): self.__interactive_obj_a = InteractiveObjectImplA() self.__interactive_obj_b = InteractiveObjectImplB() def interactive(self): """进行交互的操作""" # 通过self.__interactive_obj_a和self.__interactive_obj_b完成相应的交互操作 class DeviceType(Enum): """设备类型""" TypeSpeaker = 1 TypeMicrophone = 2 TypeCamera = 3 class DeviceItem: """设备项""" def __init__(self, id, name, type, is_default=False): self.__id = id self.__name = name self.__type = type self.__is_default = is_default def __str__(self): template = 'type: {} id: {} name: {} is_default: {}.

15.登录模块增加验证码部分

验证码登录流程,别人博客看的 实现过程 之前SSM其实就做过了,保存session中,只不过之前是将验证码的值放到session中,而这次是将验证码的值保存到redis中,并给它设置一个过期时间,120秒 引入redis和Kaptcha依赖 <!--kaptcha依赖--> <dependency> <groupId>com.github.axet</groupId> <artifactId>kaptcha</artifactId> <version>0.0.9</version> </dependency> <!--redis依赖--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency> application.properties中r配置redis spring.redis.port=6379 spring.redis.host=127.0.0.1 spring.redis.database=0 kaptcha配置信息 package com.cy.store.config; import com.google.code.kaptcha.impl.DefaultKaptcha; import com.google.code.kaptcha.util.Config; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import java.util.Properties; /** * @author ZhangHailong * @date 2022/5/18 - 12:23 * @project_name Kaptcha配置信息 */ @Configuration public class KaptchaConfig { @Bean public DefaultKaptcha getDDefaultKaptcha() { DefaultKaptcha dk = new DefaultKaptcha(); Properties properties = new Properties(); // 图片边框 properties.setProperty("kaptcha.border", "yes"); // 边框颜色 properties.

关于ros Melodic与opencv 4.5.5版本冲突cv_bridge报错 的解决办法:

关于ros与opencv版本冲突cv_bridge报错 的解决办法: 1.我的环境:ubuntu18.04+ros melodic +opencv4.5.5 2.问题:最近在跑课程项目,因为我的linux放在移动硬盘里面嘛,所以运行速度不是很快,我一般会在windows里写好再去linux,如果大家的linux不卡顿,建议大家开始写代码的时候就在linux的环境。我的windows中opencv版本是4.5.5,就是目前的最新版。写好后我就移动到linux下面嘛。编译报错,百度一下是因为linux的opencv版本太低了,需要升级,我想了一下反正早晚都得用新的,升级呗。于是卸载了老版本的opencv,安装了新的,我觉得不少小伙伴也和我一样。哎,这就是入坑的第一步啊…… 问题的样子:我的ros程序需要用到cv_bridge,这才是真正的问题,如果大家不需要cv_bridge的话一般不会出现错误……书回正传;在以前版本的使用的cv_bridge程序现在用不了了,并且程序会报错如下: OpenCV Error: Assertion failed (tlsSlots.size() > slotIdx) in releaseSlot, file /build/opencv-L2vuMj/opencv-3.2.0+dfsg/modules/core/src/system.cpp, line 1092 terminate called after throwing an instance of ‘cv::Exception’ what(): /build/opencv-L2vuMj/opencv-3.2.0+dfsg/modules/core/src/system.cpp:1092: error: (-215) tlsSlots.size() > slotIdx in function releaseSlot 咋办呢,百度呗,百度得到了结果还是挺令人满意的,下面这几个博主讲述的解决办法都非常详细,但是……不知道为啥我是没有解决这个问题的…… 方案一:修改ros目录下关于cv_bridge的文件: https://blog.csdn.net/Shushan1/article/details/116588614?spm=1001.2014.3001.5506 https://blog.csdn.net/bigdog_1027/article/details/79092263 这二位前辈写的非常非常非常详尽!大家可以先去试一下! 方案二:我成功的方案,安装最新版的cv_bridge,使用时需要在工作空间的Cmakelists文件里写明新的cv_bridge路径。 这里还是看到了这位博主的文章: https://blog.csdn.net/qq_36814762/article/details/110230127?spm=1001.2014.3001.5506 方法可行,但这篇文章过去两年,而且我用的时opencv4,不知道会出什么幺蛾子,百度了一下选择安装最新版适应opencv4的cv_bridge,这里不要安装这个官方网址下面的包包https://github.com/ros-perception/vision_opencv,因为opencv4.5.5最近才出,所以官网文件里还有很多不兼容的地方。我刚开始并不知道这样的情况,甚至想要放弃了,后来我在github上找到了解决办法。这里插一句:小伙伴们需要什么包的时候多去github上翻翻,出了问题可以在该包对应的issues那里搜索自己的问题,一般都有人遇到过,没有的话可以提问,记得把自己的环境讲清,比如我:ubuntu18+opencv4.5.5……会有大佬帮助的!github上对于cv_bridge不兼容opencv高版本是这样解释的: Since OpenCV4 is released a month ago, this package doesn’t compile. This PR adds compatibility for OpenCV4. Regarding the module_opencv4.cpp, it’s probably not the most future proof way to do this, but the package already seems to handle opencv2/3 this way so I just amended it.

报错:ImproperlyConfigured: Requested setting INSTALLED_APPS, but settings are not configured.

1. 报错现象 在idea的终端中执行 from myapp_api.models import Project, App, Server 后出现以下报错 ImproperlyConfigured: Requested setting INSTALLED_APPS, but settings are not configured. You must either define the environment variable DJANGO_SETTINGS_MODULE or call settings.config ure() before accessing settings. 2. 解决方法 退出当前环境,在shell中,用以下命令启动 python manage.py shell 就不在发生报错了.

brpc组件bvar源码解析(三)Variable、Reducer和Adder

1.Variable类 Variable是所有bvar的基类,是一个纯虚类。拥有的唯一的成员变量是_name。 Variable类中的接口分为几类: 描述相关的 子类实现纯虚函数describe,目的是将bvar的值写入ostream。 get_description不是纯虚函数,它调用了describe写入ostringstream,返回ostringstream的string。 曝光相关的 例如:expose,expose_impl,expose_as,list_exposed,count_exposed,describe_exposed,dump_exposed等。核心是expose_impl,下文介绍。 函数expose_impl 函数expose_impl是实现曝光的核心逻辑。所谓“曝光”就是把bvar的地址存到一个公共的map中,以便后续可以遍历和查询到。 具体的做法是: (1)根据prefix+name生成统一格式的曝光名称_name:非字母、非数字的全部转成下划线 (2)根据(1)生成的曝光名称_name查询所属的VarMapWithLock: 首先对_name进行了简单的hash,然后对VarMapWithLock数组s_var_maps的长度SUB_MAP_COUNT取模得到i,返回s_var_maps的第i个成员。这里这么做的目的是为了减少VarMapWithLock中的锁竞争的频率。 (3)根据_name查询VarMapWithLock中是否存在key为_name的记录 VarMapWithLock其实就是加了锁的hashmap。 如果查不到,则插入pair<name, VarEntry>,VarEntry的var变量赋值this值,display_filter变量赋值入参display_filter。 display_filter是枚举类型DisplayFilter,表示显示到文本中、html中还是全部。list_exposed函数会将入参和所有VarEntry的display_filter进行与操作,只输出满足条件的bvar。 (4)如果(3)能查到记录,说明有同名bar已经进行了曝光,则根据gflags进行相关处理(直接abort或者打印error log) 函数hide 很容易理解,就是根据_name从对应的VarMapWithLock中删除记录。 函数list_exposed 遍历所有曝光的bvar,即遍历s_var_maps中的所有map的所有pair,选出满足display_filter条件的bvar的name保存到names数组中。 遍历s_var_maps中的每个map时,首先都需要先加锁,才能遍历map中的每个pair。为了防止个数太多、加锁时间过长,遍历每超过一定个数(256个),都主动释放一下锁。 函数describe_exposed 即根据name从s_var_maps查询到VarEntry*,调用该bvar的describe函数,结果保存到os中。 函数dump_exposed 查询所有曝光的bvar,将符合options中的通配符white_wildcards和black_wildcards条件的bvar都调用dumper->dump函数。例如white_wildcards = “foo_bar_*”; black_wildcards = “*var5”。函数返回值是dump的bvar的个数。 如果通配符white_wildcards是空的,那么先通过list_exposed得到所有曝光的bvar的name,然后对name进行排序,遍历name数组,对于符合通配符条件的name,调用describe_exposed函数将该bvar的描述保存到ostream,然后调用dumper->dump函数,传入name和保存描述的ostream转成的字符串。 Dumper是一个纯虚类,由开发者自己继承实现。 2.Reducer类 Reducer类定义: 3个模板类型: T:bvar保存的值的类型 Op:“累加”的op InvOp:与“累加”相反操作的OP,默认是VoidOp即无具体操作;这个介绍采样的时候再具体介绍。 成员变量: 构造函数: add_cr_non_integral是如果T不是整型则增加const&修饰。 identity赋值T的默认构造函数生成的对象,如果T是POD类型,则T()就是0值。 _combiner:AgentCombiner<T, T, Op>类的对象;AgentCombiner的第1、第2模板参数都是T,说明它的结果类型和元素类型是相同的、都是T(介绍AgentCombiner时说过这2个类型可以不同) _sampler:ReducerSampler<Reducer, T, Op, InvOp>类型的指针,此处设置为NULL,只有当前bvar有采样需要,即成员函数get_sampler被调用时_sampler才会被new出来。 _series_sampler:嵌套类SeriesSampler类型的指针,此处设置为NULL,后面介绍采样时再介绍。 _inv_op:InvOp类的对象。 Op类的对象在_combiner中有保存,所以不需要重复保存; 函数operator<< 函数operator<<是对bvar增加值时调用的,例如 bvar::Adder<int> sum; sum << 1 << 2 << 3 << 4; LOG(INFO) << sum.

中介模式(python)

""" 中介模式:用一个中介对象来封装一系列的对象交互,中介者使各对象不需要显示地相互引用, 从而使其耦合松散,而且可以独立地改变他们之间的交互 """ class HouseInfo: """房源信息""" def __init__(self, area, price, has_window, has_bathroom, has_kitchen, address, owner): self.__area = area self.__price = price self.__has_window = has_window self.__has_bathroom = has_bathroom self.__has_kitchen = has_kitchen self.__address = address self.__owner = owner def get_address(self): return self.__address def get_owner_name(self): return self.__owner.get_name() def show_info(self, is_show_owner=True): template = "面积: {}平方米, 价格: {}元, 窗户: {}, 卫生间: {}, 厨房: {}, 地址: {}, 房东: {}." print(template.format(self.__area, self.__price, '有' if self.__has_window else '无', self.

华硕触控板无法在Win11中使用的解决办法

​笔记本的触摸板类似于鼠标,在没有鼠标的时候就可以使用触摸板来控制电脑。但是有用户跟小编反映自己的华硕触摸板无法在Win11中使用,这是怎么回事?想要了解这个问题,就跟着小编一起来看看吧。 更多重装系统教程尽在小白系统重装官网 1、确保您的华硕笔记本电脑上的触摸板已启用 按Windows+I启动设置应用程序,然后从左侧导航窗格中列出的选项卡中选择蓝牙和设备。 接下来,单击此处的触摸板条目。 现在,确保触摸板的切换已启用,如果未启用,请单击切换。 此外,检查配置的触摸板设置是否与预期行为匹配,并在需要时进行必要的更改。 完成更改后,重新启动计算机以使这些更改完全生效,并检查华硕触摸板现在是否开始在 Windows 11 中工作。 2、更新触摸板驱动 按Windows+S启动搜索菜单,在顶部的文本字段中输入设备管理器,然后单击相关搜索结果。 双击此处的鼠标和其他指针设备条目。 现在,右键单击出现故障的触摸板,然后从上下文菜单中选择更新驱动程序。 最后,从更新驱动程序窗口的两个选项中选择自动搜索驱动程序。 等待您的计算机安装可用的最佳驱动程序。 如果华硕触摸板在更新后停止工作,安装最新的驱动程序版本可以解决问题。如果是这样的话,很快就会发布一个带有漏洞补丁的更新版本。 如果设备管理器方法不起作用,您也可以在 Windows 11 中手动安装最新的驱动程序。此外,如果设备管理器中没有显示华硕触摸板驱动程序,有一些快速的方法可以访问它。 或者,为了节省时间和自动化任务,您可以使用专用软件。我们推荐DriverFix,因为它是最新的、无错误的且易于使用。 3、删除有冲突的第三方应用 按Windows+R启动Run命令,在文本字段中输入appwiz.cpl ,然后单击OK或点击Enter启动Programs and Features。 现在,找到有问题的程序,选择它,然后单击卸载。 按照屏幕上的说明完成该过程。

Go语言环境安装以及程序如何运行 宝塔面板Linux环境

Linux环境 Go语言环境安装以及程序如何运行 最近在学习go语言 记录下在服务器上安装go语言环境 安装配置 : 宝塔Linux面板 7.6.0 1. 文件下载 go环境文件 可以去官网下载 自己选择环境文件 官网 https://golang.google.cn/) 文件地址 https://golang.google.cn/dl/ 2 解压 文件上传到 /www/server 目录 tar -xzvf 刚上传的文件名 示例 tar -xzvf go1.18.2.linux-amd64.tar.gz 注意 如果报错 no such file or directory(文件找不到) 可以切换下登录账号 su root 3 添加环境变量 添加环境变量,使用vim 打开/etc/profile 文件。 vim /etc/profile 最底部添加 export GOROOT=/www/server/go export GOBIN=$GOROOT/bin export GOPKG=$GOROOT/pkg/tool/linux_amd64 export GOARCH=amd64 export GOOS=linux export GOPATH=/www/wwwroot/Golang export PATH=$PATH:$GOBIN:$GOPKG:$GOPATH/bin 图片示例 添加好之后,保存退出,然后执行如下命令使其生效: source /etc/profile 4 检测环境 使用 go version 检测下go环境是否安装成功

aab转apk的方法(将Android App Bundle转换为APK)--bundletool

Google Play 在2021年8月之后,对于新上架的APP,只接受AAB格式,不再支持上传APK。但是打包后,我们肯定还需要对正式发布的包进行测试,去Google Play上发测试版本非常麻烦。 还好Google为我们提供了转换工具。 bundletool官方文档:https://developer.android.google.cn/studio/command-line/bundletool bundletool下载地址:https://github.com/google/bundletool/releases aab文件先转换为apks文件,aab转换为apks后解压apks文件就是apk文件了 使用方法: 注:在同一文件夹操作不需要写路径 java -jar bundletool.jar build-apks //jar包及路径 --mode=universal //模式 --bundle=D:\work_file\20211230.aab //需要修改的aab包以及所在路径 --output=aa.apks //apks包输出路径 --ks=D:\work_file\sign.jks //签名以及路径 --ks-pass=pass:sign666 //签名密码 --ks-key-alias=sign //签名 --key-pass=pass:sign666 //签名密码 使用以下命令将aab转换为apks,请根据下载的版本名称替换。 // jar包及路径 模式 需要修改的aab包以及所在路径 apks包输出路径 签名以及路径 签名密码 签名 签名密码 java -jar bundletool.jar build-apks --mode=universal --bundle=D:\work_file\20211230.aab --output=aa.apks --ks=D:\work_file\sign.jks --ks-pass=pass:sign666 --ks-key-alias=sign --key-pass=pass:sign666

JVM调优工具Jprofiler查看远程进程分析第一种连接方式(四)

JVM调优工具Jprofiler查看远程进程分析第一种连接方式(四) 问题背景JVM调优工具Jprofiler无介绍快速安装(附安装包)(一) JVM主要需要分析的情况Linux安装Jprofiler服务端总结Lyric: 然后微微笑 问题背景 上个篇章介绍了使用Jprofiler工具查看IDEA本地进程内存占用情况和GC情况,这个篇章介绍连接远程的进程,其中有两种连接方式,因为有一种我始终没有效果,所以换了一种,但两种我都分两个篇章写出来,大家选择自己合适的就行 注意事项: 远程连接需要保持Jprofiler的windows客户端和Jprofiler的linux服务端版本保持一致,这样连接才不会出问题上传同版本的安装包可以自己下载也可以去官网下载 JVM调优工具Jprofiler无介绍快速安装(附安装包)(一) JVM主要需要分析的情况 1 Jprofiler的live memory中频繁创建的Java对象:可能是死循环、循环次数太多,递归未终止 2 Jprofiler的live memory中存在大对象:bytes[]应该边读边写,长时间不写导致bytes数组过大 3 Jprofiler的live memory中产生内存泄漏:内存泄漏的时候开启Recorded Objects分析 4 Jprofiler观察web容器的线程最大数:Tomcat的线程容量应该大于最大并发数 5 Jprofiler观察线程阻塞 6 Jprofiler观察线程死锁 Linux安装Jprofiler服务端 1 下载linux安装包 2 自己创建文件夹,使用xshell指令导入Jprofiler的linux安装包jprofiler_linux_11_1_4.tar.gz mkdir jprofiler rz -y 3 解压jprofiler_linux_11_1_4.tar.gz tar -zxvf jprofiler_linux_11_1_4.tar.gz 4 进入jprofiler11.1.4文件夹的bin目录 pwd /home/app/jprofilter/jprofiler11.1.4/bin 5 启动jprofiler,在这个bin文件夹下,执行jpenable ./jpenable 6 选择你需要分析的进程 7 Enter确定,选择模式,我选择的1为GUI模式,在线分析 8 输入一个未被占用的端口号 9 此时我需要分析的进程的日志打印了Jprofilter的启动日志 JProfiler> Protocol version 63 JProfiler> Java 8 detected. JProfiler> 64-bit library JProfiler> Listening on port: 8849.

大规模并行分布式深度学习

作者:林伟 最新的十年是人工智能爆炸的十年,人工智能已经在社会各个领域如图片,语音,语言理解,推荐算法取得重大突破,使得其判断的结果已经接近或者超越了人类。这个背后的主要原因是是互联网的不断发展使我们能够快速地积累了海量数据,再加上硬件的快速发展以及神经网络训练方式的革新,使我们越来越有能力训练深且宽的神经网络,产出了超越人类“智能”的模型,并得到广泛应用。所以如何实现大规模并行分布式深度学习就成为深度学习的研究热点,从而成为推动算法创新的关键的人工智能工程能力。 并行分布式深度学习的历史发展历程和范式 最开始推动分布式训练的场景是大规模搜索广告推荐模型。随着互联网的发展,我们需要建立一个能够满足互联网用户以及数据规模一种搜索广告推荐模型,需要通过训练能够很好对用户,网页进行有效的向量化,从而能够通过不同人或者网页的特征,找出更加相关的信息,提高人们在海量数据中匹配数据的效率。而这类模型往往需要学习出来一个非常大的特征矩阵,比如现代系统这种特征规模以及从最开始百亿[1]已经发展到千亿乃至于万亿[2],这就需要一种分布式的系统来支撑这种机器学习的模型训练。而且因为这种特征矩阵因为人群和网页这种互联网的特性,具有明显的热点效应,是非常稀疏的,使得其在访问时候常常具有在时间和空间上的不均匀性。这也是 2014年谷歌等团队在 OSDI 发表一个分布式系统《Scaling Distributed Machine Learning with the Parameter Server》[3](相关其他研究还有[4][5]),该系统(Figure 1)建立一个分布式 Key-Value 的存储系统来保存海量的特征向量,然后我们把海量训练数据分发到多个没有状态的训练工作节点(worker),每个工作节点从分布式 KV的参数服务器取得最新的参数,在当前这批数据进行训练算出在这批数据上做出的估计和希望的答案(一般是把用户最后真实点击的网页或者商品作为目标答案)的差距,从而计算出需要对于参数调整的梯度,然后在把这些梯度推送会参数服务器进行相关加权平均,汇总后再调整参数,使得整个模型的预测能够更加贴近目标值。因为稀疏的特性,为了能够充分发挥系统的性能,也因为这类模型往往追求的目标是一个动态的目标,因为人的兴趣和网页本身都是时刻在变化的。所以我们可以利用这个特性进行异步训练,也就是在训练时候可以适当使用过期的参数以及利用异步的方式来更新参数,从而能够更好的,在更大范围来容忍参数服务器参数访问的不均匀性以及分布式场景下容错以及网络通讯的压力,使得分布式训练效率更优。更加具体的可以参照 NIPS 2013 年的《More effective distributed ml via a stale synchronous parallel parameter server》等论文[5]。 标题图1参数服务器(选自[3]) 于此同时,在图片,语音和语言等感知类领域,随着海量数据的积累以及算力发展,神经网络算法终于可以取得突破性的结果,随着 AlexNet[6], GoogleNet[7],Resnet[8],模型的规模和深度也是越来越大,从而机器学习领域从神级网络算法诞生出一支独立学派:深度学习,并得到了快速爆炸性的发展,以至于如今人们谈论人工智能往往和深度学习画上了等号。但是因为GPU等硬件也是快速发展,显存大小也是同步在变大,使得这类模型还是能够在单块显卡能够放的下,加上我们可以通过 ZeRO optimizer[25],CPU-offload 等技术进一步提高 GPU 显存的使用效率,以至有文章[26]说实用的模型总是能够在单卡能够放下并且得到训练。但是即便如此,模型的参数还是有上亿的规模,需要海量的数据来训练,为了加速训练,我们还是需要使用数据并行来分布式训练,因为感知类模型往往是稠密的参数,训练每批数据后,几乎是所有的参数都需要更新,这样使得在通讯行为上有着非常显著不同于稀疏模型的特点,于是我们有了另外一种并行分布式方式:AllReduce[27]的同步的数据并行。这种分布式训练模式其实从高性能集群 HPC 领域来,也就是每个训练参与方都维护一个模型的副本,然后在训练时候,每个工作节点分到 N 分之一的数据,通过前向和反向计算,得到这个数据下模型估计值和目标指的差距,从而得到这批数据上参数需要变换的梯度,然后利用高性能 HPC 集群的通讯库原语 AllReduce 使得每个节点同时加权平均所有节点局部梯度变化,使得每个工作节点都得到全局梯度变化的副本,最后同时将该梯度变化运用于模型参数上,使得其每个工作节点上的模型副本同步得到相同的更新。AllReduce 的有可以细分为 Ring-AllReduce[26]和 Reduce-Scatter 的方式来做,其中 Ring-Allreduce 因为去中心化以及非常确定性的消息传递,使得 Nvidia 可以根据这个特性构建多个 GPU 卡的物理拓扑NVLink[9],从而能够高效进行 Ring 的 Allreduce,并且将这个通讯原语集成到自己软件 NCCL 库[10],从而大大推动同步的数据并行模型训练的开展和人工智能应用的发展。当然也有其他研究比如字节跳动的 BytePS[11] 利用参数服务器的分布式架构来进行稠密模型的 AllReduce 这个计算,以便在没有良好 NVLink 拓扑上一样能够进行高效的同步的数据并行训练。

【k8s容器日志收集】EFK收集日志,kubernetes守护进程方式部署filebeat收集k8s集群容器日志elasticsearch+kibana+filebeat

文章目录 前言部署filebeat登录kibana查看日志总结 前言 上篇文章讲了使用ECK部署Kubernetes使用ECK部署Elasticsearch8.0和Kibana集群(k8s) 这篇文章见如何使用filebeat收集k8s容器pod日志 部署filebeat 首先先要明白k8s容器日志默认存储路径是/var/log/containers/ 部署方式有三种 一是可以通过直接linux系统部署方式,收集/var/log/containers/目录下k8s容器日志,每个节点都有这个目录 二是docker容器运行filebeat,并挂载/var/log/containers数据卷,这样也能收集日志 三是在k8s上使用守护进程的方式保证每个节点都运行一个filebeat实列,并且挂在数据卷/var/log/containers,类型是hostpath 这里我们采用第三种方式,也比较方便统一管理 根据官方文档https://www.elastic.co/guide/en/beats/filebeat/current/running-on-kubernetes.html 官方已经为我们提供了响应的yml文件,只需要在其基础上修改即可 --- apiVersion: v1 kind: ConfigMap metadata: name: filebeat-config namespace: kube-system labels: k8s-app: filebeat data: filebeat.yml: |- filebeat.inputs: - type: container paths: - /var/log/containers/*.log processors: - add_kubernetes_metadata: host: ${NODE_NAME} matchers: - logs_path: logs_path: "/var/log/containers/" # To enable hints based autodiscover, remove `filebeat.inputs` configuration and uncomment this: #filebeat.autodiscover: # providers: # - type: kubernetes # node: ${NODE_NAME} # hints.

ApplicationListener

一、简介: 作用:监听容器中发布的事件,完成事件驱动模型开发。 继承关系 图 自定义一个监听器,监听ApplicationEvent及其下面的子事件;-----实现ApplicationEvent接口方式 1)写一个监听器(ApplicationListener的实现类)来监听某个事件(ApplicationEvent及其子类) 重写方法 void onApplicationEvent(ApplicationEvent event){} //当容器中发布此事件(event)后,该方法会被触发; 2)把监听器加入到容器中; 3)只要容器中有相关事件的发布,我们就能监听到这个事件; ContextRefreshedEvent:容器刷新完成(所有bean都完全创建)会发布这个事件; ContextClosedEvent:关闭容器会发步这个事件; 4)发布一个事件: applicationContext.publishEvent(ApplicationEvent event); eg:ac.publishEvent(new ApplicationEvent(new String("我发布的事件")) {}); 二、原理 针对监听到的三个事件进行原理分析: 1、ContextRefreshedEvent事件 1)容器创建对象:refresh() 2)finishRefresh();容器刷新完成;---会发布ContextRefreshedEvent事件、自定义发布的事件; 2、自己发布的事件、ContextRefreshedEvent、ContextClosedEvent 都会走下面的流程: 2.1)publishEvent(new ContextRefreshedEvent(this)); 2.1.1)获取事件的多播器(派发器):getApplicationEventMulticaster(); 2.1.2)void multicastEvent(ApplicationEvent event, @Nullable ResolvableType eventType);派发事件; 2.1.3)获取到所有的ApplicationListeners;Collection<ApplicationListener<?>> getApplicationListeners( ApplicationEvent event, ResolvableType eventType) a)如果有executor,可以支持使用executor进行异步派发; Executor executor = getTaskExecutor(); b)否则,同步的方式直接执行listener方法;invokeListener(listener, event); 拿到listener回调onApplicationEvent(ApplicationEvent event){} 3、获取事件多播器:getApplicationEventMulticaster 1)创建容器对象,refresh() //初始化EventMulticaster // Initialize event multicaster for this context. initApplicationEventMulticaster(); 4、容器中有哪些监听器? 1)容器创建对象refresh(); 2)registerListeners(); 从容器中拿到所有的监听器,把他们注册到ApplicationEventMulticaster中;’ String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.

Java 日期类

Java 日期类 第一代日期类 Date, 精确到毫秒, 代表特定的瞬间SimpleDateFormat, 允许进行格式化应用实例, Date_.java date.getTime()默认的输出格式是国外的, 需要格式转换. 用SimpleDateFormat指定输出的形式 用API手册, 比上网找博客要好用得多. package com.zhx.date_; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Date; /** * @author 朱洪曦 * @version 1.0 */ public class Date01 { public static void main(String[] args) throws ParseException { Date date = new Date(); Date date1 = new Date(1234535745); System.out.println(date.getTime()); SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日"); String format = sdf.format(date1); System.out.println(format); // 可以把格式化字符串转成Date String s = "1996年01月01日 10:20:30 星期一"

Java的Arrays类

Java的Arrays类 常用方法 Arrays.toString方法, 直接显示信息sort排序, 自然排序和定制排序 Integer arr[] = {1, -1, 7, 0, 89};可以使用Comparator接口实现定制排序Arrays.sort() 最终到了TimSort类的binarySort() 中,执行到binary Sort()方法的代码, 根据动态绑定机制, 执行我们传入的匿名内部类的 compare() 方法 Arrays模拟排序 package com.zhx.arrays_; import java.util.Arrays; import java.util.Comparator; /** * @author 朱洪曦 * @version 1.0 */ public class ArraysSortCustom { public static void main(String[] args) { int[] arr = {5, 3, 2, 6, 1, 7, 10}; bubble02(arr, new Comparator() { @Override public int compare(Object o1, Object o2) { Integer i1 = (Integer) o1; Integer i2 = (Integer) o2; return i1 - i2; } }); System.

Java 的 Math类

Java 的 Math类 常用的方法 都是静态方法 abs 绝对值求幂 Math.pow(2, 4) // 16Math.ceil()向上取整, 返回大于等于的最小整数Math.floor() 向下取整, 并转成doubleMath.round() 四舍五入生成随机数Math.random(), 返回0到1的doubleMath.max, Math.min 练习 返回2到7的整数

STM32——ADC采集

目录 ADC简介 ADC主要特征 ADC功能框图 ADC引脚 电压输入范围 通道选择 单次转换模式 连续转换模式 转换顺序 规则序列 注入序列 触发源 转换时间 中断 转换结束中断 模拟看门狗中断 DMA请求 代码讲解 宏定义: ADC简介 12位ADC是一种逐次逼近型模拟数字转换器,它有多达18个通道,可以测量16个外部和2个内部信号源。各通道的A/D转换可以单次、连续、扫描或间断模式执行.ADC的结果可以是左对齐或者是右对齐方式存储在16位数据寄存器中。 模拟看门狗特性允许应用程序检测输入电压是否超出用户定义的高/低阈值。 ADC的输入时钟不得超过14MHZ,它是由PCLK2经分频产生。 ADC主要特征 12位分辨率转换结束、注入转换结束和发生模拟看门狗事件时产生中断单次和连续转换模式从通道0到通道n的自动扫描模式自校准带内嵌数据一致性的数据对齐采样间隔时间可以按通道分别编程规则转换和注入转换均有外部触发选项间断模式双重模式(带2个或以上ADC的器件)ADC转换时间ADC供电要求:2.4V到3.6vADC输入范围:Vref-<Vin<Vref+规则通道转换期间有DMA请求产生 ADC功能框图 注意:1、ADC3的规则转换和注入转换触发与ADC1和ADC2的不同 2、TIM8_CH4和TIM8_TRGO及他们的重映射位只存在于大容量产品中 ADC引脚 名称信号类型注解Vref+输入,模拟参考正极ADC使用的高端。正极参考电压,2.4V<=Vref+<=VDDAVDDA输入,模拟电源等效于VDD的模拟电源且:2.4V<=VDDA<=VDD(3.6V)Vref-输入,模拟参考负极ADC使用的低端/负极参考电压,Vref=VSSAVSSA输入,模拟电源地等效于VSS的模拟电源地ADCx_IN[15:0]模拟输入信号16个模拟输入通道 VDDA和VSSA应该分别连接到VDD和VSS。 电压输入范围 ADC输入范围为Vref-<y=Vin<=Vref+.由Vref+、Vref-、VDDA、VSSA这四个外部引脚决定。如果我们想让输入的电压范围变宽,去到可以测试负电压或者更高的正电压,我们可以在外部加一个电压调整电路,把需要转换的电压抬升或者降低到0~3.3V,这样ADC就可以测量。 通道选择 有16个通道,可以把转换组织分成两组:规则组和注入组。在任意多个通道上以任意顺序进行的一系列转换构成成组转换。例如,可以如下顺序完成转换:通道3、通道8、通道2、通道0、通道2、通道15。 规则组:由多达16个转换组成,规则通道和它们的转换顺序在ADC_SQRx寄存器中选择,规则组中转换的总数应写入ADC_SQR1寄存器的了L[3:0]位中 注入组:由多达4个转换组成,注入通道和它们的转换顺序在ADC_JSQR寄存器中选择,注入组里的转换总数目应写入ADC_JSQR寄存器的L[1:0]中 如果 ADC_SQRx 或 ADC_JSQR 寄存器在转换期间被更改,当前的转换被清除,一个新的启动脉 冲将发送到 ADC 以转换新选择的组。 温度传感器/Vrefint内部通道 温度传感器和通道ADC_IN16相连接,内部参照电压Vrefint和ADC_IN17相连接。可以按注入或规则通道对这两个内部通道进行转换 单次转换模式 单次转换模式下,ADC只执行一次转换,该模式下即可通过设置ADC_CR2寄存器的ADON位(只适用于规则通道)启动也可通过外部触发启动(适用于规则通道或注入通道),这时CONT位为0. 一旦选择通道的转换完成: 如果一个规则通道被转换: -转换数据被存储在16位ADC_DR寄存器中 -EOC(转换结束)标志被设置 -如果设置了EOCIE,则产生中断 如果一个注入通道被转换 -转换数据被存储在16位的ADC_DRJ1寄存器中 -JEOC(注入转换结束)标志被设置 -如果设置了JEOCIE位,则产生中断 连续转换模式 在连续转换模式中,当前面ADC转换一结束马上就启动另一次转换。此模式可通过外部触发启动或通过设置ADC_CR2寄存器上的ADON位启动,此时的CONT位是1. 每个转换后: 如果一个规则通道被转换 -规则数据被存储在16位的ADC_DR寄存器中 -EOC(转换结束)标志被设置 -如果设置了EOCIE,则产生中断 如果一个注入通道被转换: -转换数据被存储在16位的ADC_DRJ1寄存器中 -JEOC(注入转换结束)标志被设置

BeanFactoryPostProcessor

BeanFactoryPostProcessor是BeanFactory的后置处理器; 使用目的:在BeanFactory标准初始化之后调用,用来定制和修改BeanFactory的内容; 工作时机:所有的bean定义已经保存加载到beanFactory中,但bean的实例还没创建; 1)IOC容器创建对象; 2)invokeBeanFactoryPostProcessors(beanfactory);执行BeanFactoryPostProcessor; 如何 找到所有的BeanFactoryPostProcessors并执行他们的方法? a)注解在Beanfactory中找到所有类型是BeanFactoryPostProcessor的组件,并执行他们的方法; b)在初始化创建其他组件前面执行;该方法是invokeBeanFactoryPostProcessors(beanFactory); ,它在registerBeanPostProcessors(beanFactory)和finishBeanFactoryInitialization(beanFactory)方法前执行;

BeanDefinitionRegistryPostProcessor

标题 执行时机:在所有bean定义信息将要被加载,bean实例还未创建时; 它优先于BeanFactoryPostProcessor执行,利用BeanDefinitionRegistryPostProcessor给容器中再额外添加一些组件; 原理: 1)IOC创建对象; 2)refresh()-->invokeBeanFactoryPostProcessors(BeanFactory); 3)从容器中获取到所有的BeanDefinitionregistryPostProcessor组件。 3.1)依次触发所有的postProcessBeanDefinitionRegistry()方法; 3.2)再来触发postProcessBeanFactory ; 4)再来从容器中找到beanFactoryPostProcessor组件,然后依次触发;

C语言 2048源码(每步细致讲解更新ing)

前言 提示:这里可以添加本文要记录的大概内容: 昨天晚上突然想用c写个2048,觉得学了这么久,没写点什么东西有点心空空,就乘着备考时间来写写看,以前就想过,也就想想,一直没去写,今天没什么课,而且还是网课,然后就先看看别人写的代码之后,自己理解之后又重新敲了一遍,写了一天也算是写了个简易的2048。 2048的代码也不难,主要就是使用数组对数组的操作,再对数组移动改变的时候的逻辑清楚就没问题了。 写的很仓促,代码不怎么好看,以后有时间会慢慢优化并增加一些功能。 提示:以下是本篇文章正文内容,下面案例可供参考 一、编译器 我用的是sublime text写的代码,使用DEVC++里也可以直接打开编译,但是中文字符会乱码,后面我想弄点背景音乐,搜了之后用vs更简便一点,使用vs代码也可以直接拿过去只需修改一点代码和添加一点代码就可以了。 二、编写代码 1.头文件,全局变量 代码如下 #include<stdio.h> #include<stdlib.h>//提供随机函数,清屏 #include<time.h>//为随机函数提供参数 #include<conio.h>//提供getch()函数 int map[4][4]={0};//游戏地图 int score=0;//分数 int movenum=-1;//移动次数 char input;//控制方向 int gameover=1;//判断游戏是否结束,0结束 int change=1;//判断数组是否改变,0不变 先创建地图大小并初始化,还有一些全局变量,这些变量是在写代码的时候来进行补充。 2.主界面 代码如下(示例): void menu(){ system("CLS");//每显示一次清屏之前的重新打印 int i=0,j=0; printf(" 欢迎来到2048\n"); printf(" ----------------------------------------\n"); printf(" W——UP S——DOWN A——LEFT D——RIGHT\n"); printf(" Please enter 0 if you do not want paly.\n"); printf(" MOVE:%d SCORE:%d\n",movenum,score); printf(" Made by XiaoQi\n"); printf(" \n |-------------------------------------------|\n"); for ( i = 0; i <= 3; i++) { for ( j = 0; j<= 3; j++) { printf("

大数据---生态圈总结

hadoop 1,数据越来越大,尤其是搜索引擎公司,数据的类别---分为三种,结构型,非结构型,半结构型,对应产生的数据库,关系型数据库,非关系型数据库;数据的来源---自己公司业务,爬虫(网络),购买(第三方交易);数据的处理---缺失字段,重要补全,不重要删除,隐私字段则脱敏 2,谷歌三篇论文 GFS(google filesystem)、产生了hdfs,解决海量数据存储;MAPREDUCE、产生了mapreduce,解决计算;BIGTABLE,产生了hbase,解决海量数据查询;最初的hadoop没有yarn,就是hdfs和mr,和hbase。 3,大数据的核心概念---集群(横向扩展),分布式(分而治之),负载均衡(性能最优) 4,hadoop的启动---start-hfs.sh start-yarn.sh hadoop-daemon.sh start namenode/secondarynamenode/datenode/resourcemanager/nodemanager ;启动时报错---要么是格式化错误,要么就是权限问题 5,hdfs设计思想有两个,需要注意的也有两点 切块存储(过大过小都会影响性能,其实所做的一切都是为了更快更好的完成存储计算查询);64-128-256(128M对应的134217728B),设置的参数是hdfs-default.xml中的hdfs.site.xml中的dfs.blocksize参数(所有的参数统属于四类---core-default.xml、hdfs.default.xml、mapred.default.xml、yarn.default.xml) 冗余存储(其实就是防止宕机影响数据的完整进行多备份),设置hdfs.default.xml中的hdfs.site.xml中的dfs.replication参数 需要注意的有两点:副本的存储和数量---存储时要避免相同的副本备份到同一个节点(备份和副本都是复制,其区别在于有无主次,后者没有);宕机时若副本设置的数量少于现存节点,会重新复制一个副本,恢复宕机后,会在一个小时后检测是否真的恢复宕机进而删除多余的副本,副本数量设置的多余总节点时会进行记账 6,hdfs的架构:主从架构(主管理,从干活) namenode ---存储元数据(相当于元类,描述原始数据的数据,简明扼要的备注原始数据),hdfs的元数据包含三部分(抽象目录树,描述整个虚拟的所有datenode共同而非单一构成的存储体系,由hdfs://hadoop01:9000入口)、(块和数据的对应关系,每个块实际是存在某一个datenode中,记录其全局唯一的id,即blockid,记录在mapred.site.xml文件中)、(记录数据块的位置,即将blockid和节点一一对应) ---处理客户端的数据读写请求,只有namenode中有元数据,只有元数据才能知道块-id-节点的对应 secondarynamenode ---备份主节点的元数据,在主节点宕机后进行数据恢复 ---减轻主节点压力,处理一些非核心问题 datenode ---负责数据的存储,原始数据存储好后生成一个id,产生一个元数据传给namenode ---执行客户端的数据读写请求,根据namenode给予的命令,存到该存的地方,读取该读的地方 7,hdfs的使用,有shell和api两种 ---shell命令:hadoop fs xxxx(类似linux命令) ---api操作:用的很少 8,hdfs的四大机制 ---心跳机制:报告namenode自己的存活状况,心跳报告周期dfs.heartbeat.interval,宕机次数dfs.namenode.handler.count 主动检查dfs.namenode.heartbeat.recheck-interval,因此默认时确定宕机需要10*3+300*2=630s ---机架策略:同样的数据不要放在同一个节点,甚至同一个机架,甚至同一个机房,甚至同一个数据中心 ---负载均衡:冗余存储的最开始是相对随机存储的,所以会有负载不均的情况,集群有自动调整的功能,dfs.datenode.balance.bandwidthPerSec,但是默认的为1M/s ,过大会影响性能,因此集群规模不大时无所谓,集群规模大时,则需要手动负载均衡,首先是调整带宽,其次是start-balancer.sh -t 10%(意思是datenode中的最大占比与最小占比相差少于10%,但不会立即执行,提升的是响应时效) 没有绝对的负载均衡。 ---安全模式:集群的自我保护模式,限制用户对集群进行部分操作(实质就是不予许产生元数据的修改,查询可以)。三种方式进入(集群启动时的顺序name-date-secondaryname,依次启动完后自动进入安全模式,namenode启动时:磁盘中只有元数据的前两部分,内存中含有元数据的所有信息,启动时会将磁盘中的元数据全部加载到内存中;datenode启动时:发送心跳报告,发送块的相应信息,将块放到该放的节点上;secondarynamenode启动时:检查块的副本数,dfs.namenode.replication.min,至少为1,检查标准块的比例,dfs.namenode.safenode.threshold-pct,检查存活的datenode个数,dfs.namenode.safenode.min.datenodes,表示退出安全模式时安全节点的个数,为0表示立刻退出安全模式,大于节点数表示永远处于安全模式,最后一项:三大标准符合30s之后退出安全模式,dfs.namenode.safemode.extension-----总结就是集群启动时进入安全模式的原因,那么namenode将硬盘中的元数据加载打内存,namenode接收datenode传来的心跳报告和块报告,再者就是检查集群)、(集群运行过程中进入安全模式:运行过程中会随时检查每个副本个数是否大于1,以及符合标准的块的比例是否达标,一旦不符则自动进入安全模式)、(集群维护或系统升级时可以手动进入: ) 安全模式时可以进行的操作---ls get tail cat 不可以的---mkdir put touchz rm 总之就是不允许元数据改变(namenode is in safe mode) 9,hdfs上传 10,hdfs下载 11,hdfs元数据合并 12,shuffle的原理 13、yarn的架构:主从架构,resourcemanager nodemanager ---resourcemanager的作用(管理所有的nodemanager、监控其运行状态,掌握其资源、为每一个job分配资源、启动每一个job的老大,也就是MRappmaster,之后由其来调度整个job) resourcemanager的组成(ASM(applicationsmanager):管理所有的应用程序、负责所有的job,启动所有的mrappmaster、监控mrappmaster的运行,失败时重启;Scheduler(调度器):就是负责调度各个job的提交顺序,调度器的分类:FIFO,顺序调度器,first in first out 先入先出 ,缺点是遇到大任务后造成后面的任务等待过长;Fair,公平调度器,n个job ,每个job占用1/n的资源,缺点是资源分配不合理,有的任务量很大资源不够,有的任务量很小资源过剩;Capacity,计算能力调度器,又叫容量调度器,内部维护的是多个FIFO队列,可以手动配置每个队列的资源,)

14.设置默认地址模块

1.业务分析 可能存在的异常: 用户在设置的时候,该地址可能同时被管理员删除,抛AddressNotFoundException异常在设置当前地址为默认之前,将该用户的所有地址都设置成非默认,即is_default设置成为0根据地址的id设置其字段is_default为1 2.持久层接口及mapper映射 /** *@描述 根据aid查找收货地址是否存在 *@参数 收货地址id *@返回值 收货地址 *@创建人 ZhangHailong */ Address selectAddressByAid(Integer aid); /** *@描述 将用户所有的收货地址设置成非默认 *@参数 用户id *@返回值 受影响的行数 *@创建人 ZhangHailong */ Integer updateNonDefaultAddress(Integer uid); /** *@描述 将当前收货地址设置成默认 *@参数 aid: 商品id, modifiedUser: 日志修改者, modifiedTime: 日志修改时间 *@返回值 受影响的行数 *@创建人 ZhangHailong */ Integer updateDefaultAddress(@Param("aid") Integer aid, @Param("modifiedUser") String modifiedUser, @Param("modifiedTime") Date modifiedTime); 在开发中我遇到了一个问题,updateDefaultAddress接口中使用了多个参数,一开始并未添加@Param注解,该接口的映射文件中的sql语句并不是按照接口参数的顺序使用的,所以会报param not found的错误,所以记住 持久层接口中的参数如果是多个,非对象的, 此时使用@Param注解对其进行添加别名 3.业务层 @Override public void setDefaultAddress(Integer uid, Integer aid, String modifiedUser) { // 先判断当前需要设置为默认的收货地址是否存在 Address address = addressDao.

使用MyBatis-plus代码生成器 遇到的错误

使用MyBatis-plus代码生成器 出错 1、使用myabtis-plus代码自动生成器,启动时出现下面这个错误 在pom.xml中添加下面依赖 <dependency> <groupId>org.apache.velocity</groupId> <artifactId>velocity-engine-core</artifactId> <version>2.2</version> </dependency> 2、代码生成器启动以后,发现已经自动创建了一些包和代码 打开entiry包下的实体类User,发现出现下面这个错误,显示包不存在 在pom.xml配置文件中添加下面依赖 <!--配置ApiModel在实体类中不生效--> <dependency> <groupId>com.spring4all</groupId> <artifactId>spring-boot-starter-swagger</artifactId> <version>1.5.1.RELEASE</version> </dependency> 至此,使用MyBatis-plus代码生成器 遇到的错误全部总结完毕。

【瑞吉外卖day01】

1.软件开发流程 需求分析-设计-编码-测试-上线运维 软件开发角色分工 软件环境:开发环境、测试环境、生产环境 2.项目技术选型与功能架构 3.数据库环境搭建 Navicat中新建数据库,运行sql,一共建好11张表: 4.maven环境搭建 1.新建maven项目,检查maven仓库配置,检查JDK版本 2.导入pom <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.4.5</version> <relativePath/> <!-- lookup parent from repository --> </parent> <groupId>com.zxn</groupId> <artifactId>reggieTakeout</artifactId> <version>1.0-SNAPSHOT</version> <properties> <java.version>1.8</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <scope>compile</scope> </dependency> <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-boot-starter</artifactId> <version>3.4.2</version> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.18.20</version> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>1.2.76</version> </dependency> <dependency> <groupId>commons-lang</groupId> <artifactId>commons-lang</artifactId> <version>2.

CobaltStrike4.0安装

CobaltStrike CobaltStrike是一款渗透测试神器,被业界人称为CS神器。CobaltStrike分为客户端与服务端,服务端是一个,客户端可以有多个,可被团队进行分布式协团操作。 CobaltStrike集成了端口转发、服务扫描,自动化溢出,多模式端口监听,windows exe 木马生成,windows dll 木马生成,java 木马生成,office 宏病毒生成,木马捆绑。钓鱼攻击包括:站点克隆,目标信息获取,java 执行,浏览器自动攻击等等强大的功能! 官网:https://www.cobaltstrike.com 环境配置 云主机 CentOS 7.6 64bit 安装 安装java环境 安装 yum install -y java-1.8.0-openjdk* 查看java版本 java -version 上传CobaltStrike包到服务器 CobaltStrike4.0资源下载 https://www.jb51.net/softs/772608.html 上传到服务器 进入CobaltStrike_4.0目录,为"agscript"、“c2lint”、"peclone"和"teamserver"文件赋予执行权限。 #进入cs目录,这里我改了文件名原资源包不是这个文件名 cd cobaltstrike4.0/ #查看 ls -l #赋予权限 chmod a+x agscript chmod a+x c2lint chmod a+x peclone chmod a+x teamserver 启动服务端 终端运行 ./teamserver 192.168.80.137 123456 #192.168.10.11 电脑的ip地址/如果是云主机就填公网ip,123456是密码 后台运行 #关闭终端依然运行,这里使用nohub 命令 & (也可以使用screen,不过需要安装一下screen) nohup ./teamserver 192.168.10.11 123456 & 参考:后台运行程序最实用的两种方法 服务器防火墙开放端口 CobaltStrike默认端口是50050,这里我修改为6000,仅做演示。

第三方软件测试

目录 概念 职责: 范围: 过程: 概念 定义:由开发者和用户以外的第三方进行的软件测试,其目的是为了保证测试的客观性 狭义上:独立的第三方测试机构,如国家级软件测试中心,各省软件评测中心,有资质的软件评测中心广义上:既非开发方亦非使用方的人来对软件进行测试 职责: 验证软件是否符合需求和设计检测错误对错误进行分类分析,将分析结果反馈给开发人员以改进软件过程管理 范围: 测试阶段:集成测试、系统测试、验收测试 主要以黑盒为主,手工+自动化测试单元测试通常由开发方实施,第三方测试通常在有一定的产品基础上进行的常见的测试内容:软件上,功能性、易用性、容错性、安全性、性能 文档上,正确性与一致性 过程: 制定测试计划和Review被测对象的功能架构设计等理解测试观点、测试用例设计以及Review测试环境构建以及测试实施(包括Bug修正后的确认测试)测试总结报告

网络通信基础

文章目录 一、IP地址概念格式 二、端口号概念 三、协议概念知名协议的默认端口 四、五元组五、协议分层OSI七层模型 六、TCP / IP五层(或四层)模型七、封装和分用数据封装的过程数据分用的过程 一、IP地址 概念 IP地址主要用于网络主机、其他网络设备(路由器)的网络地址。 简单说,IP地址就是用于定位主机的网络地址。 格式 IP地址是一个32为的二进制数,通常被分割为4个8位二进制数 常见的用“点分十进制”的方式来表示。如192.168.0.1 二、端口号 概念 在网络通信中,IP地址用于标识主机网络地址,端口号可以标识主机中发送数据、接收数据的进程。简单说:端口号用于定位主机中的进程。 端口号是0~65535范围的数字,在网络通信中,进程可以通过绑定一个端口号,来发送及接收网络数据。 **注意:**两个不同的进程,不能绑定同一个端口号,一个进程可以绑定多个端口号。 三、协议 概念 协议,网络协议的简称,网络协议是网络通信(即网络数据传输)经过的所有网络设备都必须共同遵从的一组约定、规则。如怎么样建立连接、怎么样互相识别等。只有遵守这个约定,计算机之间才能相互通信交流。 通常由三要素组成: 语法:即数据与控制信息的结构或格式语义:即需要发出何种控制信息,完成何种动作以及做出何种响应时序:即时间是先顺序的详细说明 协议(protocol)最终一线为在网络上传输的数据包的格式 知名协议的默认端口 系统端口号范围为 0 ~ 65535,其中:0 ~ 1023 为知名端口号,这些端口预留给服务端程序绑定广泛使用的应用层协议,如: 22端口:预留给SSH服务器绑定SSH协议 21端口:预留给FTP服务器绑定FTP协议 23端口:预留给Telnet服务器绑定Telnet协议 80端口:预留给HTTP服务器绑定HTTP协议 443端口:预留给HTTPS服务器绑定HTTPS协议 以上只是说明 0 ~ 1023 范围的知名端口号用于绑定知名协议,但某个服务器也可以使用其他 1024 ~65535 范围内的端口来绑定知名协议。 四、五元组 在TCP/IP协议中,用五元组来标识一个网络通信: 源IP:标识源主机源端口号:标识源主机中该次通信发送数据的进程目的IP:标识目的主机目的端口号:标识目的主机中该次通信接收数据的进程协议号:标识发送进程和接收进程双方约定的数据格式 五、协议分层 OSI七层模型 OSI:即Open System Interconnection,开放系统互连 OSI 七层网络模型是一个逻辑上的定义和规范:把网络从逻辑上分为了7层。OSI 七层模型是一种框架性的设计方法,其最主要的功能使就是帮助不同类型的主机实现数据传 输;它的最大优点是将服务、接口和协议这三个概念明确地区分开来,概念清楚,理论也比较完整。通 过七个层次化的结构模型使不同的系统不同的网络之间实现可靠的通讯。 OSI七层模型即复杂又不实用:所以OSI七层模型没有落地、实现。 实际组建网络时,只是以 OSI 七层模型设计中的部分分层,也即是以下 TCP/IP 五层(或四层)模型来实现。 六、TCP / IP五层(或四层)模型 TCP/IP是一组协议的代名词,它还包括许多协议,组成了TCP/IP协议簇。

布隆过滤器详解

什么是布隆过滤器 布隆过滤器(Bloom Filter)是 1970 年由布隆提出的。它实际上是一个很长的二进制向量和一系列随机映射函数。主要用于判断一个元素是否在一个集合中。 通常我们会遇到很多要判断一个元素是否在某个集合中的业务场景,一般想到的是将集合中所有元素保存起来,然后通过比较确定。链表、树、散列表(又叫哈希表,Hash table)等等数据结构都是这种思路。但是随着集合中元素的增加,我们需要的存储空间也会呈现线性增长,最终达到瓶颈。同时检索速度也越来越慢,上述三种结构的检索时间复杂度分别为 O ( n ) O(n) O(n), O ( l o g n ) O(logn) O(logn), O ( 1 ) O(1) O(1)。 这个时候,布隆过滤器(Bloom Filter)就应运而生。 布隆过滤器原理 布隆过滤器是由一个固定大小的二进制向量或者位图(bitmap)和一系列映射函数组成的。在初始状态时,对于长度为 m 的位数组,它的所有位都被置为0,如下图所示: 当有变量被加入集合时,通过 K 个映射函数将这个变量映射成位图中的 K 个点,把它们置为 1。 查询某个变量的时候我们只要看看这些点是不是都是 1 就可以大概率知道集合中有没有它了 如果这些点有任何一个 0,则被查询变量一定不在;如果都是 1,则被查询变量很可能存在。为什么说是可能存在,而不是一定存在呢?那是因为映射函数本身就是散列函数,散列函数是会有碰撞的。 误判率:布隆过滤器的误判是指多个输入经过哈希之后在相同的bit位置1了,这样就无法判断究竟是哪个输入产生的,因此误判的根源在于相同的 bit 位被多次映射且置 1。这种情况也造成了布隆过滤器的删除问题,因为布隆过滤器的每一个 bit 并不是独占的,很有可能多个元素共享了某一位。如果我们直接删除这一位的话,会影响其他的元素。 特性: 一个元素如果判断结果为存在的时候元素不一定存在,但是判断结果为不存在的时候则一定不存在。布隆过滤器可以添加元素,但是不能删除元素。因为删掉元素会导致误判率增加。 添加元素步骤: 将要添加的元素给 k 个哈希函数得到对应于位数组上的 k 个位置将这k个位置设为 1 查询元素步骤: 将要查询的元素给k个哈希函数得到对应于位数组上的k个位置如果k个位置有一个为 0,则肯定不在集合中如果k个位置全部为 1,则可能在集合中‘ 优点:相比于其它的数据结构,布隆过滤器在空间和时间方面都有巨大的优势。布隆过滤器存储空间和插入/查询时间都是常数 O ( K ) O(K) O(K),另外,散列函数相互之间没有关系,方便由硬件并行实现。布隆过滤器不需要存储元素本身,在某些对保密要求非常严格的场合有优势。且布隆过滤器可以表示全集,其它任何数据结构都不能;

手把手教你搭建鸿蒙hi3518开发和运行环境

前言 学习C语言,C++语言,数据结构和算法,操作系统,网络,驱动,设计模式等知识 用鸿蒙来强化就太对了。本文教你一步一步搭建鸿蒙的开发和运行环境,有点啰嗦,适合小白。 本文所涉及的所有工具都可以在这里找到(提取码ue2a) 具体有下列步骤: 组装开发板连接开发板安装串口驱动安装USB驱动安装烧录工具擦除引导程序烧录系统登录开发板修改OS启动地址运行可执行程序安装VMWARE安装编译服务器访问编译服务器编译鸿蒙产品编译鸿蒙组件打通开发板网络部署NFS新增自定义组件 组装开发板 我们选用HiSpark IPC DIY Camera产品。内部含hi3518ev300芯片。 请参考产品的安装说明书。 或者参考安装视频指导 连接开发板 开发板和PC的连接关系如下图。2条usb线(产品包装中的),其中一个三针插头,一个四针插头。 安装串口驱动 请双击USB-to-Serial Comm Port.exe。进行串口驱动安装,安装完成后。在设备管理器中应该能看到下面这样的COM接口,你的COM接口编号可能有所不同。表明串口驱动安装成功。 安装USB驱动 注意:有2个USB驱动需要安装 双击zadig-2.5.exe安装通用USB驱动,点击中间的Install 安装第2个USB驱动,这个驱动的名称是: HiUSBBurnDriver. 对应的安装文件已经放在网盘中,请自行安装。 上述2个驱动都安装成功以后,才能正常的进行USB烧录(往开发板烧录鸿蒙系统)。 安装烧录工具 直接解压HiTool-HM-5.4.9-win32-x86_64.zip文件。然后双击其中的HiTool.exe. 界面如下图。然后先将芯片切换到3518ev300 擦除引导程序 然后就是擦除uboot了,记得使用串口来擦除 有几点需要注意 由于编译服务器还没有创建,所以我把自己编译好的文件放网上了,你可以下载文件路径根据你自己的实际路径,下载下来后存放的位置COM口根据你之前设备管理器看到的那个CH340口选择确保顶部选中的芯片是3518ev300传输方式选择串口按分区烧写器件类型spi nor开始地址0,长度1M点击擦除后10秒内拔插usb电源线接口(即接4个针脚的那个usb口,小的那个usb头),让板子重启 很快就能看到擦除成功的提示 烧录系统 主要注意如下几点 使用usb口烧录(不是串口)现在需要烧录4个文件(通过右侧绿色+可以添加文件)每个文件的名称,器件类型,地址,长度要填写正确最后点击烧写 然后等待烧写成功 如果你的烧写不成功,请检查之前的usb驱动是否已安装。 登录开发板 鸿蒙系统烧录好以后,就可以进去看一下鸿蒙系统的模样了。 双击MobaXterm_Personal_20.2.exe. 也可以用你自己喜欢的终端工具 然后点击Session, 在弹出的窗口中填好相关字段 点击OK以后,会进入下面这个界面 这里是uboot程序的界面,还没有进入鸿蒙OS,原因是uboot此时不知道鸿蒙OS的启动地址。 然后我们设置启动地址 设置OS启动地址 setenv bootcmd "sf probe 0;sf read 0x40000000 0x100000 0x600000;go 0x40000000"; setenv bootargs "console=ttyAMA0,115200n8 root=flash fstype=jffs2 rw rootaddr=7M rootsize=8M"; 保存配置

配置SSH服务远程连接空闲超时退出时间(包括SSH无法登录、登录缓慢)

建议方案 设置SSH空闲超时退出时间,可降低未授权用户访问其他用户ssh会话的风险 加固建议 编辑/etc/ssh/sshd_config配置文件,将ClientAliveInterval设置为300到900,即5-15分钟,将ClientAliveCountMax设置为0。 方法1: 1.修改server端的/etc/ssh/sshd_config配置文件 ClientAliveInterval 60 :server每隔60秒发送一次请求给client,然后client响应,从而保持连接。 ClientAliveCountMax 3 :server发出请求后,客户端没有响应的次数达到3次,就自动断开连接,正常情况下,client不会不响应。 [root@Jenkins ~]# vim /etc/ssh/sshd_config ...... 112 ClientAliveInterval 60 113 ClientAliveCountMax 3 ...... 2.修改client端的/etc/ssh/ssh_config添加以下:(在没有权限修改server端的SSH配置的情况下) ServerAliveInterval 60 :client每隔60秒发送一次请求给server,然后server响应,从而保持连接。 ServerAliveCountMax 3 :client发出请求后,服务器端没有响应的次数达到3次,就自动断开连接,正常情况下,server不会不响应。 [root@Nginx ~]# vim /etc/ssh/sshd_config ...... 112 ClientAliveInterval 60 113 ClientAliveCountMax 3 ...... 3.重启sshd服务 systemctl restart sshd 方法2: 不修改配置文件,直接在SSH远程连接时命令加参数,即ssh -o ServerAliveinterval=60 root@'远程连接IP地址',这样就只会在当前需要的远程连接中保持持久的连接, 并不是所有的远程连接都需要保持持久连接的! [root@Jenkins ~]# ssh -o ServerAliveinterval=60 root@192.168.1.33 Last login: Wed May 18 14:53:19 2022 from 192.168.1.30 [root@Web1 ~]# ifconfig ens33 ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500 inet 192.

浙大版《C语言程序设计实验与习题指导(第3版)》题目集

实验3-2 计算符号函数的值 分数 10 全屏浏览题目 切换布局 作者 C课程组 单位 浙江大学 对于任一整数n,符号函数sign(n)的定义如下: 请编写程序计算该函数对任一输入整数的值。 输入格式: 输入在一行中给出整数n。 输出格式: 在一行中按照格式“sign(n) = 函数值”输出该整数n对应的函数值。 输入样例1: 10 输出样例1: sign(10) = 1 输入样例2: 0 输出样例2: sign(0) = 0 输入样例3: -98 输出样例3: sign(-98) = -1 代码长度限制 16 KB 时间限制 400 ms 内存限制 64 MB 代码实现: #include<stdio.h> main(){ int n,r; scanf("%d",&n); if(n<0){ r = -1; }else if(n>0){ r = 1; }else r = 0; printf("sign(%d) = %d",n,r); return 0; }

markdown图表语法Mermaid介绍

Markdown是一种轻量级标记语言,除了编辑文字外,还支持插入图片、表格、公式,它是很流行的一种文档编辑语言,很多博客平台都支持使用Markdown来编辑文章。Markdown还有一个好用的功能是画流程图,基于Mermaid库来渲染流程图,语法比较简洁,本文将介绍Markdown的Mermaid简单使用方法。 目录 流程图1. 定义流程图节点及节点名称2. 定义流程图方向3. 节点形状4. 节点连线5. 多节点连接6. 其它类型箭头7. 特殊字符8. 子图 时序图类图状态图甘特图饼图 Mermaid 是一个基于 Javascript 的图表绘制工具,可用于创建流程图、时序图、甘特图、类图、状态图、饼图等。 Mermaid集成到了很多 Markdown 编辑器中,本文使用的是Typora编辑器,在代码块中编写Mermaid代码,编程语言名字设置为 mermaid 。 接下来介绍Mermaid语法。 流程图 1. 定义流程图节点及节点名称 flowchart LR A[Start] Start 2. 定义流程图方向 可设置4个方向: TD - top-down,从上到下。或者使用TB(top to bottom)BT - bottom to top,从下到上RL - right to left,从右到左LR - left to right,从左到右 flowchart TD A --> B A B flowchart LR A --> B A B 3. 节点形状 默认节点形状为长方形,也可以设置为其它形状。 flowchart LR A(圆角矩形) -.

Android Intent隐式的实现,在第一界面输入用户名,点击按钮,跳转到第二个界面,显示用户名。

废话少说,先上截图!(可以给个关注吗,发了五个作品都没人关注我大哭) 首先要在配置文件设置隐式跳转的条件,我的是这样。 <activity android:name=".MainActivity2">是被指定跳转的页面 1.第一个页面代码 import android.app.Activity; import android.content.Intent; import android.os.Bundle; import android.view.View; import android.widget.Button; import android.widget.EditText; public class MainActivity1 extends Activity { //定义控件变量 private EditText editText; private Button button; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity1); // 绑定变量 editText = (EditText)findViewById(R.id.editText); button = (Button)findViewById(R.id.button); // 为Button设置监听事件 button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View arg0) { String text = ""; text = editText.getText().toString(); // 将信息放入Bundle Bundle bundle = new Bundle (); bundle.

fsevents@1.2.13: wanted {“os“:“darwin“,“arch“:“any“} (current: {“os“:“win32“,“arch“:“x64“})

报错解决方法:在安装依赖的时候 npm WARN read-shrinkwrap This version of npm is compatible with lockfileVersion@1, but package-lock.json was generated for lockfileVersion@2. I'll try to do my best with it! npm WARN deprecated fsevents@1.2.13: fsevents 1 will break on node v14+ and could be using insecure binaries. Upgrade to fsevents 2. npm ERR! code EBADPLATFORM npm ERR! notsup Unsupported platform for fsevents@1.2.13: wanted {"os":"darwin","arch":"any"} (current: {"os":"win32","arch":"x64"}) npm ERR! notsup Valid OS: darwin npm ERR!

移动端H5(JavaScript)识别二维码功能

前言 时隔一年多, 再次接触到H5识别二维码功能,这次直接写个demo方便大家学习和使用。(其实是方便自己抄自己代码…)。 直接上代码 QRcode下载地址 长的好看的都点⭐了!!! <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <script src="./reqrcode.js"></script> <style> .click_btn { padding: 10px 20px; color: #ffffff; background: #777CE3; border-radius: 8px; cursor: pointer; } </style> </head> <body> <input type="file" id="upFileDom" multiple style="display: none;" accept="image/*" onchange="dealFileData(event)" /> <span class="click_btn" onclick="clickUpFile()">点击识别二维码</span> </body> <script> // 点击识别二维码 function clickUpFile() { document.getElementById('upFileDom').click(); }; // 处理二维码信息 function dealFileData(event) { // 解析二维码 getQCode(event.

Excel导入-----后端获取Excel文件数据

@PostMapping("/getInventoryInquiryView") public RestResponse<List<String>> getInventoryInquiryView(@RequestParam("file")MultipartFile file) throws IOException { //获取工作簿对象 Workbook workbook = null; // excel分为03版本与07版本 07版本后缀名为“xlsx” 03版本后缀为“xls” //根据版本创建工作簿对象 if (file.getName().endsWith("xls")){//判断文件是否以"xla"结尾 workbook = new HSSFWorkbook(file.getInputStream());//03版本 }else { workbook= new XSSFWorkbook(file.getInputStream());//07版本 } List<String> li = new ArrayList<>(); //获取到表对象 Sheet sheetAt = workbook.getSheetAt(0); //获取表有多少行 int lastRowNum = sheetAt.getLastRowNum(); for (int i = 0; i <=lastRowNum; i++) { //获取第一行对象 Row row = sheetAt.getRow(i); //获取第一行第一个单元格对象 Cell cell = row.getCell(0); //获取单元格的参数 String stringCellValue = cell.getStringCellValue(); li.

RK3568 Android固件介绍、固件烧录、开机进系统

固件介绍 编译生成的固件在rockdev/Image-rk3568_r目录下,包含如下文件: baseparameter.img: boot-debug.img://usr固件往往没有root权限,此时可以烧它以进行root权限操作 boot.img //包含了kernel.img、resource.img、ramdisk,但Android不能直接烧kernel.img和resource.img了,取而代之的是boot.img。需要使用build.sh -K 命令来编译 kernel从而得到boot.img。 config.cfg //烧写工具的配置文件 ,可以直接导入烧写工具显示需要烧写的选项 dtbo.img //由dts编译得到,修改了dts将会编到这里 MiniLoaderAll.bin //很底层的loader程序,包含一级loader misc.img //包含recovery-wipe开机标识信息,烧写它后会进行recovery parameter.txt //分区表 pcba_small_misc.img //包含pcba开机标识信息,烧写后会进入简易版pcba模式 pcba_whole_misc.img //包含pcba开机标识信息,烧写后会进入完整版pcba模式 recovery.img //包含了recovery-ramdis、kernel、dtb、resource等,是一个精简版的小系统。完整烧录固件后第一次开机或者从未正常进系统时 开机要先跑这个;正常进过系统后 再开机 就不会跑这里了,在某些条件 如进recovery才会跑这里。所以,当遇到烧录后无法正常开机,我们改了kernel,则一定要记得烧recovery.img和boot.img 或者全烧。 resource.img //开机logo、开机充电logo等资源 super.img //包含odm、product、vendor、system、system_ext分区内容 ;所以改了Android系统层 要烧这个 uboot.img //uboot update.img //这是由零散固件打包而成的 vbmeta.img //包含avb校验信息,用于AVB校验 我们可以烧分散的img:(红色部分) 也可以烧update.img,等同于全烧。 注:(trust.img 包含BL31、BL32 ,RK3566/RK3568没生成这个,所以不需要烧写trust.img了) 安装支持RK3568的USB驱动 安装文件在SDK/RKTools/windows/DriverAssitant_v5.1.1.zip 如果以前已安装过旧版的驱动,则需更新,先卸载再安装即可。 新版驱动支持新型号芯片 也兼容旧芯片的。 烧录固件前,最好先确认一下手上的板子硬件是否正常 烧录固件前,如果板子已烧录过别人的固件,先确认一下板子能否正常开机、常见模块如屏、TP、HDMI等是否正常;接串口打印看能否正常抓log;看ADB功能是否正常。 固件烧录用到的工具及烧录注意事项 SDK/RKTools/windows/AndroidTool/RKDevTool_Release_v2.84.zip 烧录RK3568 Android11的固件,要用v2.84版。新版工具支持新型号芯片 也兼容旧芯片的。 此工具免安装,解压,双击 RKDevTool.exe 直接运行即可。 此工具有三个界面: 烧录分散固件的界面: 一般先选parameter,工具由parameter.txt知道要烧哪些分区 及 分区表是怎样的。 选了不同的parameter.txt,工具界面会变的。

文件或内容损坏无法读取 导致无法删除

简直是要命,一个文件点击删除居然会没反应,尝试各种办法,最后点击文件内部的某个文件发现是里面有文件损坏了。头疼-。。。。。然后.。。。。这样。。。。。文件所在盘符工具>检查 检查完毕后再进行删除即可。

POI结合bootstrap-fileinput上传Excel内容到数据库

一、准备工作 前言: 近期 本人在开发《订单管理系统》项目的时候,需要从SAP系统中导出物料编码信息,然后利用Excel导入数据到订单管理系统数据库中。本篇使用SSM+BootStrap-InputFile+poi的结合方式,写一个完整的导入Excel的例子。有需要的同学可以参考。 1.1、POI依赖 如果是maven项目,在pom.xml中添加下面的依赖: <!--POI 实现Excel的导入导出--> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi</artifactId> <version>3.15</version> </dependency> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi-ooxml</artifactId> <version>3.15</version> </dependency> <dependency> <groupId>commons-fileupload</groupId> <artifactId>commons-fileupload</artifactId> <version>1.3.3</version> </dependency> <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-lang3</artifactId> <version>3.7</version> </dependency> workbook需要引入的jar包下载:https://download.csdn.net/download/kay523393/85404288 1.2、bootstrap-fileinput插件下载: bootstrap-fileinput中文文档: http://www.bootstrap-fileinput.com/examples.html bootstrap-fileinput插件下载: https://download.csdn.net/download/kay523393/85404018 二、代码部分 2.1、在html页面中引入BootStrap-InputFile所需要的js和css,并在html中添加Bootstrap的model弹框。 <!-- 导入excel fileinput.css--> <link href="${pageContext.request.contextPath}/static/css/bootstrap-fileinput/fileinput.css" rel="stylesheet"> <!-- 导入excel fileinput.js --> <script type="text/javascript" src="${pageContext.request.contextPath}/static/js/bootstrap-fileinput/fileinput.js"></script> <!-- 导入Excel模态框(Modal) --> <div class="modal fade" id="importTpl"> <div class="modal-dialog" style="width:800px"> <div class="modal-content"> <div class="modal-header"> <button type="button" class="close" data-dismiss="modal" aria-hidden="true" onclick="clear_batchAdd()" id="

@Configuration注解使用

1、前言 @Configuration是Spring的注解,不是SpringBoot的!早在Spring框架的时候就有使用,但是由于那个时候配置文件还是比较流行,因此@Configuration注解并没有太盛行,甚至很多人就认为它是SpringBoot的注解。 @Configuration注解的作用:声明一个类为配置类,用于取代bean.xml配置文件注册bean对象。 @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Documented @Component public @interface Configuration { @AliasFor(annotation = Component.class) String value() default ""; boolean proxyBeanMethods() default true; } 底层代码就两个属性,一个用于声明配置类的名称,一个用于声明是否是代理对象方法(重点)。 由于有@Component注解的加持,那么被声明的配置类本身也是一个组件! 2、基础使用 @Configuration注解常常一起搭配使用的注解有@Bean、@Scope、@Lazy三个比较常见: @Bean:等价于Spring中的bean标签用于注册bean对象的,内部有一些初始化、销毁的属性… @Scope:用于声明该bean的作用域,作用域有singleton、prototype、request、session。 @Lazy:标记该bean是否开启懒加载。 这里准备User和Dog两个类 @Data @AllArgsConstructor @NoArgsConstructor public class User { private String name; private int age; private Dog dog; } @Data @NoArgsConstructor @AllArgsConstructor public class Dog { private String name; private int age; } 2.1、@Bean注解 先来看看如何声明配置一个bean对象的注册 @Configuration public class MyConfig { @Bean("

浙大版《Python 程序设计》题目集 第3章-17 删除字符

第3章-17 删除字符 输入一个字符串 str,再输入要删除字符 c,大小写不区分,将字符串 str 中出现的所有字符 c 删除。提示:去掉两端的空格。 输入格式: 在第一行中输入一行字符 在第二行输入待删除的字符 输出格式: 在一行中输出删除后的字符串 输入样例1: 在这里给出一组输入。例如: Bee E 输出样例1: 在这里给出相应的输出。例如: result: B 输入样例2: 在这里给出一组输入。例如: 7!jdk*!ASyu ! 输出样例2: 在这里给出相应的输出。例如: result: 7jdk*ASyu 实现程序 解题思路: 首先判断输入的被去掉的字符是大写还是小写。如果是大写C就是其相应的小写如果是小写C就是其相应的大写判断每一个字符是否是要删除的字符,如果是就直接continue跳过此次循环如果不是就输出 注意输出格式!!! s=input().strip() c=input() if c>='A' and c<='Z': C=c.lower() elif c>='a' or c<='z': C=c.upper() print("result: ",end="") for i in s: if i==c or i==C: continue else: print(i,end="") 测试数据

java8 stream的常用法记录

记录一下工作中常用的java8 stream用法。 package com.example.demo.test; import com.alibaba.fastjson.JSONArray; import com.example.demo.beans.entity.TMybatis; import net.minidev.json.JSONUtil; import java.util.*; import java.util.stream.Collectors; public class StreamTest { public static void main(String[] args) throws Exception{ List<TMybatis> mybatis = new ArrayList<>(); for(int i=0;i<10;i++){ TMybatis tMybatis = new TMybatis(); tMybatis.setObjid(i+1); if(i%2 == 0){ tMybatis.setRemoveTag(1); } else { tMybatis.setRemoveTag(0); } mybatis.add(tMybatis); } //求和 int add = mybatis.stream().collect(Collectors.summingInt(TMybatis::getObjid)); int add1 = mybatis.stream().collect(Collectors.summingInt(t -> { return t.getObjid() + 1; })); System.out.println(add+","+add1); //分组 Map<Integer,List<TMybatis>> groupBy = mybatis.

jenkins部署CI/CD

目录 一、CI/CD 1、为什么要 用CI / CD 2、理解持续集成、持续交付、持续部署 1、持续集成 2、持续集成目的在产生以下效益 3、持续交付 4 、持续部署 二、Jenkins CI/CD 1、 Jenkins CI/CD 流程图​ 2、Jenkins 介绍 1、Jenkins 功能 2、Jenkins 概念 3、Jenkins 目的 4、Jenkins 特性 5、产品发布流程 3、jenkins安装与使用 1、安装java和maven 2、安装jenkins 4、登录jenkins web管理界面 5、Jenkins用户权限管理 1、用户管理背景 2、安装用户管理插件 3、开启插件功能 4、验证用户管理 5、用户权限划分 6、Jenkins 参数化构建 1、参数化构建背景 2、安装插件并使用 3、 数据来源选择文件 三、部署应用Jenkins+Github+Tomcat实战 1、jenkins部署 1、安装插件 2、插件安装过程 3、配置邮箱(可选) 4、配置Jenkins私钥 5、添加后端服务器 6、配置jdk,maven命令,全局配置 7、构建发布任务 2、部署java服务器,做jenkins打包上线 3、回到jenkins页面开始构建任务 四、部署jenkins+gitlab+tomcat实战 1、gitlab本地仓库与远程仓库的配置 2、jenkins服务器的配置 3、web服务器(tomcat)环境清理 4、jenkins项目的创建与配置 5、项目构建 6、排错 五、 Gitlab+jenkins+tomcat+webhook 自动发布 1、jenkins安装插件 2、gitlab配置项目的webhook

二分查找-面试选择题

(1)有一个有序表为1,5,8,11,19,22,31,35,40,45,48,49,50当二分查找值为48的结点时,查找成功需要比较的次数。 析:第一次二分中间值是31,第二次二分因为31后的只有6个数,偶数取中间靠左,为45,第三次二分为49,第四次找到48 (2)使用二分法在序列1,4,6,7,15,33,39,50,64,78,81,89,96中查找元素81时,需要经过多少次比较。 析:四次 (3)在已经的128个数组中二分查找一个数,需要比较的次数最多不超过多少次。 析:除2,每次少一半,直到1 注:奇数二分取中间 偶数二分取中间靠左

ALS算法理解

ALS算法全称为交替最小二乘法(Alternating Least Squares),是一种基于协同过滤思想的矩阵分解算法。其亮点之一就在于优化参数时使用了交替最小二乘法,而非梯度下降算法,使得ALS算法可以进行分布式并行计算,因此其被收录于Spark的Mlib以及ML库中。下面将详细介绍这一算法: 一、核心思想 通过隐含特征(latent factor)联系用户兴趣和物品(item), 基于用户的行为找出潜在的主题和分类, 然后对item进行自动聚类,划分到不同类别/主题(用户的兴趣)。 本质是把协同过滤算法进行了一种延伸, 把用户的相似性和物品的相似性通过了一个叫做隐向量的方式进行表达 ​ 矩阵分解算法将 m × n m×n m×n 维的共现矩阵 R R R 分解成 m × k m×k m×k 维的用户矩阵 U U U 和 k × n k×n k×n 维的物品矩阵 M M M 相乘的形式。 我们的目标就是填充共现矩阵中的空缺值,从而对用户的行为产生预测。 ​​ 其中 m m m 是用户数量, n n n 是物品数量, k k k 是隐向量维度, 也就是隐含特征个数, 只不过这里的隐含特征变得不可解释了, 即我们不知道具体含义了, 要模型自己去学。 k k k 的大小决定了隐向量表达能力的强弱, k k k 越大, 表达信息就越强, 理解起来就是把用户的兴趣和物品的分类划分的越具体。

mybatis plus的简单使用

一、mybatis plus简介 MyBatis-Plus(简称 MP)是一个MyBatis的增强工具,在MyBatis的基础上只做增强不做改变。MP封装了对单表的CRUD操作,代码生成、自动分页、逻辑删除、自动填充等功能一应俱全。 MP常用注解: @TableName:指定数据库表@TableId:将成员变量指定为数据表主键。其type值有AUTO(数据库 ID 自增)、NONE(默认给出id一个 Long 类型的字符串,type默认值)、INPUT(需要自己传入一个id值)、ASSIGN_ID(使用雪花算法分配id,支持Long、String、Integer三种类型)、ASSIGN_UUID(使用雪花算法分配id,只支持String类型)@TableField:用于非主键属性,映射表字段与bean中的字段 二、mybatis plus的简单使用 1. MP配置 引入MP坐标 <!--mybatis plus--> <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-boot-starter</artifactId> <version>3.4.2</version> </dependency> 修改配置文件(properties和yml格式对应转换即可) # 连接数据库 spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver spring.datasource.url=jdbc:mysql://ip:port/databaseName?characterEncoding=UTF-8&useUnicode=true&useSSL=false spring.datasource.username=username spring.datasource.password=password 创建mapper,继承BaseMapper,通过泛型指定MP封装的CRUD操作的表格 在启动类添加Mapper扫描注解 MP分页配置(根据需要设置) 2. 单表操作 类似selectById()这样固定条件的方法直接调用即可,这里主要讲一下使用MP条件构造器Wrapper自定义条件。 条件构造器的作用是编辑sql where之后的条件语句,且只能用于单表操作,Wapper层级关系如下: 条件构造器构造方法如下: 单表CRUD: 根据条件判断是否添加表达式:wrapper.lambda.like(condition:null != a, filed: key, val:val) 3. 连接查询 多表查询需要自定义sql,可以使用注解式操作,也可以创建xml文件。 注解式: xml文件: idea模板设置可参照:https://www.jb51.net/article/199343.htm <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace=""> <!--mybatis mapper 的xml模板--> </mapper> 在pom文件的标签中设置扫描xml文件的路径 <!--配置扫描xml文件--> <resources> <resource> <directory>src/main/resources</directory> <includes> <include>**/*.

[Vue2]AntDesignVue基于Select封装「多选 + 二级级联+ 可自定义添加item 组件」

需求场景 在一个下拉选择框中,一个branch对应多个编译命令option, option1和option2是每个branch都固定拥有的选项,同时支持多选,例如最后选择的结果如下: { "branch1": ["option1", "option2", "option31", "option41"], "branch2": ["option1", "option2", "option32", "option42"], "branch2": ["option1", "option2", "option33", "option43"], ...... } ui示意图如下 AntDesignVue官网 第一反应都是去官网看看有没有现成的轮子可用,但官方给出的组件功能还是不够强大,需要基于官方组件进行二次封装。 doit-ui-web doit-ui-web基于AntDesignVue封装了很多业务常用的组件 http://my.h5house.com/component/select/two_cascader.html 在这里找到了一个最贴近业务的组件,只是可惜少了一个自定义添加item的功能,而且doit-ui-web文档中并未。 那就基于AntDesignVue自己封装吧… 实现效果 example.vue <template> <cascader-select :options="items" v-model="initData" style="width: 200px;" ></cascader-select> </template> <script> import CascaderSelect from '@/components/CascaderSelect' export default { components: { CascaderSelect }, data: () => ({ initData: null, items: [ { label: 'test1', value: 'test1', children: [ { label: 'test1-1', value: 'test1-1' }, { label: 'test1-2', value: 'test1-2' } ] }, { label: 'test2', value: 'test2', children: [ { label: 'test2-1', value: 'test2-1' }, { label: 'test2-2', value: 'test2-2' } ] } ] }), methods: { // It's for asyncApi // (itemVal: {label:string, value:string}) => Promise addHandler (itemVal) { const backItem = { label: itemVal + '_' + new Date().

【Android】解决Android Studio中的虚拟设备无法上网问题

解决Android Studio中的虚拟设备无法上网问题 前言 : 使用AndroidStudio自带的虚拟设备在调试软件时, 发现无法联网,然后用虚拟设备自带的浏览器进行网页访问也是失败的, 因此可以说明是整个虚拟设备是无法正常联网通讯的! 问题原因 :可能你的虚拟设备的DNS设置和你的电脑的DNS不在一个网段上,需要修改虚拟设备的网段与电脑的同步即可。 DNS : 域名解析, 主要用于将网址解析为IP地址 解决方式 : 先关闭虚拟设备以及AndroidStudio 进入安装SDK的文件夹 进入emulator文件夹 直接在该路径栏下输入cmd, 按回车, 进入命令提示符界面 输入 emulator.exe -list-avds, 它将列出你所拥有的的虚拟设备, 需要复制你所要修改的设备名称, 待会修改会用到 查出你电脑设备所在的DNS网段 第一种方式, 直接输入命令行查找 , ipconfig /all 第二种方式, 直接在电脑的Windows设置上查找, 设置->网络与Internet->状态->属性 修改虚拟设备的DNS, 继续在命令提示符上输入 emulator.exe -avd 设备名 -dns-server DNS1,DNS2 比如 : 我电脑的DNS服务是 8.8.8.8 和 114.114.114.114即修改名称为Pixel_2_API_30的DNS命令为emulator.exe -avd Pixel_2_API_30 -dns-server 8.8.8.8,114.114.114.114 ​ 输入命令后会自动弹出虚拟设备的界面, 此时命令行也进入该程序的命令入口 关闭掉窗口使用快捷键Ctrl+C 即可中断运行 OK , 大致解决了问题! 希望对大家有帮助! 小Tips : 在Android Studio的虚拟设备上调试软件时, 若程序没有报错, 但运行不出效果的, 可以从虚拟设备上排查问题, 而不至于在代码上排查半天也摸不着头脑。特别是需要联网的应用,我调试时发现问题出现在无法解析主机的地址上,因此可以通过虚拟设备自带的浏览器来检测是否能正常上网!

最长公共子序列 - LCS

最长公共子序列 - LCS 问题描述子序列定义子串定义公共子序列定义最长公共子序列(以下简称LCS) 动态规划解决子问题划分及依赖关系递推公式 伪代码代码实现复杂度分析 问题描述 子序列定义 给定一个序列X=<x1,x2,x3,x4…,xm>,另一个序列Z=<z1,z2,z3,z4…,zk>,若存在一个严格递增的X的下标序列<i1,i2,i3,…,ik>对所有的1,2,3,…,k,都满足x(ik)=zk,则称Z是X的子序列 比如Z=<B,C,D,B>是X=<A,B,C,B,D,A,B>的子序列 子串定义 子串的话与子序列不同,子串要求必须连续。 例如 BCDB 虽然是X=<A,B,C,B,D,A,B>的子序列 但不是它的字串 因为BCDB不连续。 而BCBD属于<A,B,C,B,D,A,B>的字串 该篇文章我们要求的是 子序列 而不是 子串 公共子序列定义 如果Z既是X的子序列,又是Y的子序列,则称Z为X和Y的公共子序列 最长公共子序列(以下简称LCS) 2个序列的公共子序列中长度最长的那个 动态规划解决 子问题划分及依赖关系 递推公式 伪代码 利用标记函数追踪解: 代码实现 public class LCS { public static void main(String[] args) { String x = "ABCBDAB"; String y = "BDCABA"; int m = x.length(); int n = y.length(); // 动态数组 int[][] c = new int[m+1][n+1]; // 标记函数数组 int[][] b = new int[m+1][n+1]; // 上边界赋值为0 for (int i=0; i<=n; i++) { c[0][i] = 0; b[0][i] = 0; } // 左边界赋值为0 for (int i=0; i<=m; i++) { c[i][0] = 0; b[i][0] = 0; } System.

stm32 BootLoader之检查栈顶地址 复位地址

检查栈顶是否合法代码如下: #define STM32_APP_BASE 0x08020000 // APP flash start address void iap_jumpapp(void) { // 检查栈顶是否合法,,确保栈顶落在0x24000000-0x24FFFFFF 之间,刚好在stm32h7的RAM范围内 if (((*(uint32_t*)(STM32_APP_BASE)) & 0xff000000 ) == 0x24000000 ) { // 检查reset入口是否正确 if (((*(uint32_t*)(STM32_APP_BASE + 4)) & 0x0fff0000 ) == 0x08020000 ) { JumpToApp = (pfunction)((*(uint32_t*)(STM32_APP_BASE + 4))); MSR_MSP(*(uint32_t*)STM32_APP_BASE); JumpToApp(); } } else { ... } } 栈顶地址 和 reset入口地址具体是什么??? 从startup_stm32h743xx.s中可以看出,程序第一个地址存放的是__initial_sp,紧接着第二个地址存放的是Reset_Handler;这两个正是所谓的栈顶地址 reset 入口 __Vectors DCD __initial_sp ; Top of Stack DCD Reset_Handler ; Reset Handler

No plugin found for prefix ‘tomcat7‘ in the current project and in the plugin groups

javaweb报错学习 对下面这个图片内容进行tomcat run 报错信息如下: No plugin found for prefix ‘tomcat7’ in the current project and in the plugin groups [org.apache.maven.plugins, org.codehaus.mojo] available from the repositories [local (D:\developer_tools\apache-maven-3.6.1\mvn_resp), alimaven (http://maven.aliyun.com/nexus/content/groups/public/)] -> [Help 1] 解决方法一: 找到这个settings.xml文件,进行编辑,在pluginGroups标签下加入下面的配置 <pluginGroups> <pluginGroup>org.apache.tomcat.maven</pluginGroup> </pluginGroups> 例如: 注意是加在外面,不要加在注释里面了! 成功页面入如下: 解决方法二: 在pom.xml文件中加入 <pluginRepositories> <pluginRepository> <id>apache.snapshots</id> <name>Apache Snapshots</name> <url>http://repository.apache.org/content/groups/snapshots-group/</url> <releases> <enabled>false</enabled> </releases> <snapshots> <enabled>true</enabled> </snapshots> </pluginRepository> </pluginRepositories> 解决方法三: 加入这个tomcat7配置 <plugin> <groupId>org.apache.tomcat.maven</groupId> <artifactId>tomcat7-maven-plugin</artifactId> <version>2.2</version> </plugin> 希望能帮到你,祝你好运! 加油!

Android事件传递(二):DOWN 在Activity、View、ViewGroup传递,除了自己本身的传递,还做了什么?

Android事件传递(一):Activity、View、ViewGroup及dispatchtouchEvent、onTouchEvent梳理 Android事件传递(三):事件动作 UP 在Activity、View、ViewGroup传递 Android事件传递(四):总结篇 下面源码基于Android11 API30 接上一篇文章,我们从Activity开始分析ACTION_DOWN动作的传递: 1 Activity#dispatchTouchEvent public class Activity extends ContextThemeWrapper implements Window.Callback,...... { ......省略其它代码...... private Window mWindow; public Window getWindow() { return mWindow; } @UnsupportedAppUsage final void attach(Context context,......) { attachBaseContext(context); mFragments.attachHost(null /*parent*/); 👉 mWindow = new PhoneWindow(this, window, activityConfigCallback); mWindow.setCallback(this); ......省略...... } public boolean dispatchTouchEvent(MotionEvent ev) { if (ev.getAction() == MotionEvent.ACTION_DOWN) { ✍空实现,你可以重写此方法实现自己的业务要求,但是只是DOWN动作会调用, 其它后续动作都不会执行该方法 onUserInteraction(); } if (getWindow().superDispatchTouchEvent(ev)) { ✍getWindow()得到的就是PhoneWindow,所以去看它的superDispatchTouchEvent(ev)方法 return true; } return onTouchEvent(ev); } public void onUserInteraction() { } } 👇 PhoneWindow.

SQL SERVER FOR XML PATH

文章目录 一、FOR XML PATH有啥用?二、写法 一、FOR XML PATH有啥用? 顾名思义,FOR XML PATH 就是将查询到的结果以XML的格式显示在查询结果中,有时使用了GROUP BY又想获取某个字段的所有值时就可以使用这个方法。 二、写法 select stuff( ( select ',' + studentName from dbo.Student where studentid = a.studentid group by studentid for xml path('') ) ,1 ,1 ,'' ) from dbo.Student a group by studentid

E5 调用API续订程序:Microsoft 365 E5 Renew Plus

Microsoft 365 E5 Renew Plus Microsoft 365 E5 Renew Plus的由来 Microsoft 365 E5 Renew Plus为Microsoft 365 E5 Renew的升级版,其功能性,易用性,美观程度上都要强于旧版。 主要功能 支持开机自启动后台调用:使用简单方便,无需购买服务器部署,本地应用程序即开即用两种可选的调用权限:用户未登录作为守护程序调用(需要客户端密码)、程序以登录用户身份直接调用(需要账户密码)自动配置API权限:登录调用的API权限支持由程序自动配置API种类齐全:43个可选的Microsoft Graph REST API Beta中的API(未来可能会继续添加)完全随机的API选用模式:从已选定的API序列中随机抽取一个或几个进行调用(个数和API随机)完全随机的API调用顺序:每轮API的调用先后顺序随机完全随机的API内容(仅部分API支持):POST写类型的API的上传内容随机完全随机的API调用时间间隔:随机区段500s-86400s自定义每日工作时间自定义:在日常工作时间进行调用,适用于从不关机重启的服务器设备每周工作日自定义:在每周的工作日进行调用,适用于从不关机重启的服务器设备运行智能暂停:防止因持续在错误配置下运行而导致的账户封禁运行配置自动保存:可保存运行配置,无需反复设置无限制账号个数:理论上允许无限制个数账号后台自动调用支持自定义客户端密钥:允许非登录调用使用自定义密钥自定义美化界面:支持自定义背景图片(半透明度以及毛玻璃效果)、亚克力背景 主界面 运行结果查看 入群须知 使用本系列产品只是增加E5续订概率,并不能保证100%续订成功续订操作有些许技术门槛,且需要具备一定的自学能力每个人的时间都是宝贵的,遇到问题先查阅帮助文档,实在无法解决时再发起提问(提问的艺术) QQ交流群:254058945 TG交流群:https://t.me/MS365E5Renew 软件下载 受支持的操作系统及运行环境安装 操作系统版本CPU架构.NET 6.0 (必选)WebView 2(可选)补丁(必选)Windows Client7 SP1(ESU) 、8.1x64下载.Net 6.0 Desktop下载WebView 2下载ESUWindows 10 ClientVersion 1607+Arm64、x64下载.Net 6.0 Desktop下载WebView 2不需要Windows 11 Client无限制Arm64、x64下载.Net 6.0 Desktop不需要不需要Windows ServerVersion 2012+x64下载.Net 6.0 Desktop下载WebView 2不需要 各版本下载地址(建议添加白名单运行) 软件版本文件说明LanZouOneDrive杀软报告包含框架(推荐)无需额外安装运行环境,可直接运行下载下载VirusTotal普通版本需要安装 .NET 6 Desktop Runtime x64下载下载VirusTotal历史版本(弃用)更兼容Windows 7,已停止更新下载下载VirusTotal 使用教程(请勿开启账号的双重验证功能) 0 如何导入旧版本程序中的账号信息?(老用户升级用 新用户请无视) 0.

多级反馈队列调度算法C语言

近期发现,网上对于多级反馈队列调度算法十分匮乏,要么代码太老,要么没什么用,限制性太大,要么copy来copy去,真没意思。正好自己操作系统上课要用,特此分享。 根据需求,自己可以在主函数中选择调度算法,包含抢占算法! //RR(SLICE); // FCFS(); //SJF(); //SRTF(); //NonPriority(); Priority(); 完整代码 #include<stdio.h> #include<stdlib.h> #include<stdbool.h> #include<unistd.h> #include<time.h> #include<string.h> #include <sys/types.h> // #include<sys/syscall.h> /*本次实验模拟实现操作系统中进程调度算法,模拟进程在不同时刻到达的情况*/ #define PNUM 5 //进程的数量 #define TIMER 10 //定时器,最长CPU区间时间 #define SLICE 2//轮转算法的时间片 int timenow=0; //当前时刻 typedef struct node{ int pid; //进程号 int priority;//进程优先级,1~3,数字越小优先级越高 int arrival; //到达时间 int burst; //CPU区间时间 int rest; //剩余时间 char state;//进程状态,'N'新建,'R'运行,'W'等待CPU(就绪),'T'终止 struct node *next; }PCB; int gantt[TIMER*PNUM]={0}; //用一个gantt数组记录调度过程,每个时刻调度的进程号 PCB *job;//所有作业的序列,带头节点(为简化编程) PCB *ready=NULL; //进程就绪队列,不带头节点 PCB *tail=NULL; //记录就绪队列的尾节点 PCB *run=NULL;//正在运行中的进程,不带头结点 PCB *finish=NULL;//已经结束的程序,不带头结点 void InitialJob() { int i=0; PCB *p,*tail; job=(PCB *)malloc(sizeof(PCB));//生成头节点,其它域无意义 job->next=NULL; tail=job; for(i=0;i<PNUM;i++) //初始化进程的值 { p=(PCB *)malloc(sizeof(PCB));//生成新节点(新进程) p->pid=i+1; p->priority=rand()%3+1;//随机生成优先级:1~3 p->arrival=rand()%TIMER;//随机生成到达时刻0-9,(预计到达就绪队列的时间) p->burst=rand()%TIMER+1;//随机生成CPU区间时间:1~10;(估计运行时间) p->rest=p->burst; p->state='N';//初始化进程的状态为'新建' p->next=NULL; tail->next=p; tail=p; //带头结点 } } void DisplayPCB(PCB *pcb) //显示队列 { struct node *p=pcb; if(pcb==NULL) {printf("

Hive合并小文件详解(参数介绍)

一、MR输出时合并小文件 参数设置 含义 set hive.merge.mapfiles=true; 默认值ture,在Map-only的任务结束时合并小文件 set hive.merge.mapredfiles=true; 默认值false,在Map-Reduce的任务结束时合并小文件 set hive.merge.size.per.task=256000000; 默认值256M, set hive.merge.smallfiles.avgsize=16000000 ; 默认值16M,当输出文件的平均大小小于16M时,启动一个独立的map-reduce任务进行文件merge reduce 计算方式:merge job后每个文件的目标大小(targetSize),用之前job输出文件的total size除以这个值,就可以决定merge job的reduce数目。merge job的map端相当于identity map,然后shuffle到reduce,每个reduce dump一个文件,通过这种方式控制文件的数量和大小 MapredWork work = (MapredWork) mrTask.getWork(); if (work.getNumReduceTasks() > 0) { int maxReducers = conf.getIntVar(HiveConf.ConfVars.MAXREDUCERS); int reducers = (int) ((totalSize +targetSize - 1) / targetSize); reducers = Math.max(1, reducers); reducers = Math.min(maxReducers, reducers); work.setNumReduceTasks(reducers); } 二、输入合并小文件,减小map数 set mapred.max.split.size=256000000; #每个Map最大输入大小 set mapred.min.split.size.per.node=100000000; #一个节点上split的至少的大小 set mapred.min.split.size.per.rack=100000000; #一个交换机下split的至少的大小 set hive.

gis之密度分析工具

ArcGIS密度分析工具有核密度、点密度、线密度三个工具。 作用 言简意赅:求密度。体现出分析目标在空间上的聚集情况 前提:简单介绍 有限元法基本思想 有限元法的基本思想,即“拆整为零,集零为整”。 实例:早期数学上求解圆面积的近似方法。首先将连续的圆分割成一些三角形,求出每个三角形的面积,再将每个小三角形面积相加,即可得到圆面积的近似值。前面是“分”的过程,后面是“合”的过程。之所以要分,是因为三角形面积容易求得。这样简单的一分一合,就很容易求出圆面积的近似值。 有限元法是在连续体上直接进行近似计算的一种数值方法 “拆整为零,集零为整”大致步骤: 1)离散化(分) “拆整为零”,即分的过程,将连续的求解区域离散为有限个部分的集合,并认为各部分只通过有线个点连接起来。 2)单元分析(合) 对每个单元分析,求出单元的特性。 “集零为整”即“合”的过程,将单元的特性装配在一起得到离散体整体的特性,并利用数值计算方法得到整个求解域上场函数的近似值。 简单密度分析 点密度和线密度分析 工作原理 以栅格像元为中心,以一定的搜索半径画圆,落在搜寻区域内的点、线具有同样的权重,先对该搜索区域内的点或线求和,再除以搜索区域的大小,从而得到密度值。 gis分析过程中 密度分析的作用是体现出分析目标在空间上的聚集情况。 求密度,需要有面积,面积的指定需要设置分析的区域,即“邻域”。 这个"邻域"的范围是可以自己根据经验定义、修改的(在操作窗口中输入)。在这个区域中,是中心点可以影响到的范围。如图下,此处设为10 定义邻域之后还需要定义栅格,定义栅格就用到了我们刚刚所讲的类似有限元的思想,将一个区域剖分成有限多个单元(在操作中指定输入像元大小,即为指定了单个的尺度,计算机工具输入单元像元大小计算:将一个区域剖分成有限多个单元),然后分别计算中心点的population对每个小单元格的影响值 紧接着领域内中心点的population对每个小单元格的影响值求和相加,再除以领域的大小,最终可以得到分析目标在空间上的密度分布

泛型详解【十分钟带你了解泛型基础知识点】

文章目录 一、泛型介绍二、泛型的优点三、泛型使用细节四、自定义泛型 1.泛型类2.泛型接口3.泛型方法总结 前言 泛型在java中有很重要的地位,在面向对象编程及各种设计模式中有非常广泛的应用。 一、泛型介绍 (1).泛型又称参数化类型,是jdk5.0出现的新特性,解决数据类型的安全性问题 (2).在类声明或实例化时,只要指定好需要的具体的类型即可 二、泛型的优点 (1).编译时,检查添加的元素的类型,提高了安全性 (2).减少了类转换的次数,提高效率 (3).不在提示编译警告 三、泛型使用细节 <E>其中E只能是引用类型,而不能是基本数据类型 在给泛型指定类型后,可以传入该类型或其子类型 泛型的定义和使用形式有两种,一种是传统形式,还有一种是简化形式,在实际开发中往往简写,可以把右边的<>中可以省略不写,相当于交给编译器,推荐第二种写法 四、自定义泛型 泛型有三种使用方式,分别为:泛型类、泛型接口、泛型方法 1.泛型类 泛型类型用于类的定义中,被称为泛型类。通过泛型可以完成对一组类的操作对外开放相同的接口。最典型的就是各种容器类,例如如:List、Set、Map。 类声明后的<>中这个T被称为类型参数,用于指代任意类型,实际上这个T只是个代表,写什么都可以。表示此时的value1,value2都是在类定义时没有明确类型,只有在使用时才告知编译器类型。出于规范,类型参数用单个的大写字母来代替,常见如下: 2.泛型接口 泛型接口与泛型类的定义及使用基本相同 接口中,静态成员也不能使用泛型 泛型接口的类型,在继承接口或实现接口的时候确定 如果没有具体指定,就默认为Object//定义一个泛型接口 3.泛型方法 此处的泛型方法指的是有自己的类型参数 泛型方法,可以定义在普通类中,也可以定义在泛型类中 当泛型方法被调用时,类型会确定(自动确认) public void eat(E e){},修饰符后没有<T,R..>eat方法不是泛型方法,而是使用了泛型,这个方法应该是在泛型类当中 泛型方法可以使用类声明的泛型,也可以使用自己声明的泛型 总结 泛型使用时会把我们前面学过的基础全使用一遍,因此学习时不能记急躁,要会独立思考,心中对泛型的基础有个框架,进阶学习时才不会卡壳,加油!

vue2+three.js的基本使用 (模型是本地文件)

第一步 安装依赖 npm install --save three 在需要使用的组件进行引用 //引入 import * as THREE from 'three'; // //引入gltf格式的模型文件需要的 import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader" //监听鼠标键盘事件时需要用到 import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls'; 算了直接上完整代码 ps:引用的模型文件要放在public文件夹下面 <template> <div class="main"> <header> <h1>THREEJSDEMO</h1> </header> <div id="scene" class="body"></div> </div> </template> <script> var elementResizeDetectorMaker = require("element-resize-detector") import * as THREE from 'three'; import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader" import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls'; export default { data(){ return{ dom:null, scene:null, mesh: null, //网格模型对象 point: null, camera: null, //相机对象 renderer: null, //渲染器对象 loader:null, controls:null, } }, created(){ }, mounted(){ this.

python实现微信、QQ聊天自动回复【纯物理】

一、功能描述 实现微信、QQ等聊天软件的自动回复功能,让你关注的人不用再等候你的回复。通过机器人或者预设消息来自动回答对方的问题。 二、实现方案 0. 方案说明 首先感谢热心网友指出了 itchat 和 wxpy 等插件方案已无法使用的问题,并且看到了基于 hook 的一种方案,不过基于 hook 方案的作者也说明可能有封号风险。 本方案主要构思则是结合各种python库分别实现:界面截图、文字识别、机器人api调用、模拟window键鼠复制文字并发送消息等功能。 从而实现对于打开的指定聊天界面定时识别聊天信息并调用api回复消息的效果。 此外,本方案的图片文字识别功能并没有使用百度AI平台提供的OCR服务,而是使用了免费的本地服务 tesserocr,不需要额外注册,tesserocr 的识别准确率和速度也足够用了,最重要的是免费~ 1. 开发环境&工具 conda + python 3.9 + pycharm 2. 必要依赖库安装 2.1 图片操作和文字识别相关库 参考文章:python3.9 安装 tesserocr 过程 tesserocr 文字识别应用安装,下载地址 本文选用的时目前最新版本的 tesseract-ocr-w64-setup-v5.0.1.20220118,经测试是适配python3.9的。 安装过程注意:勾选 Additional language data (download) 中的 Chinese-Simplied 中文简体,用于识别中文,其他默认就行conda install -c simonflueckiger tesserocr pillow找到第一步 tesserocr 安装目录下的tessdata 文件夹,全量复制到本地的conda目录下的 /envs/你的python环境对应文件夹 下,如果不知道conda目录在哪里,完成第二步后,运行下面的demo,查看报错中给出的文件路径。 from PIL import Image import tesserocr if __name__ == "__main__": pic_files = glob.

百看不如一练 100道python经典题目,拿去参考学习练手(附答案)可复制

近年来,Python在编程语言界里赚足了风头,无论是受欢迎程度,还是薪资待遇,都非常可观,相应的,Python岗位要求也越来越高,无论你是零基础还是老前辈,在Python面试中都不能轻视。 不打无准备之战,在平时我们就需要多积累,今天就给大家一份100多道Python真题合集,全是经典题目,从容易到困难,非常全面,PDF格,供大家参考学习。 题目答案一一对应,代码齐全可复制,不仅可当作练习使用,也可以当作面试参考,建议人手一份。 内容展示 求前n阶乘的和 难度:容易 ⽐如求1+2!+3!+...+20!的和。 输⼊:(不要输⼊太⼤的n防⽌数据太⼤,电脑卡死) n = 20 输出:前20阶乘的和是:2561327494111820313 答案: n = int(input("n = ")) s = 0 t = 1 for i in range(1,n+1): t *= i s += t print ("前{}阶乘的和是:{}" .format(n,s)) 百钱百鸡问题 难度:容易 百钱百鸡是我国古代数学家张丘建在《算经》⼀书中提出的数学问题:鸡翁⼀值钱五,鸡⺟⼀值钱三,鸡雏三值钱⼀。百钱买百鸡,问鸡翁、鸡⺟、鸡雏各⼏何?翻译成现代⽂是:公鸡5元⼀只,⺟鸡3元⼀只,⼩鸡1元三只,⽤100块钱买⼀百只鸡,问公鸡、⺟鸡、⼩鸡各有多少只? 输⼊: ⽆ 输出:(有多个答案,下⾯的只是其中⼀个答案) 公鸡: 0只, ⺟鸡: 25只, ⼩鸡: 75只 答案: for x in range(0, 20): for y in range(0, 33): z = 100 - x - y if 5 * x + 3 * y + z / 3 == 100: print('公鸡: {}只, 母鸡: {}只, 小鸡: {}只' .

Android AudioEffect音效移植

原文链接:https://blog.csdn.net/wkw1125/article/details/65632960 AudioEffect构造流程跟踪 为了编写新的音效实现,需要了解Android底层在AudioEffect的底层实现: 在Java层new Equalizer();后,通过JNI进入底层C/C++的实现过程。在底层,通过层层调用,由音控中枢AudioFlinger.cpp负责音效的管理,在线程中使用音效工厂EffectFactory.c读取.conf配置文件完成音效实例的创建。 AudioEffect构造流程图 详细代码跟踪参考:安卓音效AudioEffect源码剖析1——构造流程 根据上文,我做了张图帮助理解,其中将涉及到的类、头文件的关系列出,并标明了代码路径方便查找。当然,图中只列出了构造流程的关键代码。 音效工厂EffectsFactory.c中的EffectCreate方法中的三个调用: // 从配置文件读取平台支持的音效信息 ret = init(); // 在支持的音效中查找是否有指定的音效type/uuid ret = findEffect(NULL, uuid, &l, &d); // 若有,则创建音效实例 ret = l->desc->create_effect(uuid, sessionId, ioId, &itfe); 配置文件路径 init()读取运行环境的音效配置文件,如果vendor/etc/audio_effects.conf存在则使用该配置,若不存在则使用系统的system/etc/audio_effects.conf。 配置文件的路径定义在 /system/media/audio_effects/include/audio_effects/audio_effects_conf.h,有以下值: 常量值顺序AUDIO_EFFECT_VENDOR_CONFIG_FILEvendor/etc/audio_effects.conf优先AUDIO_EFFECT_DEFAULT_CONFIG_FILEsystem/etc/audio_effects.conf其次 配置文件audio_effects.conf audio_effects.conf配置文件内声明了平台所支持的音效库,新增音效库时需对该文件进行修改。 AOSP路径:/frameworks/av/media/libeffects/data/audio_effects.conf 配置内容如下: #audio_effects.conf libraries { ... bundle { path /system/lib/soundfx/libbundlewrapper.so } ... } effects { ... bassboost { library bundle uuid 8631f300-72e2-11df-b57e-0002a5d5c51b } equalizer { library bundle uuid ce772f20-847d-11df-bb17-0002a5d5c51b } ... libraries指出了音效库.so文件路径,默认是在平台的/system/lib/soundfx/目录下,新增的音效库so也要放在此处。

WLAN无线局域网2.4Ghz频段和5GHz频段的区别和选择

这两天游戏机连不上wifi,打联机游戏很气人,专门看了看IEEE802.11协议 1971年,夏威夷大学的研究员创造了第一个基于封包式技术的无线电通讯网络。这被称作ALOHNET的网络,这是最早期的无线局域网络 (WLAN) 1990年,IEEE正式启用了802.11项目,也就是俗称的WLAN技术,它的发展历史 无线射频基础: 在频率为3Hz~300GHZ之间的电磁波为无线射频频率: 波长的计算公式为: 其中波长*频率等于光速 极低频ELF 用于潜艇通信 超低频率SLF 交流电输电系统(50-60Hz) 甚低频 VLF 超声波 下面是收音机三件套: 低频LF 国际广播 是长波 中频MF 调幅(AM)广播、海事及航空通讯 是中波 高频HF 短波、民用电台 是短波 甚高频 VHF 调频(FM)广播、电视广播、航空通讯 特高频 UHF 电视广播、无线电话通讯、无线网络、微波炉 超高频 SHF 无线网络、雷达、人造卫星接收 极高频 EHF 射电天文学、遥感、人体扫描安检仪 300GHz以上 - 红外线、可见光、紫外线、射线等 2.4Ghz工作频段在特高频,协议为IEEE 802.11b/g/n 5Ghz工作频率在超高频,协议为IEEE 802.11 a/n 由于频率越低穿透能力越强,所以 2.4GHz频段,它的传输速率慢,但穿墙能力强 5GHz频段,因为频率高的传输速度高,设备较多的时候有较大的带宽和良好的稳定性,但是穿墙能力弱, 所以离路由器近的话,就选择5GHz模式 如果隔着墙的话,就选择2.4GHz模式

Excel中拼接文本字符串-CONCATENATE函数

Excel中拼接文本字符串-CONCATENATE函数 CONCATENATE函数函数简介函数语法函数说明示例 CONCATENATE函数 函数简介 CONCATENATE 函数用于Excel中,可将最多 255 个文本字符串联接成一个文本字符串。联接项可以是文本、数字、单元格引用或这些项的组合,且必须将希望在结果中显示的任意空格或标点符号指定为使用双引号括起来的参数。 ------粘百度百科 函数语法 CONCATENATE(text1, [text2], …) CONCATENATE函数语法具有下列参数(参数为:操作、事件、方法、属性、函数或过程提供信息的值。): Text1必需要连接的第一个文本项。 Text2, …可选。其他文本项,最多为 255 项。项与项之间必须用逗号隔开。 注释:也可以使用连接符号 (&) 计算运算符代替CONCATENATE函数来连接文本项。例如,=A1 & B1 返回相同的值为=CONCATENATE(A1, B1) ------粘百度百科 函数说明 CONCATENATE函数可将最多 255 个文本字符串合并为一个文本字符串。联接项可以是文本、数字、单元格引用或这些项的组合。例如,如果您的工作表的单元格 A1 中包含某个人的名字,单元格 B1 中包含这个人的姓氏,那么,您可以通过使用以下公式将这两个值合并到另一个单元格中: =CONCATENATE(A1," “,B1) 此示例中的第二个参数 (” ") 为空格字符。您必须将希望在结果中显示的任意空格或标点符号指定为使用双引号括起来的参数。 ------粘百度百科 示例 表格字段信息展示如下: 序号日期天气拼接1三月一号晴2三月二号晴3三月三号晴转阴4三月四号阴5三月五号小雨6三月六号大雨7三月七号暴雨8三月八号阴9三月九号阴转晴10三月十号晴 现在要把日期和天气拼接起来展示,便使用到了CONCATENATE函数,在D2单元格中写=CONCATENATE(B2,“的天气是”,C2)并按下回车键,拼接后的文本信息展示如下所示: =CONCATENATE(B2,“的天气是”,C2) 序号日期天气拼接1三月一号晴三月一号的天气是晴2三月二号晴三月二号的天气是晴3三月三号晴转阴三月三号的天气是晴转阴4三月四号阴三月四号的天气是阴5三月五号小雨三月五号的天气是小雨6三月六号大雨三月六号的天气是大雨7三月七号暴雨三月七号的天气是暴雨8三月八号阴三月八号的天气是阴9三月九号阴转晴三月九号的天气是阴转晴10三月十号晴三月十号的天气是晴 具体如下图所示:

MySQL 基本的SELECT语句

一.SQL分类 SQL语言在功能上分为三大类: DDL(Data Definition Language,数据定义语言) 这些不仅定义了不同的数据库,表,视图,索引,等数据库对象,还可以用来创建,删除,修改数据库和数据表的结构 主要关键字 CREATE,DROP,ALTER DML(Data Manipulation Language,数据库操作语言) 用于添加,删除,更新和查询数据库记录,并检查数据的完整性 主要关键字 INSERT,DELETE,UPDATE,SELECT SELECT是SQL语言基础,最为重要 DCL(Data Control Language,数据库控制语言) 用于定义数据库,表,字段,用户的访问权限和安全级别 主要关键字 GRANT,REVOKE,COMMIT,ROLLBACK,SAVEPOINT DQL(数据查询语言) TCL(Transaction Control LAnguage,事务控制语言) 主要关键字 COMMIT,ROLLBACK 二.SQL语言的规范与规则 1.基本规则 SQL可以写在一行或多行,为了提高可读性,各字句分行写,必要时使用缩进 每条命令以 ; 或 \g 或 \G 结束 关键字不能被缩写也不能分行 关于标点符号: 必须保证所有的(),单引号,双引号是成对结束的 必须使用英文状态下的半角输入方式 字符串类型和日期时间类数据可用单引号(' ')表示 列的表名,尽量使用双引号(" "),而且不建议省略as 简单操作 USE test1; SELECT * FROM emp; INSERT INTO emp; VALUE(1002,'TOM'); 2.SQL大小写规范 MySQL在Windows下对大小写不敏感 在linux下对大小写敏感,因此有的要区分大小写 数据库名,表名,表的别名,变量名严格区分大小写 关键字,函数名,列名(或字段名),列的别名(字段的别名)忽略大小写 推荐使用统一编写规范: 数据库名,表名,表的别名,字段名,字段的别名等都使用小写 SQL关键字,函数名,绑定变量等都使用大写 3.注释 单行注释: # 注释文字 --注释文字(--后面必须包含一个空格)

数据采集与清洗基础习题(四)Pandas初体验,头歌参考答案

数据采集习题参考答案,会持续更新,点个关注防丢失。 创作不易,一键三连给博主一个支持呗。 为了方便查找,已按照头歌重新排版,朋友们按照头歌所属门类查找实训哦,该篇为Pandas。 文章目录 实训一:Pandas初体验 第一关:了解数据处理对象--Series 编程要求 Pandas中的数据结构 第一关答案 第二关:了解数据处理对象-DataFrame 编程要求 相关知识 第二关答案 第三关:读取CSV格式数据 编程要求 相关知识 第三关答案 第四关:数据的基本操作——排序 编程要求 相关知识 第四关答案 第五关:数据的基本操作——删除 编程要求 相关知识 第五关答案 第六关:数据的基本操作——算术运算 编程要求 相关知识 第六关答案 第七关:数据的基本操作——去重 编程要求 相关知识 第七关答案 第八关:层次化索引 编程要求 相关知识 第八关答案 实训一:Pandas初体验 第一关:了解数据处理对象--Series 编程要求 创建一个名为series_a的series数组,当中值为[1,2,5,7],对应的索引为['nu', 'li', 'xue', 'xi']; 创建一个名为dict_a的字典,字典中包含如下内容{'ting':1, 'shuo':2, 'du':32, 'xie':44}; 将dict_a字典转化成名为series_b的series数组。 相关知识 Pandas是为了解决数据分析任务而创建的,纳入了大量的库和标准数据模型,提供了高效地操作大型数据集所需的工具。 对于Pandas包,在Python中常见的导入方法如下: from pandas import Series,DataFrame import pandas as pd Pandas中的数据结构 Series: 一维数组,类似于Python中的基本数据结构list,区别是Series只允许存储相同的数据类型,这样可以更有效的使用内存,提高运算效率。就像数据库中的列数据;DataFrame: 二维的表格型数据结构。很多功能与R中的data.frame类似。可以将DataFrame理解为Series的容器;Panel:三维的数组,可以理解为DataFrame的容器。 了解Series 为了开始使用Pandas,我们必需熟悉它的两个重要的数据结构:Series 和DataFrame。虽然它们不是每一个问题的通用解决方案,但可以提供一个坚实的,易于使用的大多数应用程序的基础。 Series是一个一维的类似的数组对象,包含一个数组的数据(任何NumPy的数据类型)和一个与数组关联的数据标签,被叫做索引 。最简单的Series是由一个数组的数据构成:

Windows 中使用 VS2019 开发 CMake 项目

文章目录 0. 前言1. 使用 VS2019 编译 SPDLOG2. 在 VS2019 中创建 CMake 项目引入 SPDLOG 0. 前言 目标:使用 VS2019 构建 CMake 项目,或导入、开发已有 CMake 项目。为什么要这么做? 跨平台:目前的项目需要跨平台开发,主力平台是Linux,Windows主要做适配工作。世界上最好的IDE:2010的时候,我就是用VS开发的,现在也算是重操旧业…… 本文内容: 以 SPDLOG 为例,使用 VS2019 编译已有的 CMake 项目以 SPDLOG 为例,使用 VS2019 创建 CMAKE 项目,引入并使用编译好第三方包 1. 使用 VS2019 编译 SPDLOG SPDLOG 是 C++ 中常用的日志工具,也是我本人选择使用的,因此以本项目为例来尝试如何在 Windows 下通过 VS 2019 编译已有的 CMake 项目。第一步:下载 SPDLOG 源码。第二步:通过 VS2019 打开 SPDLOG 源码目录。 打开方式以及打开结果如下图所示。PS:打开项目后可能需要一点时间才能加载 SPDLOG 文件夹中的内容。 第三步:配置并编译项目 这一步的工作类似于 Linux 中的 cmake .. && make -j右键点击 CMakeLists.

python是垃圾?

前一段时间,跟一个人聊天,因为我是从事python行业的,无意中聊到python,他的回答,差点以为一个正常的聊天要转变成语言的battle 他跟我说:python绝对是垃圾!当时我一脸懵,怎么还带人身攻击?要battle语言吗? 心想着这一定是想要battle语言,我没有先急着反驳他,想了解一下原因:原来这位老兄学了python2年,每天下班花费业余时间去学习python,但是在python基础就开始迷茫,没有学到有用的东西,这才来了一句:python绝对是垃圾的结论。 这又是个半路学习python放弃的案例,对于这类,咱只想说:学了两年,没有效果,肯定是你的学习方法有问题! 也就是说其实没有学会,跟python是不是垃圾没有一点关系,关键是看人。 所以,在这里针对向这位老兄一样学习python没有效果的,先不要抱怨。先一定要找到原因,然后去解决问题才是关键。 明确学习目标,选择方向 准备开始学习python的时候,先要了解清楚python的应用方向,现在python大致主要从事以下领域: web开发网络爬虫数据分析人工智能自动化运维与自动化测试等 了解清楚之后,根据自己的需求和特性去选择要学习的部分,学习所需要掌握的技能 制定Python学习计划(100天) 学习目录: Day 01~15 - Python 语言基础 Day 16~20 - Python 语言进阶 Day 21~30 - Web 前端入门 Day 31~35 - 玩转 Linux 操作系统 Day 36~40 - 数据库基础和进阶 Day 56~60 - 实战 Flask Day 61~65 - 实战 Tornado Day 66~75 - 爬虫开发 Day 76~90 - 数据分析和机器学习 Day 91~100 - 团队项目开发 最为重要的就是基础要学好,地基打牢固,这里就说一下基础怎么学呢? Day 01~15 - Python 语言基础 Day01 - 初识Python Python简介 - Python的历史 / Python的优缺点 / Python的应用领域

权限框架SpringSecurity(二)——前后端分离登录

文章目录 1. 默认处理登录方式2. 自定义过滤器3. 项目实战配置3.1 配置类3.2 自定义Token过滤器3.3 TokenService3.4 登录 对于前后端分离项目,前后端交互通用的数据格式是 JSON。 1. 默认处理登录方式 在SpringSecurity中,默认处理登录的方式是通过 key/value 的形式来获取传递登录参数,来看下源码。 用户登录的用户名/密码是在 UsernamePasswordAuthenticationFilter 类中处理的,具体的处理代码如下: // 部分代码略 public class UsernamePasswordAuthenticationFilter extends AbstractAuthenticationProcessingFilter { private String usernameParameter = "username"; private String passwordParameter = "password"; public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) { // 部分代码略 String username = this.obtainUsername(request); username = username != null ? username : ""; username = username.trim(); String password = this.obtainPassword(request); password = password !

16.为什么进行抓包测试

有些时候公司没有标准的接口文档,测试人员只能抓包来获取接口信息。 抓包可以迅速找到请求,通过抓包可以查看整个请求过程,以及响应过程,可以通过抓包来分辨前台还是后台bug。 通过抓包,可以查看是否有敏感信息泄露,比如用户密码和个人账户信息等数据。 通过抓包进行测试,拦截请求,修改请求数据,查看对应响应结果,抓包本身就是接口测试的一部分。

web测试与app测试的区别(面试问到几率极高)

前言 看过了千里大腿的blog,再加上最近也有一些同学问我web与app测试的区别。所以在这里也献丑,写一篇帖子。希望对大家有所帮助。 笔者做了快三年的测试了。大部分时间都在做app的测试,web测试也做了半年左右。其实我觉得这两者并没有什么大的区别。 仅仅从功能测试的层面上来讲的话,在流程和功能测试上是没有区别的。那么区别在哪里呢? 我个人觉得就是由于载体不一样,所以系统测试和一些细节可能会不一样。 那么我们就要先来了解,web和app的区别。 而两者的主要区别体现在如下几个方面: 1 系统结构方面 Web项目,B/S架构,基于浏览器的;Web测试过程中,客户端会随服务器端同步更新,所以只需更新服务器端即可 App项目,C/S架构,基于客户端的;App测试过程中,只要修改了服务端,那么客户端用户所有核心版本都需要进行回归测试1次 2 性能方面 Web项目,需要监测响应时间、CPU、Memory,另外则还需系统能支持多少用户同时在线;超过最大用户数,系统会给出什么样的反映 App项目,需要监测响应时间、CPU、Memory,另外则还需监测流量、电量等 3 兼容方面 Web项目 首先,考虑操作系统兼容(Windows7、Windows10、Linux等);其次,考虑浏览器兼容(IE6、IE8、Firefox、Chrome、360等) App项目 首先,考虑设备系统兼容(Android【华为、联想、小米、三星等】、 iOS【ipad、iphone】、Windows【Win7、Win8】、OSX【Mac】);其次,考虑手机设备的大小、型号、分辨率的兼容 4 测试工具方面 Web测试,自动化工具通常使用Selenium,性能测试工具通常使用LoadRunner / JMeter App测试,自动化工具通常使用Appium / Monkey,性能测试工具通常使用JMeter 首先从系统架构来看的话,web测试只要更新了服务器端,客户端就会同步更新。而且客户端是可以保证每一个用户的客户端完全一致的。但是app端是不能够保证完全一致的,除非用户更新客户端。如果是app下修改了服务端,意味着客户端用户所使用的核心版本都需要进行回归测试一遍。 接着是性能方面,web页面可能只会关注响应时间,而app则还需要关心流量、电量、CPU、GPU、Memory这些了。至于服务端的性能是没区别,这里就不谈。 然后是兼容方面,web是基于浏览器的,所以更倾向于浏览器和电脑硬件,电脑系统的方向的兼容,不过一般还是以浏览器的为主。而浏览器的兼容则是一般是选择不同的浏览器内核进行测试(IE、chrome、Firefox)。app的测试则必须依赖phone或者是pad,不仅要看分辨率,屏幕尺寸,还要看设备系统。系统总的来说也就分为Android和iOS,不过国内的Android的定制系统太多,也是比较容易出现问题的。一般app的兼容测试三种方法,云测试,请团队测试,真机测试。云测试咱们稍后再聊,这里说说真机的选择。首先要选择主流的机型,其次要选择不同的分辨率,尺寸,然后就是不同的操作系统。 WEB测试和App测试从流程上来说,没有区别。都需要经历测试计划方案,用例设计,测试执行,缺陷管理,测试报告等相关活动。从技术上来说,WEB测试和APP测试其测试类型也基本相似,都需要进行功能测试、性能测试、安全性测试、GUI测试等测试类型。 他们的主要区别在于具体测试的细节和方法有区别,比如:性能测试,在WEB测试只需要测试响应时间这个要素,在App测试中还需要考虑流量测试和耗电量测试。 兼容性测试:在WEB端是兼容浏览器,在App端兼容的是手机设备。而且相对应的兼容性测试工具也不相同,WEB因为是测试兼容浏览器,所以需要使用不同的浏览器进行兼容性测试(常见的是兼容IE6,IE8,chrome,firefox)如果是手机端,那么就需要兼容不同品牌,不同分辨率,不同android版本甚至不同操作系统的兼容。(常见的兼容方式是兼容市场占用率前N位的手机即可),有时候也可以使用到兼容性测试工具,但WEB兼容性工具多用IETester等工具,而App兼容性测试会使用Testin这样的商业工具也可以做测试。 安装测试:WEB测试基本上没有客户端层面的安装测试,但是App测试是存在客户端层面的安装测试,那么就具备相关的测试点。 还有,App测试基于手机设备,还有一些手机设备的专项测试。如交叉事件测试,操作类型测试,网络测试(弱网测试,网络切换) 交叉事件测试:就是在操作某个软件的时候,来电话、来短信,电量不足提示等外部事件。 操作类型测试:如横屏测试,手势测试 网络测试:包含弱网和网络切换测试。需要测试弱网所造成的用户体验,重点要考虑回退和刷新是否会造成二次提交。弱网络的模拟,据说可以用360wifi实现设置。 从系统架构的层面,WEB测试只要更新了服务器端,客户端就会同步会更新。而且客户端是可以保证每一个用户的客户端完全一致的。但是APP端是不能够保证完全一致的,除非用户更新客户端。如果是APP下修改了服务器端,意味着客户端用户所使用的核心版本都需要进行回归测试一遍。 还有升级测试:升级测试的提醒机制,升级取消是否会影响原有功能的使用,升级后用户数据是否被清除了。 结语 这篇贴子到这里就结束了,最后,希望看这篇帖子的朋友能够有所收获。欢迎留言,或是关注我的专栏和我交流。

Torch 、torchvision 、Python 版本对应关系以及安装 GPU 或 CPU 版本的 pytorch

文章目录 1. torch - torchvision - python 版本对应关系2. CUDA Toolkit 和PyTorch的对应关系3. 安装说明3.1 用 anaconda 安装 pytorch3.2 不用 anaconda 管理环境3.3 对 NVIDIA 驱动的要求3.4 下载 .whl 文件离线安装3.5 使用 pip 语句在线安装3.6 安装 torch-cpu 1. torch - torchvision - python 版本对应关系 从表中可以看出,在使用 anaconda 创建虚拟环境时,将 python 的版本定为 3.7 最为合适,当然最好还是根据你自己的需要选择 python 版本。 conda create -n 环境的名字 python=3.7 2. CUDA Toolkit 和PyTorch的对应关系 3. 安装说明 3.1 用 anaconda 安装 pytorch anaconda 新建虚拟环境后,直接在 pytorch 官网官网链接 找到 “Install” 按钮。这里一键搞定torch,torchvision,cudatoolkit 等等。有以下几点需要注意和知晓的:

docker-compose快速搭建hadoop

1、docker-compose.yml version: "3" services: namenode: image: bde2020/hadoop-namenode:2.0.0-hadoop3.2.1-java8 container_name: namenode restart: always ports: - 9870:9870 - 9000:9000 volumes: - ./hadoop/dfs/name:/hadoop/dfs/name environment: - CLUSTER_NAME=test env_file: - ./hadoop.env datanode: image: bde2020/hadoop-datanode:2.0.0-hadoop3.2.1-java8 container_name: datanode restart: always depends_on: - namenode volumes: - ./hadoop/dfs/data:/hadoop/dfs/data environment: SERVICE_PRECONDITION: "namenode:9870" env_file: - ./hadoop.env resourcemanager: image: bde2020/hadoop-resourcemanager:2.0.0-hadoop3.2.1-java8 container_name: resourcemanager restart: always environment: SERVICE_PRECONDITION: "namenode:9000 namenode:9870 datanode:9864" env_file: - ./hadoop.env nodemanager1: image: bde2020/hadoop-nodemanager:2.0.0-hadoop3.2.1-java8 container_name: nodemanager restart: always environment: SERVICE_PRECONDITION: "namenode:9000 namenode:9870 datanode:9864 resourcemanager:8088"

MySQL基础-18 视图

视图 含义:虚拟表,和普通表一样使用 mysql 5.0.1 版本出现的新特性,是通过表动态生成的数据,只保存了sql逻辑,不保存查询结果。 应用场景: 多个地方用到同样的查询结果该查询结果使用的sql语句较复杂 好处: 重用sql语句简化复杂的sql操作,不知道它查询的细节保护数据,提高安全性 1 创建视图 语法: create view 视图名 as 查询语句; 案例 查询姓名中包含a字符的员工名、部门名和工种信息 CREATE VIEW myv1 AS SELECT `last_name`,`department_name`,`job_title` FROM `employees` e JOIN `departments` d ON e.`department_id`=d.`department_id` JOIN `jobs` j ON j.`job_id`=e.`job_id`; SELECT * FROM `myv1` WHERE last_name LIKE '%a%'; 查询各部门的平均工资级别 CREATE VIEW myv2 AS SELECT AVG(salary) ag,department_id FROM `employees` GROUP BY department_id; SELECT * FROM myv2; SELECT myv2.`ag`,g.grade_level FROM myv2 JOIN job_grade g ON myv2.

MySQL基础-19 存储过程和函数

存储过程和函数 1 变量 分类: 系统变量 全局变量【作用域:服务器每次启动将为所有的全局变量赋初始值,针对于所有的会话(连接)有效,但不能跨重启】会话变量【作用域:仅仅针对于当前会话有效】 自定义变量 用户变量局部变量 1.1 系统变量 说明,变量由系统提供,属于服务器层面 使用的语法: 查看所有的系统变量 SHOW GLOBAL VARIABLES; SHOW session VARIABLES; 查看满足条件的部分系统变量 show global|session variables like '%char%'; 查看指定的某个系统变量的值 select @@global|session.系统变量名; 为某个系统变量赋值 方法一: set global|session 系统变量名=值; 方法二: set @@global|session.系统变量名=值; 注意: 如果是全局级别,则需要加global,如果是会话级别,则需要加session,如果不写,则默认为session。 1.2 自定义变量 使用步骤: 声明 赋值 使用 1.2.1 用户变量 作用域:针对于当前会话有效 声明并初始化 方法一: set @用户变量名=值; 方法二: set @用户变量名:=值; 方法三: select @用户变量名:=值; 赋值 方法一: set @用户变量名=值; set @用户变量名:=值; select @用户变量名:=值; 方法二: select 字段 into @变量名

从请求的body中获取参数数据

private String getBodyString(HttpServletRequest request) { StringBuilder sb = new StringBuilder(); InputStream inputStream = null; BufferedReader reader = null; try { inputStream = request.getInputStream(); reader = new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8)); String line = “”; while ((line = reader.readLine()) != null) { sb.append(line); } } catch (IOException e) { e.printStackTrace(); } finally { if (inputStream != null) { try { inputStream.close(); } catch (IOException e) { e.printStackTrace(); } } if (reader !

微信小程序 - 云开发轮询实现定时推送订阅消息

前言 受众:已有小程序和云开发经验(没有的话照着流程和官方文档也应该可以实现) 关于小程序的消息推送,我了解到的有以下几种实现方式 1、模板消息,已于2020 年 1 月 10 日下线 2、通过服务端的统一服务消息下发推送,因为模板消息现已下线,现只支持公众号。统一服务消息官方文档 2、通过关注公众号通过公众号实现长期的消息推送 3、订阅消息,包含一次性订阅消息和长期订阅消息 订阅消息官方文档 关于技术实现的选择 关于小程序的消息推送的几种实现方式,先简单说一下各自的优缺点: 1、统一服务消息 优点:可以长期多次发送 缺点:因为模板消息现已下线,现只支持公众号 2、通过公众号实现 优点:可以长期多次发送 缺点:需要引导关注公众号,没有公众号还得注册一个,以下还有一些注意事项 1、公众号和小程序需要在同一个微信开放平台下,保证拿到相同的UnionID 2、如果需要在消息模板上加上小程序的入口,需要微信公众号和小程序做关联 3、小程序和公众号都必须是认证过的 4、小程序需要提前知道公众号的appid和appsecret 5、发送消息之前需要拿到用户对应于公众号的openid 3、订阅消息实现 订阅消息,包含一次性订阅消息和长期订阅消息,可惜长期订阅消息只对指定类目开放 一次性订阅消息 优点:服务端,云开发都可以实现推送 缺点:每次需要授权,每次授权同意只推送一次 哎,没什么可挑的,最终选择的是订阅消息的一次性订阅消息,下面是微信官方介绍 小程序订阅消息 功能介绍 消息能力是小程序能力中的重要组成,我们为开发者提供了订阅消息能力,以便实现服务的闭环和更优的体验。 订阅消息推送位置:服务通知订阅消息下发条件:用户自主订阅订阅消息卡片跳转能力:点击查看详情可跳转至该小程序的页面 消息类型 1. 一次性订阅消息 一次性订阅消息用于解决用户使用小程序后,后续服务环节的通知问题。用户自主订阅后,开发者可不限时间地下发一条对应的服务消息;每条消息可单独订阅或退订。 2. 长期订阅消息 一次性订阅消息可满足小程序的大部分服务场景需求,但线下公共服务领域存在一次性订阅无法满足的场景,如航班延误,需根据航班实时动态来多次发送消息提醒。为便于服务,我们提供了长期性订阅消息,用户订阅一次后,开发者可长期下发多条消息。 目前长期性订阅消息仅向政务民生、医疗、交通、金融、教育等线下公共服务开放,后期将逐步支持到其他线下公共服务业务。 3. 设备订阅消息 设备订阅消息是一种特殊类型的订阅消息,它属于长期订阅消息类型,且需要完成「设备接入」才能使用。 设备订阅消息用于在设备触发某些需要人工介入的事件时(例如设备发生故障、设备耗材不足等),向用户发送消息通知。详见设备订阅消息文档。 使用说明 步骤一:获取模板 ID 在微信公众平台手动配置获取模板 ID: 登录 https://mp.weixin.qq.com 获取模板,如果没有合适的模板,可以申请添加新模板,审核通过后可使用。 步骤二:获取下发权限 一次性订阅消息、长期订阅消息,详见接口 wx.requestSubscribeMessage 设备订阅消息,详见接口 wx.requestSubscribeDeviceMessage 步骤三:调用接口下发订阅消息 一次性订阅消息、长期订阅消息,详见服务端接口 subscribeMessage.send 设备订阅消息,详见服务端接口 hardwareDevice.send 注意事项 用户勾选 “总是保持以上选择,不再询问” 之后,下次订阅调用 wx.

MySQL基础-17 事物的介绍

事物的介绍 1 TCL 语言 transaction Control language 事务控制语言 2 事务 一个或一组sql 语句组成一个执行单元,这个执行单元要么全部执行要么全部不执行。 3 事务的属性(ACID) 原子性(Atomicity) 原子性指事务是一个不可分割的工作单位,事务中的操作要么都发生,要么都不发生。一致性(Consistency) 事务必须使数据库从一个一致性状态变换到另外一个一致性状态。隔离性(Isolation) 事务隔离性指一个事务的执行不能被其他事务干扰,即一个事务内部操作及使用的数据对并发的其他事务是隔离的,并发执行的各个事务之间不能互相干扰。持久性(Durability) 持久性是指一个事务一旦被提交,它对数据库中数据的改变就是永久性的,接下来的其他操作和数据故障不应该对其有任何影响。 4 事务的创建 分类: 隐式事务:事务没有明显的开启和结束的标记,比如:insert,update,delete 语句。显示事务:有明显的开启和结束的标记,前提:必须设置自动提交事务功能为禁用:set autocommit=0; #查看事务是否开启 SHOW VARIABLES LIKE 'autocommit'; 步骤1:开启事务 SET autocommit=0; START TRANSACTION; #可选的 步骤2:编写事务中的sql语句步骤3:结束事务 commit; 提交事务 callback;回滚事务 savepoint 节点名; 设置保存点 案例 CREATE TABLE account( id INT PRIMARY KEY AUTO_INCREMENT, username VARCHAR(20), balance DOUBLE ); INSERT INTO account(username,balance) VALUES('张无忌',1000),('赵敏',1000); #开启事务 SET autocommit=0; START TRANSACTION; #编写一组事务 UPDATE account SET balance=500 WHERE username='张无忌'; UPDATE account SET balance=1500 WHERE username='赵敏'; #结束事务 COMMIT; SELECT * FROM account 演示 savepoint 的使用

git bash shell 脚本 :从文件获取git仓库列表 git clone所有仓库

前言 如果有很多的git 仓库地址,一个个git clone 比较的繁琐,这时可以使用shell 脚本来做这件事情首先需要把所有的git 仓库的url(地址),放在一个指定的文件内,执行shell脚本,读取文件,获取所有的git clone 的地址,依次clone 功能简介 从文件获取git 仓库的列表,文件:git_urls.cfg,实例内容如下 git@gitee.com:zhangsz0516/crc16_calc.git git@gitee.com:zhangsz0516/lpms.git git@gitee.com:zhangsz0516/pm_tools.git 【备注】使用时,git 仓库地址改为自己的仓库地址依次 git clone 所有的仓库,Linux shell 脚本 cat命令,可以获取文件的内存,并且默认自动以【空白符】分隔,所以git 仓库列表使用【回车】,一行一个git 仓库地址即可 git clone all 脚本 脚本内容如下: #! /bin/bash function git_clone_all() { git_cfg="git_urls.cfg" git_url_list=`cat $git_cfg` # echo $git_url_list for url_path in $git_url_list do echo "git url : $url_path" echo "git clone $url_path" git clone $url_path --recurse-submodules echo ">>>>>>>>>>>>>>>>>>>>" done } echo "--- git clone all start ---"

Spring Boot中单独使用OpenFeign代替HttpClient/RestTemplate

背景 在Spring Boot项目中,有时候需要访问其他服务,用到的客户端技术一般是使用HttpClient或者RestTemplate封装为一个小工具类,这种方法可行,但是有些缺点: 请求的URL很分散,不一样维护响应信息需要重新反序列化 所以,有没有更好的解决方案,让我们就像controller调用service那样来直接调用其他服务,并且不需要反序列化,直接自动把响应结果封装成为一个对象? 有的!OpenFeign可以在SpringBoot中单独使用!及其方便! 说明:现在使用的是Spring Cloud亲生的OpenFeign,不是奈飞的feign! 单独使用OpenFeign 导包 <properties> <java.version>1.8</java.version> <spring-cloud.version>2020.0.5</spring-cloud.version> </properties> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>${spring-cloud.version}</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> </dependency> 开启openFeign package com.xywei.springboot.demohttp; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.openfeign.EnableFeignClients; @EnableFeignClients(basePackages = {"com.xywei.springboot.demohttp.openfeign"}) @SpringBootApplication public class DemoHttpApplication { public static void main(String[] args) { SpringApplication.run(DemoHttpApplication.class, args); } } @EnableFeignClients(basePackages = {"com.xywei.springboot.demohttp.openfeign"}) 其中的**basePackages **表示feign调用所在的包 配置openFeign接口 package com.xywei.springboot.demohttp.openfeign; import com.xywei.springboot.demohttp.entity.User; import com.xywei.springboot.demohttp.vo.BaseResult; import org.

哈希表-数据结构(C语言)

哈希表 什么是哈希表 我们在网站上注册账号时,当填好用户名后,系统都会判断用户名是否已被使用,如果已被使用,系统就会提示该用户名已被注册。那么系统是如何检测用户名是否被使用的呢?我们能想到的最简单的方法就是逐个比较,但是如果用户名有很多,查找效率就显得很低。还有一种方法就是把用户名按字典序排序进行二分查找,这个方法的效率的确是高了很多,可是前提是用户名是有序的,而有些时候我们并不能将用户名进行排序。那么还有没有更好的方法呢? 我们可以用 哈希表 来解决这个问题。哈希表又叫散列表,关键值通过哈希函数映射到数组上,查找时通过关键值直接访问数组。在上面的例子里,我们将用户名通过哈希函数映射成一个整数,也就是数组的存储位置,在检测时用同样方法计算出存储位置,如果位置上已有元素则表示用户名已经被注册。 哈希函数指的是关键值和存储位置建立的对应关系,查找时只要根据这个关系就能找到目标位置。一般我们只要通过一次查找就能找到目标位置,但有些关键字需要多次比较和查找才能找到,这是为什么呢?因为哈希表里,可能存在关键字不同但是哈希地址相同的情况,也就是产生了冲突。一般情况下,冲突是不可避免的,因为关键字集合往往比哈希地址集合大很多。 要提高哈希表的查找效率,关键在于合理的构造哈希函数和优秀的解决冲突的方法。哈希函数的构造方法有很多种,我们应该如何构造优秀的哈希函数来减少冲突呢?如果发生了冲突,我们该如何处理冲突,减少比较次数提高查找效率呢? 创建哈希表 这一课我们来学习如何创建哈希表。首先我们来定义哈希表结构体HashTable接下来我们来定义两个变量,一个是char 类型的二维指针变量 elem, 用来存储前面问题里的用户名,还有一个是int 类型的变量 size, size 表示哈希表的容量。接下来我们来实现结构体 HashTable 的初始化函数init , 函数只有一个HashTable 类型的参数h. void init(HashTable *h) { } 我们先把函数定义写好,稍后再来实现。 4. 我们在初始化函数里完成以下两个步骤: 将哈希表 h 的 size 设置为 1000, 表示哈希表的长度,然后给二维指针变量 elem 动态分配 size 个 char * 乐星的内存。 5. 接下来我们给每个元素动态分配 100 个char 类型的内存, 之后赋上初值。 由于元素都是字符串,这里我们写个for 循环,用变量i 从 0 循环到不小于 哈希表 h 的 size 时退出,把每个元素都赋为空。 在后面哈希表的查找中,我们需要判断该位置上是否已有字符串。 6. 这样我们就把结构体HashTable 的初始化函数写完了,那么现在我们在主函数里创建一个HashTable 的指针变量hashtable, 并给它分配HashTable 类型的内存。 然后调用初始化函数 init 完成对哈希表的初始化。

微信小程序真机调试regeneratorRuntime is not defined错误

原因是微信小程序代码中使用了async / await语法,语法太高级小程序编译不出来, 需要引用regeneratorRuntime这个模块。 具体操作可以新建一个文件夹,然后在这个文件夹目录上运行命令行窗口,npm init 得到一份package.json文件(一路回车,最后yes)。 安装依赖:npm i regenerator-runtime -S,在node_modules中就能得到regenerator-runtime这个文件。然后再返回你报错的小程序文件中去,在utils文件夹中导入刚才regenerator-runtime中的runtime.js文件。 最后,查找一下哪个js代码文件中使用了async / await语法,就引用该runtime.js文件。 例如:import regeneratorRuntime from './utils/runtime.js'

Docker本地搭建Hadoop高可用,Hbase,Spark,Flink,Zookeeper集群

欢迎关注微信公众号:小满锅 前期准备 安装docker yum安装 #安装 Docker $ yum -y install docker #启动 Docker 后台服务 $ service docker start 脚本安装 $ sudo yum update $ curl -fsSL https://get.docker.com -o get-docker.sh # 执行这个脚本会添加 docker.repo 源并安装 Docker。 $ sudo sh get-docker.sh 安装docker-compose # 获取脚本 $ curl -L https://github.com/docker/compose/releases/download/1.25.0-rc2/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose # 赋予执行权限 $chmod +x /usr/local/bin/docker-compose 镜像加速 打开/创建 /etc/docker/daemon.json 文件,添加以下内容: { "registry-mirrors": ["http://hub-mirror.c.163.com"] } 搭建基本容器镜像 #镜像拉取 docker pull centos7 #创建一个容器,作为基础容器,后期制作为镜像 docker run -it --name hadoopimages centos /bin/bash #将scala和jdk的包拷贝到容器里 docker cp scala-2.

Excel文件的导出操作

1.先把模板文件拉入到项目中 2. @GetMapping("exportBusinessReport") public void exportBusinessReport(HttpServletResponse response) throws Exception{ //准备数据 Map map=reportService.getBusinessReportData(); //把数据写出到Excel文件 //getClass()获取对象 //getClassLoader()获取类加载器 //getResource()//获取资源 //getPath()//获取路径 String path = this.getClass().getClassLoader().getResource("tempaltes").getPath(); path = path.substring(1); //工作簿对象---“区别XSSFWorkbook对应的是xlsx格式的文件HSSFWorkbook对应的是xls格式的文件” XSSFWorkbook workbook = new XSSFWorkbook(path+"//report_template.xlsx"); //获取到表 XSSFSheet sheetAt = workbook.getSheetAt(0); //行对象----下标以0开始 XSSFRow row2 = sheetAt.getRow(2); //单元格对象 XSSFCell cell25 = row2.getCell(5); //报表日期日期赋值 cell25.setCellValue(map.get("reportDate")+""); //把文件送到用户端 response.setHeader("content-disposition","attachment;filename=report.xlsx"); ServletOutputStream os = response.getOutputStream(); workbook.write(os); //释放资源 os.flush(); os.close(); workbook.close(); 3.导出后:

小技巧-windows命令行copy命令合并多个csv文件到一个文件中

一、准备好文件,放到一个新建的单独目录下 3个格式一样的csv文件,放到同一个目录下,例如: mytest1.csv 文件内容如下: "col1","col2","col3" "xx1111111111111111111111111111111111111","yy222222222222222222222222222222222","333333333333333333333333333333333333" mytest2.csv 文件内容如下: "col1","col2","col3" "1xx1111111111111111111111111111111111111","1yy222222222222222222222222222222222","1333333333333333333333333333333333333" mytest3.csv 文件内容如下: "col1","col2","col3" "2xx1111111111111111111111111111111111111","2yy222222222222222222222222222222222","2333333333333333333333333333333333333" 二、执行拷贝COPY命令,达到合并的目的 命令格式:copy *.csv ..\merge.csv C:\Users\Administrator\Desktop\test>copy *.csv ..\merge.csv mytest1.csv mytest2.csv mytest3.csv 已复制 1 个文件。 merge.csv文件内容如下: "col1","col2","col3" "xx1111111111111111111111111111111111111","yy222222222222222222222222222222222","333333333333333333333333333333333333""col1","col2","col3" "1xx1111111111111111111111111111111111111","1yy222222222222222222222222222222222","1333333333333333333333333333333333333""col1","col2","col3" "2xx1111111111111111111111111111111111111","2yy222222222222222222222222222222222","2333333333333333333333333333333333333" 三、处理合并后的文件重复标题部分和非法的文件结尾文本 1. 使用notepad++先全部替换 标题内容为空白,而后单独把复制一行标题到merge后的文件第一行中 2. 手动删除merge后的文件内容中的最后的特殊字符。到此为止,合并完成。文本内容效果如下: "col1","col2","col3" "xx1111111111111111111111111111111111111","yy222222222222222222222222222222222","333333333333333333333333333333333333" "1xx1111111111111111111111111111111111111","1yy222222222222222222222222222222222","1333333333333333333333333333333333333" "2xx1111111111111111111111111111111111111","2yy222222222222222222222222222222222","2333333333333333333333333333333333333"

软件开发常用的四种模式

对于一个优秀的软件开发团队来说,有效的管理开发项目,可以增强开发人员之间的协作,节省整个软件项目的开发时间,因此软件开发经理或开发团队在项目启动前,要选择一种最适合手头项目的软件开发模式,使整个团队拥有更好的工作效率,而目前主要的软件开发模式大致可以分为四种,对于软件项目来讲不同的开发模式都有各自的特点,至于哪一种的方法最合适自己,那就要看软件开发经理如何选择了。 一、瀑布开发模式 瀑布开发模式是一种传统的软件开发模式,瀑布法是一个刚性的线性模型,其中包括顺序阶段(需求,设计,实施,验证,维护),其中每一个阶段的目标性都很明确。而且在进入下一阶段之前,每个阶段目标必须100%地完成,但这种模式如果进行回溯修改时会比较麻烦。 但该方法的线性特性使其易于理解和管理。如果软件项目对稳定要求比较高,那可以选择这种开发模式。在使用瀑布开发模式时丰富的软件开发经验会比较有帮助。然而,由于刚性结构和严格的控制特点,通常会导致项目的开发时间比较慢、成本比较昂贵。 二、快速应用开发模式 快速应用开发模式是一个比较精简的软件开发流程,可以以低投资成本生产高质量的软件。这种RAD流程可以使开发人员快速适应不断变化的市场需求。快速调整的能力可以帮助企业节省开发成本。快速应用程序开发模式分为四个阶段:需求规划,用户设计,构建和切换。重复用户设计和施工阶段,直到满足用户的所有要求。 RAD对于具有明确定义的业务目标及用户组的开发项目最有效,比较适用于一些中小型软件开发项目,或者是开发时间比较紧迫的软件项目。然而,它需要技术人员具有丰富开发经验,以及要非常了解用户的核心需求。 三、敏捷开发模式 敏捷开发模式有许多不同的形式,包括:Scrum,Crystal,Extreme Programming(XP)和Feature-Driven Development(FDD)。它通过迭代开发,关注互动沟通等方法来降低软件开发过程中的风险,同时也可以减少在开发中的资源消耗。好处是通过早期发现和修复缺陷来提高开发的效率。但这种模式比较依赖用户的信息反馈,而且这种模式比较适用于小规模的软件开发公司,习惯于“瀑布法”的程序员,管理层和组织可能难以适应敏捷。 四、DevOps部署模式 DevOps部署模式增强了软件开发部门之间的协作,如开发,测试和运营。它着重于改进软件的上市时间,降低新版本的故障率,缩短BUG修复的交付时间,优先考虑最小的中断以及最大的可靠性等。 使用DevOps部署模式对提高客户满意度,提高产品质量,提高员工的生产力和效率得益(Efficiency Gain)等方面非常有用。但DevOps也有一些缺点: 有些客户不想持续更新他们的软件 一些行业在允许进入运营阶段之前,需要进行大量测试 不同部门使用的不同环境可能导致软件开发过程中一些问题不会显现出来 一些质量属性需要人为的相互作用,这会减慢软件的交付流程 这四种是软件开发最常用的模式。每个模式都有自己的优势,弱点。在选择软件项目的开发模式时希望这篇内容可以帮助到大家。 ps:微信搜一搜【争知拙见】,获取更多干货!

Apache Tomcat安装配置

Tomcat是由Apache软件基金会下属的Jakarta项目开发的一个Servlet容器。Tomcat 技术先进、性能稳定,而且免费,因而深受Java 爱好者的喜爱并得到了部分软件开发商的认可,成为目前比较流行的Web 应用服务器。 Tomcat安装方法 1、下载Tomcat后(回复tomcat获得下载链接),在电脑本地得到一个压缩包。 2、解压完成后就可以了。(记住该解压文件的存放位置,后面环境变量配置会用到) Tomcat使用方法 Tomcat环境变量配置教程 1、鼠标右键点击【这台电脑】-->选择【属性】->【高级系统设置】-->【系统变量】。 2、然后,点击“系统变量”框下的【新建】按钮。(1)新建CATALINA_BASE变量变量名:CATALINA_HOME变量值:Tomcat安装位置,即刚刚解压文件夹下bin文件所在位置。 3、新建CATALINA_HOME变量变量名:CATALINA_HOME变量值:变量值同上,填Tomcat的安装位置。 4、找到Path变量,点击编辑 变量名:Path 变量值:%CATALINA_HOME%bin。 5、打开cmd命令提示符,输入startup后回车,就可以看到Tomcat成功启动了。 tomcat怎么修改默认端口号 1、tomcat的安装路径,进去conf目录,打开server.xml文件。 2、打开server.xml文件之后,可以看到默认是8080端口。 3、您可以自行修改。 4、如果想同时使用多个tomcat的话,还需要改动8009端口,这里将端口改为18009 5、改动8005端口,这里将端口改为18005 6、重启tomcat之后,在浏览器输入“http://localhost:9999/”,打开了tomcat,代表设置成功,也可以再打开另外一个tomcat,查看两个tomcat是否都能启用。 7、如果是安装版的tomcat的话,在安装的时候,会提示设置端口 Tomcat常见问题 如何将web项目部署在tomcat上 1、将tomcat集成到eclipse中。在eclipse中的Servers上点击配置一个容器。如果这个Servers没有显示,需要通过windows--show view中勾选servers。 2、eclipse添加本地tomcat容器。点击servers下面的“create a new server” 3、或者通过windows--preferences--servers进入服务的配置. 4、在打开的preferences窗口中,在顶部的输入框输入server,然后选择Runtime,点击右侧的【add】。 5、选择自己电脑上安装Tomcat版本,选择完成后点击【next】。 6、选择Tomcat安装位置。选择完成后点击【finish】。 7、tomcat容器上添加删除web项目。在tomcat上右键“Add and Remove” 添加web项目,将项目选中到右侧。 8、启动tomcat,加载tomcat上的web工程项目。在tomcat上右键,点击“Start”,或者在工具栏上点击“start”图标启动web项目。 ps:微信搜一搜【争知拙见】,获取更多干货!