安装方式 1.我们学任何一门语言如果不会怎么办当然是去他的官网下面是官网地址https://nodejs.org
2.***淘宝镜像https://npm.taobao.org/mirrors/node***这里面有这个node的js安装包
3.Windows安装https://nodejs.org/zh-cn/download/
安装完毕后 打开cmd 执行node -v就会显示版本这样则安装成功 下面我们了解一下Nodejs是什么我们看一下官方说法 作为异步事件驱动的JavaScript运行时,Node旨在构建可伸缩的网络应用程序。 在下面的“hello world”示例中,可以同时处理许多连接。 在每次连接时都会触发回调,但是如果没有工作要做,Node将会休眠。
NodeJs是否是单线程 不是,主线程Javascript线程是单线程,libuv提供线程池,NodeJs不仅仅是一个Javascript引擎,而是一套运行时,不能将Javascript线程孤立出来。
NodeJs优缺点以及适合的场景 由于主线程Javascript线程是单线程,所以主线程不能做CPU密集操作(比如什么加解密之类的,这种操作只能有Javascript线程运行,会阻塞事件循环),所以NodeJs适合I/O密集场景,比如常见的(TCP/HTTP服务器)
对于前端开发者来说,几乎没有语言门槛
跨平台,NodeJs在主流操作系统都有对应的二进制程序
标准库强大,第三方库也很多,降低了造轮子成本
易于部署,服务器安装一个NodeJs程序配合NPM包管理器即可运行,不用像PHP那样还要安装扩展,配置前端HTTP服务器
步骤 第一步导入http模块 const http = require("http"); 第二部创建http服务 const server = http.createServer((request, response) => { }) 第三部开启服务器(开启监听) server.listen("4399",() => { console.log("success"); }) 下面来实操一下 1.创建index.js
2.编写代码
const http = require('http'); const server = http.createServer((req, res) => { console.log(req.method, req.url) //req.method 本次请求的请求方法,有GET/POST/PUT //req.url 本次请求的路径(不包含域名) res.end("你好") //res.end 输出数据并结束本次响应 }) server.listen(8080, () => console.
python可由win32com.client模块连接kepserver,用于读取工业设备数据。连接使用的参数是opcServer名称、IP地址,这里提供一个连接测试程序:
import logging from win32com.client import gencache logging.basicConfig(level='DEBUG') logger = logging.getLogger('dll_dispatch') OPC_DA_DLL = gencache.EnsureModule('{28E68F91-8D75-11D1-8DC3-3C302A000000}', 0, 1, 0) #需注册OPCDAAuto.dll opcServer = OPC_DA_DLL.OPCServer() def getOpcServer(): node = '127.0.0.1' for svr in opcServer.GetOPCServers(node): print(svr) def connectOpc(progID): node = '127.0.0.1' opcServer.Connect(progID, node) logger.info('已连接到opc - [{}:{}]'.format(node, progID)) if __name__ == '__main__': # 获取本机可用的opcserver getOpcServer() # 连接KepServer progID = input("KEPServer ID:") connectOpc(progID) opcServer.Disconnect() input() 程序输出了本机可用的opcServer名称,选择一个输入回车,完成连接测试:
九宫格布局在制作一些Web App时还是经常可以用到的,本篇文章带大家了解一下CSS九宫格布局的几大实现方法。有一定的参考价值,有需要的朋友可以参考一下,希望对大家有所帮助。
前提说明
除非特别说明,以下几种方式的通用html结构如下:
123456789 除特别说明,布局中用到的css reset代码如下:/* 基础 */
.box{
background: #e4f7fd61;
border: 2px solid #0786ada1;
border-radius: 8px;
}
ul{
padding: 0;
}
.box li{
list-style: none;
text-align: center;
line-height: 200px;
background: rgba(146, 203, 230, 0.65);
border-radius: 8px;
}
方法一、margin负值实现
原理margin负边距
关键点1. 最外层的包裹元素等于:li宽度*3+li右间距*2
2. 如果li是右间距,则ul的margin-right为负的li间距值。
3. 父元素ul使用overflow:hidden;形成bfc,以清除浮动带来的影响(父元素塌陷)。
4. margin-bottom和margin-top的配合,是同right的理的,消除最后一排li撑开的底边距。
5. li要浮动。外边距方向和ul设置负值的外边距方向一致。
关键代码.box{
width: 940px;
}
ul{
overflow: hidden;
margin-right: -20px;
margin-bottom: -20px;
margin-top: 0;
}
.box li{
float: left;
table的宽度是自适应的,而且部分TD是固定宽度。原则上应该讲table的宽度设置成一个固定的值,而不应该设置成一个根据屏幕变化的值。现在来看下如何设置表格td单元格的宽度。
例1:Table的宽度为600px,Table的td所有宽度总和不到600px,浏览器会自动按照td的宽度的比例算出宽度
我是200px我也是200px 运行结果:两个td都是300px;
Table的宽度为600px,前两个td的宽度已经为600px,那么第三个td的宽度没有指定,这样的话第三个td的宽度是根据内容出现宽度的,然后前两个再按照比列计算宽度。
例2:前两个td小于table宽度,那么最后一个td就起到补全的作用
我是200px我也是200px我是根据内容的 例3:Table中的td内,如果放置块状元素超过td的宽度,并且table的table-layout: fixed;(fixed表示td的宽度是定长的,不随td内容变化而变化)。这样尽量不要再td里写overflow: auto; 因为这样在IE6,7不会出现滚动条的,最好的办法是套一个div,宽度设置成100%
我是自由宽度
1,第一种需求,只给当前页加序号
(1),给你的数据加上 templet属性
,cols: [[
{field:'tourPlayerId', width:80, title: 'ID1', sort: true,fixed: 'left',}
,{field:'zizeng', width:80, title: '排名',fixed: 'left',templet:'#zizeng'}
(2),在table的下面加上:
{{d.LAY_TABLE_INDEX+1}}
这样的话 下一页里面的排序不会连着上一页的,只会重新从1开始排序
2,第二种方法,包括分页的数据也加上序号
加上type属性,
设定列类型。可选值有:normal(常规列,无需设定)、checkbox(复选框列)、space(空列)、numbers(序号列)。注意:该参数为 layui 2.2.0 新增。而如果是之前的版本,复选框列采用 checkbox: true、空列采用 space: true
所以你这里只需要用到type:'numbers'就可以了,
效果如下:
以上这篇layui 给数据表格加序号的方法就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持脚本之家。
private Integer yzIdcard(String name , String idcard){ String host = "http://checkone.market.alicloudapi.com"; String path = "/chinadatapay/1882"; String method = "POST"; // String appcode = "c20ddc9f3116423ab8edaf9f98bcc09e"; Map<String, String> headers = new HashMap<String, String>(); //最后在header中的格式(中间是英文空格)为Authorization:APPCODE 83359fd73fe94948385f570e3c139105 headers.put("Authorization", "APPCODE " + appCode); //根据API的要求,定义相对应的Content-Type headers.put("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8"); Map<String, String> querys = new HashMap<String, String>(); Map<String, String> bodys = new HashMap<String, String>(); bodys.put("idcard", idcard); bodys.put("name", name); try { /** * 重要提示如下: * HttpUtils请从 * https://github.com/aliyun/api-gateway-demo-sign-java/blob/master/src/main/java/com/aliyun/api/gateway/demo/util/HttpUtils.java * 下载 * * 相应的依赖请参照 * https://github.
给组件设置样式不生效问题 我们在使用组件或者自己写的标签样式不生效,可以从一下几个方面考虑,解决
目标对象问题 首先要检查自己设置的样式有没有设置在对应的对象身上,可以打开浏览器的开发工具,检查对象,该对象是否由你设置的属性
比如说使用a-modal组件的使用,注意对话框的父盒子为body,如果我们选择的对象不对,设置的样式就肯定不会生效
权重问题 我们打开浏览器的开发工具,选择查看对象,filter过滤样式,查看生效的样式的权重,然后将自己设置的选择器权重高于当前生效的权重
使用组件的深层选择器 /deep/
去除style标签中的scoped 此时为了不影响其他的样式,最好给标签加上id,利用id去选择
各主要城市数据分析岗位薪资水平分析 一、项目背景 由于个人考虑转行数据分析,故通过对招聘信息数据的分析,了解该岗位的市场需求、行业分布、薪资水平,以便明确求职方向
二、数据获取 数据来源于boss直聘网,通过爬虫采集
采集的城市主要为一线、新一线等较为发达的城市
爬虫代码如下:
from selenium import webdriver
from bs4 import BeautifulSoup
driver = webdriver.Chrome(r'D:\PycharmProjects\python_present\boss直聘爬取\chromedriver.exe')
cities = [{"name": "北京", "code": 101010100, "url": "/beijing/"},
{"name": "上海", "code": 101020100, "url": "/shanghai/"},
{"name": "广州", "code": 101280100, "url": "/guangzhou/"},
{"name": "深圳", "code": 101280600, "url": "/shenzhen/"},
{"name": "杭州", "code": 101210100, "url": "/hangzhou/"},
{"name": "天津", "code": 101030100, "url": "/tianjin/"},
{"name": "苏州", "code": 101190400, "url": "/suzhou/"},
{"name": "武汉", "code": 101200100, "url": "/wuhan/"},
{"name": "
改成 select * from tablename desc limit 0,9 就可以了
比如
// 获取前十条记录
public List GetPayListTopTen() {
List userList = new ArrayList();
Cursor cursor = db.rawQuery("select * from account desc limit 0,9", null);
cursor.moveToFirst();
while (!cursor.isAfterLast() && (cursor.getString(1) != null)) {
Payment pay = new Payment();
pay.setId(cursor.getInt(0));
pay.setMoney(cursor.getString(1));
pay.setText(cursor.getString(2));
pay.setTime(cursor.getString(3));
userList.add(pay);
cursor.moveToNext();
}
cursor.close();
return userList;
}
新建工作空间catkin_ws/src
git clone http....到src
切换到工作空间catkin_make
source ./catkin_ws/devel/setup.bash
之前也是自己想着学python,在网上看了很多资料,然后选择了pycharm这个开发软件,软件就是很简单,自己可以去他的官网上面下载,但是一定要选择好对应的安装包,自己是Windows电脑就选择Windows版本,是苹果的就选择MacOS的,但是个人感觉还是选择最新版本的最好,但是如果有特殊要求的除外
关于有些小伙伴可能不太习惯英文版,想要改成中文版,也是有办法的,等你软件安装好后,你应该会进入这个界面(以下界面原本都是英文版,是后期变成中文版的)
这个时候你可以点击插件,也就是第三个按钮,进入这个界面
这个时候可以在搜索栏里面输入Chinese进行搜索
安装好之后,只要一直点击ok,就可以了,软件会自动重启,再次打开就是中文版的了
希望这篇文章可以帮到你
现在textview显示语句,如果我将滚动到很远的底部.看起来promis textview变得很大.有办法解决吗?
星空下的一切都是promis textview的一部分.它是一个包含多个换行符的单个字符串
另一个截图
产生承诺的代码
prm = doc.getElementsByTagName("promise");
for (int j = 0; j < prm.getLength(); j++) {
prom += parser.getValue(e, KEY_PROMISES, j) + "\n";
}
prom.substring(0,prom.lastIndexOf('\n'));
布局
android:id="@+id/widget32"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
android:id="@+id/top"
android:layout_width="wrap_content"
android:layout_height="wrap_content" >
android:id="@+id/face"
android:layout_width="68dp"
android:layout_height="68dp"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true" />
android:id="@+id/name"
android:layout_width="243dp"
android:layout_height="35dp"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true"
android:layout_toRightOf="@id/face"
android:text="from" />
android:id="@+id/office"
android:layout_width="242dp"
android:layout_height="wrap_content"
android:layout_alignBottom="@+id/face"
android:layout_alignParentRight="true"
android:layout_below="@+id/name"
android:layout_toRightOf="@id/face"
android:text="subject" />
android:id="@+id/ratingBar1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_below="@+id/top"
android:numStars="6"
android:singleLine="false" />
android:id="@+id/promises"
小米9是小米最新的旗舰手机,很多动手爱好者、手机爱好者都喜欢刷机,那么小米9的刷机方法是什么呢?下面就来给大家介绍一下。
注意: 刷机有风险,入行需谨慎
步骤
第一步:
你需要给自己的小米9解锁,解锁直接在MIUI论坛申请就可以了,在这里不做讲解。
第二步:
你的手机正确解锁之后,不需要root,因为这个时候的root还不够彻底,我们接下来要做的就是给手机刷入大名鼎鼎的第三方rec(TWRP),在这里我给大家提供了一键刷入版,不过需要电脑配合。在文章末尾我会把本文用到的所有工具上传。
打开我提供的工具包,里面有个压缩包「小米9-TWRP3.23最新版-一键刷入」。
解压。
运行「recovery-twrp一键刷入工具」。
只要你驱动安装好,手机连接正常,应该马上就能刷入了。
第三步:
利用刚刚我们刷好的rec直接安装第三方ROM即可。
在关机状态下同时按住电源键 和 音量+ 按键,进入rec界面,点「安装」。
然后找到我们下载的刷机包即可自动安装。
安装完成后会自己进入系统。
第四步:
按理来说,装完第三方ROM就已经完美root了,不需要我们其他的操作。
以上就是关于“小米手机刷机教程,小米9刷第三方ROM”的全部内容,希望对你有帮助。
推荐阅读: 安卓手机怎么刷机 教你刷成其他版本的系统
推荐阅读: 手机刷机好不好 手机刷机优缺点汇总
实现在山东地图上使用经纬度标注水波纹点。
1.引入js
<script type="text/javascript" src="<%=path%>/skin/jquery.js"></script> <script type="text/javascript" src="<%=path%>/skin/echarts4.1.0.js"></script> <script type="text/javascript" src="<%=path%>/skin/js/shandong.js"></script> 2.html定义dom
<div style="width:200px;height:200px" id="sdmap"></div> 3.map
var dom = document.getElementById("sdmap"); var myChart = echarts.init(dom); window.addEventListener('resize', function () {myChart.resize()}) var option = null; // 散点在地图上的坐标 var geoCoordMap = { "滨州数字经济产业园":[117.63,37.45], "滨州跨境电商产业园":[118.03,37.55], "德州跨境电商产业园":[116.29,37.25] }; // 将坐标与值对应并反映在地图上 var convertData = function (data) { var res = []; for (var i = 0; i < data.length; i++) { var geoCoord = geoCoordMap[data[i].name]; if (geoCoord) { res.
1.ntp同步配置内容,其中IP1、IP2代表同步时钟源IP,IP3代表本机IP
server IP1 server IP2 restrict IP3 nomodify notrap noquery restrict 192.168.0.1 mask 255.255.255.0 nomodify notrap server 127.127.1.0 # local clock fudge 127.127.1.0 stratum 10 第三行解释:
restrict [ 客户端IP ] mask [ IP掩码 ][参数]
“客户端IP” 和 “IP掩码” 指定了对网络中哪些范围的计算机进行控制,如果使用default关键字,则表示对所有的计算机进行控制,参数指定了具体的限制内容,常见的参数如下:
◆ ignore:拒绝连接到NTP服务器
◆ nomodiy: 客户端不能更改服务端的时间参数,但是客户端可以通过服务端进行网络校时。
◆ noquery: 不提供客户端的时间查询
◆ notrap: 不提供trap远程登录功能,trap服务是一种远程时间日志服务。
◆ notrust: 客户端除非通过认证,否则该客户端来源将被视为不信任子网 。
◆ nopeer: 提供时间服务,但不作为对等体。
◆ kod: 向不安全的访问者发送Kiss-Of-Death报文。
2.配置完成后,关闭ntpd服务,测试与时钟同步源之间是否可以同步上
service ntpd stop
ntpdate -u IP1或IP2
此时发现同步失败,执行ntpdate -d IP1,显示报错:xxx.xxx.xxx.xxx: Server dropped: no data
简单区分 px 一个盒子是100px * 100px px指的是逻辑像素,也叫css像素
在适配时,使用px作为单位并不合适。
px特点 IE无法调整那些使用px作为单位的字体大小;国外的大部分网站能够调整的原因在于其使用了em或rem作为字体单位;Firefox能够调整px和em,rem,但是有大部分的国产浏览器使用IE内核 em 指的是一个汉字的宽度,2em表示两个汉字的宽度
1em = 1个font-size的大小
如:font-size:20px; 1em = 20px 10em = 200px
em不足:它是相对于父元素的font-size来说的。
适配使用em也不合适,因为它一直是相对于父元素的font-size来说的
em是一个相对长度的单位,是相对于当前对象内文本的字体尺寸。如过我们未设置当前文本的字体尺寸,那么em就会相对于浏览器的默认字体尺寸
在浏览器中默认字体尺寸为16px,换句话说1em=16px,一般我们在写自适应布局时经常会用到em为单位。通过在CSS中的body选择器中设置font-size值来简化代码,使得页面中所有的em都相对于body值。
em 是相对长度单位。相对于当前对象内文本的字体尺寸。如当前对行内文本的字体尺寸未被人为设置,则相对于浏览器的默认字体尺寸。(引自CSS2.0手册)
任意浏览器的默认字体高都是16px。所有未经调整的浏览器都符合: 1em=16px。那么12px=0.75em,10px=0.625em。为了简化font-size的换算,需要在css中的body选择器中声明Font-size=62.5%,这就使em值变为 16px*62.5%=10px, 这样12px=1.2em, 10px=1em, 也就是说只需要将你的原来的px数值除以10,然后换上em作为单位就行了。 em特点: em的值并不是固定的;em会继承父级元素的字体大小。 所以我们在写CSS的时候,需要注意两点:
body选择器中声明Font-size=62.5%;
将你的原来的px数值除以10,然后换上em作为单位;
重新计算那些被放大的字体的em数值。避免字体大小的重复声明。
也就是避免1.2 * 1.2= 1.44 的现象。比如:
你在 #content 中声明了字体大小为1.2em,那么在声明 p 标签的字体大小时就只能是1em,而不是1.2em, 因为此em非彼em,它因继承 #content 的字体高而变为了1em=12px。
rem r表示root root是根的意思 指html标签 1rem ==> html标签中的font-size的大小 1em ==> 父标签中的font-size的大小
rem是CSS3中新增的一个相对单位,它与em的区别在于使用rem为元素设定字体大小时,仍然是相对大小,但相对的只是HTML根元素。它的使用非常简单,通过改变根元素的大小就可以改变它的值 rem特点 rem 相对单位,相对于根元素 <html> ;相对大小和绝对大小的优点于一身;修改根元素就成比例地调整所有字体大小;避免字体大小逐层复合的连锁反应. 选择使用什么字体单位主要由你的项目来决定,如果你的用户群都使用最新版的浏览器,那推荐使用rem,如果要考虑兼容性,那就使用px,或者两者同时使用。
http://www.ikbc.com.cn/Private/Files/5e5d21653dcd42e49de245ede7dc548e.pdf
咱们的这个一加6T手机也就是OnePlus 6T最新的固件rom包了, 这个rom包也是大家常用的,因为这个原版的系统包大家可以用来进行升级用,也可以用来进行系统更新用的,之前论坛里也是有个别的机友在找相关的rom包的,可是一直没有找到,所以下面特意整理了一个,这个原版的系统包也是很实用的,大家可以下载下来直接采用官方自带的recovery来进行升级了,如果你也需要的话就一起来看看操作吧:
官方固件rom刷机包下载:
手机系统更新日志:
手机优化屏幕指纹功能
手机提升稳定性及修复已知问题
手机全新视觉风格来袭,让你耳目一新
手机新增全新Android 9.0导航交互方式,等你来尝鲜
手机全新智能电池管理
手机更新 Android 安全补丁至 2018.9
手机更多惊喜和细节优化等你发现
手机更强大的勿扰模式,勿扰行为和时间都由你来定义
优化手机Ami换机版本升级后能够自动重连
优化手机旧手机数据选择页的数据加载时间
优化手机支持数据接收恢复同步进行,更高效
优化手机安装大型游戏时的应用加载速度
优化手机卸载应用时,垃圾文件清理更彻底
(本文来源) https://www.netded.com/a/jishuyingyong/2018/1108/37544.html
不离不弃:
不离不弃(bù lí bù qì)意思是永远在身边,永不分离,永不抛弃。引自中国四大名著之一的《红楼梦》中宝钗宝玉观锁这一情节。
共赴鸿蒙:
鸿濛指宇宙形成前的混沌状态。出处:战国·庄子《庄子·在宥》:“云将东游,过扶摇之枝,而适遭鸿蒙。” 翻译:云将到东方巡游,经过神木扶摇的枝旁恰巧遇上了鸿蒙。共赴鸿蒙便为一起走完余生。
扩展资料:
不离不弃出自《红楼梦》中薛宝钗的金锁上刻的两句话中的一句。 意思是永远在身边,不分离,不抛弃的意思。
您可以参考《红楼梦》的有关章节:
宝钗“挪近前来。宝玉亦凑了上去,从项上摘了下来,递在宝钗手内。宝钗看毕,又重新翻过正面来细看,口内念道:“莫失莫忘,仙寿恒昌。”
念了两遍,乃回头向莺儿笑道:“你不去倒茶,也在这里发呆作什么?”莺儿嘻嘻笑道:“我听这两句话,倒象和姑娘的项圈上的两句话是一对儿。”宝玉听了,忙笑道:“原来姐姐那项圈上也有八个字,我也赏鉴赏鉴。”
宝钗道:“你别听他的话,没有什么字。”宝玉笑央:“好姐姐,你怎么瞧我的了呢?”宝钗被缠不过,因说道:“也是个人给了两句吉利话儿,所以錾上了,叫天天带着,不然,沉甸甸的有什么趣儿。”一面说,一面解了排扣,从里面大红袄上将那珠宝晶莹黄金灿烂的璎珞掏将出来。
宝玉忙托了锁看时,果然一面有四个篆字,两面八字,共成两句吉谶:“不离不弃,芳龄永继。”宝玉看了,也念了两遍,又念自己的两遍,因笑问:“姐姐这八个字倒真与我的是一对。"
注意:“不离不弃”是在《红楼梦》中创作的一个短语,并不是一个正统意义上的成语,各大字典均无收录为成语。
参考资料来源:百度百科-不离不弃
1132:石头剪子布 时间限制: 1000 ms 内存限制: 65536 KB
提交数: 29385 通过数: 15475
【题目描述】 石头剪子布,是一种猜拳游戏。起源于中国,然后传到日本、朝鲜等地,随着亚欧贸易的不断发展它传到了欧洲,到了近现代逐渐风靡世界。简单明了的规则,使得石头剪子布没有任何规则漏洞可钻,单次玩法比拼运气,多回合玩法比拼心理博弈,使得石头剪子布这个古老的游戏同时用于“意外”与“技术”两种特性,深受世界人民喜爱。
游戏规则:石头打剪刀,布包石头,剪刀剪布。
现在,需要你写一个程序来判断石头剪子布游戏的结果。
【输入】 第一行是一个整数NN,表示一共进行了NN次游戏。1≤N≤1001≤N≤100。
接下来N行的每一行包括两个字符串,表示游戏参与者Player1,Player2的选择(石头、剪子或者是布):
S1S2S1S2
字符串之间以空格隔开S1S1,S2S2只可能取值在{"Rock", "Scissors", "Paper"}(大小写敏感)中。
【输出】 输出包括NN行,每一行对应一个胜利者(Player1或者Player2),或者游戏出现平局,则输出Tie。
【输入样例】 3 Rock Scissors Paper Paper Rock Paper 【输出样例】 Player1 Tie Player2 【参考代码】 C代码:
#include <stdio.h> #include <string.h> #define N 110 char player1[N],player2[N]; int main() { int n; scanf("%d",&n); while(n--) { scanf("%s %s",player1,player2); if(strcmp(player1,player2)==0) printf("Tie\n"); else if((strcmp(player1,"Rock")==0 && strcmp(player2,"Scissors")==0) || (strcmp(player1,"Scissors")==0 && strcmp(player2,"Paper")==0) || (strcmp(player1,"Paper")==0 && strcmp(player2,"
QGIS3.18.3(自带QT5)+VS2019二次开发环境搭建及测试 前言一、环境搭建前的准备二、开始搭建项目,设置环境三、测试注意 前言 按网上的qt+qgis+vs的编译流程总是出现不同的问题,实验很久也没完全成功,看网上除了自己编译之外,还可以采用官网已经编译好的QGIS版本+VS搭建QGIS二次开发环境,本文主要记载自己成功搭建QGIS二次开发环境并且测试的流程
提示:以下是本篇文章正文内容,下面案例可供参考
一、环境搭建前的准备 1.本文所搭建的二次开发环境各软件版本为QGIS3.18.3(自带QT5)+VS2019-----release x64
2.VS2019中安装VS 2017编译器
3.安装QGIS3.18.3
4.下载osgeo4w-setup-x86_64.exe
双击osgeo4w-setup-x86_64.exe
Andvance Install
Install from Intenet
选择安装路径D:\OSGeo4W64
选择安装包路径D:\OSGeo4W64\Temp
Direct Connection
随便选择一个站点
在"Search"框中输入"qt5-devel"(表示搜索qt5二次开发的依赖库),点击一下对应的"Skip"(如果已经安装则是Keep状态),即可下载相应版本的二次开发依赖库,如下图:
再在"Search"框中输入"qgis-devel"(表示搜索qgis二次开发的依赖库),点击对应的"Skip",即可下载相应版本的二次开发依赖库,如下图:
下一步,取消勾选
下一步、弹出对话框中点击确定、完成
完成后依赖项如图:
每个找出五个文件夹下的压缩文件,分别解压,会得到五个apps文件夹,分别将五个文件夹复制到D:\QGIS-3.18.3(即你的QGIS安装文件夹)
二、开始搭建项目,设置环境 1.打开VS,下载QT VS Tools插件
2.QT VS Tools插件中设置QT版本
3.用户环境变量配置(设置完后重启电脑)
“Path”:添加"$(QGis安装路径)\bin"
“QTDIR”:设置为"$(QGis)安装路径\apps\Qt5"
4.打开VS,新建Qt Widgets Application项目,命名为gisTest2–next–next–finish
5.gisTest2项目右键属性,C/C++ 点击常规,附加包含目录设置,如下图:
6.gisTest2项目右键属性,链接器中,点击常规,附加库目录设置,如下图:
7.gisTest2项目右键属性,链接器中,点击输入,附加依赖项设置,如下图:
8.将下列目录中的dll文件复制到gisTest2项目.exe文件同级目录中(D:\QGIS_workspace\gisTest2\x64\Release)
D:\QGIS-3.18.3\apps\qt5\bin
D:\QGIS-3.18.3\apps\qgis\bin
D:\QGIS-3.18.3\bin
9.将D:\QGIS-3.18.3\apps\qt5\plugins\中的platforms文件夹复制到D:\QGIS_workspace\gisTest2\x64\Release\路径下,如图:
三、测试 1.将如下代码取代gisTest2项目的main.cpp中的内容:
#include "gisTest2.h" #include <qgsapplication.h> int main(int argc, char* argv[]) { QgsApplication a(argc, argv, true); QgsApplication::setPrefixPath("D:\QGIS-3.18.3\apps\qgis", true);//注意切换你的路径 QgsApplication::initQgis(); //初始化QGIS应用 gisTest2 w; //创建一个窗体,类似于Qt w.
本篇文章为转载,原作者文章地址:Centos7开启SSH服务 - KinwingHU - 博客园 (cnblogs.com)
在虚拟机(Vmware Workstation)下,安装了CentOS7,现在想通过SSH工具连接虚拟机中的CentOS7
1、 首先,要确保CentOS7安装了 openssh-server,在终端中输入 yum list installed | grep openssh-server
此处显示已经安装了 openssh-server,如果又没任何输出显示表示没有安装 openssh-server,通过输入 yum install openssh-server
来进行安装openssh-server
2、 找到了 /etc/ssh/ 目录下的sshd服务配置文件 sshd_config,用Vim编辑器打开
将文件中,关于监听端口、监听地址前的 # 号去除
然后开启允许远程登录
最后,开启使用用户名密码来作为连接验证
保存文件,退出
3、 开启 sshd 服务,输入 sudo service sshd start
检查 sshd 服务是否已经开启,输入ps -e | grep sshd
或者输入netstat -an | grep 22 检查 22 号端口是否开启监听
4、 在Vmware Workstation中,查看CentOS7的属性,发现网络连接方式是采用的 NAT 方式连接的
5、 在Vmware Workstation中,点击编辑=》虚拟网络编辑器,进入虚拟网络编辑器,查看发现 NAT 模式的连接采用的网络适配器名称为VMnet8
6、在 windows 主机中,在命令行中输入ipconfig 查看主机IP,找到 VMnet8 的连接信息,此处 ip 为192.
其实就一行代码。在AndroidManifest中加一行代码就行。
做个记录,这个太坑了。
下面是windowSoftInputMode各值的含义:
【A】stateUnspecified:软键盘的状态并没有指定,系统将选择一个合适的状态或依赖于主题的设置
【B】stateUnchanged:当这个activity出现时,软键盘将一直保持在上一个activity里的状态,无论是隐藏还是显示
【C】stateHidden:用户选择activity时,软键盘总是被隐藏
【D】stateAlwaysHidden:当该Activity主窗口获取焦点时,软键盘也总是被隐藏的
【E】stateVisible:软键盘通常是可见的
【F】stateAlwaysVisible:用户选择activity时,软键盘总是显示的状态
【G】adjustUnspecified:默认设置,通常由系统自行决定是隐藏还是显示
【H】adjustResize:该Activity总是调整屏幕的大小以便留出软键盘的空间
【I】adjustPan:当前窗口的内容将自动移动以便当前焦点从不被键盘覆盖和用户能总是看到输入内容的部分
文章目录 一、warm-up1、什么是Warmup2、为什么使用Warmup3、Warmup的实现方法3.1 constant warmup3.1 gradual warmup3.3 WarmupMultiStepLR3.3.1 build_lr_scheduler3.3.2 WarmupMultiSetpLR3.3.3 仿真 4、总结 二、PyTorch学习之六个学习率调整策略1、等间隔调整学习率 StepLR1.1 参数1.2 示例· 2、按需调整学习率 MultiStepLR2.1 参数2.2 示例 3、指数衰减调整学习率 ExponentialLR3.1 参数3.2 示例 4、余弦退火调整学习率 CosineAnnealingLR4.1 参数4.2 示例 5、自适应调整学习率 ReduceLROnPlateau5.1 参数 6、自定义调整学习率 LambdaLR6.1 参数: 一、warm-up 学习率是神经网络训练中最重要的超参数之一,针对学习率的优化方式很多,Warmup是其中的一种
1、什么是Warmup Warmup是在ResNet论文中提到的一种学习率预热的方法,它在训练开始的时候先选择使用一个较小的学习率,训练了一些epoches或者steps(比如4个epoches,10000steps),再修改为预先设置的学习来进行训练。
2、为什么使用Warmup 由于刚开始训练时,模型的权重(weights)是随机初始化的,此时若选择一个较大的学习率,可能带来模型的不稳定(振荡),选择Warmup预热学习率的方式,可以使得开始训练的几个epoches或者一些steps内学习率较小,在预热的小学习率下,模型可以慢慢趋于稳定,等模型相对稳定后再选择预先设置的学习率进行训练,使得模型收敛速度变得更快,模型效果更佳。
Example:
3、Warmup的实现方法 3.1 constant warmup Resnet论文中使用一个110层的ResNet在cifar10上训练时,先用0.01的学习率训练直到训练误差低于80%(大概训练了400个steps),然后使用0.1的学习率进行训练。
3.1 gradual warmup constant warmup的不足之处在于从一个很小的学习率一下变为比较大的学习率可能会导致训练误差突然增大。于是18年Facebook提出了gradual warmup来解决这个问题,即从最初的小学习率开始,每个step增大一点点,直到达到最初设置的比较大的学习率时,采用最初设置的学习率进行训练。gradual warmup的实现模拟代码如下:
""" Implements gradual warmup, if train_steps < warmup_steps, the learning rate will be `train_steps/warmup_steps * init_lr`. Args: warmup_steps:warmup步长阈值,即train_steps<warmup_steps,使用预热学习率,否则使用预设值学习率 train_steps:训练了的步长数 init_lr:预设置学习率 "
1.概述 转载:将 elasticsearch 写入速度优化到极限
基于版本: 2.x – 5.x
在 es 的默认设置,是综合考虑数据可靠性,搜索实时性,写入速度等因素的,当你离开默认设置,追求极致的写入速度时,很多是以牺牲可靠性和搜索实时性为代价的.有时候,业务上对两者要求并不高,反而对写入速度要求很高,例如在我的场景中,要求每秒200w 条的平均写入速度,每条500字节左右
接下来的优化基于集群正常运行的前提下,如果是集群首次灌入数据,可以将副本数设置为0,写入完毕再调整回去,这样副本分片只需要拷贝,节省了索引过程.
综合来说,提升写入速度从以下几方面入手:
加大 translog flush ,目的是降低 iops,writeblock
加大 index refresh间隔, 目的除了降低 io, 更重要的降低了 segment merge 频率
调整 bulk 线程池和队列
优化磁盘间的任务均匀情况,将 shard 尽量均匀分布到物理主机的各磁盘
优化节点间的任务分布,将任务尽量均匀的发到各节点
优化 lucene 层建立索引的过程,目的是降低 CPU 占用率及 IO
translog flush 间隔调整 从 es 2.x 开始, 默认设置下,translog 的持久化策略为:每个请求都flush.对应配置项为:
index.translog.durability: request 这是影响 es 写入速度的最大因素.但是只有这样,写操作才有可能是可靠的,原因参考写入流程.
如果系统可以接受一定几率的数据丢失,调整 translog 持久化策略为周期性和一定大小的时候 flush:
index.translog.durability: async index.translog.sync_interval: 120s index.translog.flush_threshold_size: 1024mb index.translog.flush_threshold_period: 120m 索引刷新间隔调整: refresh_interval refresh_interval
创建vue3时,报错“command failed: npm install --loglevel error”,核心错误如下图所示。
解决方法
第一步:找到.vuerc的文件,一般在C盘。
第二步:将里边的“useTaobaoRegistry”从true改为false。
JavaScript函数:
函数是由事件驱动的或者当它被调用时执行的可重复使用的代码块。
实例: 1.JavaScript 函数定义:
函数就是包裹在花括号中的代码块,前面使用了关键词 function;
当调用该函数时,会执行函数内的代码。
可以在某事件发生时直接调用函数(比如当用户点击按钮时),并且可由 JavaScript 在任何位置进行调用。
注意:JavaScript 对大小写敏感。关键词 function 必须是小写的,并且必须以与函 数名称相同的大小写来调用函数。
例:
2、带参数的函数
可以发送任意多的参数,由逗号 (,) 分隔;
语法:
变量和参数必须以一致的顺序出现。第一个变量就是第一个被传递的参数的给定的值,以此类 推。
例:
3、带返回值的函数:
通过使用 return 语句可以实现将函数返回值返回调用它的地方;
在使用 return 语句时,函数会停止执行,并返回指定的值;
注意:整个 JavaScript 并不会停止执行,仅仅是函数。JavaScript 将继续执行代 码,从调用函数的地方。 例: 在您仅仅希望退出函数时 ,也可使用 return 语句。返回值是可选的:
如果 a 大于 b,则上面的代码将退出函数,并不会计算 a 和 b 的总和。
4.局部 JavaScript 变量:
在 JavaScript 函数内部声明的变量(使用 var)是局部变量,所以只能在函数内部访问它。(该变量的作用域是局部的)。
您可以在不同的函数中使用名称相同的局部变量,因为只有声明过该变量的函数才能识别出该变量。
只要函数运行完毕,本地变量就会被删除。
5.全局 JavaScript 变量:
在函数外声明的变量是全局变量,网页上的所有脚本和函数都能访问它。
6.JavaScript 变量的生存期: JavaScript 变量的生命期从它们被声明的时间开始。
局部变量会在函数运行以后被删除。
全局变量会在页面关闭后被删除。
深度学习常用的优化算法包括:梯度下降,随机梯度下降,小批量随机梯度下降,动量法,AdaGrad,RMSProp,Adam。这些优化算法又涉及到指数加权移动平均。下面先介绍什么是指数加权移动平均。
1. 指数加权移动平均 指数加权移动平均是几个概念拼到一起的,包括加权平均与移动平均。
加权平均:平均分为算术平均和加权平均,算术平均指各项的权重都相等。加权平均各项权重不等。
移动平均:移动平均常用于时间序列的平均计算。例如,取前n个时刻的值取平均。相当于有一个窗口在不断向前滑动。
指数加权平均:每一项的权重不等,并且是指数函数的形式。尝试用的形式如下:
v t = γ v t − 1 + ( 1 − γ ) g t (1) v_t=\gamma v_{t-1}+(1-\gamma)g_t\tag1 vt=γvt−1+(1−γ)gt(1)
v t v_t vt是当前时刻的指数加权移动平均值。 g t g_t gt是当前时刻的值。一般令 v 0 = 0 v_0=0 v0=0。则 v 1 , v 2 , v 3 v_1,v_2,v_3 v1,v2,v3分别为:
v 1 = ( 1 − γ ) g 1 v 2 = γ v 1 + ( 1 − γ ) g 2 = γ ( 1 − γ ) g 1 + ( 1 − γ ) g 2 v 3 = γ v 2 + ( 1 − γ ) g 3 = γ 2 ( 1 − γ ) g 1 + γ ( 1 − γ ) g 2 + ( 1 − γ ) g 3 (2) v_1=(1-\gamma)g_1\\ v_2=\gamma v_1+(1-\gamma)g_2=\gamma(1-\gamma)g_1+(1-\gamma)g_2\\ v_3=\gamma v_2+(1-\gamma)g_3=\gamma^2(1-\gamma)g_1+\gamma(1-\gamma)g_2+(1-\gamma)g_3\tag2 v1=(1−γ)g1v2=γv1+(1−γ)g2=γ(1−γ)g1+(1−γ)g2v3=γv2+(1−γ)g3=γ2(1−γ)g1+γ(1−γ)g2+(1−γ)g3(2)
数据表的记录如下
5112 960024
5112 960025
5112 960026
5112 960027
5112 960028
5113 960043
5113 960044
5113 960045
5113 960046
select product_id, concat_ws('_',collect_set(promotion_id)) as promotion_ids from product_promotion group by product_id 执行结果:
5112 960024_960025_960026_960027_960028
5113 960043_960044_960045_960046
Time taken: 3.116 seconds
collect_list: 合成数值, 但是有重复
collect_set: 合成数组,但是已去重
了解python之进程与线程 // 本文虽然叫作 “了解python进程与线程”, 但还是有点难度的。 可以先查阅另外一篇文字,快速入门。 Python快速入门多线程与多进程
1.进程 进程(Process,有时也被称为重量级进程)是程序的一次执行,每个进程都有自己的地址空间、内存、数据栈以及记录运行轨迹的辅助数据,操作系统管理运行的所有进程,并为这些进程公平分配时间。进程可以通过fork和spawn操作完成其他任务。因为各个进程都有自己的内存空间和数据栈等,所以只能使用进程间通信(IPC),而不能直接共享信息。
2.线程: 线程(Thread,有时被称为轻量级的进程)跟进程有些相似,不同的是所有线程运行在同一个进程中,共享运行环境。线程有开始、顺序执行和结束3个部分,有一个自己的指令指针,记录运行到什么地方。一个进程中的各个线程之间共享同一片数据空间,所以线程之间可以比进程之间更好更方便的共享数据和相互通信。
线程一般是并发执行的,正是由于这种并行和数据共享的机制,使得多个任务的合作变的可能。实际上,在单CPU系统中,真正的并发并不可能,每个线程会被安排每次只运行一小会,然后就把CPU让出来,让其他线程运行。
在进程的整个运行过程中,每个线程都只做自己的事,需要在跟其他线程共享运行结果。多个线程共享同一片数据不是完全没有危险的,由于数据访问顺序不一样,因此可能会导致数据结果不一致的问题,这叫做竞态条件。大多数线程库都带有一系列同步原语,用于控制线程的执行和数据访问。
每个线程都有他自己的一组CPU寄存器,称为线程的上下文,该上下文反映了线程上次运行该线程的CPU寄存器的状态。 指令指针和堆栈指针寄存器是线程上下文中两个最重要的寄存器,线程总是在进程得到上下文中运行的,这些地址都用于标志拥有线程的进程地址空间中的内存。
线程可以被抢占(中断)。在其他线程正在运行时,线程可以暂时搁置(也称为睡眠) -- 这就是线程的退让。 线程可以分为:
内核线程:由操作系统内核创建和撤销。用户线程:不需要内核支持而在用户程序中实现的线程。 Python3 线程中常用的两个模块为:
_threadthreading(推荐使用) thread 模块已被废弃。用户可以使用 threading 模块代替。所以,在 Python3 中不能再使用"thread" 模块。为了兼容性,Python3 将 thread 重命名为 "_thread"。
3.多线程和多进程 什么叫多任务?
简单的说就是系统可以同时运行多个任务。比如,一边用浏览器上网,一边听音乐,一边聊天,这就是多任务。假如现在已经有三个任务在运行了,查看任务管理器,可以看到很多任务在后台运行,只是在桌面没有显示。对于操作系统来说,一个任务就是一个进程,开启多个任务就是多进程。
有些进程不止可以做一件事,比方说word可以是同时打字、拼写检查、打印等。在一个进程内部,要同时做多件事,就需要同时运行多个线程。
多线程类似于同时执行多个不同的程序,多线程运行有以下几个优点:
1)使用线程可以把占据长时间的程序中的任务放到后台去处理
2)用户界面可以更加吸引人,比如用户单击一个按钮,用于触发某些事件的处理,可以弹出一个进度条显示处理的进度
3)程序的运行速度可能加快
4)在实现一些等待任务(如用户输入、文件读写、网络收发数据等)的时候,使用多线程更加有用。在这种情况下,我们可以释放一些珍贵的资源(如内存占用等)。
线程在执行过程中与进程还是有区别的。每个独立的线程有一个程序运行的入口、顺序执行序列和程序的出口。但是线程不能独立执行,必须依存在进程中,由进程提供多个线程执行控制。
由于每个进程至少要干一件事,因此一个进程至少有一个线程。多线程的执行方式和多进程是一样的,也是由操作系统在多个线程之间相互切换,让每个线程都短暂交互运行,看起来就像同时执行一样。同时执行多线程需要多核CPU才能实现。
如果要同时执行多个任务,怎们办?
第一种方法:启动多个进程,每个进程虽然只有一个线程,但是多个进程可以一起执行多个任务。第二种方法:启动一个进程,在一个进程内启动多个线程,这样多个线程也可以一起执行多个任务第三种方法:启动多个进程,每个进程在启动多个线程,这样同时执行的任务就更多了,这种模式过于复杂,实际上很少采用。 同时执行多个任务时,各个任务之间需要相互通信和协调,有时候任务1需要暂停,等待任务2完成后才能继续执行;有时任务3和任务4不能同时执行。多进程、多线程程序的复杂度远远高于前面的单进程、单线程的程序。
综上所述:
多线程是多个相关联的线程的组合,多进程是多个相互独立的进程的组合。线程是最小的执行单元,进程至少由一个线程组成。 4.并发和并行 一个程序在计算机中运行,其底层是处理器通过运行一条条的指令来实现的。
并发,英文叫作 concurrency。它是指同一时刻只能有一条指令执行,但是多个线程的对应的指令被快速轮换地执行。比如一个处理器,它先执行线程 A 的指令一段时间,再执行线程 B 的指令一段时间,再切回到线程 A 执行一段时间。
由于处理器执行指令的速度和切换的速度非常非常快,人完全感知不到计算机在这个过程中有多个线程切换上下文执行的操作,这就使得宏观上看起来多个线程在同时运行。但微观上只是这个处理器在连续不断地在多个线程之间切换和执行,每个线程的执行一定会占用这个处理器一个时间片段,同一时刻,其实只有一个线程在执行。
并行,英文叫作 parallel。它是指同一时刻,有多条指令在多个处理器上同时执行,并行必须要依赖于多个处理器。不论是从宏观上还是微观上,多个线程都是在同一时刻一起执行的。
并行只能在多处理器系统中存在,如果我们的计算机处理器只有一个核,那就不可能实现并行。而并发在单处理器和多处理器系统中都是可以存在的,因为仅靠一个核,就可以实现并发。
举个例子,比如系统处理器需要同时运行多个线程。如果系统处理器只有一个核,那它只能通过并发的方式来运行这些线程。如果系统处理器有多个核,当一个核在执行一个线程时,另一个核可以执行另一个线程,这样这两个线程就实现了并行执行,当然其他的线程也可能和另外的线程处在同一个核上执行,它们之间就是并发执行。具体的执行方式,就取决于操作系统的调度了。
5.全局解释器锁(GIL) python虚拟机的访问由全局解释器锁控制,这个锁能保证同一个时刻只有一个线程运行。
在多线程环境中,python虚拟机按照以下方式执行:
1)设置GIL
Python快速入门多线程与多进程 多线程 多线程的含义 进程我们可以理解为是一个可以独立运行的程序单位,比如打开一个浏览器,这就开启了一个浏览器进程;打开一个文本编辑器,这就开启了一个文本编辑器进程。但一个进程中是可以同时处理很多事情的,比如在浏览器中,我们可以在多个选项卡中打开多个页面,有的页面在播放音乐,有的页面在播放视频,有的网页在播放动画,它们可以同时运行,互不干扰。为什么能同时做到同时运行这么多的任务呢?这里就需要引出线程的概念了,其实这一个个任务,实际上就对应着一个个线程的执行。
而进程呢?它就是线程的集合,进程就是由一个或多个线程构成的,线程是操作系统进行运算调度的最小单位,是进程中的一个最小运行单元。比如上面所说的浏览器进程,其中的播放音乐就是一个线程,播放视频也是一个线程,当然其中还有很多其他的线程在同时运行,这些线程的并发或并行执行最后使得整个浏览器可以同时运行这么多的任务。
了解了线程的概念,多线程就很容易理解了,多线程就是一个进程中同时执行多个线程,前面所说的浏览器的情景就是典型的多线程执行。
并发和并行 一个程序在计算机中运行,其底层是处理器通过运行一条条的指令来实现的。
并发,英文叫作 concurrency。它是指同一时刻只能有一条指令执行,但是多个线程的对应的指令被快速轮换地执行。比如一个处理器,它先执行线程 A 的指令一段时间,再执行线程 B 的指令一段时间,再切回到线程 A 执行一段时间。
由于处理器执行指令的速度和切换的速度非常非常快,人完全感知不到计算机在这个过程中有多个线程切换上下文执行的操作,这就使得宏观上看起来多个线程在同时运行。但微观上只是这个处理器在连续不断地在多个线程之间切换和执行,每个线程的执行一定会占用这个处理器一个时间片段,同一时刻,其实只有一个线程在执行。
并行,英文叫作 parallel。它是指同一时刻,有多条指令在多个处理器上同时执行,并行必须要依赖于多个处理器。不论是从宏观上还是微观上,多个线程都是在同一时刻一起执行的。
并行只能在多处理器系统中存在,如果我们的计算机处理器只有一个核,那就不可能实现并行。而并发在单处理器和多处理器系统中都是可以存在的,因为仅靠一个核,就可以实现并发。
举个例子,比如系统处理器需要同时运行多个线程。如果系统处理器只有一个核,那它只能通过并发的方式来运行这些线程。如果系统处理器有多个核,当一个核在执行一个线程时,另一个核可以执行另一个线程,这样这两个线程就实现了并行执行,当然其他的线程也可能和另外的线程处在同一个核上执行,它们之间就是并发执行。具体的执行方式,就取决于操作系统的调度了。
多线程适用场景 在一个程序进程中,有一些操作是比较耗时或者需要等待的,比如等待数据库的查询结果的返回,等待网页结果的响应。如果使用单线程,处理器必须要等到这些操作完成之后才能继续往下执行其他操作,而这个线程在等待的过程中,处理器明显是可以来执行其他的操作的。如果使用多线程,处理器就可以在某个线程等待的时候,去执行其他的线程,从而从整体上提高执行效率。
像上述场景,线程在执行过程中很多情况下是需要等待的。比如网络爬虫就是一个非常典型的例子,爬虫在向服务器发起请求之后,有一段时间必须要等待服务器的响应返回,这种任务就属于 IO 密集型任务。对于这种任务,如果我们启用多线程,处理器就可以在某个线程等待的过程中去处理其他的任务,从而提高整体的爬取效率。
但并不是所有的任务都是 IO 密集型任务,还有一种任务叫作计算密集型任务,也可以称之为 CPU 密集型任务。顾名思义,就是任务的运行一直需要处理器的参与。此时如果我们开启了多线程,一个处理器从一个计算密集型任务切换到切换到另一个计算密集型任务上去,处理器依然不会停下来,始终会忙于计算,这样并不会节省总体的时间,因为需要处理的任务的计算总量是不变的。如果线程数目过多,反而还会在线程切换的过程中多耗费一些时间,整体效率会变低。
所以,如果任务不全是计算密集型任务,我们可以使用多线程来提高程序整体的执行效率。尤其对于网络爬虫这种 IO 密集型任务来说,使用多线程会大大提高程序整体的爬取效率。
Python 实现多线程 在 Python 中,实现多线程的模块叫作 threading,是 Python 自带的模块。
Thread 直接创建子线程
首先,我们可以使用 threading.Thread 来创建一个线程,创建时需要指定 target 参数为运行的方法名称,如果被调用的方法需要传入额外的参数,则可以通过 Thread 的 args 参数来指定。示例如下:
import threading import time def target(second): print(f'Threading {threading.current_thread().name} is running') print(f'Threading {threading.current_thread().name} sleep {second}s') time.sleep(second) print(f'Threading {threading.
1. 背景 在嵌入式产品开发中,通常都会定制自己公司的Linux发行版,所谓发行版,即根据自家产品的功能和特性定制bootloader、kernel、rootfs,最后得到这三个的镜像文件。
定制Linux发行版是一件耗时耗力、技术含量比较高的一项大工程,对于很多公司来说,是没有这个人力和财力来做这件事的,所以大多数公司会选择现有的开源工具来定制自己家的 Linux 发行版。
据我所知,当前比较主流的开源工具有两款,分别是 Buildroot 和 Yocto,它们都是开源的工程,思想也大体相同,就是将很多的开发包集成到开源工具中,然后根据自家产品的功能和特性进行配置,配置完成后进行编译时就会只编译并集成被配置的开发包,没被配置的开发包不会下载或者不会被集成到最终的镜像文件中。
在汽车电子行业,Yocto 是主流,至于为啥我也不知道,Buildroot 和 Yocto 我都有研究过一点点,但是在工作中目前只接触过 Yocto,所谓“没有实践就没有发言权”,所以本章就只介绍一下Yocto。
2. 官方资源 官网:https://www.yoctoproject.org/
yocto项目快速开始手册:https://www.yoctoproject.org/docs/2.1/yocto-project-qs/yocto-project-qs.html
yocto项目开发参考手册:https://www.yoctoproject.org/docs/1.5/ref-manual/ref-manual.html
3. 组成 Recipes:.bb/.bbappend文件,即配方文件,描述了从哪获取软件源码,如何配置,如何编译。bbappend和bb的区别主要在于bbappend是基于bb的,功能是对相应的bb文件作补充和覆盖,有点类似于“重写”的概念。
Class:.bbclass文件,即类文件,包含在配方文件之间共享的有用信息。比如autotools该类,其中包含Autotools使用的任何应用程序的常用设置。Yocto项目参考手册中的“ 类 ”一章提供了有关类及其使用方法的详细信息。https://www.yoctoproject.org/docs/2.5/ref-manual/ref-manual.html#ref-classes
Configuration:.conf文件,即配置文件,我们可以用它来改变构建方式,比如conf/local.conf可以配置机器配置选项,分发配置选项,编译器调整选项,常规通用配置选项和用户配置选项 。
conf/bblayers.conf中可以添加用到的layer层路径,从而在编译时将他们添加进去。层是组织文件和目录结构的元数据(配置文件、配方)集合。
4. 配置 Yocto的目的很简单,它要经过一级一级配置,逐步缩小配方,直至得到uboot、kernel、rootfs这三个image。每一级需要哪些配方,由该级对应的配置文件(conf/bb)决定。越上级的配置是越笼统的,越下级的配置越细致。如果下级的配置项相对于上级有补充或者冲突,则以下级的内容为准,可以认为下级会对上级进行“重写”。
有关构建的路线和流程:对于整个发行版构建,虽然每一级的配方由(conf/bb)决定,但是每一级路线和方向的选择,是由我们最终bitbake的对象决定的,BitBake需要一些基本配置文件才能完成构建。这些文件是*.conf文件。最低限度必需的文件作为示例文件驻留 在build/conf。比如我们最终bitbake avi-image-core,我们想要获得rootfs.img,那么:
第一步Poky就会从local.conf开始,一路向下,一级一级配置,直到配置到和rootfs有关的那一堆bb,最终形成完整完全的配方 第二步获取配方需要的资源,比如各种软件包,比如kernel的源码 第三步把所有的资源编译出我们需要的镜像 在conf/local.conf文件提供了许多定义构建环境的基本变量:
Target Machine Selection(目标机器选择): 由 MACHINE 控制 Download Directory(下载目录): 由 DL_DIR 控制 Shared State Directory(共享状态目录): 由 SSTATE_DIR 控制 Build Output(构建输出): 由 TMPDIR 控制 Distribution Policy(分配策略): 由 DISTRO 控制 Packaging Format(打包格式): 由 PACKAGE_CLASSES 控制 SDK Target Architecture(SDK目标架构): 由 SDKMACHINE 控制 Extra Image Packages(额外的image包): 由 EXTRA_IMAGE_FEATURES 控制 5.
近几年,人们对电子数码设备的需求也不断提升,显示器作为终端显示产品也不断更新迭代。目前极少数显示器配备USB Type-C接口,但是在苹果、华为、三星、坚果、华硕、小米等品牌的笔记本则大多都支持通过USB Type-C接口来进行音视频数据传输。
Type-C除了能够用来传输文件、音视频之外,它还支持最高100W(20V/5A)的充电功率,再加上体积小巧、正反面都可插拔的特性。
应用场景一:如果你在家里或者公司里配备了带Type-C接口的显示器,那么在回家或者回公司时就可以少买一根HDMI线和少带一个笔记本充电器了。对于追求桌面整洁的朋友来说是十分实用的,上面说到的Type-C接口需要是全功能的接口。
应用场景二:通过Type-C接口给iPad/笔记本传输视频信号和供电,让iPad/笔记本在一定程度上提升生产力;当我们在谈iPad/笔记本作为一个生产力工具时,它往往就在产品性能、屏幕大小和键盘触控体验几个方面上遭到质疑;如果给iPad/笔记本扩展出一个大屏幕,那么在生产力上就得到了一定程度的提升。
应用场景三:可以通过Type-C接口直接连接部分全功能安卓手机扩展一个大屏幕,这种手机给显示器投屏一般有两种模式:手机模式和PC电脑模式;手机模式就是显示器端显示的画面与手机端的内容一致,电脑模式则是类似电脑双屏中的“扩展模式”,此时你可以将手机屏幕当做鼠标的触控板,像操作电脑软件一样来操作手机APP。
应用场景四:Type-C接口可以直连任天堂Swtich、PS4/PS5/PS3、XBOX等三大游戏主机,大屏显示器玩游戏更舒心。
现在高端或者定位偏生产力和商用的显示器厂商,大多都会配备全功能Type-C的接口,不管是推进桌面无线化,还是提升笔记本、手机和iPad生产力来说,这个接口都是功能强大而且体积小巧的。
乐得瑞科技推出的双口DRP USB PD Controller LDR6282,顺利通过了USB-IF的PD3.0认证,TID: 2127。LDR6282芯片具有双C口DRP及USB PD3.0控制功能,广泛应用于USB-C Docking,USB-C 显示器,USB-C手机音频转接器,嵌入式安卓/linux系统等场合,在支持标准USB PD3.0/QC2.0/QC3.0协议的基础上,还专门针对任天堂游戏机Switch的视频扩展功能进行了特别适配,兼容性非常优秀
LDR6282规格书资料
该芯片内置64K flash可以通过云端连接升级内部固件。让复杂的产品设计也可以安枕无忧,即使产品已经交付到了终端消费者手里仍然可以通过手机端APP或者是PC端应用程序进行固件升级。
该方案还可以适用于DC输入传统的的桌面显示器
需要进一步讨论或技术文档参考资料可下方留言讨论。
————————————————
版权声明:本文为CSDN博主「Legendary_008」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/Legendary_008/article/details/113053020
什么是IO? IO是输入输出的意思,也就是Input和Output,这不是重点,重点是IO是相对谁,在我们编写代码的时候也有I/O的概念。以Java为例,InputStream一般都伴随read方法,OutputStream一般对应write方法,也就是说,从哪读,写到哪去?所有的IO都是相对于内存,严格来说是内存的缓冲区。所有的程序都需要加载到内存中才能使用,而普通程序(除操作系统外)都无法直接访问硬件(外设),所有的 外设也没法直接访问用户空间中的用户程序,对于一个普通程序的一次普通IO来说,所有的数据都是先加载到内核空间的缓冲区,然后再被copy到用户空间的缓冲区,我们去read这个缓冲区。
IO接口:IO设备的代言人 大部分的输入输出设备,都有两个组成部分。第一个是它的接口,第二个才是实际的 I/O 设备。我们的硬件设备并不是直接接入到总线上和 CPU 通信的,而是通过接口,用接口连接到总线上,再通过总线和 CPU 通信。
而IO接口标识了设备状态,设立了缓冲区,标识了设备ID,完成了地址转换,甚至可以分析指令。也就是说真实的IO设备根本不会和总线直接交互。
CPU 是如何控制 I/O 设备的? CPU不会直接和I/O设备交互,所有的操作都要通过接口,那么这就牵扯出CPU是如何控制接口的?
程序查询方式:由CPU通过程序不断查询I/O设备是否已经做好准备,从而控制I/O设备与主机交换信息。
CPU在和接口交互之前,并不知道这个设备是好是坏,是闲是忙,所以需要先询问。接口接收到具体的操作请求之后,会查询状态寄存器里当前设备的状态,然后通过控制总线告诉CPU我是闲还是忙。如果闲,也就是ready状态,地址总线和数据总线开始传输数据到接口,进而到IO设备。如果忙,那就再次请求,直到闲为止。
这种方式大量占用CPU资源,CPU向IO设备发起读指令之后,设备如果未准备就绪,CPU会一直循环等待,直到就绪读取为止,这是一个同步的过程。
程序中断方式:中断的方式依然需要用到CPU,只不过CPU不会一直等了,由同步的方式,转为异步。
硬件方面需要增加响应电路用于唤醒和中断CPU,软件方面需要增加中断服务。中断请求是由设备发送给CPU的单向请求
CPU发起请求,然后继续执行原有业务,IO设备查询设备状态,状态就绪,通过响应电路向CPU发起中断请求,CPU接收响应,保护当前正在执行的业务数据,然后进行数据传输,数据传输完毕,重新执行被中断的业务,循环往复。
直接存储器存取(DMA):先了解什么是DMA,DMA 技术就是我们在主板上放一块独立的芯片,称为协处理器(DMAC)。在进行内存和 I/O 设备的数据传输的时候,我们不再通过 CPU 来控制数据传输,而直接通过DMA。协处理器没有CPU强大,主要作用就是用于数据传输控制。
该操作基本不占用CPU,使CPU在数据传输期间也可以做其他事情,进一步解放了CPU,使CPU不用在IO这件事情上劳心劳力。
DMA方式中,主存与I/0设备之间有一条数据通路(专用数据总线),则交换信息时无需像中断一样调用中断服务程序,数据不经过CPU,直接通过这条线传输,所以DMA是需要硬件支持的。
那数据如何 通过DMA的方式进行传输呢? 1.设置DMA:I/O 设备可以告诉 CPU,我这里有数据要传输给你,此时DMAC是不知道的,所以需要CPU告诉DMAC,从哪拿,拿多少,写到哪去,也就是源地址的初始值以及传输时候的地址增减方式,传输的数据长度,目标地址初始值和传输时候的地址增减方式。
2.如果我们要从硬盘上往内存里面加载数据,这个时候,硬盘就会向 DMAC 发起一个数据传输请求。这个请求并不是通过总线,而是通过一个额外的连线。
3.然后,我们的 DMAC 需要再通过一个额外的连线响应这个申请。
4.于是,DMAC 这个芯片,就向硬盘的接口发起要总线读的传输请求。数据就从硬盘里面,读到了 DMAC 的控制器里面。
5.然后,DMAC 再向我们的内存发起总线写的数据传输请求,把数据写入到内存里面。循环往复,直到数据传输完毕。
这样其实也出现了一个问题,这种传输操作其实类似于多线程,DMAC在干活,CPU也在干活,内存他们俩都要用,总线他们俩都要用,冲突了怎么办?
结论就是DMAC>CPU,DMA的优先级要高于CPU,DMA有插队的权利,但是权利有限,若DMA和CPU同时访问主存,CPU将总线占有权让给DMA,这种行为称为窃取或挪用。窃取时间一般为一个存取周期,故称为窃取周期。
DMA与中断的比较: 1.DMA需要硬件支持,数据传输完全通过硬件传输数据;程序中断需要程序传送
2.程序中断需要等待指令执行完成保护现场,然后再执行;DMA随时进行数据传输
3.DMA优先级更高
基于DMA的零拷贝机制,Kafka为什么这么快?
用户态和内核态:多数计算机有两种运行模式,用户态和内核态。软件中最基础的部分是操作系统,它运行在内核态。在这个模式中,操作系统具有对所有硬件的完全访问权,可以执行机器能够运行的任何指令。软件的其余部分运行在用户态,在用户态下,只使用了机器指令中的一个子集。而一个数据,需要加载到内核态之后再拷贝到用户态才能被程序使用。
以一次传统的socket数据传输为例
1.从硬盘上,读到操作系统内核的缓冲区里。这个传输是通过 DMA 搬运的。
2.内核缓冲区里面的数据,复制到我们应用分配的内存里面。这个传输是通过 CPU 搬运的。
3.从我们应用的内存里面,再写到操作系统的 Socket 的缓冲区里面去。这个传输,还是由 CPU 搬运的。
4.从 Socket 的缓冲区里面,写到网卡的缓冲区里面去。这个传输又是通过 DMA 搬运的。
版权声明:以上文章中所选用的图片及文字来源于网络以及用户投稿,由于未联系到知识产权人或未发现有关知识产权的登记,如有知识产权人并不愿意我们使用,如果有侵权请立即联系:55525090@qq.com,我们立即下架或删除。
简介: 代换-置换网络SPN的工作
原理及示例
Feistel结构和DES算法
AES算法
迭代密码
迭代密码的核心是一个密钥编排方案和一
个轮函数
密钥编排方案对密钥k进行变换,生成Nr个
子密钥(也叫轮密钥),记为k1,k2,...,kNr
轮函数g是一个状态加密函数,以ki为密钥
对当前状态wr-1进行变换,输出新的状态值
wr,即g(wr-1,ki)=wr;轮函数是单射函数,
存在一个逆变换g-1,有g-1(wr,ki)=wr-1
迭代密码的加解密过程
将密钥k编排成Nr个轮密钥k1,k2,...,kNr
加密:
将明文x定义为初始状态w0,经过Nr轮变换得
到wNr为密文y,即
w0=x, w1=g(w0,k1), w2=g(w1,k2), ...
wNr-1=g(wNr-2,kNr-1), wNr=g(wNr-1,kNr)
y=wNr
迭代密码的加解密过程
解密:
将密文y定义为初始状态wNr,经过Nr轮逆变换
得到w0为明文x,即
y=wNr, wNr-1=g-1(wNr,kNr),wNr-2=g-1(wNr-1,kNr-1)
...
w1=g-1(w2,k2), w0=g-1(w1,k1),
x=w0
代换-置换网络
代换-置换网络(Substitution-Permutation
Network)是一种简单的迭代密码
处理的明文单元和状态值长度为l×m
轮函数g包括两个核心变换——代换和置换,分别
记为πs和πp,有
πs : {0,1}l → {0,1}l
#include #include
/** 函数名: GetIniKeyString
* 入口参数: title
* 配置文件中一组数据的标识
* key
* 这组数据中要读出的值的标识
* filename
* 要读取的文件路径
* 返回值: 找到需要查的值则返回正确结果
* 否则返回NULL*/
char *GetIniKeyString(char *title,char *key,char *filename)
{
FILE*fp;int flag = 0;char sTitle[32], *wTmp;static char sLine[1024];
sprintf(sTitle,"[%s]", title);if(NULL == (fp = fopen(filename, "r"))) {
perror("fopen");returnNULL;
}while (NULL != fgets(sLine, 1024, fp)) {//这是注释行
if (0 == strncmp("//", sLine, 2)) continue;if (‘#‘ == sLine[0]) continue;
wTmp= strchr(sLine, ‘=‘);if ((NULL != wTmp) && (1 ==flag)) {if (0 == strncmp(key, sLine, wTmp-sLine)) { //长度依文件读取的为准
了解python之面向对象 面向对象概念: 面向对象编程(Object Oriented Programming,简称OOP)是一种程序涉及思想。OOP把对象作为程序的基本单元,一个对象包含数据和操作数据的函数。面向对象程序设计把计算机程序视为一组对象的集合,每个对象都可以接收其他对象发过来的消息,并处理这些消息,计算机程序的执行就是一系列消息在各个对象之间的传递。
在python中,所有数据类型都被视为对象,也可以自定义对象。自定义对象数据类型就是面向对象中的类(Class)的概念。
面向对象术语介绍:
类:用来描述具有相同属性和方法的对象的集合。类定义了集合中每个对象共有的属性和方法。对象是类的实例。类变量(属性):类变量在整个实例化的对象中是公用的,类变量定义在类中,且在方法之外,类变量通常不作为实例变量使用。类变量也称为属性。数据成员:类变量或者实例变量用于处理类及其实例对象的相关数据。方法重写:如果从父类继承的方法不能满足子类的需求,就可以对其进行改写,这个过程称为方法的覆盖,也称为方法的重写。实例变量:定义在方法中的变量只作用于当前实例的类。多态:对不同类的对象使用同样的操作。封装:对外部世界隐藏对象的工作细节。继承:即一个派生类(derived class)继承基类(base class)的字段和方法。继承允许把一个派生类的对象作为一个基类对象对待,以普通类为基础建立专门的类对象。实例化:创建一个类的实例,类的具体对象。方法:类中定义的函数。对象:通过类定义的数据结构实例,对象包括两个数据成员(类变量和实例变量)和方法。 python中的类提供了面向对象编程的所有基本功能;类的继承机制允许多个基类,派生类可以覆盖基类中的任何方法、方法中可以调用基类中的同名方法。对象可以包含任意数量和类型的数据。
类的定义与使用 1)类的定义:
class MyCLass(object): i=123 def f(self): return 'hello world' 从面可以看到类的语法如下:
class ClassName(object): <statement-1> ... <statement-N> python中定义类使用class关键词,class后面接类的名字,如上面例子中的MyClass,类的名字通常是大写开头的单词;紧接着是(object),表示MyClass这个类是从哪个类继承下来的。通常,如果没有合适的继承类,就使用object类,这是所有类最终都会继承的类。类包含属性(相当于函数中的语句)和方法(类中的函数)。
2)类的使用
class MyClass(object): i=123 def f(self): return 'hello world' use_class=MyClass() #类的实例化。即创建一个类的实例,use_class变量称为类的具体对象 print('调用类的属性:',use_class.i) #调用类的属性,就是前面我们说的类变量 print('调用类的方法:',use_class.f()) #调用类的方法 ##输出结果: 调用类的属性: 123 调用类的方法: hello world 上面定义的f()函数可以不用self参数吗?
在类定义方法的要求:在类中定义方法时,第一个参数必须是self。除了第一个参数外,类的方法和普通函数没有区别,可以使用默认参数,可变参数,关键字参数等。
类中调用方法的要求:要调用方法,在实例变量上直接调用即可。除了self不用传递参数,其他参数正常传入。
类对象支持两种操作,即属性引用和实例化。
属性引用的标准语法:
obj.name # obj代表类对象,name代表属性
深入类 1)类的构造方法
class MyClass(object): i=123 def __init__(self,name): self.name=name def f(self): return 'hello world' use_class=MyClass('lucky') #类的实例化。即创建一个类的实例,use_class变量称为类的具体对象 print('调用类的属性:',use_class.
文章目录 1、torch.mul()2、torch.mm()3、torch.matmul()3.1 输入都是二维3.2 输入都是三维3.3 输入的维度不同 1、torch.mul() torch.mul(a, b)是矩阵a和b对应位相乘torch.mul(a, b)中a和b的维度相等,但是,对应维度上的数字可以不同,可以用利用广播机制扩展到相同的形状,再进行点乘操作 # 比如a的维度是(1, 2),b的维度是(1, 2),返回的仍是(1, 2)的矩阵 >>> a = torch.rand(1, 2) >>> b = torch.rand(1, 2) >>> torch.mul(a, b) # 返回 1*2 的tensor # 乘列向量 >>> a = torch.ones(3,4) >>> a tensor([[1., 1., 1., 1.], [1., 1., 1., 1.], [1., 1., 1., 1.]]) >>> b = torch.Tensor([1,2,3]).reshape((3,1)) >>> b tensor([[1.], [2.], [3.]]) >>> torch.mul(a, b) tensor([[1., 1., 1., 1.], [2., 2., 2.
类加载子系统 类的加载阶段可以分为三个阶段,这三个阶段为加载阶段、链接阶段、初始化阶段。
阶段一(加载阶段 Loading): 通过一个类的获取定义此类的二进制字节流转化为方法区的运行时数据结构在内存中生成一个代表这个类的 java.lang.Class 对象,作为该类的访问入口 阶段二(链接阶段 Linking): 验证:目的在于确保Class文件的字节流包含信息符合当前虚拟机要求,保证被加载类的正确性,不会危害虚拟机自身安全准备:为类变量分配内存并且设置该类变量的默认初始值,即零值。 注:在链接阶段如果变量被final修饰,则直接被赋值
private static int a = 1; private static final int b = 2; 小编用代码和字节码文件来说明一下: 查看字节码文件,由于<clinit>是初始化阶段发生的(也就是在阶段三),只能看到a被赋值为1,说明b是在链接阶段被赋值的(在阶段三中看不到b被赋值),所以证明final是在链接阶段发生的
(这里在IDEA中装上jclasslib插件就可以看到字节码文件了,View-Show Bytecode With Jclasslib就可以看到当前类的字节码文件啦)
阶段三(初始化阶段 Initialization): 初始化阶段就是执行类构造器方法 <clinit>()的过程。该方法体是编译器自动收集类中的所有类变量(静态成员)的赋值动作和静态代码块中的语句合并而来(简单的说:<clinit>()为static的动作的合并语句),<clinit>() 执行前,父类的<clinit>() 已经执行完毕。<clinit>() 方法在多线程下被同步加锁。 例:说明一下<clinit>()
在<clinit>()里可以看到,num -->1-->2,number -->20 -->10,按照顺序执行,除此之外,我们还发现声明可以放在后面,但是调用变量必须在声明后调用
为了说明<clinit>是被同步加锁的,来看下面的代码的执行结果:
public class ClinitThreadTest { public static void main(String[] args) { Thread t1 = new Thread("线程1"){ @Override public void run() { System.out.println(Thread.currentThread().getName() + "开始"); C c = new C(); System.
最近整理的几道常见的面试题
1.px和em的区别?
答:px和em都是长度单位,区别是,px的值是固定的,指定是多少就是多少,计算比较容易。em得值不是固定的,并且em会继承父级元素的字体大小。
2.BFC是什么?
答:BFC(块级格式化上下文),一个创建了新的BFC的盒子是独立布局的,盒子内元素的布局不会影响盒子外面的元素。在同一个BFC中的两个相邻的盒子在垂直方向发生margin重叠的问题
BFC是指浏览器中创建了一个独立的渲染区域,该区域内所有元素的布局不会影响到区域外元素的布局,这个渲染区域只对块级元素起作用
3.html语义化是什么?
答:当页面样式加载失败的时候能够让页面呈现出清晰的结构
有利于seo优化,利于被搜索引擎收录(更便于搜索引擎的爬虫程序来识别)
便于项目的开发及维护,使html代码更具有可读性,便于其他设备解析。
4.HTML与XHTML——二者有什么区别?
答:1. 所有的标记都必须要有一个相应的结束标记
2. 所有标签的元素和属性的名字都必须使用小写
3. 所有的 XML 标记都必须合理嵌套
4. 所有的属性必须用引号 “” 括起来
5. 把所有 < 和 & 特殊符号用编码表示
6. 给所有属性赋一个值
7. 不要在注释内容中使用 “–”
8. 图片必须有说明文字
5.哪些css属性可以继承?
答:可继承: font-size font-family color, ul li dl dd dt;
不可继承 :border padding margin width height ;
6.css优先级算法如何计算?
答: !important > id > class > 标签
!important 比 内联优先级高
优先级就近原则,样式定义最近者为准;
以最后载入的样式为准;
7.例举3种强制类型转换和2种隐式类型转换?
答:强制(parseInt(),parseFloat(),Number())
matlab关于colorbar的整理(绘制不等间距colorbar, colorbar的大小位置调节等 1. 绘制不等间距colorbar2. colorbar的大小位置调节3. 更改colorbar上的刻度、给colorbar加单位 对matlab关于colorbar的一些小细节进行整理,希望对一些人能够有所帮助~ 1. 绘制不等间距colorbar 本人常用的方法是将某一区间内的数值全都换成同一个数字,最后绘制替换后的数字。
(1) 将某一区间的数值换成同一个数字(本人习惯写一个函数),要注意转换后的数字与转换前的不要有重合,否则会把转换前后数字弄混。
function [R] = Model_to20_unequal_compare(vari,level) %此函数进行不等间距前的变量转换 % vari是要转换的变量,level是目标的不等间距,R是转换后的变量 R = vari; R(find(vari<0.1)) = -200.1; %将R里面小于0.1的全都换成-200.1 R(find(vari>=0.1&vari<0.28)) = -195.1; %将R里面大于等于0.1,小于0.28的全都换成-195.1 R(find(vari>=0.28&vari<0.46)) = -190.1; R(find(vari>=0.46&vari<0.64)) = -185.1; R(find(vari>=0.64&vari<0.82)) = -180.1; R(find(vari>=0.82&vari<1)) = -175.1; R(find(vari>=1&vari<1.8)) = -170.1; R(find(vari>=1.8&vari<2.6)) = -165.1; R(find(vari>=2.6&vari<3.4)) = -160.1; R(find(vari>=3.4&vari<4.2)) = -155.1; R(find(vari>=4.2&vari<5)) = -150.1; R(find(vari>=5&vari<6)) = -145.1; R(find(vari>=6&vari<7)) = -140.1; R(find(vari>=7&vari<8)) = -135.1; R(find(vari>=8&vari<9)) = -130.1; R(find(vari>=9&vari<10)) = -125.
1.isArray()是Array类型的一个静态方法,可以用于判断一个值是否为数组 语法
Array.isArray(obj) 参数
obj :需要检测的值。 返回值
如果值是 Array,则为true; 否则为false。 举个例子 var a = [1,2,3]; console.log(typeof a); console.log(Array.isArray(a)); 输出结果如图所示:
我们可以看到,通过typeof运算符输出数组的类型是Object ,而我们使用Array.isArray()方法可以直接返回布尔值,在条件表达式中,我们使用这个方法是非常适用的。
2.instanceof判断 instanceof 运算符用于检测构造函数的 prototype 属性是否出现在某个实例对象的原型链上。
语法
object instanceof constructor 参数
object某个实例对象 constructor某个构造函数 描述
instanceof 运算符用来检测 constructor.prototype 是否存在于参数 object 的原型链上。 举个例子 const a = []; const b = {}; console.log(a instanceof Array); console.log(a instanceof Object); console.log(b instanceof Array); 输出结果如图所示:
解析:我们可以看出,使用nstanceof运算符可以分别数组和对象,由此来判断数组是数组
3.constructor判断 实例化的数组拥有一个constructor属性,这个属性指向生成这个数组的方法。
const a = []; console.log(a.constructor) 输出结果如图所示:
由此可见,数组中有一个叫Array的函数实列话,要是被判断的对象是其他类型的数组的话,我们可以看一下以下代码:
uniapp-省市区三级联动 插件地址:https://ext.dcloud.net.cn/plugin?id=1301
目前还是个前端小白,所以都是找别人的插件来使用,如果有更好的求分享!!!
导入插件 我是用Hbuilder直接导入:
遇到的错误 报错:
Avoid using non-primitive value as key, use string/number value instead. 09:39:45.540 found in
解决:
v-for循环里,key值重复
报错:Duplicate keys detected: ‘[object Object]’. This may cause an update error.
09:41:20.954 found in
解决:还是键值的问题,检测到重复的键值
修改插件中的代码:
v-for="(item,index) in cityData" :key=“index”
修改内容 修改:
1.将原插件的四级联动修改成了三级联动
2.在最后一次地区选择方法中,加入一个返回值,可以返回给input标签
this.bb=this.province+" “+this.city+” "+this.area;
this.$emit(“conceal”,this.bb);
3.可以修改插件的高度
this.heightCot = (res.safeArea.height * 2) / 3
4.设置插件弹出时机
通过设置popup初始为false
点击输入框 设置 this.popup=true
代码 插件的内容
erha-picker.vue
<template> <view> <view class="
联机重做日志大致分为两种状态:当前正在写的和当前没有写的,丢失不同状态的联机重做日志文件,其处理方式也是不一样的,下面分别介绍。
联机重做日志文件须知
查看当前数据库中联机重做日志文件的状态
SQL> select group#,thread#,sequence#,members,archived,status from v$log;
GROUP# THREAD# SEQUENCE# MEMBERS ARC STATUS
---------- ---------- ---------- ---------- --- ----------------
1 1 1 1 NO CURRENT
2 1 0 1 YES UNUSED
3 1 0 1 YES UNUSED
注意视图中的status列,该列标示着联机重做日志的状态,共有6中可选值
UNUSED ---标示从未用过。一般刚刚创建或open resetlogs打开后,联机重做日志组为这一状态。
CURRENT ---表示当前的。
ACTIVE ---表示活动的。虽然不是当前状态,但也有可能正被使用或要被使用,比如crash recovery时可能存在这中联机重做日志组
CLEARING ---日志正在清空,当执行 alter database clear logfile语句时,该日志组状态为这种状态,语句执行完毕后,操作的日志组状态变为UNUSED.
INACTIVE ---不活动状态。表示改组日志中的内容已经被归档或顺利写入数据文件,该组日志可被继续重用。
CLEARING_CURRENT ---日志正在清空,但是由于清空出错,如I/O设备无法访问,导致清空工作不能顺利完成。
由上述视图可见,group 1 的联机重做日志组位当前状态,然后在查询v$logfile视图,即可看到联机重做日志组对应的文件
SQL> select group#,member from v$logfile;
GROUP#
----------
MEMBER
--------------------------------------------------------------------------------
一、什么是深拷贝 深拷贝作用在引用类型上!例如:Object,Array
深拷贝不会拷贝引用类型的引用,而是将引用类型的值全部拷贝一份,形成一个新的引用类型,这样就不会发生引用错乱的问题,使得我们可以多次使用同样的数据,而不用担心数据之间会起冲突。
二、为什么要使用深拷贝 我们希望在改变新的数组(对象)的时候,不改变原数组(对象)
三、如何进行深拷贝 1、for循环 2、使用json.stringify和json.parse实现深拷贝 JSON.stringify把对象转成字符串,再用JSON.parse把字符串转成新的对象。
缺点:它会抛弃对象的构造函数,深拷贝之后,不管这个对象原来的构造函数是什么,在深拷贝之后都会变成Object。
这种方法能正确处理的对象只有 Number, String, Boolean, Array, 扁平对象,
也就是说,只有可以转成JSON格式的对象才可以这样用,像function没办法转成JSON。
3、递归拷贝实现深拷贝,解决循环引用问题 4、ES插件lodash
在做编程题目的时候经常会遇到“斐波那契数列”相关的题目,尤其在做OJ中。下面说一些方法:
(一)递归
递归是最慢的会发生重复计算,时间复杂度成指数级。
long long fac(int n)
{
if(n==1) return 1;
else if(n==2) return 2;
else return fac(n-1)+fac(n-2);
}
(二)循环
利用临时变量来保存中间的计算过程,加快运算。
long long fac(int n)
{
long long a=1,b=2,c;
if(n==1) return 1;
else if(n==2) return 2;
else
{
for(int i=3;i<=n;i++)
{
c=a+b; a=b; b=c;
}
}
return b;
}
(三)矩阵乘法+空间换时间(减少乘法,取模运算)
数列的递推公式为:f(1)=1,f(2)=2,f(n)=f(n-1)+f(n-2)(n>=3)
用矩阵表示为:
进一步,可以得出直接推导公式:
由于矩阵乘法满足结合律,在程序中可以事先给定矩阵的64,32,16,8,4,2,1次方,加快程序的执行时间。(有些题目需要取模运算,也可以事先进行一下)。给定的矩阵次幂,与二进制有关是因为,如下的公式存在解,满足Xi={0或1}:
为了保证解满足 Xi={0或1},对上述公式的求解从右向左,即求解顺序为Xn,Xn-1,Xn-2,....,X1,X0。
完整代码实现如下:
///求解fac(n)%100000,其中n为大于等于3的正整数
#include
#include
long long fac_tmp[6][4]={ ///存放矩阵次幂
///位置:00 01 10 11
{24578,78309,78309,46269}, ///32次幂%100000
为了下一篇文章做点准备。
首先,关于.DEF文件,MSDN有这么几行字说明:
Module-definition (.DEF) files provide the linker with information about exports, attributes, and other information about the program to be linked. Use the /DEF option to specify the .DEF file name. Because LINK provides options and other features that can be used instead of module-definition statements, .DEF files are generally not necessary.
注:模块定义文件(.DEF)文件将要链接的程序的输出函数,属性和其他信息提供给链接器(大侠注:链接是编译过程的最终步骤)。使用/def 参数以置顶.DEF文件名。因为链接提供的参数(大侠注:这些参数可能来自IDE或者命令行手动指定)可能替换模块定义语句,.DEF文件通常不是必要的。
下面是关于.DEF文件的MSDN帮助:
A module-definition (.DEF) file is a text file that contains statements for defining an .
What CASCADE?
Open CASCADE(简称OCC)平台是由法国Matra Datavision公司开发的CAD/CAE/CAM软件平台,可以说是世界上最重要的几何造型基础软件平台之一。开源OCC对象库是一个面向对象C++类库,用于快速开发设计领域的专业应用程序。
用它可以做很多三维模型,如下面两种。简单地说它可以开发三维CAD或者Solidworks等等软件,可以说强大无比。
OpenCASCADE的下载与安装
1.OpenCASCADE下载。
1)去官网下载:https://dev.opencascade.org/release
2)去CSDN下载:https://download.csdn.net/download/xipengbozai/18883824
3)下载你需要的版本,推荐下载安装版,比较省事:https://download.csdn.net/download/xipengbozai/18883824
2.OpenCASCADE安装。
1)匹配VS版本,我的是VS2017 64位版本,所以安装的是opencascade-7.4.0-vc14-64.exe
2)单机安装,选择下一步
3)然后安装full版本,也就是完全版,单击安装直到完成即可。
4)安装完的目录效果,opencascade-7.4.0是主目录,其他是附加库
OpenCASCADE的用法
1.建立项目工程,包含目录
2.添加库目录,如下所示
3.链接器-输入-附加依赖项输入如下项
TKBin.lib
TKBinL.lib
TKBinTObj.lib
TKBinXCAF.lib
TKBO.lib
TKBool.lib
TKBRep.lib
TKCAF.lib
TKCDF.lib
TKD3DHost.lib
TKDCAF.lib
TKDFBrowser.lib
TKDraw.lib
TKernel.lib
TKFeat.lib
TKFillet.lib
TKG2d.lib
TKG3d.lib
TKGeomAlgo.lib
TKGeomBase.lib
TKHLR.lib
TKIGES.lib
TKIVtk.lib
TKIVtkDraw.lib
TKLCAF.lib
TKMath.lib
TKMesh.lib
TKMeshVS.lib
TKOffset.lib
TKOpenGl.lib
TKPrim.lib
TKQADraw.lib
TKRWMesh.lib
TKService.lib
TKShapeView.lib
TKShHealing.lib
TKStd.lib
TKStdL.lib
TKSTEP.lib
TKSTEP209.lib
TKSTEPAttr.lib
TKSTEPBase.lib
TKSTL.lib
TKTInspector.lib
TKTInspectorAPI.lib
TKTObj.lib
TKTObjDRAW.lib
TKToolsDraw.lib
作者:Thomas Graf
译者:罗煜、张亮,均来自 KubeSphere 团队
Thomas Graf 是 Cilium 的联合创始人,同时也是 Cilium 母公司 Isovalent[1] 的 CTO 和联合创始人。此前 Thomas 曾先后在 Linux 内核[2]的网络、安全和 eBPF 领域从事了 15 年的开发工作。
注:本文已取得作者本人的翻译授权!
原文链接:https://cilium.io/blog/2021/05/11/cni-benchmark
大家好!????
随着越来越多的关键负载被迁移到 Kubernetes 上,网络性能基准测试正在成为选择 Kubernetes 网络方案的重要参考。在这篇文章中,我们将基于过去几周进行的大量基准测试的结果探讨 Cilium 的性能特点。应广大用户的要求,我们也将展示 Calico 的测试结果,以便进行直接对比。
除了展示测试的结果数据外,我们还将对容器网络基准测试这一课题进行更深入的研究,并探讨以下几个方面的问题:
吞吐量基准测试
容器网络是否会增加开销
打破常规:eBPF 主机路由(Host Routing)
测量延迟:每秒请求数
Cilium eBPF 和 Calico eBPF 的 CPU 火焰图对比
新连接处理速率
WireGuard 与 IPsec 加密开销对比
测试环境
测试结果汇总 在详细分析基准测试及其数据之前,我们先展示汇总的测试结论。如果您希望直接了解测试细节并得出自己的结论,也可以跳过这一节的内容。
eBPF 起决定性作用:Cilium 在某些方面优于 Calico 的 eBPF 数据路径(Data Path),例如在 TCP_RR 和 TCP_CRR 基准测试中观察到的延迟。此外,更重要的结论是 eBPF 明显优于 iptables。在允许使用 eBPF 绕过 iptables 的配置环境中,Cilium 和 Calico 的性能都明显优于不能绕过 iptables 的情况。
到目前为止,前面分享的从MDP到DQN都是值函数的方法,值函数方法的思路是先通过策略评估和策略改善两个步骤优化值函数,然后通过最优的值函数来导出最优的策略,此时的最优策略是贪婪策略,也就是在给定状态s,寻找最大状态值函数的动作,它是一个状态空间到动作空间的有限映射。
其实值函数的方法是有一些局限性的:
1、策略π是通过值函数产生的,但是有时候值函数很难计算的,比如让机器人打乒乓球,你需要前后左右移动来接球,计算小球在某一个位置是采取什么样的行动是很困难的。
2、对于高纬度或者连续的状态空间,值函数方法在得到价值函数后,很难通过比较各种动作的价值大小来制定策略。
3、值函数学习到的策略往往是贪婪的,其实有时候并非是最好的策略,比如我们在玩石头剪刀布游戏的时候,随机策略往往是最好的。
4、部分值函数在迭代后期会围绕最优价值函数波动而不收敛。
我们回顾一下强化学习的目的:通过智能体与环境的交互来获得累计回报的期望(因为每次交互是随机的,所以求期望)最大,我们定义每次试验所获得的累积回报为,也就是求期望R最大,其实我们可以直接来优化策略使得这个回报最大,这正是策略梯度的思路。策略梯度不是像值函数方法中一样把策略看作是概率集合,而是直接把策略参数化,如下:。
首先我们从免模型开始,之前已经介绍过MC和TD两种免模型方法,思路是通过与环境交互来获得样本,然后进行后续的值函数计算,我们现在从极大似然的角度来看策略梯度:
假如有一次试验结果如下:
,s表示状态,a表示基于前面状态s采用的动作。那我们计算一下本次试验出现的概率
表示策略的参数。
那么多次试验的期望回报为:,其中
,表示每次试验回报总和。现在已经有了策略梯度的目标函数,那么只需要求解目标函数的梯度即可。
下面详细介绍一下的推导过程:
不需要是可微分的,是黑箱子。
控制了参数更新的方向和步长,类似神经网络中的学习率,为正且越大,参数更新后该试验出现的概率会越大;反之,会抑制该试验的出现。是t时刻状态s下采取动作a的概率随参数变化最陡的方向。
公式推导小技巧:
下面我们看一下策略梯度更新的流程和步骤,如下图所示:
首先根据初始策略与环境交互获取多次试验,由于在每次试验中出现的状态以及对应的动作都是随机的,所以需要把每次试验的状态-动作pair以及获得的总回报记录下来,梯度使用这些试验记录下来的值,根据公式计算策略梯度的值,然后使用
来更新策略,更新后,之前策略产生的数据就没用了,可以删除,然后根据新的策略重新与环境交互得到新试验的状态-动作pair以及获得的总回报,重新更新策略,如此往复,直到策略收敛。
策略梯度公式改进:
原梯度更新公式: (1)
1、从公式(1)看出,如果环境给予的回报始终为正,那么我们无论我们的决策如何,最终的累积的长期回报值都是一个正数。换句话说,我们会增强所有的策略,只是对于实际效果并不好的策略,我们为其提升的幅度有所降低。这样的更新方法和我们的初衷并不一致,我们降低不好行动的概率,而不是轻微提升不好的行动概率。我们可以在累计总回报上减去一个偏移量b,使得在不同的试验中有正有负,修改后公式如下:
(2)
最简单的b可以使用所有试验累计回报的期望值,如
2、从修改后公式(2)中我们可以看到一个问题,不论是那个时间段,我们都要用策略的梯度乘以所有时刻的回报值总和,这样的设计显然是不合理的。因为理论上,在t时刻我们完成了决策后,它最多只能影响t时刻之后的所有回报,并不会影响t时刻之前的回报,因为我们无法通过现在的决策影响已经发生过的事情,所以这一部分的回报值不应该计算在梯度中,所以可以做如下修改:
(3)
3、从公式(3)看出,还有改进空间,直观上讲,未来离当前越远,当前的决定应该对其产生的影响越小,修改如下:
,其中
致谢:非常感谢李宏毅老师的视频https://www.bilibili.com/video/av24724071