Verilog HDL有两大类数据类型:线网类型和寄存器类型
线网类型(nets type)表示Verilog结构化元件间的物理连线。它的值由驱动元件的值决定,例如连续赋值或门的输出。如果没有驱动元件连接到线网,线网的缺省值为z。
寄存器类型(register type)表示一个抽象的数据存储单元,它只能在always语句和initial语句中被赋值,并且它的值从一个赋值到另一个赋值被保存下来。寄存器类型的变量具有x的缺省值。
(1)线网类型(nets type)
线网类型包含多种类的线网子类型,其中wire是最常用的连线型变量,这里主要对其进行介绍。wire型数据常量用来表示以assign语句赋值的组合逻辑信号。
Verilong HDL 模块中的输入/输出信号类型缺省时自动定义为wire型。wire型信号可以用作任何方程式的输入,也可以用做“assign”语句和实例元件的输出。对于综合而言,其取值为0,1,X,Z。
wire 型变量的定义格式如下:
wire数据名1,数据名2,数据名3,……,数据名n; 例如:
wire a,b; //定义了两个wire型变量a,b wire型向量可按以下方式使用:
wire[7:0]in,out; //定义了两个8位wire型向量in,out assign out =in; 若只使用其中某几位,可直接指明,但应注意宽度要一致。如:
wire[7:0]out; wire[3:0]in assign out[5:2]=in; //out向量的第2到第5位与in向量相等 即等效于:Assign out[5]=in[3]
Assign out[4]=in[2];
Assign out[3]=in[1];
Assign out[2]=in[0]。
(2)寄存器类型(register type)
寄存器数据类型的reg是最常见的数据类型。reg类型使用保留字reg加以说明,形式如下:
Reg 数据名1,数据名2,……,数据名n; 例如:
reg a,b; //定义了两个reg型变量a,b reg[7:0]data; //定义data 为8位宽的reg型向量 (3)存储器
存储器是一个寄存器数组,若干个相同宽度的向量构成数组,reg型数组变量即为memory型变量,既可定义存储器型数据,如:
reg[7:0]mymem[1023:0]; //定义了一个宽度为8位、1024个存储单元的存储器,该存储器的名字是 mymem。
相信很多在做PC端项目的朋友都会遇到一个需求,就是用户在未登录状态从其他页面触发跳转到登录页,当用户登录成功后,再跳回用户原来的页面。
首先,我们来想一下完成这个需求的思路,要跳转那就要有路径,之前我们会在login登录里写登录成功后跳到home首页,那要完成这个需求的话,很显然是不能这样写的,我们都知道,vue给我们一个很好用的东西,叫做路由守卫,就是在路由跳转时,回触发相应的路由守卫。相关代码如下,
在router/index.js写:
//当路由跳转时会触发路由前置守卫
//to:表示到哪里去 from:表示从哪里来 next:表示放行继续往下走
router.beforeEach((to, from, next) => {
//判断如果要跳转到login页面
if (to.path == '/login') {
//将当前的路由路径保存
localStorage.setItem("preRoute", router.currentRoute.fullPath)
}
next()
})
那么此时我们就获取到了路由跳转来的地址
在login页面判断:注意:要判断是否为注册页面跳转 注册页面跳转登录页 不能回跳 跳到home页面
let refer = localStorage.getItem('preRoute')
if (refer != null&&refer!='/register') {
this.$router.push({ path: refer })
return
}
this.$router.push({ path: '/' })
题目来源:https://leetcode.cn/problems/words-within-two-edits-of-dictionary/
大致题意:
给两个字符串数组:查询数组和字典数组,若查询数组中元素在不超过两次编辑内可以与字典数组中的元素匹配,则表示匹配成功,返回查询数组中所有匹配成功的元素
字符串的一次编辑即为将某个字符换成任意其他字符,在本题中限定字符为小写字母
思路 因为本题的数据范围较小,直接使用哈希表存下字典数组,然后枚举查询数组元素的所有可能的编辑结果也是可以的。设查询数组长度为 n,字符串平均长度为 k,那么时间复杂度为 O(262nk2)
但是这类给定字典查询字符串的题目,更为简洁方便的实现方案应该是使用前缀树。
对于该题,首先根据字典数组生成前缀树,然后在前缀中匹配查询数组中的元素
因为该题允许两次编辑,所以前缀树的搜索方法需要做出改变,即在前缀树的搜索方法中加上当前可用的编辑次数,若在匹配字符串过程可以根据当前剩余编辑次数决定下一步操作:
若编辑次数大于 0,则当前字符串的匹配结果可以为在当前树节点的所有子节点中匹配剩余子串的结果进行或运算得到的,即只要有一个子节点匹配成功即可。若所有子节点都未匹配成功,则进入下一步若当前字符对应的子节点为空,则表示匹配失败,返回结果;否则进入下一步将当前节点更新为字符对应的子节点 那么解题思路可以概括为
初始化前缀树将字典数组元素插入前缀树在前缀树中匹配查询数组中的元素,若匹配成功则放入答案数组 代码:
public class TwoEditWords { public List<String> twoEditWords(String[] queries, String[] dictionary) { List<String> ans = new ArrayList<>(); // 初始化前缀树 Trie trie = new Trie(); // 将字典数组元素插入前缀树 for (String str : dictionary) { trie.insert(str); } // 在前缀树中匹配查询数组中的元素 for (String query : queries) { // 若匹配成功则放入答案数组 if (trie.search(query, 2)) { ans.add(query); } } return ans; } // 前缀树节点类 class Trie { Trie[] children; boolean isEnd; // 表示当前节点是否是某个单词的结尾 public Trie() { children = new Trie[26]; isEnd = false; } // 将 word 插入当前节点 public void insert(String word) { Trie trie = this; for (int i = 0; i < word.
异常处理器 文章目录 异常处理器前言零、前置知识一、异常处理器之XML配置二、异常处理器之注解配置总结 前言 本文也是对于如何配置异常处理器的两种方式,xml和注解来分开讲解
零、前置知识 你一定见过这样的页面,当然也是很常见了,有时候会因为一点疏忽导致各种各样的错误。
但是如果是以这样的页面直接展示给用户,肯定是很不友好的,自然用户体验也是十分差。这时候就需要有自定义异常处理器,对于出现的异常进行处理和展示更好的信息反馈给用户,让用户体验上升。
SpringMVC提供了一个处理控制器方法执行过程中所出现的异常的接口:HandlerExceptionResolver
HandlerExceptionResolver接口的实现类有:DefaultHandlerExceptionResolver和SimpleMappingExceptionResolver(自定义)
一、异常处理器之XML配置 exceptionMappings异常的映射 将prop中配置的异常key于值error形成映射关系,如果出现了该异常类的异常,properties的键表示处理器方法执行过程中出现的异常,properties的值表示若出现指定异常时,设置一个新的视图名称,跳转到指定页面
exceptionAttribute则是将异常信息共享在请求域中,value值则是用于存储异常信息的
<!--配置异常处理器--> <bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver"> <property name="exceptionMappings"> <props> <prop key="java.lang.ArithmeticException">error</prop> </props> </property> <!--设置将异常信息共享在请求域--> <property name="exceptionAttribute" value="ex"></property> </bean> 二、异常处理器之注解配置 prop操作properties配置文件时是不能使用put和get方法的 因为put和get操作的是Object类型,响应给页面的只能是字符串,Properties主要是操作配置文件的,配置文件也只能接受字符串的参数,Object类型的自然是不行的
//@ControllerAdvice将当前类标识为异常处理的组件 @ControllerAdvice public class ExceptionController { //@ExceptionHandler用于设置所标识方法处理的异常 @ExceptionHandler(ArithmeticException.class) //ex表示当前请求处理中出现的异常对象 public String handleArithmeticException(Exception ex, Model model){ model.addAttribute("ex", ex); return "error"; } } @ControllerAdvice 将当前类标识为异常处理的控制层组件,需要搭配@ExceptionHandler(异常类的Class)-----》绑定真正执行该异常的方法
形参中的ex用于存储异常的信息 model则是共享域中的数据,用于最后渲染页面的数据
总结 本文也算是配置的方式讲解,由于我也是小菜,后续会对文章进行加强,自然也很需要大家的监督,对于文章提出不足,会乐于采取大家的意见,进行整改
PDF文件我们经常在办公和学习中使用,遇到需要打印的PDF文件时,怎么才能打印出来呢?很多小伙伴自己有打印的设备,但是对打印文件的参数不知道如何设置,这要还是去店里打印,简直就是浪费钱财,今天教大家两种打印PDF文件的方法,一起来学习一下吧。
打印方法一
第一种将PDF文件打印出来的方法是使用这个PDF转换助手,虽然这个工具主要是用来转换文件格式的,但它也有很多其它的实用功能哦,如我们就可以使用它来打印文件,下面来看看具体步骤吧。
① 首先,在电脑上打开软件,点击选择【PDF编辑】,进入后将需要打印的PDF文件添加进来。
② 文件添加进来后,页面上方有一些编辑工具可以使用,其中就有打印功能,点击【打印】。
③ 点击打印后,在弹出的窗口中点击【首选项】,这里我们可以设置文件打印的方向,设置好后点击【确定】。
④ 最后,把文件需要打印的页面范围和份数进行设置,最后点击【打印】,文件就会打印出来啦。
打印方法二
第二种打印方法是使用一个专业的PDF编辑工具来打印文件,这个工具对PDF文件的编辑功能很强大,大家在电脑上或者是手机上都能够操作,下面来看看具体是如何打印的吧。
① 首先,打开软件,把PDF文件添加进来后,点击上方的【打印】。
② 在弹出的窗口中,点击【页面设置】,可以选择打印的纸张、打印方向和边距,设置好后点击【确定】。
③ 最后,可以在页面中把文件需要打印的范围进行选择,也支持页面的缩放功能,把所有的参数都设置好后,就可以点击右下角的【打印】,这样PDF文件就会按我们设置的那样打印出来啦。
以上就是给大家分享的两种如何打印PDF文件的方法啦,非常的简单方便,有需要打印文件的小伙伴可以去尝试一下,希望可以帮助到你。
1、先下载linux版本的jdk压缩包,示例压缩包为:jdk-8u151-linux-x64.tar.gz(推荐java8版本)
下载地址:https://www.oracle.com/java/technologies/downloads/
2、 使用WinSCP工具(工具无限制,只要能上传到服务器就行)上传jdk压缩包到服务器存放路径,示例路径为:/data/read_business_world/jdk
3、移动至jdk压缩包存放路径解压文件,依次执行命令如下
移动至存放目录:cd /data/read_business_world/jdk/
解压压缩包(会获得对应的jdk文件,如jdk1.8.0_151,可根据需求改名):tar -zxvf jdk-8u151-linux-x64.tar.gz
4、配置jdk环境变量路径,依次执行命令如下
修改系统配置文件:vi /etc/profile
将以下内容加入profile文件中:
# jdk环境变量路径 export JAVA_HOME=/data/read_business_world/jdk/jdk1.8.0_151 export JRE_HOME=${JAVA_HOME}/jre export CLASSPATH=.:${JAVA_HOME}/lib:${JRE_HOME}/lib:$CLASSPATH export JAVA_PATH=${JAVA_HOME}/bin:${JRE_HOME}/bin export PATH=$PATH:${JAVA_PATH} 保存配置成功后,使文件生效:source /etc/profile
5、查看jdk版本,查看是否安装成功,依次执行命令如下
查看jdk版本(如出现jdk版本即安装成功):javac -version
Source map 学习攻略_番茄出品 start 事情的起因:番茄我最近在学习如何调试 JavaScript,发现高频出现 Source map,但是我对它又不是很了解,经常造成学习上的阻塞。随即就开始深入学习 Source map, 学习完毕,到如今写一篇博客记录收获。 一、从源码转换讲起 随着时代的发展,JavaScript 脚本正变得越来越复杂。大部分源码(尤其是各种函数库和框架)都要经过转换,才能投入生产环境。
常见的源码转换,主要是以下三种情况:
(1)压缩,减小体积。比如 jQuery 1.9 的源码,压缩前是 252KB,压缩后是 32KB。 (2)多个文件合并,减少 HTTP 请求数。 (3)其他语言编译成 JavaScript。 这三种情况,都使得线上实际运行的代码不同于开发时的代码,调试代码排查问题就变得困难重重。
通常,JavaScript 的解释器会告诉你,第几行第几列代码出错了。但是,这对于转换后的代码毫无用处。举例来说,jQuery@1.9 压缩后只有 3 行,每行 3 万个字符,所有内部变量都改了名字。你看着报错信息,感到毫无头绪,根本不知道它所对应的原始位置。
这就是 Source map 想要解决的问题。
编译后的 Vue.js 的源码
二、什么是 Source map 简单来说 Source map 就是一个存储信息的文件,里面储存着位置信息。
Source map 英文释义:源程序映射。位置信息:转换后的代码 对应的 转换前的代码 位置映射关系。 有了 Source map,就算线上运行的是转换后的代码,调试工具中也可以直接显示转换前的代码。这极大的方便了我们开发者调试和排错。
三、如何使用 Source map 只要在转换后的代码尾部,加上一行如下代码即可。
//# sourceMappingURL=main.js.map 注意
= 后的名称,依据对应 map 文件名定义;map 文件可以放在网络上,也可以放在本地; 四、如何生成 Source map 4.
目录
一,什么是结构体
二,如何定义结构体
三,如何使用结构体变量
1.结构体变量的赋值和初始化
2.如何取出结构体变量中的每一个成员
3.通过函数对结构体变量进行输入和输出 4.结构体变量的运算
一,什么是结构体 结构体(struct)是由一系列具有相同类型或不同类型的数据构成的数据集合,也叫结构。把一些基本数据类型组合到一起形成的一个新的复合数据类型,结构体和其他类型基础数据类型一样,例如int类型,char类型只不过结构体可以做成你想要的数据类型,以方便日后的使用。
什么时候我们需要使用结构体呢
在实际问题中有时候我们需要几种数据类型一起来修饰某个变量。例如一个学生的信息就需要成绩(浮点型),性别(字符),年龄(整形)等等。这些数据类型都不同但是他们又是表示一个整体,要存在联系,那么我们就需要一个新的数据类型。
#include<stdio.h> int main (void) { int age; float score; char sex; int age2; float score2; char sex2; return 0; } 上方程序定义了两个学生的成绩,年龄,性别,但我们所希望的是有一个变量可以同时储存一个学生的成绩,年龄,性别(均为基本类型变量),因为当同时定义多个学生的上方信息时,由于它并不是一个有机整体,可能会导致输入信息的错乱(例如:同学1的年龄可能会和同学2的成绩可能会放入同一个整体),为了表示一些复杂数据,而基本类型变量无法满足我们的需求,这时就需要定义一个结构体。
二,如何定义结构体 定义结构体相当于定一个一个新的数据类型,而不是在定义变量。
第一种方式(推荐):
struct student { int age; float score; char sex; }; 第二种方式:
在定义结构体数据类型的同时,定义变量名,但这个只能定义一次,第二次想使用结构体时就会出问题。
struct student { int age; float score; char sex; }st; 第三种方式:
这种方式也可以定义结构体,但是未说明数据类型名,后续使用会不方便。
struct { int age; float score; char sex; }st; 如上我们使用第一种方式定义了一个struct student数据类型,他其中就包括一个学生的成绩,年龄,性别这三个基本变量,在主函数中,我们就可以使用这个结构体数据类型来定义变量。
题目来源:https://leetcode.cn/problems/next-greater-element-iv/
大致题意:
给一个数组,求出每个位置之后大于当前元素的第二个元素值,如果没有则为 -1
比如数组 [1, 2, 4, 3],索引 0 之后大于 1 的第二个元素值为 4,索引 1 之后大于 2 的第二个元素值为 3,剩下两个位置右侧没有满足要求的值
思路 使用单调栈可以求出大于当前位置的第一个元素值,那么如何求出第二个值呢
可以通过套娃单调栈来实现
首先使用维护一个非递增的单调栈,在遍历数组更新单调栈的过程中,如果当前元素大于单调栈栈顶元素,则表明当前元素是单调栈栈顶元素右侧的第一个更大元素。此时,弹出单调栈栈顶元素入辅助栈,也就是每次将单调栈弹出元素放入辅助栈。
那么,辅助栈中的元素都已经遇到了右侧第一个更大元素。于是可以在遍历数组时,判断辅助栈是否为空,在辅助栈不为空时,可以判断当前位置元素是否大于辅助栈中元素,若大于,则表明在辅助栈中的这些元素遇到了右侧第二个更大元素
具体实现时,因为辅助栈无需关注入栈顺序,更关注元素值的大小,所以使用优先队列更为合适
那么解题思路可以概括为:
初始化单调栈和辅助队列,栈和队列存储的都是元素在数组中的索引。初始化答案数组元素都为 -1遍历数组当辅助队列不为空时,判断当前遍历元素与辅助队列最小值的关系,若当前元素大于辅助队列最小值,则队首元素出队,并更新对应索引的第二个更大元素。重复这个过程直至辅助队列为空或者当前遍历元素不大于辅助队列最小值当单调栈不为空,判断当前遍历元素是否大于栈顶元素,若大于则弹出栈顶元素入辅助队列,重复这个过程直至单调栈为空或者当前遍历元素小于等于栈顶元素将当前元素索引放入单调栈重复 2 - 5 步,直至遍历结束 代码:
public int[] secondGreaterElement(int[] nums) { int n = nums.length; // 单调栈 Deque<Integer> firstStack = new ArrayDeque<>(); // 辅助队列,队列元素按照数组中的值升序排序 PriorityQueue<Integer> secondQueue = new PriorityQueue<>((a, b) -> nums[a] - nums[b]); // 初始化答案数组 int[] ans = new int[n]; Arrays.fill(ans, -1); // 遍历数组 for (int i = 0; i < n; i++) { // 如果辅助队列不为空,且当前元素大于辅助队列最小值 while (!
我是 Redis, 当程序员用指令 ./redis-server /path/to/redis.conf 把我启动的时候,第一个参数必须是redis.conf 文件的路径。
这个文件很重要,就好像是你们的 DNA,它能控制我的运行情况,不同的配置会有不同的特性和人生,它掌握我的人生命运,控制着我如何完成高可用、高性能。合理的配置能让我更快、更省内存,并发挥我最大的优势让我更安全运行。
以下这些配置大家必知必会,需要大家掌握每个配置背后的技术原理,学会融合贯通并在生产中正确配置,解决问题。避免出现技术悬浮,原理说的叭叭叭,配置像个大傻瓜。
本文配置文件版本是 Redis 7.0。
1.1 常规通用配置 这些是我的常规配置,每个 Redis 启动必备参数,你一定要掌握,涉及到网络、模块插件、运行模式、日志等。
MODULES 这个配置可以加载模块插件增强我的功能,常见的模块有 RedisSearch、RedisBloom 等。关于模块加载可以参考【5.6 布隆过滤器原理与实战】章节集成布隆过滤器便是通过以下配置实现加载布隆过滤器插件。
loadmodule /opt/app/RedisBloom-2.2.14/redisbloom.so NETWORK 这部分都是与网络相关的配置,很重要滴,配置不当将会有安全和性能问题。
bind bind用于绑定本机的网络接口(网卡),注意是本机。
每台机器可能有多个网卡,每个网卡都有一个 IP 地址。配置了 bind,则表示我只允许来自本机指定网卡的 Redis 请求。
❝ MySQL:“bind 是用于限制访问你的机器 IP 么?”
非也,注意,这个配置指的并不是只有 bind 指定的 IP 地址的计算机才能访问我。如果想限制指定的主机连接我,只能通过防火墙来控制,bind 参数不也能起到这个作用。
举个例子:如果我所在的服务器有两个网卡,每个网卡有一个 IP 地址, IP1,IP2。
配置 bind IP1,则表示只能通过这个网卡地址来的网络请求访问我,也可以使用空格分割绑定多个网卡 IP。
我的默认配置是bind 127.0.0.1 -::1 表示绑定本地回环地址 IPv4 和 Ipv6。- 表示当 ip 不存在也能启动成功。
protected-mode ❝ MySQL:网络世界很危险滴,你如何保证安全?
默认开启保护模式,如果没有设置密码或者没有 bind 配置,我只允许在本机连接我,其它机器无法连接。
本文旨在介绍,如何从零开始写Makfile,实现多文件、多目标、多级目录的代码编译。
目录
一、Makefile基础
1、编写c代码
2、编写Makefile
3、编译 & 执行 & 清除编译产物
二、多个依赖文件编译
1、编写一个头文件public.h
2、编写一个新的c文件main_lib.c
3、修改main.c
4、修改Makefile
5、编译 & 执行 & 清除编译产物
三、同一目录生成多个目标文件
1、新增一个main1.c
2、修改Makefile
3、编译 & 分别执行 & 清除编译产物
四、静态库文件(.a文件)的编译打包和链接
1、更改代码目录结构
2、修改 lib 目录下的 main_lib.c
3、编写 lib 目录下的 Makefile
4、编写 bin 目录下的 Makefile
5、编译lib & 编译bin & 执行可执行文件 & 清除编译产物
五、多层目录递归编译
1、在根目录下编写 Makefile 文件
2、编译 & 清理编译产物
六、参考
一、Makefile基础 1、编写c代码 编写一个简单的main.c就行
#include <unistd.h> #include <stdio.h> int main(void) { printf("Hello world!\n"); return 0; } 2、编写Makefile 同级目录下创建一个文件,名称为Makefile(建议文件名称就固定为Makefile)
简介 是一个vue官方出品的 管理组件切换 的 插件
路由,用来找路。管理路径之间的切换,不同url对应不同的组件核心思想:在同一个页面根据url进行组件切换,类似动态组件, 最终在 router-view 处出口路由一般最多3级版本对应: vue2 对应 v3.x | vue3 对应 v4.x 区分路由 前端路由 (hash路由)
在同一个html页面, 显示不同的内容(组件). 进而建立了URL和组件之间的对应关系
在同一个页面, 借助锚链接实现同一页面的不同部分的跳转
第一章: http://localhost:5500/index.html#chap1
第二章: http://localhost:5500/index.html#chap2
像#chap1, #chap2...这样的锚链接, 也叫做hash路由 也称为前端路由
后端路由
提供接口(数据)服务, 将不同请求方式+url, 映射到处理函数. 建立了URL和处理函数之间的对应关系
入门案例🟢 Vue三步
引入vue.js创建页面容器实例vue实例 VueRouter
引入vue-router.js定义组件对象定义路由规则routes route: 路由规则, URL和组件的对应关系routes: 由路由规则组成的数组 定义创建路由对象router 用于管理路由规则 挂载router到根实例 改造html
编写路由链接 router-link编写路由出口 router-view <!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> <!
0 四种方式 父子传参事件总线 busprovided/injectedVuex 1 父子组件通信 父传子props, 子传父$emit
2 兄弟 通过父组件转发
老大->父组件->老二 (单向)
One.vue 老大提交自定义事件 <template> <div> 老大子组件: <input type="text" v-model="msg" /> <button @click="$emit('send',msg)">发送</button> </div> </template> <script> export default { name: 'One', data() { return { msg: '' } }, } </script> Two.vue 老二接收参数 <template> <div>老二子组件: {{ msg }}</div> </template> <script> export default { name: 'Two', props: { msg: { type: String }, }, } </script> App.vue 父组件监听自定义事件 <template> <div id="
1. C2的基础 什么是C2? C2, Command and Control, 命令与控制。主要是指攻击者通过与恶意软件的交互,对被害者进行控制,从而实施恶意活动的含义。从语义上来讲,C2即可用作为名词(基础设施)也可以作为动词(交互的行为),例如C2服务器(名词做定语)、攻击者进行C2。
什么阶段会有C2? 对于我这种新手来说,在面试的时候被问到一个问题,就是C2是在什么阶段进行的。当时脑子一下子有点懵,觉得C2不是就在中马后进行嘛。后在才想明白,这个问题其实背后考察的是对基本的攻击链路熟悉情况。我们先从杀伤链上来讲,主要分为以下的步骤:
侦查(Reconnaissance)武器化(Weaponization)散布/载荷投递(Delivery)恶用/漏洞利用(Exploitation)设置/驻留(Installation)命令与控制(Command & Control)目标达成/恶意活动(Action on Objectives) C2的作用是什么? 以上的这种杀伤链是适用于普遍的网络入侵的,但在APT攻击中,APT攻击的目的往往不是为了破坏,而是为了窃密、监听[1]。
因此,在APT攻击中,C2通信常会有以下的用处:
用于攻击者的指令下发用于资源下发和数据上传 因此C2架构的总体作用可以理解为:
C2 架构也就可以理解为,恶意软件通过什么样的方式获取资源和命令,以及通过什么样的方式将数据回传给攻击者。[1]
2. C2的技术 从使用的协议上进行分类 HTTP/HTTPSFTPDNSSMTP
文章目录 一.简介1.1 集成学习1.2 随机森林 二.集成学习—投票分类器2.1 概念2.2 代码实现 三.集成学习—bagging和pasting3.1 简介3.2 Scikit-Learn中使用bagging和pasting3.3 包外评估3.4 随机补丁和随机子空间 四.集成学习—随机森林4.1 简介4.2 API使用4.3 极端随机树4.4 特征重要性 五.集成学习—提升法Boosting5.1 简介5.2 AdaBoost5.2 AdaBoost原理解析5.3 AdaBoost的API使用5.4 梯度提升5.5 梯度提升原理5.6 梯度提升API使用 一.简介 1.1 集成学习 一群人的智慧总是比一个人强,这就是集成学习的核心思想。如果你聚合一组预测器(比如分类器或回归器)的预测,得到的预测结果也比最好的单个预测器要好。这样的一组预测器称为集成,这种技术也叫集成学习。
1.2 随机森林 我们训练一组决策树分类器,每一棵树都基于训练集不同的随机子集进行训练。做出预测时,只需要获得所有树各自的预测,然后得票最多的类别作为预测结果。这样一组决策树的集成被称为随机森林,随机森林是迄今可用的最强大的机器学习算法之一。
二.集成学习—投票分类器 2.1 概念 如果我们已经训练好了一些分类器,并且每个分类器的准确率都比较客观,为了创建一个更好的分类器,最简单的方法就是聚合每个分类器的预测,然后将的票最多的结果作为预测类别。这种大多数投票分类器称为硬投票分类器。事实上,即使每个分类器都是弱学习器(意味着它的的预测效果只比随机预测好一点),通过集成依然可以实现一个强学习器
当预测器尽可能相互独立时,集成方法的效果最优。获得多种分类器的方法之一就是使用不同的算法进行训练(例如逻辑回归、SVM、Knn等)。这会增加它们犯不同类型错误的机会,从而提高集成的准确率。
2.2 代码实现 使用到了随机森林、SVM和逻辑回归来集成一个投票分类器
from sklearn.ensemble import RandomForestClassifier #随机森林分类器 from sklearn.ensemble import VotingClassifier #投票分类器 from sklearn.linear_model import LogisticRegression from sklearn.svm import SVC from sklearn.datasets import load_iris from sklearn.model_selection import train_test_split from sklearn.metrics import accuracy_score iris=load_iris() #加载数据集 X_train, X_test, Y_train, Y_test = train_test_split(iris.
目录 1. 使用CUDA_VISIBLE_DEVICES
2. 使用cuda()和torch.cuda.set_device()
3. 使用device
4. 使用torch.nn.DataParallel
1. 使用CUDA_VISIBLE_DEVICES 使用CUDA_VISIBLE_DEVICES设置显卡https://blog.csdn.net/qq_43307074/article/details/127659967 2. 使用cuda()和torch.cuda.set_device() torch.cuda常用指令https://blog.csdn.net/qq_43307074/article/details/127628498?spm=1001.2014.3001.5501方法1和方法2可以同时使用,比如在运行代码时使用:
CUDA_VISIBLE_DEVICES=2,3 python test.py 而在代码内部又指定:
model.cuda(1) 那么model会在GPU3上运行。原理是CUDA_VISIBLE_DEVICES遍历当前可见的设备,并从零开始为可见设备编号。CUDA_VISIBLE_DEVICES使得只有GPU2,3可见,程序就会把这两张显卡编号为GPU0,1,2,3,cuda(1)把model加载到了GPU1上,则实际使用的显卡是GPU3。
如果利用.cuda()或torch.cuda.set_device()把模型加载到多个显卡上,而实际上只使用一张显卡运行程序的话,那么程序会把模型加载到第一显卡上,在运行代码时使用:
CUDA_VISIBLE_DEVICES=2,3 python test.py 而在代码内部又指定:
model.cuda('cuda:1,0') 那么model会在GPU3上运行。
3. 使用device 3.1. 检查所用的device import torch x = torch.tensor([[1,2,3],[4,5,6]]) print(x.device) 3.2. 模型/数据指定GPU,具体有以下几种形式: import torch cuda = torch.device('cuda:0'/'cuda') x = torch.tensor([1,2,3],device = cuda) print(x.device) import torch device = torch.device('cuda:0'/'cuda') x = torch.rand((4,5)).to(device) print(x.device) import torch x = torch.tensor([1,2,3],device = torch.device('cuda:0'/'cuda') print(x.device) import torch device = torch.
1.1 .Sql注入攻击原理 SQL注入漏洞可以说是在企业运营中会遇到的最具破坏性的漏洞之一,它也是目前被利用得最多的漏洞。要学会如何防御SQL注入,首先我们要学习它的原理。
针对SQL注入的攻击行为可描述为通过在用户可控参数中注入SQL语法,破坏原有SQL结构,达到编写程序时意料之外结果的攻击行为。其成因可以归结为以下两个原因叠加造成的:
程序编写者在处理应用程序和数据库交互时,使用字符串拼接的方式构造SQL语句。未对用户可控参数进行足够的过滤便将参数内容拼接进入到SQL语句中。
注入攻击的本质,是把用户输入的数据当做代码执行。这里有两个关键条件:用户能够控制输入。
原本程序要执行的代码,拼接了用户输入的数据。
1.2 .Sql审计方法 手动找的话,可以直接找到sqlmapper.xml文件或者直接搜索 select、update、delete、insert “String sql=”等关键词,定位SQL xml配置文件。
如果 sql 语句中有出现 $ 进行参数拼接,则存在SQL注入风险。
当找到某个变量关键词有 SQL 注入风险时,可以再根据调用链找到该存在注入风险的业务逻辑代码,查看参数来源是否安全、是否有配置SQL危险参数过滤的过滤器,最终确认是否存在SQL注入。以下给出可能造成sql注入攻击的关键字,审计时可根据实际情况进项查找
常见SQL语句关键词
关键词解释ResultSet数据库结果集的数据表,通常通过执行查询数据库的语句生成。executeQuery执行查询select数据库中的查询关键字insert数据库中的插入关键字update数据库中的修改关键字delete数据库中的删除关键字where数据库中的条件关键字union数据库中的联合查询关键字drop数据库中的删除数据库关键字create数据库中的创建数据库关键字count数据库中的返回匹配行数关键字java.sql.Connection与特定数据库的连接类Statement是 Java 执行数据库操作的重要接口jdbcTemplate最基本的Spring JDBC模板PreparedStatement预编译的 SQL 语句的对象queryForInt数据库查询方法关键字queryForObject数据库查询方法关键字queryForMap数据库查询方法关键字getConnection获取sql连接outfile数据库中把表数据导出关键字load_file数据库中导入数据的关键字 【一一帮助安全学习,所有资源一一】
①网络安全学习路线
②20份渗透测试电子书
③安全攻防357页笔记
④50份安全攻防面试指南
⑤安全红队渗透工具包
⑥网络安全必备书籍
⑦100个漏洞实战案例
⑧安全大厂内部教程
1.3Sql注入漏洞危害 1 、 攻击者可以做到
业务运营的所有数据被攻击对当前数据库用户拥有的所有表数据进行增、删、改、查等操作若当前数据库用户拥有file_priv权限,攻击者可通过植入木马的方式进一步控制DB所在服务器若当前数据库用户为高权限用户,攻击者甚至可以直接执行服务器命令从而通过该漏洞直接威胁整个内网系统 2、可能对业务造成的影响
① 用户信息被篡改
② 攻击者偷取代码和用户数据恶意获取
线上代码被非法篡改,并造成为恶意攻击者输送流量或其他利益的影响
1.4 Sql注入漏洞代码示例 Java 代码动态构建 SQL Statement stmt = null; ResultSet rs = null; try{ String userName = ctx.getAuthenticatedUserName(); //this is a constant String sqlString = "
问题描述 因为addressable的加载顺序是随机的,一直没想到怎么定义加载顺序,看到别人写的代码突然有的想法,比较笨拙简单,思路就是通过判断需要先加载的ab包是否加载成功,再决定是否加载下一个需要加载的ab包
解决方案: 参考代码思路:
//音效的加载 AssetBundle bundle = AssetBundle.LoadFromFile(path);//加载AssetBundle资源 AudioClip clip = bundle .GetAsset<AudioClip>(); //加载音效文件 if(clip.LoadAudioData()) //如果ab包加载成功 Debug.Log("音频已成功加载");//这里可以继续加载下一个需要加载的ab包 else{ DebugLogError("音效加载失败"); return; } //将clip赋给AudioSource使用播放... //音效的卸载 //当clip音效被AudioSource播放完成后 if(clip.UnloadAudioData()) Debug.Log("音效卸载成功"); else Debug.LogError("音效卸载失败");
一、简介 vue-admin-template是基于vue-element-admin的一套后台管理系统基础模板(最少精简版),可作为模板进行二次开发。
GitHub地址:GitHub - PanJiaChen/vue-admin-template: a vue2.0 minimal admin template
建议:你可以在 vue-admin-template 的基础上进行二次开发,把 vue-element-admin当做工具箱,想要什么功能或者组件就去 vue-element-admin 那里复制过来。
二、使用 修改项目名称 vue-admin-template 改为 “自己定义的项目名称”
解压压缩包
进入目录
cd “自己的项目名称下”
安装依赖
npm install
启动。执行后,浏览器自动弹出并访问http://localhost:9528/
npm run dev
三、源码目录结构 |-dist 生产环境打包生成的打包项目
|-mock 产生模拟数据
|-public 包含会被自动打包到项目根路径的文件夹
|-index.html 唯一的页面
|-src
|-api 包含接口请求函数模块
|-table.js 表格列表mock数据接口的请求函数
|-user.js 用户登陆相关mock数据接口的请求函数
|-assets 组件中需要使用的公用资源
|-404_images 404页面的图片
|-components 非路由组件
|-SvgIcon svg图标组件
|-Breadcrumb 面包屑组件(头部水平方向的层级组件)
|-Hamburger 用来点击切换左侧菜单导航的图标组件
|-icons
|-svg 包含一些svg图片文件
|-index.js 全局注册SvgIcon组件,加载所有svg图片并暴露所有svg文件名的数组
|-layout
|-components 组成整体布局的一些子组件
|-mixin 组件中可复用的代码
月份的选择,初始化当前月,前进切换到前一个月,后退后退到后一个月。
1、初始化当前月份的日期,放到数组dayArr里
2、计算当前月份的第一天是星期几
3、计算当前月份有几天
4、计算前一个月最后一天是几号
5、补齐页面显示前一个月的日期
6、补齐页面显示后一个月的日期
7、详细步骤在js注释
页面效果图
代码部分
<template> <div class="monthPage"> <div class="calendar"> <!-- 星期 --> <div class="weekBox"> <div v-for="(item, index) in dayArr" :key="index" class="weekTit"> {{ item }} </div> </div> <!-- 天数 --> <div class="itemBox" id="dateBox"> <div v-for="(item, index) in dateArr" :key="index" class="dateItem"> <!-- 本月日期--> <div class="dateNo">{{ item.No }}</div> <!-- 非本月日期 --> <div v-show="!item.show" class="oneLabel noData"> <div class="dateNo">{{ item.No }}</div> </div> </div> </div> </div> </template> <script> import { onMounted, reactive, toRefs, watch } from "