openGL中绕任意轴旋转 1 代码2 参考文献: 直接上代码,具体细节请看参考文献部分
1 代码 glm::mat4 RotateArbitraryLine(glm::vec3 v1, glm::vec3 v2, float theta) 第一个参数v1是旋转轴的尾部,第二个参数v2是旋转轴的头部,第三个参数theta是绕v1v2轴的角度; //绕任意轴的旋转 glm::mat4 RotateArbitraryLine(glm::vec3 v1, glm::vec3 v2, float theta) { glm::mat4 rmatrix; float a = v1.x; float b = v1.y; float c = v1.z; glm::vec3 p1 = v2 - v1; glm::vec3 p = glm::normalize(p1); float u = p.x; float v = p.y; float w = p.z; float uu = u * u; float uv = u * v; float uw = u * w; float vv = v * v; float vw = v * w; float ww = w * w; float au = a * u; float av = a * v; float aw = a * w; float bu = b * u; float bv = b * v; float bw = b * w; float cu = c * u; float cv = c * v; float cw = c * w; float costheta = glm::cos(theta); float sintheta = glm::sin(theta); rmatrix[0][0] = uu + (vv + ww) * costheta; rmatrix[0][1] = uv * (1 - costheta) + w * sintheta; rmatrix[0][2] = uw * (1 - costheta) - v * sintheta; rmatrix[0][3] = 0; rmatrix[1][0] = uv * (1 - costheta) - w * sintheta; rmatrix[1][1] = vv + (uu + ww) * costheta; rmatrix[1][2] = vw * (1 - costheta) + u * sintheta; rmatrix[1][3] = 0; rmatrix[2][0] = uw * (1 - costheta) + v * sintheta; rmatrix[2][1] = vw * (1 - costheta) - u * sintheta; rmatrix[2][2] = ww + (uu + vv) * costheta; rmatrix[2][3] = 0; rmatrix[3][0] = (a * (vv + ww) - u * (bv + cw)) * (1 - costheta) + (bw - cv) * sintheta; rmatrix[3][1] = (b * (uu + ww) - v * (au + cw)) * (1 - costheta) + (cu - aw) * sintheta; rmatrix[3][2] = (c * (uu + vv) - w * (au + bv)) * (1 - costheta) + (av - bu) * sintheta; rmatrix[3][3] = 1; return rmatrix; } 2 参考文献: https://www.
容易出问题的点有两个:
1.回调函数如果用了非匿名的function,则函数方法名后面不能加括号,否则会直接执行这个方法。
2.bootstrap的表单form里面不能有name或者id为submit的按钮或者input,否则会造成servlet无法被提交的问题,点击提交按钮页面会直接被刷新一次。解决方法是把该按钮拎到form表单之外,或者改掉id和name为submit的属性值。
目录
一、201706-1 打酱油
AC代码
二、201706-2 公共钥匙盒
思路:
AC代码
一、201706-1 打酱油 AC代码 #include <bits/stdc++.h> using namespace std; int main() { int n; int sum=0; int p; cin>>n; p=n/10; sum=p; while(p>2) { if(p/5) { sum+=2*(p/5); p-=p/5*5; } else if(p/3) { sum+=p/3; p-=p/3*3; } } cout<<sum; return 0; } 二、201706-2 公共钥匙盒 思路: 因为钥匙借还时间不冲突,所以可以把开始时间和结束时间分开存储。对借的时间从小到大排序,还的时间也排序,对钥匙的标记判断钥匙是否借还。
对于同一把钥匙还钥匙的时间肯定比借钥匙的时间晚,所以判断结束的条件就是还完最后一把钥匙。
按照时间顺序对借还的钥匙一起排序,进行操作,操作如下:
当借钥匙的的时候查找一下钥匙的位置,然后把那个位置置空
当还钥匙的时候,从左向右找空位置,找到了就放回去。
AC代码 #include <bits/stdc++.h> using namespace std; struct DATA { int w; int s; }; struct DATA1 { int w; int c; }; bool cmp(DATA a,DATA b) { return a.
#include<stdio.h> /*使用n=strlen(s)时加这个#include<string.h>*/ int main(void) { char s[100];/*定义变量*/ int i, j, n, k; printf("请输入一串有重复字符的字符串:\n"); gets_s(s);/*输入字符串*/ for (n = 0; s[n] != '\0'; n++)
;
/*用于得到字符串长度,也可以使用n=strlen(s);*/ for (i = 0; i < n ; i++) { for (j = k = i + 1; j < n ; j++) if (s[j] != s[i]) s[k++] = s[j]; s[k] = '\0'; } printf("去掉重复字符后结果为:\n"); puts(s); /*也可以这样写,printf("去掉重复字符后结果为:%s\n", s);*/ }
#include<stdio.h> int main() { printf("请输入四个数:\n"); double a,b,c,d,max; scanf("%lf%lf%lf%lf",&a,&b,&c,&d); max=a; if(b>max) max=b; if(c>max) max=c; if(d>max) max=d; printf("最大值为%.2lf\n",max); return 0; }
目录
解决方案:
出现问题:
题目描述:
AC代码
解决方案: 1、首先明白题意:红绿灯的显示情况是从第一个数据时间算起的。所以每到一个灯的时候就要判断一下这个灯在我们前面花费的时间里经过的状况。
2、红绿灯的规则:红灯停(等到绿灯时刻同行),绿灯行,黄灯等一等(等过黄灯到红灯再到绿灯才能走)。
3、实现:
(1)每个红绿灯都有一个循环周期为(r+g+y).所以我们算灯当前的状态只需要对当前所有的花费%(r+g+y)就能得到当前一轮的红绿灯用了多久的时间。
(2)对每种红绿黄灯的等待情况进行分析——分析之前花费的时间到达当前红绿灯路口时,红绿灯的状态。我主要是计算(所有的花费%(r+g+y)- t ) 的时间处于哪个灯的时间状态。进行时间计算。
出现问题: 自己一开始一直60分,代码思路一直没有问题,主要就是因为 花费的所有时间爆内存了,int存储(long int)的数值大小是10的32次方,大小不满足。用long long的形式存储才能满足题目要求,这里注意如果是用c输出 打印的时候是%lld。
题目描述: 试题编号:201812-2试题名称:小明放学时间限制:1.0s内存限制:512.0MB问题描述: 题目背景
汉东省政法大学附属中学所在的光明区最近实施了名为“智慧光明”的智慧城市项目。具体到交通领域,通过“智慧光明”终端,可以看到光明区所有红绿灯此时此刻的状态。小明的学校也安装了“智慧光明”终端,小明想利用这个终端给出的信息,估算自己放学回到家的时间。
问题描述
一次放学的时候,小明已经规划好了自己回家的路线,并且能够预测经过各个路段的时间。同时,小明通过学校里安装的“智慧光明”终端,看到了出发时刻路上经过的所有红绿灯的指示状态。请帮忙计算小明此次回家所需要的时间。
输入格式
输入的第一行包含空格分隔的三个正整数 r、y、g,表示红绿灯的设置。这三个数均不超过 106。
输入的第二行包含一个正整数 n,表示小明总共经过的道路段数和路过的红绿灯数目。
接下来的 n 行,每行包含空格分隔的两个整数 k、t。k=0 表示经过了一段道路,将会耗时 t 秒,此处 t 不超过 106;k=1、2、3 时,分别表示出发时刻,此处的红绿灯状态是红灯、黄灯、绿灯,且倒计时显示牌上显示的数字是 t,此处 t 分别不会超过 r、y、g。
输出格式
输出一个数字,表示此次小明放学回家所用的时间。
样例输入
30 3 30
8
0 10
1 5
0 11
2 2
0 6
0 3
3 10
0 3
首先要写头文件#include<string>
否则可能会报错
其次要写头文件#include<iostream>
否则会报错:[Error] 'cout' is not a member of 'std'
最后要记住头文件#include<iostream>一定要写在最后,如果头文件顺序反了,可能会出现运算符重载的问题,会报错比如说:<<符号无匹配之类的
输出水仙花数 水仙花数定义
// 水仙花数 // 如果一个三位数值, // 每个位上的数值的立方,相加,等于这个数值本身, // 那么这个数值就是水仙花数 水仙花数判断条件
// 通过for循环,生成从100-999的所有3位数值 // 获取这个三位数,每一位上的数值 // 123,需要获取到1,2,3,这三个数 // 通过if判断,输出符合条件的数值 // 三个数值的立方和,等于这个三位数本身 JavaScript代码
for(var i = 100 ; i<= 999 ; i++){ var a = parseInt(i / 100); var b = parseInt(i % 100 / 10); var c = i % 10 ; if( a*a*a + b*b*b + c*c*c == i){ console.log(i+'是水仙花数'); } }
1.安装sudo apt install autocutsel
2.运行autocutsel -f
解决方案链接
在控制器上面增加以下内容即可
header("Access-Control-Allow-Origin: *"); //如果需要设置允许所有域名发起的跨域请求,可以使用通配符 * ,如果限制自己的域名的话写自己的域名就行了。 // 响应类型 *代表通配符,可以指出POST,GET等固定类型 header('Access-Control-Allow-Methods:* '); // 响应头设置 header('Access-Control-Allow-Headers:x-requested-with,content-type');
需求: 在arcgispro使用modelbuilder制作包含相交、汇总统计两个工具功能的gp工具,并且将其发布到portal,并在portal上操作该gp服务
效果图: 模型工具: 链接:https://pan.baidu.com/s/1MKSQpKZP7CVPQNWQDamAPA 提取码:md6x 具体实现: 1、制作gp工具。
1)将相交工具和汇总统计工具拖拽到modelbuilder界面这个是老套路;关键点是其中的相关参数设置需要注意:
①、模型的输入和输出建议使用模型参数,下图中带了字母P的是模型参数;
②其中“输入要素”数据的输入采用绝对路径。例如:C:\Users\admin\Desktop\新建文件夹 (2)\jsydgz.shp和C:\Users\admin\Desktop\新建文件夹 (2)\红线数据.shp,
③而模型的中间过程数据和输出参数采用相对路径,例如:%scratchworkspace%\output,在这里是通过引用临时工作空间来存储输出结果。 这个临时工作空间是在modelbuilder的环境(environments)下指定,同时注意需要在包含modelbuilder的工具箱所在的文件夹下创建一个名为“scratch.gdb”的文件地理数据库(我也不知道为什么,反正不这样出错过很多次),并在环境(environments)的临时工作空间(scratchworkspace)去指定这个“scratch.gdb”。 (今天又测试发现,也不一定需要手动创建scratch.gdb,只要在环境中指定一个gdb即可,但是手动创建scratch.gdb一定能成功。)
2)在模型属性面板配置模型的参数名称和数据类型
3)运行模型 ,必须确保模型能够成功运行。
2、发布gp服务。arcgispro菜单栏“share分享”——WebTool——在WebTool下拉列表找到刚刚成功运行的gp工具,在弹出的界面中设置相应的参数,如下图。
3、使用gp服务。发布成功之后在portal中查看刚刚发的gp服务,最终效果见开头“效果图”部分。
扩展: 解压包含shp的zip文件,并基于这个shp来与另一个面做相交运算以及汇总统计。其中解压zip采用Python制作的gp工具,并将gp工具添加到modelbuilder以进行后续的相交和汇总统计。
链接:https://pan.baidu.com/s/1lKEvGoEaOfr6dSXRdqiLpA 提取码:3y7g 参考文档: https://pro.arcgis.com/zh-cn/pro-app/help/analysis/geoprocessing/share-analysis/best-practices-authoring-web-tools-with-modelbuilder.htm
https://pro.arcgis.com/zh-cn/pro-app/help/analysis/geoprocessing/share-analysis/authoring-web-tools-with-python-scripts.htm
解决Deepin系统WiFi网速慢的问题 1. 问题描述2. 可能的原因3. 解决方案 1. 问题描述 最近正在尝试使用国产深度公司的deepin操作系统,系统界面非常漂亮,明显能看得出在UI上花了很大的功夫。
另一个选择使用deepin的原因就是,deepin在华为的加持下集成了应该说是国内目前最好的软件生态了。系统内置的wine版软件比Ubuntu中安装的wine版软件要好用得多,甚至可以支持TIM的截屏功能。除了在少数软件如Seafile的界面缩放上翻了车(但对使用影响不大),总体来说觉得deepin是Linux系统中对中文环境支持最好、软件生态(国内软件生态)支持最好的Linux操作系统了。
但是,在使用过程中,我发现系统在使用USB网桥时网速和网络延迟情况正常,但是使用WiFi的时候,即使是内网访问服务器网速最高也只能达到500KB/s左右,而在同等条件下,使用Windows系统则可以跑满无线网络带宽。
2. 可能的原因 这是一个有趣的问题,查看网络连接情况,发现WiFi带宽确实只有区区12Mbps,应该是无线网卡的配置或驱动上出了问题。
3. 解决方案 为确保无线网卡工作正常,首先建议更换网卡驱动。查看网卡型号后,在Linux无线驱动下载对应型号的、对应内核版本的驱动文件,并将其解压到 /lib/firmware目录下,重启。
更换完成后,重启查看WiFi速率,仍然不正常。根据IEEE对802.11的标准,现代一般路由器都支持802.11n/ac以上的标准,理论上信号良好时,带宽是能够达到54Mbps以上的,但是实际测试下来,下行速率仍然超不过500KB/s,那么就该怀疑是网卡的配置上出了问题。
打开终端,输入命令:
iwconfig 查看当前WiFi连接情况,编辑无线网卡配置:
sudo vim /etc/modprobe.d/iwlwifi.conf 发现在deepin的默认配置下,802.11n这个选项是默认关闭的。在早期的路由器很多还不支持11n的情况下,启用11n会降低WiFi搜网的速度,但现在11n应该是最基本的WiFi协议了,无线路由器可以不支持11ac,但要是连11n都不支持,那也不用拿到市面上来卖了。
因此,现修改配置如下:
options iwlwifi 11n_disable=0 bt_coex_active=0 power_save=0 swcrypto=1 重启计算机后,就会发现网速恢复正常了。
1. 模拟通信系统架构 ①信源与输入变换器:将模拟信号转换为电信号;
②调制器
③信道(包含噪声)
④解调器
⑤输出变换器与输出信号
2. 数字通信系统架构 ①信源与输入变换器:将模拟信号转换为电信号;
②数字编码器
③ 调制器
④信道(包含噪声)
⑤解调器
⑥数字解码器
⑦输出变换器与输出信号
ps:数字机顶盒的“模拟-数字”转换模块是独立的,作用是在模拟的电视终端将数字信号转换为模拟信号。
3. 数字通信系统功能架构 ①信源与输入变换器:将模拟信号转换为电信号;
②信源编码:减少冗余;
③信道编码:增加冗余;
④调制器
⑤信道(包含噪声)
⑥解调器
⑦信道解码
⑧信源解码
⑨输出变换器与输出信号
4. 数字通信系统的优缺点 优点:
抗干扰能力强;便于现代数字信号处理技术对数字信息进行处理、变换、储存;易于集成,使通信设备微型化,重量轻;易于加密处理,且保密性好。 缺点:
一般需要较大的传输带宽;系统设备较复杂。
#!/bin/sh
#================================生成CA===============================
#生成ca和私钥
openssl genrsa -aes256 -passout pass:****** -out ca.key 2048
#openssl rsa -in ca.key -pubout -out ca_pub.key
#生成ca证书请求and自签名
openssl req -new -x509 -sha256 -days 90 -key ./ca.key -out ./ca.crt
#error while loading serial number
echo "01" > /etc/pki/CA/serial
#=============================生成证书==================================+
#openssl req -x509 -sha256 -nodes -days 90 -newkey rsa:2048 -keyout self.key -out self.crt -subj /CN=*.abc.com
openssl genrsa -aes256 -passout pass:****** -out server.key 2048
#生成证书请求文件
openssl req -sha256 -new -days 90 -key .
1 绪论 国家食品药品监督管理局对有源医疗器械的监管越发重视,为保证有源医疗器械在日益复杂的电磁环境中能正常工作并不对周围环境中其他电子电气设备产生电磁干扰,需要符合医疗器械产品电磁兼容标准要求。
2012 年 12 月 17 日,国家食品药品监督管理局发布第 74 号公告图1.1所示,要求自 2014 年 1 月 1 日起实施YY 0505—2012《医用电气设备 第 1-2 部分:安全通用要求 并列标准:电磁兼容要求和试验》医疗器械行业标准,自此电磁兼容成为医疗器械型式检验中的强制检验项目, 所有二类、三类有源医疗器械必须满足电磁兼容标准要求。
图1.1 国家食品药品监督管理局发布第 74 号公告
该文主要针对静电放电放电抗扰度试验从测试原理、目的、仪器、试验方法、放电点位置做一详细说明,总结静电放电可能对设备造成的后果并结合实例进行解析,给出一些常见的整改措施并结合现状提出一些对未来的展望。
2 电磁兼容知识简介 2.1电磁兼容定义
电磁兼容(Electro Magnetic Compatibility, EMC):国家标准GB/T 4365-2003《电磁兼容术语》对电磁兼容所下的定义为“设备或系统在其电磁环境中能正常工作且不对该环境中任何事物构成不能承受的电磁骚扰的能力”,该定义包含了两部分内容,一是发射,即设备或系统应不对外界造成不能承受的电磁骚扰;二是抗扰度,即设备或系统应能承受其所在环境内的电磁骚扰。
在有源医疗器械领域,现行有效的电磁兼容通用标准是 YY 0505-2012,其中关于抗扰度的试验方法,基本都是参考的GB/T 17626系列标准。其基本思路是,使用发生器产生骚扰信号,通过特定的路径与被测设备耦合,观察被测设备(Equipment Under Test, EUT)的表现从而判断试验结果是否符合要求。
2.2何为静电放电
在 GB/T4365-2003《电工术语 电磁兼容》中,对ESD定义如下:“具有不同静电电位的物体互相靠近或直接接触引起的电荷转移”。针对电气和电子设备,依据我国目前现行有效的 GB/T 17626.2-2018《电磁兼容 试验和测量技术 静电放电抗扰度试验》,通过建立通用和可重现的基准,来评估设备受到静电放电干扰时能否保持基本性能。在实际测试中,采用静电放电发生器,模拟放电现象[1]。
2.3静电放电的干扰机理
静电放电其实是一种自然现象。两种不同的材料相互摩擦时,由于介电强度不同,就会产生静电电荷。当其中一种材料上的静电电荷积累到一定程度,在与另一个物体接触时,就会击穿其间介质通过这个物体到大地的阻抗形成通路而进行放电。人体放电模型简图,见图2.1。
图2.1 人体放电模型简图
其中,在考虑了人的身高体型差异、与接地平面的接近程度等因素之后,人体电容的典型值为 60~300 pF,而 150 pF 为常用的平均值。
放电电阻Rd代表了从人体手部接触端到接收设备静电放电的最坏情况下的阻抗,典型值为 330 Ω。充电电阻Re取50~100MΩ。
为了模拟EUT使用过程中有可能遇到的静电现象,GB/T 17626.2-2018 标准中规定的静电放电测试,分为直接放电和间接放电两种方式。间接放电的原理是在一定空间范围内产生指定强度的静电场,通常采用的试验方法为对水平耦合版和垂直耦合板在距离EUT0.1m处进行放电,检测EUT在该静电场中是否能正常工作。直接放电分为接触放电和空气放电,通过将静电电荷直接施加到设备表面的方式,检测EUT是否能正常工作[2]。
2.4静电放电的试验步骤
静电放电试验所需设备:静电放电发生器 绝缘桌 HCP&VCP 参考接地板GRP,如图2.
思路:题目说是包括中间所有的整数所以我们会想用两个数组进行比较只要有一个不同的那就不符合,那咋比较了因为两个数组里面的元素的顺序不同所以我们要让他顺序相同,所以对坐差的数组进行从小到大的排序,后面的就天机不可泄露啊(__) 嘻嘻……
#include <stdio.h> int main() { int a[101];//存放输入得数 int b[101];//存放输入数差值 int c[101];//存放本身的差值 int k = 0; int i,j; int temp; int n;//表示总共有多少个数 scanf("%d",&n); for(i = 0;i < n;i ++) { scanf("%d",&a[i]); } for(i = 0;i < n - 1;i ++) { if(a[i] - a[i + 1] < 0) { b[k] = -(a[i] - a[i + 1]); k ++; } else { b[k] = a[i] - a[i + 1]; k ++; } } //冒泡排序 for(i = 0;i < k - 1;i ++) { for(j = 0;j < k - 1 - i;j ++) { if(b[j] > b[j + 1]) { temp = b[j]; b[j] = b[j + 1]; b[j + 1] = temp; } } } for(i = 0;i < n - 1;i ++) { c[i] = i + 1; } for(i = 0;i < n - 1;i ++) { if(b[i] !
从本篇文章开始,作者正式开始研究Python深度学习、神经网络及人工智能相关知识。第一篇文章主要讲解神经网络基础概念,同时讲解TensorFlow2.0的安装过程及基础用法,主要结合作者之前的博客和"莫烦大神"的视频介绍,后面随着深入会讲解具体的项目及应用。基础性文章,希望对您有所帮助,如果文章中存在错误或不足之处,还请海涵~同时自己也是人工智能的菜鸟,希望大家能与我在这一笔一划的博客中成长起来。
文章目录 一.白话神经网络二.神经网络概念梳理三.TensorFlow1.TensorFlow简介2.安装过程3.基础入门 四.总结 同时推荐前面作者另外三个Python系列文章。从2014年开始,作者主要写了三个Python系列文章,分别是基础知识、网络爬虫和数据分析。2018年陆续增加了Python图像识别和Python人工智能专栏。 Python基础知识系列:Pythonj基础知识学习与提升Python网络爬虫系列:Python爬虫之Selenium+Phantomjs+CasperJSPython数据分析系列:知识图谱、web数据挖掘及NLPPython图像识别系列:Python图像处理及图像识别 代码下载地址(欢迎大家关注点赞):
https://github.com/eastmountyxz/AI-for-TensorFlowhttps://github.com/eastmountyxz/AI-for-Keras 作者theano人工智能系列:
[Python人工智能] 一.神经网络入门及theano基础代码讲解
[Python人工智能] 二.theano实现回归神经网络分析
[Python人工智能] 三.theano实现分类神经网络及机器学习基础
[Python人工智能] 四.神经网络和深度学习入门知识
[Python人工智能] 五.theano实现神经网络正规化Regularization处理
[Python人工智能] 六.神经网络的评价指标、特征标准化和特征选择
[Python人工智能] 七.加速神经网络、激励函数和过拟合
参考文献:
神经网络和机器学习基础入门分享 - 作者的文章
Stanford机器学习—第五讲. 神经网络的学习 Neural Networks learning
吴祖增前辈:神经网络入门(连载之一)
吴祖增前辈:神经网络入门(连载之二)
斯坦福机器学习视频NG教授: https://class.coursera.org/ml/class/index
书籍《游戏开发中的人工智能》、《游戏编程中的人工智能技术》
网易云莫烦老师视频(强推):https://study.163.com/course/courseLearn.htm?courseId=1003209007
TensorFlow在Win10上的安装教程和简单示例 - Suffering
[Tensorflow2.0] Tensorflow2.0的安装教程 - 牛andmore牛
一.白话神经网络 第一部分将简单讲解"莫烦大神"网易云课程对神经网络的介绍,讲得清晰透彻,推荐大家阅读;第二部分将讲述我的理解。开始吧!让我们一起进入神经网络和TensorFlow的世界。
首先,什么是神经网络(Neural Networks)?
计算机神经网络是一种模仿生物神经网络或动物神经中枢,特别是大脑的结构和功能,它是一种数学模型或计算机模型。神经网络由大量的神经元连接并进行计算,大多数情况下人工神经网络能在外界信息的基础上改变内部结构,是一种自适应的过程。
现代神经网络是一种基于传统统计学建模的工具,常用来对输入和输出间复杂的关系进行建模,或探索数据间的模式,神经网络是一种运算模型,有大量的节点或神经元及其联系构成。和人类的神经元一样,它们负责传递信息和加工信息,神经元也能被训练或强化,形成固定的神经形态,对特殊的信息有更强烈的反应。
神经网络是如何工作的呢?
如上图所示,不管这是一只跳跃飞奔的猫,或是一只静静思考的猫,你都知道它是一只猫,因为你的大脑已经被告知过圆眼睛、毛茸茸、尖耳朵的就是猫,你通过成熟的视觉神经系统判断它是猫。计算机也是一样,通过不断的训练,告诉哪些是猫、哪些是狗、哪些是猪,它们会通过数学模型来概括这些学习的判断,最终以数学的形式(0或1)来分类。目前,谷歌、百度图片搜索都能清晰识别事物,这些都归功于计算机神经系统的飞速发展。
神经网络系统由多层神经层构成,为了区分不同的神经层,我们分为:
输入层:直接接收信息的神经层,比如接收一张猫的图片输出层:信息在神经元中传递中转和分析权衡,形成输出结果,通过该层输出的结果可以看出计算机对事物的认知隐藏层:在输入和输出层之间的众多神经元连接组成的各个层面,可以有多层,负责对传入信息的加工处理,经过多层加工才能衍生出对认知的理解 神经网络举例说明
如下图所示,通常来说,计算机处理的东西和人类有所不同,无论是声音、图片还是文字,它们都只能以数字0或1出现在计算机神经网络里。神经网络看到的图片其实都是一堆数字,对数字的加工处理最终生成另一堆数字,并且具有一定认知上的意义,通过一点点的处理能够得知计算机到底判断这张图片是猫还是狗。
计算机是怎么训练的呢?
首先,需要很多的数据,比如需要计算机判断是猫还是狗,就需要准备上千万张有标记的图片,然后再进行上千万次的训练。计算机通过训练或强化学习判断猫,将获取的特征转换为数学的形式。
我们需要做的就是只给计算机看图片,然后让它给我们一个不成熟也不准确的答案,有可能100次答案中有10%是正确的。如果给计算机看图片是一张飞奔的猫(如下图),但计算机可能识别成一条狗,尽管它识别错误,但这个错误对计算机是非常有价值的,可以用这次错误的经验作为一名好老师,不断学习经验。
那么计算机是如何学习经验的呢?
它是通过对比预测答案和真实答案的差别,然后把这种差别再反向传递回去,修改神经元的权重,让每个神经元向正确的方向改动一点点,这样到下次识别时,通过所有改进的神经网络,计算机识别的正确率会有所提高。最终每一次的一点点,累加上千万次的训练,就会朝正确的方向上迈出一大步。
最后到验收结果的时候,给计算机再次显示猫的图片时,它就能正确预测这是一只猫。
激励函数是什么东东?
接着再进一步看看神经网络是怎么训练的。原来在计算机里每一个神经元都有属于它的激励函数(Active Function),我们可以利用这些激励函数给计算机一个刺激行为。当我们第一次给计算机看一只飞奔的猫时,神经网络中只有部分神经元被激活或激励,被激活传递下去的信息是计算机最为重视的信息,也是对输出结果最有价值的信息。
如果预测的结果是一只狗,所有神经元的参数就会被调整,这时有一些容易被激活的神经元就会变得迟钝,而另一些会变得敏感起来,这就说明了所有神经元参数正在被修改,变得对图片真正重要的信息敏感,从而被改动的参数就能渐渐预测出正确的答案,它就是一只猫。这就是神经网络的加工过程。
二.神经网络概念梳理 前面通过白话文讲述了神经网络之后,接下来我们对神经网络的概念从头再梳理一遍,这也是为后续深入学习奠定基础。
gitlab上传
打开gitlab创建新项目
在右键打开git
git config --global user.name “用户名”
git config --global user.email “邮箱”
git remote add origin http://项目.git
git add .
git status 查看
git commit -m “111”
git push -u origin master
输入用户名和密码
刷新gitlab
http://www.postgres.cn/docs/10/
在c#项目中用到的二进制、十六进制与字节数组的相互转换
class HexCommon { /// <summary> /// 16进制字符串转字节数组 /// 如01 02 ff 0a /// </summary> /// <param name="hexString"></param> /// <returns></returns> public static byte[] strHexToByte(string hexString) { hexString = hexString.Replace(" ", ""); if ((hexString.Length % 2) != 0) hexString += " "; byte[] returnBytes = new byte[hexString.Length / 2]; for (int i = 0; i < returnBytes.Length; i++) { string temp = hexString.Substring(i * 2, 2).Trim(); returnBytes[i] = Convert.ToByte(temp, 16); } return returnBytes; } /// <summary> /// 6进制字符串转字节数组 /// </summary> /// <param name="
Mybatis执行sqlSession.insert()和sqlSession.update() 在执行sqlSession.insert()和sqlSession.update()后需要进行 sqlSession.commit(),否则数据库不会插入数据,而且自增长id的情况下,在下一次成功的时候,会将未commit的数据id跳过。
@Test public void testUpdate(){ //mybatis配置文件 String resource = "conf.xml"; //使用类加载器加载mybatis的配置文件(它也加载关联的映射文件) InputStream is = MyTest1.class.getClassLoader().getResourceAsStream(resource); //构建sqlSession的工厂 SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(is); //创建能执行映射文件中sql的sqlSession SqlSession sqlSession = factory.openSession(); String statement1 = "com.test.my.mapping.userMapper.updateUser"; User user1 = new User(); user1.setId(1); user1.setName("马超"); user1.setAge(60); int update = sqlSession.update(statement1, user1); //如果没有commit,数据库是不会插入数据的 sqlSession.commit(); sqlSession.close(); } @Test public void testAdd(){ //mybatis配置文件 String resource = "conf.xml"; //使用类加载器加载mybatis的配置文件(它也加载关联的映射文件) InputStream is = MyTest1.class.getClassLoader().getResourceAsStream(resource); //构建sqlSession的工厂 SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(is); //创建能执行映射文件中sql的sqlSession SqlSession sqlSession = factory.
经过了查看tp6文档,我从几十行代码优化到几行代码就解决了多条件搜索功能!
我查看了下文档,是使用高级查询,运用模糊查询,就可以轻松解决多条件查询功能!
好了,废话不多说,下面直接上代码
$list = Db::name('message') ->field($field) ->where([ ['repeated', 'like', $sel_join. '%'], ['client', 'like', $sel_client. '%'], ['url', 'like', $url. '%'], ['date', 'between time', [$startTime, $endTime]], ['phone', 'like', $phone. '%'], ['delete_time', '=' , '0'] ]) ->order($order) ->paginate(['list_rows' => $limit, 'page' => $page]) ->toArray(); 可以多看看文档,还是有益处的!
转自:蜜雪冰城官网:http://www.mixuejm.cn/
文章目录 github看笔记的好处如何解决加载慢的问题 github看笔记的好处 markdown和code能一起使用真是非常方便,在本地使用jupyter notebook书写笔记,然后上传到github上,不仅自己复习的时候方便查阅,还能帮到其他有需要的人。在github上查看ipynb文件以及大文件时,需要加载很长时间,而且经常加载失败。使用起来很不方便而且让人头疼、浪费时间。比如我查看优达学城的一个深度学习的小项目,如果直接访问github仓库里的ipynb文件的话,会遇到加载失败或者等很久情况,如下图:
你也可以点击这个链接,体验一下加载速度:点击这里,然后自己打开ipynbj结尾的笔记 如何解决加载慢的问题 文件打不开很让人头疼,但是一个好的方法可以解决:
免费的nbviewer开源项目,解决了上面的问题。所有上传到github上的ipynb文件,都会同步到nbviewer服务器上。笔记也经过了渲染,显示效果很棒,而且访问速度非常快,使用方法是在nbviewer主页上,输入别人或自己的github用户名,找到自己创建的仓库,再找到对应的笔记。比如上面无法显示的笔记,去nbviewer上查看的话,能快速打开笔记,方便查看笔记内容。例如输入刚才那位用户的ID:q759729997 或者刚才项目位置:q759729997/Udacity_nd101_cn_p4
瞬间就能打开自己想看的项目:
你们点击链接体验一下加载速度:点击这里 深度学习项目 ,然后再打开ipynb的笔记。
几万行的代码可以瞬间打开,不用因为加载失败或者打不开让你头疼。
你可别学经常使用github的不会这个技能。它可以让你大大的节省时间学习其他知识。
一,gradle的定义 1,gradle是基于Apache Maven概念的项目自动化构建开源工具。他是使用一种基于groovy的 特定领域语言来声明项目配置,抛弃了 基于 XML的各种繁琐配置。
虽然gradle都是基于groovy的,但是由于其提供了一整套DSL,所以在开发gradle脚本时几乎脱离了groovy的感知。我们在这里将gradle当做一个独立的部署工具。因此不去深究,因为这个对于我们去了解gradle并没有多大的的问题。
2,gradle项目领域
每个项目都会有自己的gradle领域,配置脚本文件名默认是不变的build.gradle。
project之间如果出现父子关系,只有根project的build.gradle才会有setting.gradle配置文件,该配置文件的作用的声明其包含的子项目。
3,Task任务
每个project是由N个Task组织成的一个“有向无环图”,task之间有依赖关系从而决定了他们的执行顺序。
依赖方式:
task taskA( dependsOn : 'taskB')<<{ println 'task' } Task的三种来源以及创建方式 第一种就是gradle默认自带了几种task
Dependencies:显示所有Project(项目)的依赖信息
Projects:显示所有Project,包括根project以及子project。
Properties:显示一个Project所包含的所有Property
第二种就是直接在project中显式创建
hello << { println ' Hello Task' } 第三种直接是成品Task的方式进行引入
通过Apply方式引入,表达方式为Apply plugin:‘groovy’
proprety:属性
Project不仅包含Task而且还包含;property这个属性,,property磨人自带了一些属性而且同时也可以通过扩展ext的方式进行自定义扩展属性。
gradle的工作流程 一次的gradle工作流分为三大部分,主要是
(1)解析setting.gradle文件然后去遍历根目录,检查子项目是否满足规定。
(2)解析每个子project的gradle,然后根据Task去构建项目之间的有向无环图。
(3)直接执行,涉及到刷新下载依赖,以及build构建发布包等等。
gradle脚本详解-- 单project项目的文件详解 buildscript { repositories { jcenter() maven { url "https://plugins.gradle.org/m2/" } } dependencies { classpath 'com.netflix.nebula:gradle-netflixoss-project-plugin:5.1.1-rc.1' } } apply plugin: 'nebula.netflixoss' apply plugin: 'groovy' apply plugin: 'idea' group = 'com.
描述 os.popen() 方法用于从一个命令打开一个管道。
在Unix,Windows中有效
os.popen(command[, mode[, bufsize]]) command -- 使用的命令。 mode -- 模式权限可以是 'r'(默认) 或 'w'。 bufsize -- 指明了文件需要的缓冲大小:0意味着无缓冲;1意味着行缓冲;其它正值表示使用参数大小的缓冲(大概值,以字节为单位)。负的bufsize意味着使用系统的默认值,一般来说,对于tty设备,它是行缓冲;对于其它文件,它是全缓冲。如果没有改参数,使用系统的默认值。 返回一个文件描述符号为fd的打开的文件对象
示例 #!/usr/bin/python3 import os, sys # 使用 mkdir 命令 a = 'mkdir nwdir' b = os.popen(a,'r',1) print (b) 结果:
open file 'mkdir nwdir', mode 'r' at 0x81614d0 参考文章1:Python os.popen() 方法
参考文章2:管道 pipe是什么?(进程通信的一种方式)
web.xml配置 <filter> <filter-name>IPFILTER</filter-name> <filter-class>com.supconit.ticc3.util.common.IpFilter</filter-class> </filter> <!--定义filter拦截的地址--> <filter-mapping> <filter-name>IPFILTER</filter-name> <url-pattern>/datamonitor/founded/*</url-pattern> </filter-mapping> 自定义过滤器配置 public class IpFilter implements Filter { private static final Logger logger = Logger.getLogger(IpFilter.class); private static final Map<String,String> IP_MAP = new HashMap<>(); @Override public void init(FilterConfig filterConfig) throws ServletException { Properties pro = new Properties(); FileInputStream in = null; try { String fileName = this.getClass().getClassLoader().getResource("ip_config.properties").getPath(); in = new FileInputStream(fileName); pro.load(in); pro.forEach((k, v) -> { IP_MAP.put((String) k, (String) v); }); in.
GRE是一种隧道技术,它规定了如何将一种网络协议封装在另外一种网络协议中,比如局域网使用OSPF,广域网使用EGP,使用GRE可以将OSPF封装在EGP中,使OSPF可以跨广域网传播。
举个通俗的例子,你参加了刚刚结束的高考,但是你有一个富二代同学直接留学出国了,某天你想给他寄封信(请忽略电话、微信、电子邮件等方式),在国内的时候你们都说中国话,写汉字,现在信中也当然是汉字了,这就相当于OSPF协议,但是信件在邮件的过程中会经过好几个国家,他们不一定认识汉字,所以收信人和寄信人的地址就不能再用汉字了,需要用英文,英文就相当于EGP协议,而将你写好的信装起来的信封就相当于GRE技术。
信件在传递的过程中,中间转发的人看的是英文,相当于中间路由器使用的是EGP,你的富二代同学收到以后拆开信封才能看到你使用汉字写的信,就相当于边界路由器打开GRE的封装看到里面的OSPF协议。
ffmpeg -re -stream_loop -1 -i 2minTransformers6281_trailer1080p.flv -vcodec copy -f flv rtmp://192.168.1.26:1935/live/PFM_test_HD_test1
会出问题:
解决方法,ffmpeg版本太低,需要安装高版本的ffmpeg
身份证取景框的实现主要是借助于camera 组件及cover-view组件
先看下案例
wxml代码
<view class="camera_box"> <camera class="camera" wx:if="{{!show}}" device-position="back" flash="off" binderror="error"> <cover-view class="id_m"> <cover-image class="img" src="https://cdn.ctoku.com/201910234221235312.png"></cover-image> </cover-view> </camera> <image class="camera_img" src="{{src}}" wx:if="{{show}}"></image> <view class="action"> <button class="takeBtn" type="primary" bindtap="takePhoto" wx:if="{{!show}}"></button> <button class="saveImg" type="primary" bindtap="saveImg" wx:if="{{show}}"></button> <button class="cancelBtn" wx:if="{{show}}" type="primary" bindtap="cancelBtn"></button> </view> </view> js代码
Page({ /** * 页面的初始数据 */ data: { src: '', show: false }, cancelBtn () { this.setData({show: false}) }, saveImg () { wx.showModal({ title: '图片地址', content: this.data.src, }) }, takePhoto() { const ctx = wx.
学习新项目的方法
第一步:如同学自行车,首先你要让它跑起来,不要一上来就企图学习轮子什么组成,怎么传动的,最开始应该让你的项目跑起来,最后再试图去观察它的核心。
第二步:跑起来之后你就可以去学习项目的各项组成,试图去理解它为什么工作,怎么工作,可以去互联网上寻找一些博客理解。
第三步:思考怎样去优化它,理解它的原理。
记住:学习一个新知识不是为了去学习原理而装b,你使用就是为了使用,当开始考虑一些高阶的请求的时候再去学原理,不要本末倒置,为了去学原理而学原理。学原理不是目的,而是一种方法。
希望今后自己能多看一些博客和技术文档。视频可以快速带你入门,但是需求推动你往底部深入的时候,要更多的去看技术文档和博客。
要想有所成,必须有所舍,既要又要的年代已经过去,你总面临取舍,你总要舍弃才会有所得。没有必要计较眼前的得失,希望几年之后,你不会后悔当初的决定。就像转专业一样,即使当时很痛苦,也要比之后后悔
2019年11月27日09:11:18
应用层级分析: 级 别类 型类名注 释作用A1接口ApplicationContext应用上下文(环境获取、 bean容器、 消息资源、 事件发布器、 资源加载器)B1接口WebApplicationContextweb应用上下文( ServletContext 获取、 属性名称的定义{作用域, 服务上下文, 上下文参数和属性})C1接口ConfigurableWebApplicationContext配置web应用上下文(设置ServletContext、 设置和获取ServletConfig、 设置和获取configLocation)B2接口ConfigurableApplicationContext配置应用上下文(设置环境、 添加BeanFactory后置处理器、 添加应用监听器、 获取容器、 刷新、 属性名称的定义{转换服务, 环境, 系统属性, 系统环境})C2抽象类AbstractApplicationContext抽象应用上下文(核心类 refresh() 方法 刷新应用上下(其中12步操作)) 应用接口 ApplicationContext 继承 EnviromentCapable, ListableBeanFactory, MessageSource, ApplicationEventPublisher, ResourcePatternResolver 接口
AbstractApplicationContext 上下文核心类 (通用的上下文功能) 抽象实现的 org.springframework.context.ApplicationContext 接口。不要求配置使用的存储类型;简单地实现通用的上下文功能。使用模板方法设计模式,需要具体的子类来实现抽象方法。
主要方法 refresh() 作用就是刷新应用上下文。 (12步操作)
spring 源码分析 应用上下文刷新
AbstractRefreshableApplicationContext 核心容器 (DefaultListableBeanFactory) 继承 org.springframework.context.support.AbstractApplicationContext 抽象类。 创建 Bean 容器,并加载 Bean。
1、refreshBeanFactory() 实现上级抽象方法, 用于创建 DefaultListableBeanFactory 容器
2、loadBeanDefinitions(DefaultListableBeanFactory) 定义抽象方法, 留给子类实现。 用于加载 BeanDefinition
目录 入侵检测系统(IDS)概念入侵检测系统的分类根据数据源分类1 基于主机的入侵检测系统(HIDS)2 基于网络的入侵检测系统(NIDS) 根据检测原理分类1 异常入侵检测。2 误用入侵检测。 根据体系结构分类1.集中式2.等级式3.协作式 根据工作方式分类1 离线检测。2 在线监测。 入侵检测功能1 监控、分析用户和系统的活动2 发现入侵企图或异常现象3 记录、报警和响应 入侵检测系统(IDS)概念 入侵检测系统(intrusion detection system,简称“IDS”)是一种对网络传输进行即时监视,在发现可疑传输时发出警报或者采取主动反应措施的网络安全设备。它与其他网络安全设备的不同之处便在于,IDS是一种积极主动的安全防护技术。
在本质上,入侵检测系统是一个典型的"窥探设备"。它不跨接多个物理网段(通常只有一个监听端口),无须转发任何流量,而只需要在网络上被动的、无声息的收集它所关心的报文即可。对收集来的报文,入侵检测系统提取相应的流量统计特征值,并利用内置的入侵知识库,与这些流量特征进行智能分析比较匹配。根据预设的阀值,匹配耦合度较高的报文流量将被认为是进攻,入侵检测系统将根据相应的配置进行报警或进行有限度的反击。
入侵检测系统组成,基本组件如图所示:
事件产生器(Event generators),它的目的是从整个计算环境中获得事件,并向系统的其他部分提供此事件。
2.事件分析器(Event analyzers),接收事件信息,经过分析得到数据,并产生分析结果,并将判断的结构转变为警告信息。
3.响应单元(Response units ),它是对分析结果作出反应的功能单元,它可以作出切断连接、改变文件属性等强烈反应,也可以只是简单的报警。
4.事件数据库(Event databases )事件数据库是存放各种中间和最终数据的地方的统称,它可以是复杂的数据库,也可以是简单的文本文件。 入侵检测系统的分类 根据数据源分类 1 基于主机的入侵检测系统(HIDS) 主要用于保护运行关键应用的服务器,通过监视与分析主机的审计记录和日志文件来检测入侵,日志中包含发生在系统上的不寻常活动的证据,这些证据可以指出有人正在入侵或者已经成功入侵了系统,通过查看日志文件,能够发现成功的入侵或入侵企图,并启动相应的应急措施。
2 基于网络的入侵检测系统(NIDS) 主要用于实时监控网络关键路径的信息,它能够监听网络上的所有分组,并采集数据以分析现象。基于网络的入侵检测系统使用原始的网络包作为数据源,通常利用一个运行在混杂模式下的网络适配器来进行实时监控,并分析通过网络的所有通信业务。
根据检测原理分类 1 异常入侵检测。 异常入侵检测是指能够根据异常行为和使用计算机资源的情况检测入侵。基于异常检测的入侵检测首先要构建用户正常行为的统计模型,然后将当前行为与正常行为特征相比较来检测入侵。常用的异常检测技术有概率统计法和神经网络方法两种。
2 误用入侵检测。 误用入侵检测技术是通过将收集到的数据与预先确定的特征知识库里的各种攻击模式进行比较,如果发现有攻击特征,则判断有攻击。完全依靠特征库来做出判断,所以不能判断未知攻击。常用的误用检测技术有专家系统、模型推理和状态转换分析。
根据体系结构分类 1.集中式 集中式入侵检测系统包含多个分布于不同主机上的审计程序,但只有一个中央入侵检
测服务器,审计程序把收集到的数据发送给中央服务器进行分析处理。这种结构的入侵检测系统在可伸缩性、可配置性方面存在致命缺陷。随着网络规模的增加,主机审计程序和服务器之间传送的数据量激增,会导致网络性能大大降低。并且一旦中央服务器出现故障,整个系统就会陷入瘫痪。此外,根据各个主机不同需求配置服务器也非常复杂。
2.等级式 在等级式(部分分布式)入侵检测系统中,定义了若干个分等级的监控区域,每个入侵
检测系统负责一个区域, 每一 级入侵检测系统只负责分析所监控区域,然后将当地的分析结果传送给上一级入侵检测系统。这种结构存在以下问题。首先,当网络拓扑结构改变时,区域分析结果的汇总机制也需要做相应的调整:其次,这种结构的入侵检测系统最终还是要把收集到的结果传送到最高级的检测服务器进行全局分析,所以系统的安全性并没有实质性改进。
3.协作式 协作式入侵检测系统将中央检测服务器的任务分配给多个基于主机的入侵检测系统,这些入侵检测系统不分等级,各司其职,负责监控当地主机的某些活动。所以,可伸缩性、安全性都得到了显著的提高,但维护成本也相应增大,并且增加了所监控主机的工作负荷,如通信机制,审计开销,踪迹分析等。
根据工作方式分类 1 离线检测。 离线检测系统是一种非实时工作的系统,在事件发生后分析审计事件,从中检查入侵事件。这类系统的成本低,可以分析大量事件,调查长期情况,但由于是事后进行的,不能对系统提供及时的保护,而且很多入侵在完成后会删除相应的日志,因而无法进行审计。
2 在线监测。 在线监测对网络数据包或主机的审计事件进行实时分析,可以快速响应,保护系统安全,但在系统规模较大时难以保证实时性。
入侵检测功能 入侵检测系统能在入侵攻击对系统发生危害前检测到入侵攻击,并利用报警与防护系统驱逐入侵攻击。在入侵攻击过程中,尽可能的减少入侵攻击所造成的损失,在攻击后,能收集入侵攻击的相关信息,作为防范系统的知识添加到知识库中,从而增强系统的防范能力。
1 监控、分析用户和系统的活动 这是完成入侵检测任务的前提条件。通过获取进出某台主机及整个网络的数据,来监控用户和系统的活动。那么最直接一般的方法就是“抓包”,将数据流中的所有包都抓下来进行分析。
1.简述字符集UTF-8和GB2312的区别
UTF-8:通用转换格式,国际编码,包含世界所有国家使用的字符,英文8位1字节中文24位一字节(即一个中文文字占用3个字节空间)
GB2312 :简体中文字符集,文字编码采用双字节来表示(即不论中英文字符一个字符占用两个字节空间)
总结:UTF-8字符类型全面,但中文字符占用空间较多,适合外语使用频率高的使用环境,GB2312中文占用空间小但英文占用空间却大,适用中文使用频率高的环境。
2.datetime 类型和timestamp类型的相同点和不同点是什么?
相同点:两者都可用来表示YYYY-MM-DD HH:MM:SS[.fraction]类型的日期。
不同点: 两者的存储方式不一样 ,两者所能存储的时间范围不一样
3MySQL支持的数据类型主要有哪几类?17属于什么类型?‘17’属于什么类型?
tinyint、smallint、mediumint、int(integer)、bigint、float、double、decimal、tinytext、text、mediumtext、longtext、varchar、char、blog等
17属于 int整形,‘17’属于char字符串型
4.简述系统变量、全局变量和会话变量的关系。
系统变量包括全局变量和会话变量
全局变量在MySQL启动时由服务器自动初始化为默认值,主要影响整个MySQL的实列的全局设置,大部分都是作为MySQL的服务器调节参数存在。对全局变量修改会影响整个服务器。
会话变量在每次建立一个新的连接时,由MySQL初始化,会话变量定义是前面加一个@符号,随时定义和使用,会话结束就释放。对会话变量修改会影响到当前会话(当前数据库连接)
删除字符串中连续的重复字符 题目:实现删除字符串中连续的重复字符(除字母和数字)。
输入为字符串,将字符串中连续重复的,不是字母且不是数字的字符删去,然后输出处理后的字符串。
输入字符串最长50个字符,之后截断,只输出处理后的字符串。
例如
输入11+++2==13回车
输出11+2=3
代码:
#include <stdio.h>
#include <string.h>
#include <ctype.h>
int main(){
char a[51];//这里定义两个数组,我打算以数组b来输出数组a的值,并去掉重复的值
char b[51]={0};
int i,j=1;
scanf("%50s",a);
b[0]=a[0];
for(i=1;a[i]!=’\0’;i++)//判断不为结束符时
{
if(a[i]<‘0’||a[i]>‘z’||(a[i]>‘9’&&a[i]<‘A’)||(a[i])>‘Z’&&a[i]<‘a’)//判断不是字母和数字时
{
if(a[i]==b[j-1])//当a一个元素值等于b里面对应位置的前一个值时,直接跳过,然后进行下一次for循环
{
continue;
}
b[j] = a[i];//将a里面的值和赋给对应的b位置上
j++;
}
}
printf("%s",b);
return 0;
}
有错误的地方希望大家指出来,互相讨论_
一、静态网页项目 1.前端项目源码下载 链接:https://pan.baidu.com/s/15jCVawpyJxa0xhCJ9SwTCQ
提取码:m4an
2.编写nginx.conf和Dockerfile,放在项目根目录下 (1). 创建nginx.conf 替换原镜像中的配置文件,并将对应的端口设置到9000(端口可自己设定) worker_processes 1; events { worker_connections 1024; } http { include /etc/nginx/mime.types; default_type application/octet-stream; #有字体文件,加载css样式不出错 sendfile on; tcp_nodelay on; keepalive_timeout 30; server { listen 9000; server_name localhost; root /usr/share/nginx/dist; autoindex on; autoindex_exact_size off; autoindex_localtime on; location ~* \.(eot|ttf|ttc|otf|eot|woff|woff2|svg)$i{ try_files $uri $uri/ =404; index index.html index.htm; #设置首页 add_header Access-Control-Allow-Origin *; } } } (2). 创建构建镜像的文件, Dockerfile FROM nginx RUN mkdir /usr/share/nginx/dist RUN rm -rf /etc/nginx/nginx.
线性插值或 Lerp 函数会返回一个基于 Alpha 输入的 A 与 B 输入间的混合值。 在给定的示例中,当 Alpha 值为 0 时,将返回 A 的 100% 的值。 当 Alpha 值为 1 时,将返回 B 的 100% 的值。
1.查看phpinfo信息 找到对应的vc集成库版本等信息,我这里的是vc14、x86、nts内容的
2.下载所需扩展 需要注意安装redis扩展除了要安装redis外,还要安装igbinary 下载 igbinary //下载地址 http://windows.php.net/downloads/pecl/releases/igbinary 从这个地址找到对应的版本下载,我这里下载的是
解压文件,然后将 php_igbinary.dll 、php_igbinary.pdb这两个文件复制到当前php版本的ext文件夹里面,我的是在这里
下载redis //下载地址: https://windows.php.net/downloads/pecl/releases/redis/ 从这个地址找到对应的版本下载,我这里下载的是
解压文件,然后将 php_redis.dll 、php_redis.pdb这两个文件复制到当前php版本的ext文件夹里面,我的是在这里
3.修改php.ini配置文件 需要注意哦,如果本地有多个版本的php的话,需要找到对应版本的php里的php.ini文件哦
往php.ini文件里添加以下内容
extension=php_igbinary.dll extension=php_redis.dll 需要注意php_igbinary.dll 在前
4.保存php.ini后,重启phpstudy 5.打开phpinfo查看redis扩展是否安装成功 如果出现下面图结果的话,说明安装成功
6.如果弹出“php-cgi.exe 无法定位程序输入点zend_empty_string 于动态链接库”的话,可以通过以下办法解决哦 需要看下是否安装了igbinary,如果没有的话,请按2中的方法安装哦看下下载的版本对不对,下载版本不对的话,会报这个错误的;重新下载对应版本的就可以了
裁员,也是一门学问,
可谓博大精深!
以下,是互联网公司的裁员的多种方法:
-正文开始-
1
35岁+不予续签的理由:
千禧一代网感更强。
95后不予通过试用期的理由:
已婚已育员工更有责任心。
2
通知接下来要过苦日子,
让一部分不肯同甘共苦的员工自己走人,
以“兄弟”和“非兄弟”来区别员工。
3
强制996。员工如果平衡不了工作和家庭,
可在离婚或离职里二选一。
4
不布置任何工作,但下班前必须提交千字工作日报。
5
不给活干+指责员工不干活。
教唆工作量超负荷的同事在背后议论你。
6
转岗到陌生岗位上,没人教、不适应、跟不上节奏,
导致绩效不合格,被名正言顺开除。
7
8小时工作制——说好了8小时,
少一分、一秒,都不算8小时(但可以多)。
上班不考勤、不打卡,针孔摄像头监工,计算工作时长
点开弹窗也算摸鱼,即可轻松解除劳动合同。
8
员工家中有急事,不批假。
强行请假则计入旷工,满三天,无偿辞退。
9
进行学历、经历、资格再查,借机解雇员工,
以其“欺诈”导致劳动合同无效,解除劳动关系。
10
突击式裁员,15:00面谈,15:10收拾走人。
11
午夜在工作群@所有人,要求5分钟内汇报,
管你睡觉还是洗澡。
12
制定微信“5分钟内反馈”制度。
13
每年举办名义“加薪评选”,
50%通不过加薪考核、保持原薪;50%加薪1%。
14
给编程/视频/图像工作者,
配备I3处理器4G内存ps2014,
设置网络权限,使其工作无法正常开展。
15
路由器限速100kb/s。
16
积极离职者,前几名有丰厚奖励,先到先得。
后报名者奖励依次递减(拼团更优惠)。
17
公司临时通知已搬迁到新疆石河子分公司,
员工需自费去边疆报到,逾期视同离职。
18
在考核里加入高数考试,
全员参与,由HR批卷给分,不及格者算绩效不达标。
19
规定日期(第二天)前办理离职,可获N+1补偿,
逾期无效。
20
【初级】把阅读量计入考评,要求员工全员转发朋友圈。
【进阶】要求全员使用公司统一定制头像。
【究极】要求统一制服。
21
“八字与公司不和,面相与公司不搭,气场与公司不符。”
机房巡检 机房巡检步骤及内容x86服务器巡检思科系交换机配置信息显示命令华为系交换机配置信息显示命令防火墙巡检查看信息虚拟化巡检主要查看内容存储巡检1.硬件设备巡检2.通过系统查看存储状态 小型机巡检1.硬件设备巡检2.通过系统查看信息3.AIX系统巡检 机房巡检步骤及内容 x86服务器巡检 1.巡检步骤:
(1)服务器前机身查看: 查看液晶面板指示灯是否正常查看硬板指示灯是否正常 (2)服务器后机身查看: 主要查看电源模块、网口、光线口 2.告警日志查看方式:
【1】用网线将电脑与后机身IMM接口或systemMGT口连接【2】将电脑IP改为192.168.70.***(第四段除1和125)【3】ping 192.168.70.125【4】在浏览器IP地址栏输入以上IP【5】输入用户名和密码查看服务器信息 思科系交换机配置信息显示命令 switch> 用户模式 1:进入特权模式enable
switch> enable
switch#
2:进入全局配置模式configure terminal
switch> enable
switch#configure terminal
switch(conf)#
3:配置信息查看
switch> enable
switch# show version 察看系统中的所有版本信息
show interface vlan 1 查看交换机有关ip 协议的配置信息
show running-configure 查看交换机当前起作用的配置信息
show interface fastethernet 0/1 察看交换机1 接口具体配置和统计信息
show mac-address-table 查看mac 地址表
show running-config 查看运行的所有配置
show arp all 查看arp信息
show memory 查看内存资源使用率
show fna 查看风扇
show power 查看电源
Vue基础知识
1:Vue生命周期以及钩子函数 Vue实例有一个完整的生命周期,也就是从开始创建、初始化数据、编译模板、挂载DOM渲染、更新渲染、销毁等一系列过程,我们称为是Vue的生命周期,也就是说从Vue实例创建到销毁这一过程,称为是生命周期
我们先来看一张非常经典的图片
每一个组件或者是实例都会经过一个完整的生命周期,总共分为三个部分:初始化,运行中,销毁。
实例和组件通过new Vue()创建出来之后会初始化事件和生命周期,然后执行beforeCreate钩子函数(此时,数据还没有开始挂载,只是一个空壳,无法访问到数据以及真是的DOM,这时一般不做挂在数据或者是绑定事件等);然后执行created函数(这个时候可以使用到数据,以及可以更改数据,这里是在渲染前倒数第二次更改数据的机会,不会触发其他的钩子函数。一般在这里做数据的获取);接下来开始找实例或者组件对应的模板,编译模板为虚拟的DOM放入到reader函数中准备渲染,然后执行beforeMount钩子函数(在这个函数中虚拟的DOM以及创建成功,马上就要渲染,在这里可以更改数据,这里是渲染前倒数第一次更改数据的机会,不会触发其他钩子函数,可以做初始数据的获取);接下来开始render,渲染出真实的DOM,然后执行mounted钩子函数(此时组件已经出现在页面中,真实的DOM已经处理好了,事件都已经挂在好了,可以操作真实的DOM等事件);当组件或者是实例的数据更改之后,会立即执行beforeuUpdate()然后虚拟的DOM机制会重新构建虚拟的DOM与上一次虚拟的DOM树利用diff算法进行对比之后重新渲染,一般不做什么事
当更新完成之后,执行updated(数据已经更新完成,DOM也重新render完成,可以执行更新之后的虚拟DOM),当通过某种途径调用$destroy,立即执行beforeDestroy(一般在这里面做一些善后工作,例如清楚计时器,清除指令绑定事件等,去除组件的数据绑定,监听,只剩下DOM空壳之后,这个时候执行destroyed,销毁
钩子函数:
beforeCreate() {}
created() {}
beforeMount() {}
mounted() {}
beforeUpdate() {}
updated() {}
beforeDestroy() {}
destroyed() {}
要注意的一点是:以上的生命周期钩子函数中,都是自动绑定this,因此就可以直接访问Vue实例中的数据,这就可以对实例的属性或者函数进行运算;也就是说我们就不能使用ES6的语法对生命周期钩子函数进行改造成箭头函数,这是因为箭头函数的this指向的是符上下文,箭头函数不存在this,箭头函数会向上寻找this的父上下文,所以就和我们期待的this就有所不同。
之前看到一篇写的很好的关于生命周期的博客,可以参考一下
https://mp.weixin.qq.com/s?src=11×tamp=1581051837&ver=2143&signature=4IUmKlHwNgVfv9kKGdVsjpPnvma3bcQ47BCwNvh*r88ioOgjRgVqzLNCmH2W2kzbTW8VlsVUrTwABZHxaE1bX4aLtqyxsoeq1sathoDrllf9SlvX1KAKax7c6D0RZ9TG&new=1
数据绑定 {{}} 说到绑定数据,最简单的方式就是使用{{ }}
如上图所示,定义一个变量msg,然后使用{{}} 绑定数据
v-model v-model 绑定表单元素中的值 实现数据双向绑定
如上例,使用v-model绑定数据我们可以看到当改变表单中的数据时,同时下面再次引用时的数据也发生改变
v-bind 那么我们知道v-bind也可以实现绑定,但是==v-bind是用来绑定属性的并且不能实现数据双向绑定,他是单向绑定==
如上图所示,绑定value属性,然后改变表单中的数据,不会影响变量的值 ,v-bind可以简写成为:属性名="",
除此之外,v-bind除了可以绑定属性之外,还可以绑定单个或者是多个类名称
绑定单个类名称
绑定多个类名称
或者也可以使用这样的方式实现
<p v-bind:class="{'p1':false,'p2':true}">{{msg}}</p> 同时 v-bind也可以直接绑定样式style
<p v-bind:style="{color:'red'}">{{msg}}</p> 或者使用变量
v-for 循环绑定 同时v-for也可以绑定多个数据(v-for支持第二个参数既当前变量的索引)
条件渲染v-if 一般使用v-if,v-else,v-else-if条件判断,常用在某种情况下显示某种元素
<div v-if="Math.random() > 0.5"> Now you see me </div> <div v-else> Now you don't </div> v-show v-show是用来显示元素,为true显示,为false不显示
Ubuntu系统使用apt-get install 下载的mysql 然后远程连接一下,发现拒绝了,然后总结了一下8.0mysql远程连接可能会出现的问题 这些问题大致可以分为三种 第一种 由于是因为8.0才出的问题(当然稍微低一点的可能也会有同样的问题,具体到什么版本我也不太确定,但是听说5.7也有这个问题,再往下真的不知道了)所以就放在最上面了
主要问题,在连接时
查看mysql配置
sudo vim /etc/mysql/mysql.conf.d/mysqld.cnf 最好使用sudo打开,因为这个文件默认是只读的。
bind-address = 127.0.0.1
找到这个改为0.0.0.0
bind-address = 0.0.0.0
保存重启mysql
第二种 没有授予连接权限,主要在于连接的用户,一般都是root(当然也可以是别的)
先查看下你的root用户
select Host,User from mysql.user; use mysql; update user set host = "%" where user = "root"; 然后记得添加一句,让你的配置立刻生效
flush privileges; 第三种 这种本来应该比较重要,防火墙问题,3306端口未被开放。但是我查了一下我的防火墙默认竟然是关着的,我也是服了。关于Ubuntu防火墙的问题可以查看这篇,Ubuntu的防火墙还是比原始的iptable简单得多的。
Ubuntu的防火墙设置
从菜鸟教程复制过来的,
转载地址:https://www.runoob.com/numpy/numpy-array-creation.html
1.创建未初始化的narray数组 格式如下:
numpy.empty(shape=, dtype=, order=) 示例:
mport numpy as np x = np.empty([3,2], dtype = int) print (x) 结果如下: [[ 6917529027641081856 5764616291768666155] [ 6917529027641081859 -5764598754299804209] [ 4497473538 844429428932120]] 2.创建0数组,元素全部为0 格式:numpy.zeros(shap, dtype, order)
示例:
import numpy as np # 默认为浮点数 x = np.zeros(5) print(x) # 设置类型为整数 y = np.zeros((5,), dtype = np.int) print(y) # 自定义类型 z = np.zeros((2,2), dtype = [('x', 'i4'), ('y', 'i4')]) print(z) 结果如下:
[0. 0. 0.
<dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-generator</artifactId> <version>3.2.0</version> </dependency> <dependency> <groupId>org.apache.velocity</groupId> <artifactId>velocity-engine-core</artifactId> <version>2.1</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.47</version> </dependency> <dependency> <groupId>org.freemarker</groupId> <artifactId>freemarker</artifactId> <version>2.3.23</version> </dependency> 一定记得增加freemarker依赖
效果图 背景图片 下载ECharts npm install echarts --save 引入并注册全局ECharts 在 main.js 文件里引入并注册 ( 这里是 Vue3.0 的模板 )
import Vue from 'vue' import App from './App.vue' import router from './router' import store from './store' import echarts from 'echarts' Vue.prototype.$echarts = echarts Vue.config.productionTip = false new Vue({ router, store, render: h => h(App) }).$mount('#app') 在组件中使用ECharts <template> <div class='wrapper'> <div class='chart' id='chart'></div> </div> </template> <script> export default { data () { return {} }, mounted () { this.
mybatis中<![CDATA[]]>的作用 在使用mybatis 时我们sql是写在xml 映射文件中,如果写的sql中有一些特殊的字符的话,在解析xml文件的时候会被转义,但我们不希望他被转义,所以我们要使用<![CDATA[ ]]>来解决。
<![CDATA[ ]]> 是什么,这是XML语法。在CDATA内部的所有内容都会被解析器忽略。
如果文本包含了很多的"<“字符 <=和”&"字符——就象程序代码一样,那么最好把他们都放到CDATA部件中。
但是有个问题那就是 等这些标签都不会被解析,所以我们只把有特殊字符的语句放在 <![CDATA[ ]]> 尽量缩小 <![CDATA[ ]]> 的范围。
实例如下:
<select id="allUserInfo" parameterType="java.util.HashMap" resultMap="userInfo1"> <![CDATA[ SELECT newsEdit,newsId, newstitle FROM shoppingGuide WHERE 1=1 AND newsday > #{startTime} AND newsday <= #{endTime} ]]> <if test="etidName!=''"> AND newsEdit=#{etidName} </if> </select> 因为这里有 “>” “<=” 特殊字符所以要使用 <![CDATA[ ]]> 来注释,但是有 标签,所以把等 放外面
标题关于MSF侦听模块的第一次使用 侦听模块exploit/multi/handler在使用这个模块的时候也被这个功能惊呆了,不管外网内网都能反弹shell,就是windows10的防火墙过不去,windows7的查不到,可能不更新的原因吧。如果想过墙只能自己加免杀的代码喽,反正我是还没学到呢。或者去百度shellter下载剥壳机自己加免杀的,有两个版本免费版和专业版,本人亲测免费版过不了windows10的墙也不知道能过啥,专业版买不起,有钱可以试试,估计windows10墙是杀不掉的,好了,不说废话了。开始实操!
准备工作:虚拟机linux kali4.0 靶机windows7
首先去https://www.cnblogs.com/backlion/p/6000544.html在里面有各种msf生成payload命令,根据自己的需求来生成payaload我们这里是windows7的靶机所以选生成windows的payload复制粘贴到一个新建的txt文档上。
修改里面的LHOST和LPORT值 注意LHOST值改成kali主机IP 也就是使用侦听模块的kali LPORT改成一个没用端口这里我用的1124
把这段代码复制到kali终端里执行生成一个shell.exe文件
在文件夹里面找到这个shell.exe文件复制到靶机windows7里面我这里是复制的各位用的时候看你们的手段了。
好了到这里就可以利用侦听模块了在msf下进入到侦听模块中 use exploit/multi/handler
在侦听模块中加载payload攻击模块也就是刚才自己生成的那个模块
show options 查看配置在这里我们需要配置一下LHOST 和 LPORT
LHOST和LPORT的配置和刚才修改文本中的值一样
set lhost 192.168.50.125
set lport 1124
show options查看是否配置完成
这里我们配置完成之后就可以run运行侦听了 这里我们点击windows7里面shell.exe文件,kali成功拿到shell
接下来你们懂的,嘿嘿!!!
这里在教大家一个实用的命令在命令行下输入chcp 65001解决乱码问题
本人亲测外网内网均可使用windows10只要你能解决防火墙和杀毒软件问题拿到shell也没问题反正我是不会了,
问题阐述:
[root@linuxprobe yum.repos.d]# mount -o loop /dev/cdrom /media/cdrom
mount: no medium found on /dev/sr0
解决方法:
对应的虚拟机右键---->设置——硬件——CD/DVD——设备状态的“已连接”和“启动时连接“都勾选就可以了,两个空格都选上就可以了。
我们一般用rolling+apply(fun,par)来进行滑动窗口处理某类序列,例如做量化交易时间序列,标的序列等等; 但如果apply函数有参数的话就需要注意。 apply的函数和参数实际上类似于指针的内存地址传递,也就是说滚动执行中参数par实际上是会变化的,如果要在fun中保存这个参数值就需要注意,不能用“=”来赋值,例如
def rolling_buy(code):
code_local=code
df_code=pd.DataFrame(df_tradePrice[int(code)]) df_code.reset_index(level=0, inplace=True) df_code.set_index(['date'],inplace=True) buy_price=df_code.loc[buy_date,'close'] ...... ....... **trade=pd.Series({'code':code_local,'buy_date':buy_date,'sell_date':sell_date,'buy_price':buy_price,'sell_price':sell_price,'return':re},name=self.Number)** self.d_result=self.d_result.append(trade) return self.Number **No=code_list.rolling(1).apply(rolling_buy,raw=True)** 上述函数对各个股票按code进行处理,然后汇总在d_result中,注意黑色部分code_local=code,“=”是内存赋值,所以结果表格d_result中,'code’就会出现乱数值。
因此这里要用值copy语句
code_local=code_local=copy.copy(code)
问题解决
前言 很多朋友在使用scrapy编写爬虫的时候,都能感受到这个框架的在定制性方面的强大。我们完成一个爬虫只需要定义好Spider抽取规则即可。即使再复杂一点的需求,我们也可以通过pipeline来控制爬虫的输出,middleware来控制下载中的请求定制。可是大家有没有想过scrapy是如何将我们的初始种子url一步步的下载、解析、加入新队列,周而复始的运行呢?
这篇文章我来带着大家通过阅读文档,源码,来一步步的理清我们的思路。
阅读方法 直接阅读源码,往往会给人一头雾水的感觉,如果脑中没有一定架构概念的话,很容易陷入到代码的汪洋中。这里我们通过三个步骤来阅读他的源码:
先看懂scrapy的官方文档,也就是架构页面。下载scrapy源码,从文件夹根目录开始看,选择重要的部分研究。使用pycharm执行爬虫,完整观察一个爬虫运行的周期。 下面开始按照步骤一步一步的来。
scrapy的官方文档 scrapy的文档中内容很多,官网左侧的导航栏分为五个主题:
First steps。不用说,这部分大家肯定学写爬虫时候都看过,主要是将安装和编写第一个爬虫Basic concepts。这一部分主要是scrapy的各个组件,包括命令行(Command line tool),选择器(Selectors)等等,这部分文档过于细化,只是一个各个组件的清单,没法帮我们理清“数据(种子url)的来龙去脉(下载、解析...)”Built-in services。这一部分主要是爬虫的监控方面,包括日志、状态收集等。Solving specific problems。这部分主要是一些专题,比如部署爬虫等。Extending Scrapy。这部分的第一个topic"Architecture overview"讲的主要是整个scrapy的数据流向,这部分就是这篇博客主要阅读的部分。剩下的部分讲的主要是针对各个部分如何进行扩展。All the rest。这部分主要是发布的记录等。 打开Architecture overview:
我们主要分析下面的数据流图:
我们写爬虫时候经常用到的就是图中浅蓝色的spiders和深蓝色的middlerwares,以及浅绿色的pipelines和一些定制话的downloader,因此相对于熟悉的组件也是这些。
但是真正控制数据流向的是engine和scheduler两个部分,而scrapy完美的把他们隐藏了起来,让我们专注于开发爬虫业务。因此我们要格外主要这两个重要的组件。
我第一次看见这个架构图时候第一个直观的感觉,engine应该是最复杂的部分,他从spider、downloader、pipeline、scheduler四个组件控制requests、responses、items三类数据,其中还要涉及到下载的异步问题,之前看网上说scrapy中使用了Twisted网络异步框架,应该用到的就是这里。
而scheduler应该起到一个队列的作用,存储爬虫url列表。
当然以上都是我的猜测,下面来看下官网对上图的数据流动介绍:
"引擎"从"爬虫"获取种子url。"引擎"将种子url推入"调度器",并向“调度器”请求一个url。“调度器”返回“引擎”一个url。”引擎“将url送入”下载器“,同时中间经过”下载器中间件“。”下载器“把下载的页面又通过”下载器中间件“,发送回”引擎“。”引擎“将下载的页面送入”爬虫“,同时中间经过”爬虫中间件“。”爬虫“解析下载的页面(这部分就是我们最经常写的解析方法),把结果和新链接发给”引擎“,同时经过”爬虫中间件“。”引擎“将结果发送给pipeline,把新链接发给”调度器“,并向“调度器”请求一个url。重复上述过程,直到”调度器“中没有剩余链接。 从上述过程我们就可以看出:
”引擎“在scrapy中起到的是一个关键性的位置,从第2步开始到第8步就是一个大循环,终止条件就是”调度器“中不再有新的url链接。而”调度器“主要维护一个队列,相应”引擎“的需求。”下载器“专注于下载。”爬虫“主要是我们来编写,符合业务需求。pipeline主要将抓取结果持久化。”下载中间件“以及”爬虫中间件“主要应对于平时开发时候遇到的实际处理流程。 所以”引擎“和”调度器“是scrapy中最核心的东西,搞懂他们,scrapy的源码我们也就看懂了。
在这页官方文档的最后,特意提到了异步编程与Twisted,因此我猜测”引擎“应该就是基于Twisted实现的,用来处理多线程问题以及异步下载。
在看完文档中对于scrapy的架构介绍后,我们上github下载一下最新的scrapy源码,开始接下里的分析。
scrapy的源码结构 一开始源码的时候,肯定是一片一片的不容易找到重点,我们按照前面的思路,先找到scrapy的心脏——”引擎“。
打开源码文件夹:
这里面core文件夹包含了引擎、调度器、以及下载组件,所以我们着重来看core中的内容:
core中引擎和调度器分别写在两个单独的py文件中,下载器单独组成了一个包,里面根据不同的协议列出了不同的实现下载实现方法。另外两个scrapyer.py、spidermw.py分别是用于解析页面的模块和管理爬虫中间件的模块。
我们在浏览这个core文件夹下每个py文件,会发现它们都在一开始引入了twisted包下面的模块,比如defer、task、reactor以及twisted自带的HTTPClient。因此到这里,我猜测scrapy就是一个披着twisted实现的爬虫框架,而上面爬虫架构图中各种异步同步的数据流动,应该就是借助twisted实现。
后序 但是scrapy源码还是比较复杂的,这里先提供给大家一个TinyScrapy的例子,模仿Scrapy的类名进行了简化,大家可以先看这篇文章“Scrapy源码分析(二):一个参考Scrapy实现的爬虫框架TinyScrapy”,对爬虫引擎、调度器有一个基本的认识。
目录 什么是owasp top10?排行榜(1)SQL 注入(2)失效的身份认证和会话管理(3)跨站脚本攻击 XSS(4)直接引用不安全的对象(5)安全配置错误(6)敏感信息泄露(7)缺少功能级的访问控制(8)跨站请求伪造 CSRF(9)使用含有已知漏洞的组件(10)未验证的重定向和转发 什么是owasp top10? OWASP(开放式Web应用程序安全项目)的工具、文档、论坛和全球各地分会都是开放的,对所有致力于改进应用程序安全的人士开放,其最具权威的就是“10项最严重的Web 应用程序安全风险列表” ,总结了Web应用程序最可能、最常见、最危险的十大漏洞,是开发、测试、服务、咨询人员应知应会的知识。(笔者这里记录2019版本的)
排行榜 (1)SQL 注入 点击传送门进入详解——>传送门
(2)失效的身份认证和会话管理 点击传送门进入详解——>传送门
(3)跨站脚本攻击 XSS 点击传送门进入详解——>传送门
(4)直接引用不安全的对象 点击传送门进入详解——>传送门
(5)安全配置错误 点击传送门进入详解——>传送门
(6)敏感信息泄露 点击传送门进入详解——>传送门
(7)缺少功能级的访问控制 点击传送门进入详解——>传送门
(8)跨站请求伪造 CSRF 点击传送门进入详解——>传送门
(9)使用含有已知漏洞的组件 点击传送门进入详解——>传送门
(10)未验证的重定向和转发 点击传送门进入详解——>传送门
我们在爬虫做请求的时候,一般会在request中添加请求头:Accept-Encoding,往往会指定方式为“gzip,deflate,br”三种压缩方式。
gzip和deflate为传统的压缩格式
br指的是Brotli,Google在2015年时候发布的新的数据压缩算法,而我们的工具request的response等文本只支持gzip,deflate格式的解压缩,还不支持br形式的解压缩。因此在打印输出时会出现所谓的“乱码”,也就是压缩后的网页信息。
因此我们在使用request这一类的python包时,不能抓包时候像浏览器请求一样,“gzip,deflate,br”三种方式都可接受,只能接受“gzip,deflate”两种。
脱离文档流:绝对定位、固定定位、浮动
定位 — position 定位方式为:top、left、bottom、right。加上margin无效。
使用绝对定位和固定定位后,行内元素变成块元素
相对定位 — relative 占据原先位置(不脱离文档流)从自身位置出发 绝对定位 — absolute 不占据原先位置(脱离文档流)位置从浏览器出发(一般情况需要给父元素加上相对定位 — 使其从父元素位置出发【父相子绝】)行内块元素使用,变为块元素 固定定位 — fixed 不占据原先位置(脱离文档流)
位置从浏览器出发(与父盒子无关)
行内块元素使用后变为块元素
position 的值
通过position属性进行居中对齐 /* 上下左右全局中 */ 标签选择器{ position: relative; // 相对定位 left: 50%; top: 50%; transform: translate(-50%, -50%); // 上下左右全局中 } /* 上下局中 */ 标签选择器{ position: relative; // 相对定位 top: 50%; transform: translateY(-50%); // 上下局中 } /* 左右局中 */ 标签选择器{ position: relative; // 相对定位 left: 50%; transform: translateX(-50%); // 左右局中 } 浮动 — float 浮动的属性值 脱离文档流,向指定方向移动,遇到 父元素边界或者 相邻浮动元素才会停下来父元素没有设置宽高,子元素设置浮动会导致父元素高度为零(需要清除浮动)。 当把框 1 向右浮动时,它脱离文档流并且向右移动,直到它的右边缘碰到包含框的右边缘:
上一篇文章我们介绍了如何使用SpringBoot+Netty开发JT808网关,这一篇文章将压力测试JT808网关。
网上看过一些百万级部标网关的文章,没有给出服务器配置,没有给出发送速率,没有给出测试报告,完全就是噱头,我们要保持清醒的头脑,一切以数据说话。
使用模拟终端压测工具,压测工具会发送五种消息:终端注册、终端注销、终端鉴权、心跳、位置汇报。JT808网关接收并解析位置信息后发送到RabbitMQ,gnss-web订阅RabbitMQ的位置消息并统计收到的位置数量。对比压测工具总共发送的位置数量和web收到的位置数量是否一致。
由于交通部的压力检测要求不高,我们不按交通部的要求压测,测试时会将发送速率提高2倍以上,看系统的承压能力达到多少。
服务器:腾讯云和阿里云Linux
配置:CPU:4核 内存:8G 带宽:5M
环境:JDK13,RabbitMQ,Redis,其中RabbitMQ和Redis使用Docker容器创建
测试程序:网关jt808-server、web后台gnss-web
消息序列化:ProtoBuf
模拟压测终端台数:3333、10000、12000
流程:启动docker容器的Redis和RabbitMQ,再启动gnss-web,加载20000台终端的信息到Redis缓存,再启动jt808-server。
1.首先我们先压测RabbitMQ的收发性能,吞吐量每秒可以达到2W+ 2.压测3333台终端 RabbitMQ的吞吐量:
服务器负载信息:
压测工具发送的位置数量:2523083
web收到的位置数量:2523083
web收到的位置信息:
总结:压测时间:40分钟,位置数量:2523083,RabbitMQ吞吐量:3000+/s,CPU占用率:35-40%,带宽:1.5M
3.压测10000台终端 查看JT808网关线程,未发现有BLOCK阻塞线程。
总结:压测时间:40分钟,位置数量:1千万,RabbitMQ吞吐量:5000/s,CPU占用率:75-80%,带宽:3.5M
3.优化了性能后压测12000台终端 CPU比以前下降了不少:
JT808网关线程良好,未发现有BLOCK阻塞线程
停掉压力测试后我们检查一下会不会有内存泄漏,这是GC前的状态:
执行GC垃圾回收后,内存一下子下降了,绿色代表快照前的状态,如果进度条有红色,则表示有内存泄漏。这里全部为绿色,没有出现内存泄漏:
内存 显存,cpu,GPU 1 硬件上的区别1 内存条2 cpu如下图:3 显存:属于显卡的组成部分,主要负责存储GPU需要处理的各种数据;4 GPU:在显卡上,属于显卡的芯片,又称图形处理单元;5 显卡: 2 作用上的区别3 cpu和GPU的关系1 CPU2 GPU 1 硬件上的区别 这几个部分在硬件上就是独立并存的,不是一个东西;不过cpu和内存是一对,GPU和显存是一对;这两对各自完成各自的任务;
1 内存条 内存就是内存条,一般就是电脑上显示的4G,8G,16G内存条,cpu在计算的时候很多数据存储到这个内存条;也就是内存和cpu配对;
2 cpu如下图: 3 显存:属于显卡的组成部分,主要负责存储GPU需要处理的各种数据; 4 GPU:在显卡上,属于显卡的芯片,又称图形处理单元; 5 显卡: 结构:
电容:电容是显卡中非常重要的组成部件,因为显示画质的优劣主要取决于电容的质量,而电容的好坏直接影响到显卡电路的质襞。 [4]
显存:显存负责存储显示芯片需要处理的各种数据,其容量的大小,性能的高低,直接影响着电脑的显示效果。新显卡均采用DDR3/DDR5的显存, 主流显存容量一般为1GB ~ 2GB。 [4]
GPU及风扇:GPU即显卡芯片,它负责显卡绝大部分的计算工作,相当干CPU在电脑中的作用。GPU风扇的作用是给GPU散热。 [4]
显卡接口:通常披叫作金手指,可分为PCI、 AGP和PCI Express三种,PCI和AGP显长接口都基本被淘汰, 目前市面上主流显卡采用PCI Express的显卡。 [4]
外设接口:显长外设接口担负着显卡的输出任务,目前的新显卡包括一个传统VGA模拟接口和一个或多个数字接口(DVI、HDMI和DP)。 [4]
桥接接口:目前中高端显卡可支持多块同时工作,它们之间就是通过桥接器连接桥接口。
2 作用上的区别 cpu和内存条的关系相当于加工车间和车间临时小存库;cpu的计算材料都是来源于这个临时小存库内存;GPU和显存的关系类似于cpu和内存条的关系GPU和显卡的关系:GPU是显卡重要的部件,是显卡的心脏和大脑;显卡是由gpu(图像处理器)+显存+PVC版+金手指+挡板+接口+电容电阻等元件+散热器共同组成的,因为gpu最重要,所以约定俗成GPU往往是显卡的代名词。显存是用来存数据,GPU是用来计算; 3 cpu和GPU的关系 CPU擅长逻辑控制,串行的运算
GPU擅长的是大规模并发计算
cuda是NVIDIA公司设计的专门针对自家芯片的通用并行计算架构。通过CUDA显卡可以用来进行并行运算
1 CPU 1)CPU有强大的ALU(算术运算单元)
2)大的缓存(可降低延时,保存很多的数据在缓存里,当需要访问的这些数据,只要在之前访问过的,直接在缓存里面取即可。)
3)有复杂的逻辑控制单元
2 GPU GPU是基于大的吞吐量设计。GPU的特点是有很多的ALU(绿色)和很少的cache. cache的目的不是保存后面需要访问的数据的,这点和CPU不同,而是为thread提高服务的。
[1]https://blog.csdn.net/u012370185/article/details/94641724
应很多朋友的要求,今天分享一下如何使用SpringBoot和Netty构建高并发稳健的JT808网关,并且是兼容JT808-2011和JT808-2019的网关,此网关已经有多个客户在商用。
JT808网关作为部标终端连接的服务端,承载了终端登录、心跳、位置、拍照等基础业务以及信令交互,是整个系统最核心的模块,一旦崩溃,则所有部标终端都会离线,所有信令交互包括1078和主动安全的信令交互也会大受影响。所以,JT808网关的并发性稳定性健壮性成为整个系统最重要的考量之一。
很多朋友用Mina或者Netty编写网关程序时遇到过很多问题:
线程阻塞、内存溢出等。将所有数据转成16进制字符串,用字符串操作数据。字符串处理的效率是最低的,当终端越来越多时,性能问题就会凸显。应当充分使用Netty的ByteBuf处理数据。未充分利用Netty的pipeline链式处理器,将所有的业务都放在一个handler中处理。JT808消息类型多,几十上百个,如果采用if/else或者枚举case判断,造成业务处理类臃肿庞大,维护和新增业务处理及其困难。今年推出的JT808-2019,不知道如何兼容扩展。 本文使用JDK8+的环境开发,使用SpringBoot2.x以及Netty4.x,如有不懂JDK8的新语法,请查阅资料。
此网关的特性:
支持JT808-2011、JT808-2019、JT1078报警、主动安全报警使用MQ和Redis解耦,多模块数据共享订阅,不与任何数据库关联多环境开发跨平台,部署简单支持ProtoBuf和JSON序列化本公司首创的利用策略模式的底层封装库,模板可用于任何协议的开发,简化了网络编程的复杂度,只专注于业务开发,无任何网络编程经验的人员都可接手,节省开发成本。 1.通用TcpServer创建 public class TcpServer { public TcpServer(int threadPoolSize, int port) { NioEventLoopGroup bossGroup = new NioEventLoopGroup(1); NioEventLoopGroup workerGroup = new NioEventLoopGroup(); ServerBootstrap serverBootstrap = new ServerBootstrap(); serverBootstrap .group(bossGroup, workerGroup) .channel(NioServerSocketChannel.class) .option(ChannelOption.SO_BACKLOG, 1024) .childOption(ChannelOption.SO_KEEPALIVE, true) .childOption(ChannelOption.TCP_NODELAY, true) .childHandler(new ChannelInitializer<NioSocketChannel>() { @Override protected void initChannel(SocketChannel ch) throws Exception { } }); serverBootstrap.bind(port).addListener(future -> { if (future.isSuccess()) { //启动成功 } else { //启动失败 } }); } } 首先看到,我们创建了两个NioEventLoopGroup,这两个对象可以看做是传统IO编程模型的两大线程组。bossGroup负责监听端口,accept 新连接的线程组,这个线程数不宜过大,1-2个即可。workerGroup是负责处理每个连接的数据读写的线程组,默认线程数为CPU核心数的2倍。用通俗易懂的例子就是,一个企业运作,当然要有一个老板负责从外面接活,然后下面有很多员工负责具体干活,老板就是bossGroup,员工就是workerGroup。bossGroup接收完连接,扔给workerGroup处理。ChannelOption.
在创建第一个django项目时输入:
django-admin startproject HelloWorld
报错:
pkg_resources.DistributionNotFound: The ‘pytz’ distribution was not found and is required by Django
参考了网上很多方法都没有解决,最后解决办法是:
安装pytz模块(时区模块)
python -m pip install pytz
这一节将比较仔细的讲述一个比较重要的知识,就是模型的保存和加载。我们都知道深度学习模型在训练一些大数据集的时候往往需要很长的时间,如果这时候突然断网了或者停电了,那训练不就GG了吗?如果我想再次使用这个模型,难道要重新来过?当然不。在Tensorflow2.0中官方提供了多种模型保存和加载的方式,我们可以训练一定次数进行保存方便下次打开代码时接着进行训练,听起来是不是十分方便呢?接下来让我们来看一看具体的代码实现部分,我们采用最简单的MNIST数据集来演示模型保存和加载的过程。
一.模型简单配置 1.导入相关库。
from __future__ import absolute_import, division, print_function, unicode_literals import os import tensorflow as tf from tensorflow import keras from tensorflow.keras import layers 2.读取Mnist数据集。
(train_images,train_labels),(test_images,test_labels) = tf.keras.datasets.mnist.load_data() 3.选取部分数据集进行训练快速训练(这部分不是重点,因此简单配置一下)。在这里训练图像需要reshape成一维值,因为我们前期并没有经过卷积,而是直接传入MLP(多层感知机)进行训练。
train_labels = train_labels[:1000] test_labels = test_labels[:1000] train_images = train_images[:1000].reshape(-1,28*28)/255.0 #转一维并归一化 test_images = test_images[:1000].reshape(-1,28*28)/255.0 #转一维并归一化 4.搭建简单的模型。这里蛮提一下sparse_categorical_crossentropy损失函数和categorcial_crossentropy函数的差别,如果你的标签label是纯数字未经过one-hot编码则用前者,如果经过one-hot编码则用后者。
def creat_model(): model = tf.keras.models.Sequential([ layers.Dense(512,input_dim=784,activation='relu'), layers.Dropout(0.2), #防过拟合 layers.Dense(10,activation='softmax') ]) model.compile(optimizer='adam',loss='sparse_categorical_crossentropy',metrics=['accuracy']) return model model = creat_model() 5.打印模型概要。
model.summary() 二.模型训练参数自动保存 1.以 checkpoints 形式保存,我们可以用tf.keras.callbacks.ModelCheckpoint这个函数允许模型在训练的过程中和训练结束时回调保存的模型。我们首先要定义模型文件要保存的路径,接着设置ModelCheckpoint一些相关参数,最后将将其作为回调传入模型进行训练。
checkpoint_path = 'training_1/cp.ckpt' #模型保存路径和名称 checkpoint_dir = os.
报错如下 java.lang.ClassNotFoundException: com.fasterxml.jackson.databind.ObjectMapper at org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1360) at org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1182) at servlet.jsonServlet.doPost(jsonServlet.java:32) at servlet.jsonServlet.doGet(jsonServlet.java:40) at javax.servlet.http.HttpServlet.service(HttpServlet.java:634) at javax.servlet.http.HttpServlet.service(HttpServlet.java:741) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:199) at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96) at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:528) at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:139) at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:81) at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:678) at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87) at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343) at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:798) at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66) at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:810) at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1500) at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) at java.lang.Thread.run(Thread.java:748) 我是 ObjectMapper objectMapper = new ObjectMapper();这段代码出问题,于是:
解决方法 1.按住ctrl,鼠标左键点ObjectMapper ,打开了依赖的jar包。发现文件最上面出现download…的字样,点击下载。
2.耐心等下载完成。完成后,file选项卡打开project structure…
1/使用PL/SQL或者命令行工具使用sqlplus命令登录你的数据库,
先确认数据库的编码字符集:
select userenv(‘language’) from dual;
2/环境变量添加办法:右击我的电脑,点击“属性–>高级系统变量—》环境变量",在用户变量中新建键值分别为NLS_LANG:SIMPLIFIED CHINESE_CHINA.ZHS16GBK
3/在PLSQL中点击菜单 tools后点击preferences 在弹出的设置窗口中找到 Appearance下的language,当前显示:Chinese.lang,更改设置为none即可
4/退出重新登录plsql,再次查询有中文的数据的表,不显示乱码
关于.htaccess文件又不懂的同学可以去点击以下链接去了解
点击这里
当我们遇到目标限制了很多文件后缀名的情况时,我们可以考虑使用.htaccess进行绕过
首先我们先上传一个.htaccess文件,文件内容如下
SetHandler application/x-httpd-php
这段内容的作用是使所有的文件都会被解析为php文件
上传成功之后我们准备上传木马
木马后缀名只要不是目标所限制的就可以,文件内容为php一句话木马
上传成功之后使用蚁剑进行连接,连接成功,获得webshell
注意,如果.htaccess文件也被限制,可以试一下后缀名大小写,例如.Php
其次,大小写如果不行,还可以试试后缀名加空格
一、概述
ADC转换就是输入模拟的信号量转换成数字量。读取数字量必须等转换完成后,完成一个通道的读取叫做采样周期。采样周期一般来说=转换时间+读取时间,而转换时间=采样时间+12.5个时钟周期。采样时间是你通过寄存器告诉STM32采样模拟量的时间,设置越长越精确
二、STM32 ADC采样频率的确定
ADCCLK通常是由“AHB分频”->“HCLK(MHz)”->“APB2分频”->“ADC分频”得到的,ADC使用若干个ADC_CLK周期对输入电压采样,采样周期数目可以通过ADC_SMPR1和ADC_SMPR2寄存器中的SMP[2:0]位而更改。每个通道可以以不同的时间采样,就是设置采样周期SampleTime。
总转换时间如下计算:
TCONV(转换时间) = 采样时间(设置采样周期SampleTime)+ 12.5个周期,其中12.5个周期是采集12位AD时间是固定的。
采样时间周期类型:
000:1.5周期 100:41.5周期
001:7.5周期 101:55.5周期
010:13.5周期 110:71.5周期
011:28.5周期 111:239.5周期
例如:
当ADCCLK=14MHz(周期) 和 1.5周期的采样时间:
赫兹转换:1MHZ=1000KHZ=1000000HZ
时间换算:1s(秒)=1000ms(毫秒),1s=10^3ms(毫秒)=10^6us(微秒)=10^9ns(纳秒)=10^12ps(皮秒)
周期与频率的关系:T=1/f,f=1/T(其中f为频率,T为周期)
得出每秒14MHz,那么1HZ的时间周期为 1/14000000s
TCONV(转换时间) = 1.5周期 + 12.5周期 = 14周期 = 14/14000000秒 = 1us(微秒)
三、具体分析如下
(1)我们的输入信号是50Hz (周期为20ms),初步定为1周期200个采样点,(注:一周期最少采20个点,即采样率最少为1k) ,每2个采样点间隔为20ms/200=100us,在一个输入信号周期(20ms)内100us就要采集一次,以下计算都是以一个输入信号的周期为单元进行计算。
ADC可编程的通道采样时间我们选最小的1.5周期,则ADC采样周期一周期大小为
根据采集时间间隔来计算采集完200个点需要以什么样的频率才能完成,这个频率就是ADCCLK,当采样时间1.5周期:100us/1.5≈66us。 根据f=1/T公式,ADC时钟频率为1/66us=1/0.000066s≈15151.515Hz≈15KHz。
ADC可编程的通道采样时间我们选71.5 周期,则ADC采样周期一周期大小为(100us/71.5)。 100us/71.5≈1.3986us,ADC时钟频率为1/1.3986us=1/0.0000013986s≈0.715MHz。
(2)接下来我们要确定系统时钟:我们 用的是 8M Hz 的外部晶振做时钟源(HSE),估计得 经过 PLL倍频 PLL 倍频系数分别为2的整数倍,最大72 MHz。为了 提高数据 计算效率,我们把系统时钟定为72MHz,(PLL 9倍频)。则PCLK2=72MHz,PCLK1=36MHz;
我们通过设置时钟配置寄存器(RCC_CFGR) 中 有 为ADC时钟提供一个专用的可编程预分器,将PCLK2 8 分频后作为ADC 的时钟,则可知ADC 时钟频率为 9MHz
文章目录 一、服务器210安装redis服务二、服务器220远程访问服务器210的redis服务 服务器IPRedis服务器(主)192.168.1.210Redis服务器(从)192.168.1.220 一、服务器210安装redis服务 1、准备编译环境,安装编译器gcc,工具make。
yum install -y gcc yum install -y make 2、官网https://redis.io/下载redis。
wget http://download.redis.io/releases/redis-5.0.5.tar.gz 3、解压,安装软件包。
ls tar xzf redis-5.0.5.tar.gz #解压软件包 ls mv redis-5.0.5 /usr/local/redis #将redis-5.0.5移动至/usr/local/redis目录 cd /usr/local/redis/ #进入目录 make #安装 4、直接前台启动redis服务,如下图。
/usr/local/redis/src/redis-server 5、ctrl+c,退出前台redis服务。
6、设置redis服务后台启动。
方法一
nohup /usr/local/redis/src/redis-server /usr/local/redis/redis.conf #后台启动redis服务 方法二
vi /usr/local/redis/redis.conf #编辑配置,修改daemonize项为yes,如下图。 /usr/local/redis/src/redis-server /usr/local/redis/redis.conf #启动redis服务 7、启动redis服务,启动redis-cli客户端,本地测试Redis存储。
/usr/local/redis/src/redis-server /usr/local/redis/redis.conf netstat -anp |grep redis /usr/local/redis/src/redis-cli 8、查找并编辑redis.conf,在下图位置**“JUST COMMENT THE FOLLOWING LINE.”**下方,增加redis服务器本机IP(192.168.1.210),设置后其他主机也可以远程访问本机的redis服务,未设置则只能本机127.0.0.1才可访问redis服务。
find / -name redis.conf vi /usr/local/redis/redis.conf 9、防火墙开放6379端口,否则远程主机无法连接redis服务。
firewall-cmd --zone=public --add-port=6379/tcp --permanent firewall-cmd --reload firewall-cmd --zone=public --query-port=6379/tcp 10、重启redis服务,成功启动服务如下图,两个IP监听6379端口。
windows 系统上的命令, 分为外部命令和内部命令, 外部命令存放磁盘, 内部命令存放内存, 像 dir, cd, md, copy, type, ren等都属于内部命令, 内部命令隐藏在系统的两个文件上面: io.sys, msdos.sys 当计算机启动时就将这两个文件加载并常驻内存中,
工具/原料 windows
百度经验
copy 命令的使用 快捷键 win + R 打开任务管理器, 输入: cmd 点击: 确定
在 cmd 里面输入: copy /? 来查看 copy 命令的语法及使用、
语法:
copy [/D] [/V] [/N] [/Y] [/-Y] [/Z] [/L] [/A | /B] source [/A | /B]
[+ source [/A | /B] [+. . .]] [destination [/A | /B]]
参数:
source 指定要复制的文件
点击【阅读原文】,可以查看 jsliang 更多文章~
今日 LeetCode 题目解题放在公众号次条推送,小伙伴可以自行前往查看~ 一 目录 不折腾的前端,和咸鱼有什么区别
目录一 目录二 前言三 二维降一维四 递归降维五 flat() 降维六 参考文献 二 前言 在业务场景或者刷 LeetCode 的时候,曾经碰到多次碰到一个问题:
如何将二维甚至多维的数组转换成一维数组? 讲起将多维转成一维,突然想起一个词叫做【降维打击】,下面将这种二维甚至多维的打成一维数组的方法,叫做【降维】
这篇文章和你一起探讨下转换的方法~
三 二维降一维 我们先来个简单的:
二维数组如何降级成一维数组? 很多时候,我们的数组层次并没有那么深,只有个二维数组,所以我们可以了解下一些快捷的使用方法。
reduce() 二维降一维
const oldArr = [1, 2, [3, 4]];
const newArr = oldArr.reduce((prev, curr) => (prev.concat(curr)), []);
console.log(newArr);
// [1, 2, 3, 4]
concat() 二维将一维
const oldArr = [1, 2, [3, 4]];
const newArr = [].concat(...oldArr);
const newnewArr = Array.
一、啥是网页授权 现在,我们要实现一个微信内网页,通过微信访问网页时,网页会展示微信用户的个人信息。因为涉及到用户的个人信息,所以需要有用户授权才可以。当用户授权后,我们的网页服务器(开发者服务器)会拿到用户的“授权书”(code),我们用这个code向微信服务器领取访问令牌(access_token)和用户的身份号码(openid),然后凭借access_token和openid向微信服务器提取用户的个人信息。
第一步:用户同意授权,获取code第二步:通过code换取网页授权access_token第三步:拉取用户信息(需scope为 snsapi_userinfo) 授权是由微信发起让用户进行确认,在这个过程中是微信在与用户进行交互,所以用户应该先访问微信的内容,用户确认后再由微信将用户导向到我们的网页链接地址,并携带上code参数。
订阅号无法开通此接口,服务号需要微信认证。
二、获取流程 1、设置网页授权回调域名 先到公众平台官网中的开发者中心页配置授权回调域名。填写域名,而不是URL。
2、用户同意授权,获取code 引导用户访问此页面:
https://open.weixin.qq.com/connect/oauth2/authorize?appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=SCOPE&state=STATE #wechat_redirect 若提示“该链接无法访问”,请检查参数是否填写错误,是否拥有scope参数对应的授权作用域权限。 参数是否必须说明appid是公众号的唯一标识redirect_uri是授权后重定向的回调链接地址, 请使用 urlEncode 对链接进行处理response_type是返回类型,请填写codescope是应用授权作用域,snsapi_base (不弹出授权页面,直接跳转,只能获取用户openid),snsapi_userinfo (弹出授权页面,可通过openid拿到昵称、性别、所在地。并且, 即使在未关注的情况下,只要用户授权,也能获取其信息 )state否重定向后会带上state参数,开发者可以填写a-zA-Z0-9的参数值,最多128字节#wechat_redirect是无论直接打开还是做页面302重定向时候,必须带此参数 如果用户同意授权,页面将跳转至 redirect_uri/?code=CODE&state=STATE。若用户禁止授权,则重定向后不会带上code参数,仅会带上state参数 redirect_uri?state=STATE
3、通过code换取网页授权access_token 获取code后,请求以下链接获取access_token:
https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code 参数是否必须说明appid是公众号的唯一标识secret是公众号的appsecretcode是填写第一步获取的code参数grant_type是填写为authorization_code 正确会返回json数据:
{ "access_token":"ACCESS_TOKEN", "expires_in":7200, "refresh_token":"REFRESH_TOKEN", "openid":"OPENID", "scope":"SCOPE" } 错误会返回:
{"errcode":40029,"errmsg":"invalid code"} 4、通过access_token拉取用户信息 如果网页授权作用域为snsapi_userinfo,则此时开发者可以通过access_token和openid拉取用户信息了。
请求方法:
http:GET(请使用https协议) https://api.weixin.qq.com/sns/userinfo?access_token=ACCESS_TOKEN&openid=OPENID&lang=zh_CN 参数描述access_token网页授权接口调用凭证,注意:此access_token与基础支持的access_token不同openid用户的唯一标识lang返回国家地区语言版本,zh_CN 简体,zh_TW 繁体,en 英语 正确的返回值:
{ "openid":" OPENID", " nickname": NICKNAME, "sex":"1", "province":"PROVINCE" "city":"CITY", "country":"COUNTRY", "headimgurl": "http://thirdwx.qlogo.cn/mmopen/g3MonUZtNHkdmzicIlibx6iaFqAc56vxLSUfpb6n5WKSYVY0ChQKkiaJSgQ1dZuTOgvLLrhJbERQQ4eMsv84eavHiaiceqxibJxCfHe/46", "privilege":[ "PRIVILEGE1" "PRIVILEGE2" ], "unionid": "o6_bmasdasdsad6_2sgVt7hMZOPfL" } 参数描述openid用户的唯一标识nickname用户昵称sex用户的性别,值为1时是男性,值为2时是女性,值为0时是未知province用户个人资料填写的省份city普通用户个人资料填写的城市country国家,如中国为CNheadimgurl用户头像,最后一个数值代表正方形头像大小(有0、46、64、96、132数值可选,0代表640*640正方形头像),用户没有头像时该项为空。若用户更换头像,原有头像URL将失效。privilege用户特权信息,json 数组,如微信沃卡用户为(chinaunicom)unionid只有在用户将公众号绑定到微信开放平台帐号后,才会出现该字段。 错误的返回值:
错误: 加载数据到分区表中失败。 1 报错原因: 由于 修改了 mysql 中的 hive 字符编码 然后 hive 反应比较慢 识别不到 所以 报错。 2 解决方案: 第一步: 进入mysql mysql -uroot -p123456
第二步 :查看 mysql 的 数据库
mysql> show databases;
第三步:删掉 hive
drop database hive; 第四步:重新创建 hive
mysql> create database hive;
第五步: 再次查看 database;
mysql> show databases;
第六步: 修改 hive 的字符编码
mysql> alter database hive character set latin1;
最后 : 重新
创建分区表语法
create table score(s_id string,c_id string, s_score int) partitioned by (month string) row format delimited fields terminated by '\t';
常见编码及乱码的处理 常见编码及乱码的处理前言一、字符集与编码1、字符集简介2、ASCII编码3、Latin1字符集4、UTF-8编码5、字符集兼容性6、文件编码从哪看?ASCII码表 二、乱码1、文件乱码2、HTML乱码3、JSP乱码4、GET,POST请求乱码1)get提交2)post提交 5、URL包含特殊字符6、数据库乱码1、MySQL环境变量2、MySQL字符集3、MySQL字符集的设置4、MySQL字符集的转换过程5、MySQL乱码产生的原因6、编码无损转换 常见编码及乱码的处理 本文解决的问题
编码是什么字符是什么字符集是什么编码用在哪我们常出现的错误(乱码)怎么正确的使用编码 前言 我们日常接触到的文件分ASCII是“美国信息交换标准编码”的英文字头缩写,可称之为“美标”。美标规定了用从0到127的128个数字来代表信息的规范编码,其中包括33个控制码,一个空格码,和94个形象码。形象码中包括了英文大小写字母,阿拉伯数字,标点符号等。我们平时阅读的英文电脑文本,就是以形象码的方式传递和存储的。美标是国际上大部分大小电脑的通用编码。
然而电脑中的一个字符大都是用一个八位数的二进制数字表示。这样就有256个不同的数值,可以用来表示256个不同的字符。由于美标只规定了128个编码,剩下的另外128个数码没有规范,各家用法不一。另外美标中的33个控制码,各厂家用法也不尽一致。这样我们在不同电脑间交换文件的时候,就有必要区分两类不同的文件。第一类文件中每一个字都是美标形象码或空格码。这类文件称为“美标文本文件”(ASCII Text Files),或略为“文本文件”,通常可在不同电脑系统间直接交换。第二类文件,也就是含有控制码或非美标码的文件,通常不能在不同电脑系统间直接交换。这类文件有一个通称,叫“二进制文件”(Binary Files)。
本文讨论的内容只在可读文本即ASCII系列
文章目录 常见编码及乱码的处理前言一、字符集与编码1、字符集简介2、ASCII编码3、Latin1字符集4、UTF-8编码5、字符集兼容性6、文件编码从哪看?ASCII码表 二、乱码1、文件乱码2、HTML乱码3、JSP乱码4、GET,POST请求乱码1)get提交2)post提交 5、URL包含特殊字符6、数据库乱码1、MySQL环境变量2、MySQL字符集3、MySQL字符集的设置4、MySQL字符集的转换过程5、MySQL乱码产生的原因6、编码无损转换 一、字符集与编码 1、字符集简介 **字符(Character)**是各种文字和符号的总称,包括各国家文字、标点符号、图形符号、数字等。
**字符集(Character set)**是多个字符的集合,字符集种类较多,每个字符集包含的字符个数不同,常见字符集名称:ASCII字符集、GB2312字符集、BIG5字符集、 GB18030字符集、Unicode字符集等。计算机要准确的处理各种字符集文字,需要进行字符编码,以便计算机能够识别和存储各种文字。
**字符编码(Character encoding)**是把字符集中的某个字符编码为指定字符集中字符,以便文本在计算机中存储和通过通信网络的传递。常见的例子包括将拉丁字母表编码成ASCII,ASCII将字母、数字和其它符号编号,并用7比特的二进制来表示。
**字符序 (collation)**是指同一个字符集内字符之间的比较规则。只有确定字符序后,才能在一个字符集上定义什么是等价的字符,以及字符之间的大小关系。一个字符可以包含多种字符序。MySQL字符序命名规则是:以字符序对应的字符集名称开头,以国家名居中(或以general居中),以ci、cs、或bin结尾。以ci结尾的字符序表示大小写不敏感,以cs结尾的字符序表示大小写敏感,以bin结尾的字符序表示按二进制编码值比较。
2、ASCII编码 ASCII既是编码字符集,又是字符编码,ASCII直接将字符在编码字符集中的序号作为字符在计算机中存储从数值。
例如:在ASCII中A字符在表中排第65位,序号是65,而编码后A的数值是0100 0001,即十进制的65的二进制转换结果。
3、Latin1字符集 Latin1字符集在ASCII字符集基础上进行了扩展,仍然使用一个字节表示字符,但启用了高位,扩展了字符集的表示范围。
4、UTF-8编码 UTF-8(8-bit Unicode Transformation Format)是一种针对Unicode的可变长度字符编码,又称万国码。由Ken Thompson于1992年创建。现在已经标准化为RFC 3629。UTF-8用1到6个字节编码Unicode字符。
UTF-8是一种变长字节编码方式。对于某一个字符的UTF-8编码,如果只有一个字节则其最高二进制位为0;如果是多字节,其第一个字节从最高位开始,连续的二进制位值为1的个数决定了其编码的位数,其余各字节均以10开头。UTF-8最多可用到6个字节。 如表:
1字节 0xxxxxxx
2字节 110xxxxx 10xxxxxx
3字节 1110xxxx 10xxxxxx 10xxxxxx
4字节 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
5字节 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
6字节 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
key 关键字项
bf 平衡因子
data 其它数据域
lchild rchild 左右孩子
左
右
#右选 左旋
往右偏移说明插入在s3上了,s3s是h,s2是h-1
#左旋 右旋
#下面的代码是右边减左边,其实应该是左边减右边的
from bst import BiTreeNode,BST #下面的代码是右边减左边,其实应该是左边减右边的 class AVLNode(BiTreeNode): def __init__(self,data): BiTreeNode.__init__(self,data) self.bf = 0 class AVLTree(BST): def __init__(self,li=None): BST.__init__(self,li) #左旋 def rotate_left(self,p,c): #s2 是c的左子树 s2 = c.lchild p.rchild =s2 if s2: #父亲连过来,孩子也要连回去 s2.parent = p c.lchild = p p.parent = c p.bf = 0 c.bf = 0 return c def insert_no_rec(self,val): s2 = c.
The current Dart SDK version is 2.4.0.
Because 某项目 depends on dio >=3.0.0-dev.1 which requires SDK version >2.4.0 <3.0.0, version solving failed.
首先打开pubspec.yaml文件
导入项目的时候如果报这个错误,看是哪个依赖报错的
比如上方的错误代码是dio这个依赖
可以把依赖写成这样:dio: any
然后点击pubspec.lock,稍微等待一会,写成这样的弊端是每次都要联网获取依赖版本
然后打开pubspec.lock这个文件,就可以找到适合本项目的版本了
如果有更好的方法,多多指教
在C#中,如果想根据类的字符串名动态生成类的示例对象,需要用到反射的知识。所谓反射,也就是利用程序集中的圆数据信息。凡是要用反射的程序,需要导入System.Reflection命名空间。
动态创建对象有两大类:Activator和Assembly。我更喜欢Activator类,先简单介绍下Assembly。
目录
1.Assembly的使用方法
1.1 假设你要反射一个 DLL 中的类,并且没有引用它(即未知的类型): 1.2 若要反射当前项目中的类(即当前项目已经引用它了)可以为:
2. Activator的用法
3. 实例
1.Assembly的使用方法 1.1 假设你要反射一个 DLL 中的类,并且没有引用它(即未知的类型): Assembly assembly = Assembly.LoadFile("程序集路径,不能是相对路径"); // 加载程序集(EXE 或 DLL) dynamic obj = assembly.CreateInstance("类的完全限定名(即包括命名空间)"); // 创建类的实例 1.2 若要反射当前项目中的类(即当前项目已经引用它了)可以为: Assembly assembly = Assembly.GetExecutingAssembly(); // 获取当前程序集 dynamic obj = assembly.CreateInstance("类的完全限定名(即包括命名空间)"); // 创建类的实例,返回为 object 类型,需要强制类型转换。
也可以这么使用:
Type type = Type.GetType("类的完全限定名"); dynamic obj = type.Assembly.CreateInstance(type); 2. Activator的用法 Activator 类提供好几个动态创建对象的重载方法。
1:public static object CreateInstance(Type type); 2:public static object CreateInstance(Type type, params object[] args); 其中关键在于获得一个Type类型的参数,有了这个参数才能创建一个对应类型的实例。而获取Type对象有三种方式
一、软件设计模式的概念与意义 1. 软件设计模式的概念
软件设计模式(Software Design Pattern),又称设计模式(Design Pattern),是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。它描述了在软件设计过程中的一些不断重复发生的问题,以及该问题的解决方案。也就是说,它是解决特定问题的一系列套路,是前辈们的代码设计经验的总结,具有一定的普遍性,可以反复使用。其目的是为了提高代码的可重用性、代码的可读性和代码的可靠性。
2. 学习设计模式的意义
设计模式的本质是面向对象设计原则的实际运用,是对类的封装性、继承性和多态性以及类的关联关系和组合关系的充分理解。正确使用设计模式具有以下优点。
可以提高程序员的思维能力、编程能力和设计能力。使程序设计更加标准化、代码编制更加工程化,使软件开发效率大大提高,从而缩短软件的开发周期。使设计的代码可重用性高、可读性强、可靠性高、灵活性好、可维护性强。 因此设计模式并不是Java语言的专利,它同样适用于 C++、C#、JavaScript 等其它面向对象的编程语言。
当然,软件设计模式只是一个引导。在具体的软件幵发中,必须根据设计的应用系统的特点和要求来恰当选择。对于简单的程序开发,可能写一个简单的算法要比引入某种设计模式更加容易。但对大项目的开发或者框架设计,用设计模式来组织代码显然更好。
二、软件设计模式的基本要素 软件设计模式使人们可以更加简单方便地复用成功的设计和体系结构,它通常包含以下几个基本要素:模式名称、别名、动机、问题、解决方案、效果、结构、模式角色、合作关系、实现方法、适用性、已知应用、例程、模式扩展和相关模式等,其中最关键的元素包括以下 4 个主要部分。
1. 模式名称
每一个模式都有自己的名字,通常用一两个词来描述,可以根据模式的问题、特点、解决方案、功能和效果来命名。模式名称(PatternName)有助于我们理解和记忆该模式,也方便我们来讨论自己的设计。
2. 问题
问题(Problem)描述了该模式的应用环境,即何时使用该模式。它解释了设计问题和问题存在的前因后果,以及必须满足的一系列先决条件。
3. 解决方案
模式问题的解决方案(Solution)包括设计的组成成分、它们之间的相互关系及各自的职责和协作方式。因为模式就像一个模板,可应用于多种不同场合,所以解决方案并不描述一个特定而具体的设计或实现,而是提供设计问题的抽象描述和怎样用一个具有一般意义的元素组合(类或对象的 组合)来解决这个问题。
4. 效果
描述了模式的应用效果以及使用该模式应该权衡的问题,即模式的优缺点。主要是对时间和空间的衡量,以及该模式对系统的灵活性、扩充性、可移植性的影响,也考虑其实现问题。显式地列出这些效果(Consequence)对理解和评价这些模式有很大的帮助。
三、常见设计模式分类 设计模式有两种分类方法,即根据模式的目的来分和根据模式的作用的范围来分。
1. 根据目的来分
根据模式是用来完成什么工作来划分,这种方式可分为创建型模式、结构型模式和行为型模式 3 种。
创建型模式:用于描述“怎样创建对象”,它的主要特点是“将对象的创建与使用分离”。如单例模式、原型模式、工厂方法模式、抽象工厂模式、建造者模式等 5 种创建型模式。
结构性模式:用于描述如何将类或对象按某种布局组成更大的结构。如代理模式、适配器模式、桥接模式、装饰模式、外观模式、享元模式、组合模式等 7 种结构型模式
行为型模式:用于描述类或对象之间怎样相互协作共同完成单个对象都无法单独完成的任务,以及怎样分配职责。如模板方法模式、策略模式、命令模式、职责链模式、状态模式、观察者模式、中介者模式、迭代器模式、访问者模式、备忘录模式、解释器模式等 11 种行为型模式。
2. 根据作用范围来分
根据模式是主要用于类上还是主要用于对象上来分,这种方式可分为类模式和对象模式两种。
类模式:用于处理类与子类之间的关系,这些关系通过继承来建立,是静态的,在编译时刻便确定下来了。如工厂方法模式、(类)适配器模式、模板方法模式、解释器模式属于该模式。
对象模式:用于处理对象之间的关系,这些关系可以通过组合或聚合来实现,在运行时刻是可以变化的,更具动态性。常见23种设计模式中除了以上 4 种,其他的都是对象模式。
四、面向对象设计模式七大原则 原则名称简单定义开闭原则(Open Closed Principle,OCP)对扩展开放,对修改关闭。即软件中的对象(类,模块,函数等等)应该对于扩展是开放的,但是对于修改是封闭的。单一职责原则(Single Responsibility Principle, SRP)对功能进行分类,代码进行解耦,一个类只负责一个功能领域中的相应职责。里氏替换原则(Liskov Substitution Principle,LSP)确保超类所拥有的性质在子类中仍然成立。即子类可以扩展父类的功能,但尽量不要改变父类原有的功能依赖倒置原则(Dependence Inversion Principle,DIP)依赖于抽象,不能依赖于具体实现(面向接口编程)接口隔离原则(Interface Segregation Principle,ISP)尽量将臃肿庞大的接口拆分成更小的和更具体的接口,一个类对另一个类的依赖应该建立在最小的接口。即要为各个类建立它们需要的专用接口,而不要试图去建立一个很庞大的接口供所有依赖它的类去调用。迪米特法则(Law of Demeter,LoD)又称最少知识原则(Least Knowledge Principle,LKP)只与你的直接朋友交谈,不跟“陌生人”说话。即如果两个软件实体无须直接通信,那么就不应当发生直接的相互调用,可以通过第三方转发该调用。其目的是降低类之间的耦合度,提高模块的相对独立性。合成复用原则(Composite Reuse Principle,CRP)又称组合/聚合复用原则(Composition/Aggregate Reuse Principle,CARP)要尽量先使用组合或者聚合等关联关系来实现,其次才考虑使用继承关系来实现 五、参考 C语言中文网-设计模式
关于element UI 中输入框禁止输入空格的实现 在项目开发过程中会遇到输入框禁止输入空格或者特殊字符之类的需求,其中禁止输入空格的实现方法如下所示。
1、使用vue框架中的.trim修饰符
<el-input class="nameInput" maxlength="20" v-model.trim="form.teamName" placeholder="请输入团队名称"></el-input> 2、使用原生input标签自带的keyup事件监听方法
// 实现一,简单 <el-input class="nameInput" maxlength="20" v-model="form.teamName" @keyup.native="$event.target.value = $event.target.value.replace(/^\s+|\s+$/gm,'')" placeholder="请输入团队名称"></el-input> // 实现二,更符合WEB标准,结构,表现和行为分离原则 <el-input class="nameInput" maxlength="20" v-model="form.teamName" @keyup.native="trimLR" placeholder="请输入团队名称"></el-input> //js部分 trimLR() { this.form.teamName = this.form.teamName.replace(/^\s+|\s+$/gm,'') } 以上实现方法,需要注意,原生事件onkeyup,改成了@keyup,并且需要在后边追加修饰符.native,这样就是告诉vue使用input的原生事件监听方法,此外,在方法的数据处理中,使用的是$event.target.value来代表input框的value值,不是this.value,也不是document.getElementById(‘XXX’).value。
在方法一中,虽然最终formData.title字段的值,过滤掉了首尾的空格,但是实践发现,在input框的展示上,并没有将空格过滤掉,还是展示的是有空格的数据。因此,更提倡第二种方法,使得数据和展示保持一致性,也方便后续问题的排查和维护。
尝试在方法二中,将keyup事件方法改为input或者change,虽然最终结果,value值过滤掉了空格,但是在页面展示上,value值还是保留了空格,以及光标的位置显示,有些混乱的问题,与方法一的表现差不多。所以还是提倡使用keyup事件来处理禁止输入的问题。
3、使用element UI 的表单验证功能
<el-form ref="myForm" :model="formData" :rules="rules" label-width="100px"> ... ... <el-form-item label="名称" prop="title"> <el-input placeholder="请输入名称" v-model="formData.title" maxlength=30></el-input> </el-form-item> ... ... <el-form-item> <el-button type="primary" @click="submitForm('ruleForm')">立即创建</el-button> </el-form-item> </el-form> ----------------- // 实现一 data() { // 自定义title验证规则 var validateTitle = (rule, value, callback) => { const reg = /^[a-zA-Z_\u4e00-\u9fa5]+$/ if (!
0.serial.println 与Serial.print() Arduino 的输出基本就用两个函数 print 和 println,区别在于后者比前者多了回车换行
Serial.println(data)
从串行端口输出数据,跟随一个回车(ASCII 13, 或 'r')和一个换行符(ASCII 10, 或 'n')。这个函数所取得的值与 Serial.print()一样。
Serial.println(b) 以十进制形式输出b的ASCII编码值,并同时跟随一个回车和换行符。
Serial.println(b, DEC) 以十进制形式输出b的ASCII编码值,并同时跟随一个回车和换行符。
Serial.println(b, HEX) 以十六进数据形式输出b的ASCII编码值,并同时跟随一个回车和换行符。
Serial.println(b, OCT)以八进数据形式输出b的ASCII编码值,并同时跟随一个回车和换行符。
Serial.println(b, BIN)以二进数据形式输出b的ASCII编码值,并同时跟随一个回车和换行符。
Serial.print(b, BYTE)以单个字节输出b,并同时跟随一个回车和换行符。
Serial.println(str)如果 str是一个字符串或数组,输出整个 str的 ASCII编码字符串。
Serial.println()仅输出一个回车和换行符。
1.Serial.print 与Serial.write Serial.print 发送的是字符,如果你发送97,发过去的其实是9的ascii码(00111001)和7的ascii码(00110111)。
Serial.write 发送的字节,是一个0-255的数字,如果你发97, 发过去的其实是97的二进制(01100001),对应ascii表中的“a".
package com.qst.dao; import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; //数据库连接和释放工具类 public class DBU { //数据库实例用户名,可根据自己的设置进行更改 static String user = "shixun"; //数据库实例密码,可根据自己的设置进行更改 static String password = "orcl"; //数据库实例链接地址,可根据自己的设置进行更改 static String url = "jdbc:oracle:thin:@127.0.0.1:1521:orcl"; static { try { Class.forName("oracle.jdbc.driver.OracleDriver"); } catch (ClassNotFoundException e) { e.printStackTrace(); } } public static Connection getConnection() { Connection conn = null; try { conn = DriverManager.getConnection(url, user, password); } catch (SQLException e) { e.
安装重启试了很多中方法,SVN右键始终不显示
方法1(测试没有出现)
(一)开始--运行--输入“regedit”进入注册表;
(二)进入目录:HKEY_CLASSES_ROOT/*/shellex/ContextMenuHandlers/TortoiseSVN
(三)右键TortoiseSVN--权限--高级--所有者--将所有者更改为administrator--应用--确定--确定......
(四)重启电脑,搞定!
方法2(测试无效)
在注册表里找到HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Explore\ShellIconOverlayIdentifiers将其中内容修改成如下样子。 之后启动任务管理器结束掉桌面进程 之后再选择文件--新建文件--输入explorer.exe创建新的桌面进程 方法3(实测有效)
1.卸载掉现在TortoiseSVN 后,删除注册表里与svn相关的文件,具体如下:
regedit 打开注册表,查找含有TortoiseSVN的文件,删除,我删除了以下文件夹:
HKEY_CURRENT_USER\Software\TortoiseSVN
方法4(测试无效)
打开svn->setting对话框,找到Icon Overlays, show overlays and context menu only explorer当中显示, 重启电脑。
配置如下所示:
安装环境 系统:Ubuntu18.04
ROS:Melodic
视觉传感器:Intel RealSense D435i
安装RealSense SDK github:https://github.com/IntelRealSense/librealsense
1. 下载source git clone https://github.com/IntelRealSense/librealsense cd librealsense 2. 安装依赖项 sudo apt-get install libudev-dev pkg-config libgtk-3-dev sudo apt-get install libusb-1.0-0-dev pkg-config sudo apt-get install libglfw3-dev sudo apt-get install libssl-dev 3. 安装权限脚本 sudo cp config/99-realsense-libusb.rules /etc/udev/rules.d/ sudo udevadm control --reload-rules && udevadm trigger 4. 编译安装 我发现如果和官网一样运行patch-realsense-ubuntu-lts.sh编译内核,好像会报警告错误, 但是直接忽略掉并不会有什么影响,所以直接运行编译
mkdir build cd build cmake ../ -DBUILD_EXAMPLES=true make sudo make install 5. 测试 进入librealsense/build/examples/capture,测试效果:
./rs-capture 或直接使用realsense-viewer工具查看效果:
最近一段时间在用vue写一个前端项目,想着做出来的界面可以让小伙伴们一起看看,分享一下。所以就趁着双11在阿里云买了台服务器。实践中我发现vue项目部署到服务器一共有两种方式,当然也有可能有别的方法。
一.将vue项目打包后生成的dist目录下的文件复制到springboot项目里面 1. 前端vue项目先通过npm run build生成dist目录
2.将dist中目录文件放入springboot项目的resources目录下的static文件夹
3.运行springboot项目,在浏览器地址栏输入localhost:port/index.html(port为后端项目设置的端口号,我设的为8088),所以我输入localhost:8088/index.html即可访问到前端项目
问题来了,这时候会有小伙伴问你这只是本地通过localhost来访问的,别人也访问不了看不到,不是说用外网查看的吗,下面是用外网查看该网页。
4.通过mvn package将springboot项目打包,生成jar包,然后登陆你的阿里云服务器,将jar放到服务器并运行jar包,即可通过外网访问。
①到项目根目录打开cmd,输入mvn package进行打包,生成jar文件。
②将jar包放到你的服务器上(我买的是阿里云) 并执行java -jar memoryTravel-0.0.1-SNAPSHOT.jar,即可运行jar包,项目也就运行起来了。这时候你就可以通过服务器的外网ip来访问前端的界面。
而我已经做过域名解析了,所以输入www.fengchi.site:8088/index.html也是可以访问的。
二.将vue项目部署到nginx服务器上,通过设置conf配置文件来进行外网访问。 1.下载安装nginx,从官网(nginx官网)下载回来解压就好了。接下来打开命令窗口运行nginx服务器
2.修改nginx.conf配置文件
修改过配置文件运行
./nginx -s reload 这时候你就可以通过你的外网ip+你设置的端口去访问你的前端项目了(我这里已经把47.105.177.109解决成www.fengchi.site这个域名了)
根目录build.gradle 修改
allprojects { repositories { maven { url 'http://maven.aliyun.com/nexus/content/groups/public' } //添加这句,使用阿里云镜像 mavenLocal() maven { // All of React Native (JS, Obj-C sources, Android binaries) is installed from npm url("$rootDir/../node_modules/react-native/android") } maven { // Android JSC is installed from npm url("$rootDir/../node_modules/jsc-android/dist") } google() jcenter() maven { url 'https://jitpack.io' } } }
1.问题 今天我写一个导出excel数据的一个功能,一开始我使用XSSFWorkBook导出的是xlsx格式,结果下载文件后,打开报错:
然后我又切换成HssfWorkBook,导出xls格式,结果文件可以打开,但是内容却是乱码的。且他们的文件名均不是正常格式。
然后我就以为是编码问题,就开始各种搜索poi编码的问题,然后大部分都是说的给response对象添加content-Type之类的参数,但是我加了各种参数,都还是不对。
然后我想着可能不是编码问题,我就开始使用网页端,创建一个a标签去访问我的接口,结果发现文件正常了,也可以读取了。
原因 不能使用postman等接口调用工具去请求这种需要下载文件的接口,这会有问题的。
解决方法 前端创建一个a标签,然后href属性请求接口即可,注意,不要使用ajax,axios等异步请求去请求接口,这样是下载不了的
reponse 最后再提供一个 reponse的设置吧
public static void downLoadExcel(String fileName, HttpServletResponse response, Workbook workbook) throws IOException { try { response.setCharacterEncoding("UTF-8"); response.setHeader("content-Type", "application/vnd.ms-excel"); response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName + "." + ExcelTypeEnum.XLSX.getValue(), "UTF-8")); workbook.write(response.getOutputStream()); } catch (Exception e) { throw new IOException(e.getMessage()); } } /** * Excel 类型枚举 */ enum ExcelTypeEnum { XLS("xls"), XLSX("xlsx"); private String value; ExcelTypeEnum(String value) { this.value = value; } public String getValue() { return value; } public void setValue(String value) { this.
以umi build为例,查看umi命令行工具的逻辑
首先查看package.json文件的bin字段,找到umi可执行文件的位置:
"bin": { "umi": "./bin/umi.js" }, 查看umi/bin/umi.js文件,实际逻辑是在umi/src/cli.js文件中,执行umi build
// umi/src/cli.js switch (script) { case 'build': case 'dev': case 'test': case 'inspect': case 'ui': // eslint-disable-next-line import/no-dynamic-require // build进来 require('./scripts/build') require(`./scripts/${script}`); break; default: { const Service = require('umi-build-dev/lib/Service').default; new Service(buildDevOpts(args)).run(aliasMap[script] || script, args); break; } } build命令会动态导入umi/src/scripts/build.js
umi/src/scripts/build.js import yParser from 'yargs-parser'; import buildDevOpts from '../buildDevOpts'; process.env.NODE_ENV = 'production'; process.env.UMI_UI = 'none'; // 设置两个环境变量 const args = yParser(process.argv.slice(2)); const Service = require('umi-build-dev/lib/Service').
①
②
③
④
⑤
⑥
⑦
⑧
⑨
⑩
-最终话-
成长是一个动态的过程... 再牛逼的职场人,都是从实习生成长起来的。 奇葩的实习生,可能让人心累又无奈; 厉害的实习生,会让人感叹后生可畏。 作为职场相对“弱势”的群体, 在适当允许犯错的情况下,给予实习生正确的指导; 而不是单纯压榨他们。 实习生也应该抓住机会表现自己, 毕竟,竞争激烈的职场不是象牙塔。 最后,“千万不要招实习生”只是一句善意的玩笑,嘻嘻~ 欢迎各位实习生多来互联网公司体验体验! 你的实习生生涯是怎样的? 你遇到过哪些令人印象深刻的实习生? 欢迎留言! -END-
B Y / 统筹:吓行、糙
创意/文案:吓行
构图/绘图: 赵三、飞机、糙
版权归©️吓脑湿所有,已授权“维权骑士”代为维权,
转载须经授权,翻版必究
-往期文章精选-
(点击图片跳转)
-
吓脑湿
开脑相见,严肃活泼
↑长按图片识别二维码,一键关注,不要错过网海相遇的
我们默认安装的linux系统通常都是英文字体,虽然并不影响使用,而且一定意义上来说英文可以使我们避免很多字符上的错误,但是有时候看着英文就是很头大怎么办?很简单只需要这样几步~
我的系统是linux-CentOS 6.10,就以此为例,Linux系统都是相近的
1、右键打开终端open in Terminal
2、编辑i18n
3、将LANG="en_US.UTF-8"改为LANG="zh_CN.UTF-8"
4、然后按Esc :wq保存退出,重启系统后
相信大家在开发过程中经常会遇到使用折线图、曲线图等,但是我们自己开发就会非常浪费时间了,ORCharts就解决了这个问题,他将大家所需要的折线图和曲线图已经全部封装完毕,大家只要使用即可,使用也是非常简单。
首先、引库
#import "ORLineChartView.h" 接下来就是遵守他的协议,他的协议一共有两个
ORLineChartViewDataSource, ORLineChartViewDelegate 最后就是创建并使用
第一步、创建曲线图或者折线图
ORLineChartView *lineChartView = [[ORLineChartView alloc] initWithFrame:CGRectMake(0, 0, SCREEN_WIDTH, 180)]; lineChartView.dataSource = self; lineChartView.delegate = self; //设置曲线图或折线图的风格ORLineChartStyleSlider:指示器随拖拽显示(默认)ORLineChartStyleControl:指示器由点击控制 lineChartView.config.style = ORLineChartStyleSlider; //设置曲线图或者折线图的线的宽度 lineChartView.config.chartLineWidth = 1; //设置动画时长 lineChartView.config.animateDuration = 1; //设置展示是曲线图还是折线图,默认曲线图 YES 为折线图 lineChartView.config.isBreakLine = NO; //设置X轴的Label的宽度 lineChartView.config.bottomLabelWidth = 75; //设置阴影闲的颜色 lineChartView.config.shadowLineColor = [UIColor clearColor]; //设置滑动展示数据控件的北京颜色 lineChartView.config.indicatorTintColor = [UIColor clearColor]; //设置曲线或者折现距离X轴之间的颜色渐变色 lineChartView.config.gradientColors = @[[UIColor orangeColor],[UIColor whiteColor]]; [self.view addSubview:lineChartView]; 第二步、设置Y轴或者X轴的数据源
//设置横向数据源 _xdatas = [[NSMutableArray alloc]init]; //设置纵向数据源 _ydatas = [[NSMutableArray alloc]init]; for ( NSDictionary *dic in array ) { [_xdatas addObject:dic[@"
1、在配置文件(如:application.properties)中,开启Apollo的自动更新 spring.boot.enableautoconfiguration=true 2.实现ApplicationContextAware package com.qbz.test.commons.web.config; import com.ctrip.framework.apollo.model.ConfigChangeEvent; import com.ctrip.framework.apollo.spring.annotation.ApolloConfigChangeListener; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.BeansException; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.cloud.context.environment.EnvironmentChangeEvent; import org.springframework.cloud.context.scope.refresh.RefreshScope; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; import org.springframework.stereotype.Component; /** * apollo 自动刷新 * * @author qubianzhong * @Date 20:32 2019/11/11 */ @Component @Slf4j public class ApolloRefreshConfig implements ApplicationContextAware { ApplicationContext applicationContext; @Autowired RefreshScope refreshScope; //这里指定Apollo的namespace,非常重要,如果不指定,默认只使用application @ApolloConfigChangeListener(value = {ConfigConsts.NAMESPACE_APPLICATION,"business","everything"}) public void onChange(ConfigChangeEvent changeEvent) { for (String changedKey : changeEvent.changedKeys()) { log.info("apollo changed namespace:{} Key:{} value:{}"
release包的相关配置弄好了,run也能正常安装到手机。可是这个run出来的包拷贝到手机上安装就是安装不了,我猜想应该是Android studio有限制吧,毕竟不是打release包的正常方式。
Build——>Build APK 这样方式打出的包,拷贝到手机上可以正常安装。
在Android studio里面打包,一般采用gradlew,我执行./gradlew clean 命令一直报错,
Error:Could not initialize class com.android.sdklib.repositoryv2.AndroidSdkHandler 这种错误是因jdk版本不对的原因,我java -version的版本是11,可是gradlew是需要的8版本,推断gradlew使用的系统环境变量中的java版本。(说个题外话,我java -version是能找到Java 的,说明.bash_profile环境变量PATH中是有java配置的,可是我打开.bash_profile没有找到,不知道为啥)
为啥,run和build apk,就能正常呢?首先这两种方式打包用的是Android stuido里面自带的gradle,然后java使用的也是Android studio里面的
Android studio里面的java版本是8,所以打包正常。
所以,gradlew要想打包正确,就得引用正确的java版本,那么把java 8版本配到.bash_profile里面。
然后./gradlew clean和./gradlew assembleRelease就能正确打包了
Android中gradlew命令的基本使用
Gradle-Could not determine java version from '11'
一篇文章讲清楚Gradle与Gradle Wrapper的区别
MAC系统-JAVA_HOME配置
本来这点小事是没必要写一篇文章的,但是无奈导入的过程中遇到了很多问题,而且网上也真的是一个解决办法都没找到,找来找去就那么几篇文章,讲的方法还都差不多!
首先是jetbrain官方的主题网站 jetbrain主题网址
整体配色方案都还是不错的,于是就心动的点进去下载,得到了一个jar包
然后,按照网上的教程import setting 导入失败
所以说我们遇到什么困难,都不要怕。。。。也不要去网上找教程,自己去找他的解决办法,尤其是这个东西还是在官网上下载的,所以去官网康康。
实际上看到这么简洁的页面确实很绝望,但是我们遇到什么困难。。。。。
我实际上对这个Monocai还是挺执着的,所有能点的地方都点了,还是没找到官方给出的正确导入方式,于是,我出于好奇的点了第一个样式进去
。。。。。
为啥这种教程不是每个样式中都会提示
详细说一下 打开你的ideaFile->setting->plugins
然后选择你刚下的jar包导入,重启idea。完毕! 非常重要的一点上面忘记说了,你必须要确保的你的idea版本在2019.1以上,否则是无法导入官方的主题的!
最近在开发一个微信小程序,本地图片资源比较大,而微信小程序上传又有2M的限制,本来准备将图片放到云服务器里面,但是又看到了一个很好的方法,这次来测试一下!
本地图片 用于切换背景的图片
在没有将图片转为网络地址,微信小程序的代码为:
将图片转为网络地址后:
测试成功 将1799KB减少到了146KB,大大减少了小程序的内存。但是要想真正远程存储图片还是要有一个自己的服务器,可以自由的使用!
操作系统实验一 lab0 基础操作及准备 1.lab0要求我们准备好实验所需的工具,但实际上大部分工具我们在大二时就已经安装完毕,比如Ubuntu和VMware。而且我们在逐渐的使用中也已经熟悉了自己喜欢的文本编辑器和操作方式,同时一些命令行的基本操作也已经烂熟于心,例如ls查找文件,clear清除信息,history查询历史命令行记录,mkdir新建文件夹,gedit或者vi或者vim则都可以新建文件,使用的是不同的文本编辑器,rm删除文件等等。
2.当然这些操作都较为基本,最主要的操作还是makefile或者make操作以及gcc编译器编译并执行c程序,chxomd编译py程序。
新的工具QEMU以及我的安装模式 在Linux运行环境中,QEMU用于模拟一台x86计算机,让ucore能够运行在QEMU上。为了能够正确的编译和安装 qemu,尽量使用最新版本的qemu,或者os ftp服务器上提供的qemu源码。在 Ubuntu 系统中,版本可以通过 gcc -v 或者 gcc --version 进行查看。
安装方式1:可直接使用ubuntu中提供的qemu,只需执行如下命令即可。
sudo apt-get install qemu-system 安装方式2:也可采用下面描述的方法对qemu进行源码级安装。需要到网站上下载源码并进行一系列神奇的命令行操作。这里不再赘述。
我的安装方式:
尝试过两种安装方式后第一个报错另一个则安装方式稍显繁琐。于是我仔细在第一种方式中改进。如果直接运行指导书中的命令会报错,看英文的意思大概是很多东西没有安装。所以想到不加参数而直接使用命令:
sudo apt-get install qemu 发现报错中出现友好提示,recommend:util操作可能解决这个问题。所以我尝试运行:
sudo apt-get install qemu-util 这个命令实际上将包括模拟x86所用的所有包都下载了,所以自然之后再运行指导书中的命令后就不会报错,至此实验所需工具安装完毕!
lab1 练习1:理解通过make生成执行文件的过程。 1.操作系统镜像文件ucore.img是如何一步一步生成的?(需要比较详细地解释Makefile中每一条相关命令和命令参数的含义,以及说明命令导致的结果)
总结起来,总的步骤可以分为以下五步完成:
(1)通过GCC编译器将Kernel目录下的.c文件编译成OBJ目录下的.o文件。
(2)ld命令根据链接脚本文件kernel.ld将生成的*.o文件,链接成BIN目录下的kernel文件 。
(3)通过GCC编译器将boot目录下的.c,.S文件以及tools目录下的sign.c文件编译成OBJ目录下的*.o文件。
(4)ld命令将生成的*.o文件,链接成BIN目录下的bootblock文件。
(5)dd命令将dev/zero, bin/bootblock,bin/kernel 写入到bin/ucore.img
①编译命令:
命令展示详细信息后都是用的GCC,将.c文件编译成为.o文件。
-l: 对于其中命令-I的含义如下:-I /home/hello/include表示将/home/hello/include目录作为第一个寻找头文件的目录。
-o: 经查询,-o OUTPUT’–output=OUTPUT’使用OUTPUT作为’ld’产生的程序的名字;如果这个选项没有指定,缺省的输出文件名是’a.out’.脚本命令’OUTPUT’也可以被用来指定输出文件的文件名。
-t:’–trace’打印’ld’处理的所有输入文件的名字。
-T: SCRIPTFILE’–script=SCRIPTFILE’把SCRIPTFILE作为连接脚本使用. 这个脚本会替代’ld’的缺省连接脚本(而不是增加它的内容),所以命令文件必须指定所有需要的东西以精确描述输出文件. 如果SCRIPTFILE在当前目录下不存在,‘ld’会在’-L’选项指定的所有目录下去寻找.多个’-T’选项会使内容累积.
-M:’–print-map’
打印一个连接位图到标准输出.一个连接位图提供的关于连接的信息有如下一些:目标文件和符号被映射到内存的哪些地方普通符号如何被分配空间.所有被连接进来的档案文件,还有导致档案文件被包含进来的那个符号。
举个例子:
cc boot/bootasm.S //编译bootasm.c
gcc -c boot/bootasm.S -o obj/boot/bootasm.
首先将数据转化为文本或者数字格式 将距离1900年1月1日的毫秒数转化为日期
=TEXT((INT(E4/1000)+8*3600)/86400+70*365+19,"yyyy-MM-dd hh:mm:ss") UTC时间 和GMT时间
北京时间(UTC +08)= 格林威治时间(UTC +00)+8个小时
=TEXT((INT(F4/1000)+8*3600)/86400,"yyyy-MM-dd hh:mm:ss") # 从1900年1月1日 开始 =TEXT((INT(F4/1000)+8*3600)/86400+70*365+19,"yyyy-MM-dd hh:mm:ss") # 从1970年1月1日 开始
人们总是对未知充满好奇,迫使他们满怀热情去求知,去解答。对于游戏也应如此,想让玩家对游戏满怀热情,玩游戏时不会感觉太无聊,我认为最重要的就是能够让玩家时刻对游戏接下来发生的事充满期待,激发玩家的好奇心。这对游戏自身的玩法性充满挑战。
优秀的画质,耐人寻味的剧情,题材新颖,有趣的游戏玩法等等都是一款优秀的游戏所不可或缺的。
迷宫,因为其复杂性和不可预知性让一大批人深深为之着迷。对于迷宫的解释,百度百科上是这样说的:
迷宫 指的是充满复杂通道,很难找到从其内部到达入口或从入口到达中心的道路,道路复杂难辨,人进去不容易出来的建筑物。通常比喻复杂艰深的问题或难以捉摸的局面。
所以说,在游戏中,迷宫能够提高游戏的玩法性和趣味性,玩家在迷宫中运用自己的智慧找到出口,成就感瞬间爆棚,也就更想要继续玩下去。
迷宫玩法,通常在解谜冒险类游戏中出现,其他类型的游戏也有一定的涉及,如果再在迷宫中加入一些随机事件,相信游戏的随机性和趣味性也会大大提高。
正是因为这么多的原因,作为游戏开发者,更应该学习开发迷宫玩法,其中迷宫生成算法必不可少。
经典的迷宫生成算法有四种:递归回溯算法,递归分割算法,随机Prim算法,Kruskal+并查集。关于详细介绍,许多大佬的博客解释的很清晰,这里不再赘述,作者选了一种生成的迷宫比较自然的随机Prim算法。
算法见解 下面是个人对算法的一些小见解
前提:算法考虑的均是方形迷宫
迷宫生成的基本流程是
1.先生成一个由有限个周围四面均是墙的封闭区域组成的方形大区域,例如5×5的迷宫就是由25个这种封闭区域组成的。
2.开始消除迷宫中间的部分墙壁(边框除外),只需保证迷宫内任意相邻两区域是互通的,这样就可以推出迷宫内任意两区域都是互通的。有了这个保障,迷宫的出口和入口就可以在四个边框上随意指定位置,不会出现无解的迷宫,也增加了生成迷宫的随机性。同时,让迷宫中的每一块区域充分利用,不会出现某一块区域永远无法到达的情况。
了解流程之后,首先就要考虑迷宫的存储方式,一种方式是用二维数组存储,例如用数字0代表墙壁,数字1代表道路就像这样:
int[,] maze = { { 0,1,0,0,0} ,{ 0,1,1,0,0} ,{ 0,0,1,1,0} ,{ 0,0,0,1,1} ,{ 0,0,0,0,0} }; 还有一种方式是用两个二维数组,适合墙壁没有厚度或者厚度很小的迷宫,一个存储所有行的墙壁(类似横着的线)信息,一个存储所有列的墙壁(类似竖着的线)信息,数字0代表没有墙壁,数字1代表墙壁存在,也可以用bool变量表示。
作者在这里选用第二种,因为和算法结合性较好。
随机Prim算法描述
1.在初始生成的全区域封闭迷宫中随机选择一个区域作为当前区域
2.将区域四周未消除的墙加入列表中
3.循环执行以下方法,直至列表为空
随机从列表选择一面墙
如果墙两边区域存在一区域未被连通,就消除这面墙,并将这面墙两边区域附近未消除的墙加入列表(迷宫边框的墙壁除外)
从列表中移除这面墙
4.随机选取迷宫边框上的两个墙壁分别作为出口和入口(出口和入口可能会非常接近)
了解了原理,接下来就是在Unity实现,先看效果图
代码实现 首先定义一个迷宫类
public class MazeWall { //true表示墙壁存在,false表示墙壁不存在 public bool[,] rowWall;//存储迷宫所有行的墙壁信息 public bool[,] colWall;//存储迷宫所有列的墙壁信息 public int rowsum;//迷宫有多少行 public int colsum;//迷宫有多少列 /// <summary> /// 判断区域是否连通,四面墙有一面墙打通即为连通 /// </summary> /// <param name="
7-3 插入排序还是堆排序 (25 分)
根据维基百科的定义:
插入排序是迭代算法,逐一获得输入数据,逐步产生有序的输出序列。每步迭代中,算法从输入序列中取出一元素,将之插入有序序列中正确的位置。如此迭代直到全部元素有序。
堆排序也是将输入分为有序和无序两部分,迭代地从无序部分找出最大元素放入有序部分。它利用了大根堆的堆顶元素最大这一特征,使得在当前无序区中选取最大元素变得简单。
现给定原始序列和由某排序算法产生的中间序列,请你判断该算法究竟是哪种排序算法?
输入格式:
输入在第一行给出正整数 N (≤100);随后一行给出原始序列的 N 个整数;最后一行给出由某排序算法产生的中间序列。这里假设排序的目标序列是升序。数字间以空格分隔。
输出格式:
首先在第 1 行中输出Insertion Sort表示插入排序、或Heap Sort表示堆排序;然后在第 2 行中输出用该排序算法再迭代一轮的结果序列。题目保证每组测试的结果是唯一的。数字间以空格分隔,且行首尾不得有多余空格。
输入样例 1:
10
3 1 2 8 7 5 9 4 6 0
1 2 3 7 8 5 9 4 6 0
输出样例 1:
Insertion Sort
1 2 3 5 7 8 9 4 6 0
输入样例 2:
10
3 1 2 8 7 5 9 4 6 0
安装neovim brew install neovim 设置配置文件 新建配置文件:
cd ~/.config mkdir nvim && cd nvim touch init.vim 写入配置:
" Specify a directory for plugins call plug#begin('~/.vim/plugged') Plug 'neoclide/coc.nvim', {'branch': 'release'} Plug 'scrooloose/nerdtree' "Plug 'tsony-tsonev/nerdtree-git-plugin' Plug 'Xuyuanp/nerdtree-git-plugin' Plug 'tiagofumo/vim-nerdtree-syntax-highlight' Plug 'ryanoasis/vim-devicons' Plug 'airblade/vim-gitgutter' Plug 'ctrlpvim/ctrlp.vim' " fuzzy find files Plug 'scrooloose/nerdcommenter' "Plug 'prettier/vim-prettier', { 'do': 'yarn install' } Plug 'christoomey/vim-tmux-navigator' Plug 'morhetz/gruvbox' Plug 'HerringtonDarkholme/yats.vim' " TS Syntax " Initialize plugin system call plug#end() inoremap jk <ESC> nmap <C-n> :NERDTreeToggle<CR> vmap ++ <plug>NERDCommenterToggle nmap ++ <plug>NERDCommenterToggle "
这里写目录标题 Project 使用插件,过滤项目不想提交的文件1.添加插件 .ignore2. 过滤文件的位置如下图3. 使用插件添加过滤文件 Moudle Project 使用插件,过滤项目不想提交的文件 1.添加插件 .ignore 插件添加完毕,需要重启,才可以生效。
2. 过滤文件的位置如下图 3. 使用插件添加过滤文件 选中项目右键~,如图操作
我选择了如图选项,随即在项目的 .gitignore 文件内会自动添加相应内容。
### Android template # Built application files *.apk *.ap_ *.aab # Files for the ART/Dalvik VM *.dex # Java class files *.class # Generated files bin/ gen/ out/ release/ # Gradle files .gradle/ build/ # Local configuration file (sdk path, etc) local.properties # Proguard folder generated by Eclipse proguard/ # Log Files *.
声明:本文仅供学习用,旨在分享
基于项目需要,运用了PyQt进行了桌面版APP的开发,在此将一些常用方法进行总结。
1、环境的安装及配置:
本人运用的是pycharm2016.3.2专业版,python3.6.0 64位,这两者的安装及配置不再阐述。首先是安装相应模块,运用豆瓣源安装,安装顺序为:sip=4.19.8>>>>PyQt5=5.11.3>>>>PyQt5-tools=5.11.3.1.4>>>>PyInstaller=3.5,
例如:pip install sip==4.19.8 -i http://pypi.douban.com/simple --trusted-host pypi.douban.com。基于经验安装顺序最好不要调换,否则有时会出现无法正常运行的情况。安装完毕后配置打包环境:File---->settings---->Tools---->External Tools后选择加号按钮,如下图
之后再按照下图内容进行填写:
其中:-D:指打包成多个文件,-D与-F对应,-F是打包成一个单独的文件
-p:即path,指定python安装包路径
-i:指定图标所在目录
编写完代码后一般右键选择External Tools再选择刚才创建的工具即可打包
有时打包会出现Unable to run PyInstaller - “Please install PyWin32 or pywin32-ctypes”的情况,需要到在PyInstaller文件夹中找到文件compat.py,并把以下两行进行替换后保存即可。
from win32ctypes.pywin32 import pywintypes替换为import pywintypes from win32ctypes.pywin32 import win32api替换为import win32api 除此外有时打包报for real_module_name, six_moduleAttributeError: ‘str’ object has no attribute 'items’错误,这时运行pip install -U --pre setuptools即可。
2、上述的模块安装后,就可以开始进行界面设计,首先是创建窗口,对于窗口类型pyqt提供了QMainWindow、QWidget、QDialog三种类型。其中:
QMainWindow窗口包含菜单栏、工具栏、状态栏、标题栏等,是最常见的窗口形式,也可以说是GUI程序的主窗口。QWidget类是所有用户界面对象的基类,是用户界面最基础的原子,也可以容纳其他的widget,它接收鼠标、键盘产生的事件,然后回应。需注意的是setCentralWidget是只能由mainwindow类调用的。QDialog是对话框窗口的基类,派生自QWidget,主要用来执行短期任务,或者与用户进行互动,它可以是模态的,也可以是非模态的,应用场景比如可在关闭主程序关闭按钮时弹出询问是否关闭,或者当界面的按钮过多不美观时可把一些按钮放在这种对话框中,例如注册。 所以如果是主窗口,就使用QMainWindow类;如果不确定,有可能作为顶层窗口,也有可能嵌入到其他窗口,就使用QWidget类;如果是对话框,就使用QDialog类。在功能上QMainWindow > QWidget > QDialog。
3、接下来将运用一个简单的实例,模拟登录后界面的跳转及登录时信息填写错误后的提示来演示这三种类型的使用,代码如下:
# -*- coding: utf-8 -*- '''多窗口反复切换''' import sys # 导入系统 from PyQt5 import QtCore, QtWidgets from PyQt5.
过滤器中的url-pattern中的 / 和 /* 为 /*时 <filter-mapping> <filter-name>testFilter1</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> 会过滤所有请求,包括对静态资源的访问,都会进入过滤器。
为 / 时 <filter-mapping> <filter-name>testFilter1</filter-name> <url-pattern>/</url-pattern> </filter-mapping> 这种时,精确匹配,即只过滤请求路径为/的请求。
同理当为/test时,则只过滤请求路径为/test的请求。
并不是说 / 会排除对静态资源的过滤。
linux 报错: Address already in use的解决方法 参考自 https://blog.csdn.net/lsr40/article/details/77775858
写在前面 自己的测试环境:Ubuntu 16.04
自己在运行程序的时候遇到这种情况 Address already in use
,先杀掉对应的进程,然后再次运行自己的程序就可以了
具体步骤: 第一步:
netstat -apn | grep 11411 (这里的11411是端口号,我的是11411,读者朋友需要替换成自己被占用的那个端口号)
运行之后得到的结果如下图:这里的最后一部分信息就是对应的pid,然后我们通过 kill -9 pid 就可以杀掉对应的进程(例如,kill -9 11893 )
但是运行kill指令之前,我们还是要确定下到底这个是在哪里开的进程,能不能随便杀掉,所以需要确认一下
第二步:
ps -ef | grep 11893 这样就可以看到自己这个进程到底是那个用户开的,在哪里开的,如下图:
这边显示了两行,每行都是以用户名开头的,第一个就是普通用户开启的进程,就是我们之前运行的程序,第二个是执行的 grep 11893 这个命令生成的,可以先不用管他
第三步:就是最后一步,执行
kill -9 11893 强制 kill 掉就OK了!
参考连接:
[1] 杀掉某个进程!怎么查看pid,报错:Address already in use https://blog.csdn.net/lsr40/article/details/77775858
尝试将mybatis所学进行一个总的归纳
文章目录 概述架构流程三层结构接口层数据处理层基础支撑层 工作流程 源码部分全局配置文件解析过程mapper映射文件解析过程SQL加载与组装过程执行查询过程缓存过程延迟加载过程获取Mapper代理过程mybatis插件过程 类关系总结设计模式 概述 mybatis是什么?
mybatis是一款半自动化的持久层框架,它封装了JDBC操作,支持定制化SQL,高级映射。但它的数据库无关性较低,2个不同的数据库,可能需要2套SQL语句
mybatis的基本使用?
编写全局配置文件编写mapper映射文件加载配置文件,生成SqlSessionFactory创建SqlSession,通过SqlSession调用mapper映射文件中的SQL语句来执行数据库操作 架构流程 三层结构 接口层 使用SqlSession和Mapper接口,来完成对SQL语句的调用,日常开发中主要接触这一层
数据处理层 这一层是mybatis进行的工作,负责SQL语句组装,查询参数绑定,结果集映射
基础支撑层 这一层可以理解为我们全局配置里的内容。包括数据库连接信息,事务管理信息,配置缓存,编写mapper映射文件中的SQL语句等
工作流程 向SqlSession传入SQL语句的id,以及查询参数找到待执行的SQL信息,交给Executor执行器处理Executor负责对SQL语句进行组装拼接,后交给StatementHandler处理StatementHandler封装了JDBC的操作,它负责根据SQL信息,生成对应的Statement,并利用ParameterHandler进行查询参数的解析与绑定,后执行查询StatemenHandler查询完毕,将结果集交由ResultSetHandler进行结果集信息的解析与封装处理(参数解析,结果集解析,都会用TypeHandler来做类型转换,java类型与JDBC类型) 源码部分 全局配置文件解析过程 获得配置文件的InputStream,创建Document对象利用Xpath语法,解析各个配置节点将信息封装到Configuration对象中,生成SqlSessionFactory 源码过程
SqlSessionFactoryBuilder # build |- XMLConfigBuilder # parse |- XMLConfigBuilder # parseConfiguration mapper映射文件解析过程 一个mapper.xml映射文件,由namespace属性作为唯一标识拥有namespace属性的mapper.xml映射文件,会被注册到Configuration中的mapperRegistry中,以便后续生成mapper代理对象一个mapper.xml,对应一个MapperBuilderAssistant对象,这个builderAssistant对象解析并保存了该mapper.xml中的公共标签,如parameterMap,resultMap,cache,sql,这些标签可能在某个CRUD标签里被使用解析CRUD标签,即 select | update | insert | delete 标签,一个CRUD标签,被封装成一个MappedStatement对象,以标签的id属性作为唯一标识,MappedStatement里包含了SQL语句信息,参数映射信息,结果集映射信息 源码过程
XMLConfigBuilder # mapperElement |- XMLMapperBuilder # parse |- XMLMapperBuilder # configurationElement SQL加载与组装过程 SQL装载
在解析mapper映射文件中的CRUD标签时,对SQL语句进行了解析和封装将一个CRUD标签,封装成SqlNode,并将其子元素(可能是文本节点,也可能是动态SQL节点),也封装成SqlNode,利用组合模式,对这些SqlNode进行组装,最终将SqlNode和Configuration封装在一起,形成SqlSource有动态SQL标签的,或者有${} 的,会被封装成DynamicSqlSource,其余的,会被封装成RawSqlSource(在Executor执行时都会解析并封装成StaticSqlSource)SqlSource和其他信息,一起被封装为MapperStatement,一个CRUD标签,对应一个MappedStatement 源码过程
XMLMapperBuilder # buildStatementFromContext |- XMLStatementBuilder # parseStatementNode |- XMLLanguageDriver # createSqlSource |- XMLScriptBuilder # parseScriptNode SQL组装