1. 有两个矩阵:A和B(矩阵实际上就是二维数组)
A矩阵和B矩阵可以做乘法运算必须满足A矩阵的列的数量等于B矩阵的行的数量
运算规则:A的每一行中的数字对应乘以B的每一列的数字把结果相加起来
矩阵乘法的结果为行与列的关系为:行数量为A的行数量, 列数量为B的列数量
2. 因为每一次都是A的行与B的列,所以最外层的两层循环可以使用A的行的数量的变化,B的列的数量进行变化
而最里面的循环可以是A的列或者是B的行来进行变化,因为A的列和是B的行数量是相等的,这样就可以使用三层循环来解决,代码如下:
public class Main { public static void main(String[] args) { int matrixA[][] ={ {1, 1}, {1, 1} }; int matrixB[][] = { {1, 1}, {1, 1} }; int matrix[][] = matrixMultiple(matrixA, matrixB); print(matrix); } private static void print(int[][] matrix) { for(int i = 0; i < matrix.length; i++){ for(int j = 0; j < matrix[0].length; j++){ System.out.print(matrix[i][j] + " "); } System.
异常报错 学习Spring Boot的时候做一个简单的表单提交demo发现一直报错
Required String parameter 'username' is not present 解决方案 查阅资料很多人遇到的问题是给Controller的 @RequestParam注解补全 @RequestParam(value = “name”, required = false) 后就能解决,但是我这边这个username参数是必须要的,而且添加了还是不能解决问题,最后认真检查发现原因出在html页面上的input中的name不小心写错了~~囧,修正后即可解决问题,
<input type="text" name="username"
今天碰到一个坑,就是在quartus里面打开ModelSim-Altera进行仿真的时候报错,说是找不到路径。 一般的解决办法是: 在quartus中打开tool——options改正路径为D:\quartus\quartus13.1\modelsim_ase\win32aloem。也就是quartus安装路径下的win32aloem,因为当你点击右边三个点的按钮选取文件路径的时候在你的选项中就是出现这样的路径显示。但是有些情况下是解决不了问题的。还是会报错。 这个时候你必须手动修改下有系统点击确定的路径,在后面加上一个斜杠。 D:\quartus\quartus13.1\modelsim_ase\win32aloem\ 确定后,再次返回运行就会进入仿真界面。
1、原理图
原理图的实质就是电路板的模拟电路设计图,反应的是电路板上各个元器件之间的物理接线关系、电子元器件的电气特性等。一般情况下,我们不会直接将电路板上的模拟电路设计图全部绘制在一起,这样的话,如果电路板过于复杂的话,整个原理图就会显得十分拥挤,不容易识别、分析,因此,我们可以将单独的元器件分离开来,作为一个单独的小模块,绘制在原理图上,这样我们就可以单独分析单个模块功能。
2、网络标号
上述情况下,如果将模块从整个原理图结构中分开,但是又不破坏整个原理图的完整性,就需要使用网络标号。网络标号的实质就是一串字符串,而他的特性就是只要这一串字符串一致,那么就表示这两个地方在电气特性上是直连的。
网络标号的命名规则是见名知意,比如Ffid_nCS表示RFID射频模块的CS片选信号。
3、网络标号边上的尖括号
一般在原理图上都会出现这样的尖括号:
这个一般是在原理图中表示跨页输入输出。因为原理图一般在设计的时候,会根据开发板上的功能,进行模块细分:控制、audio、camera、memory、RF等,但是这些是能在一张A4纸上全部显示的(原理图1页设计一般都是在A4大小左右),这就需要跨页,而这种尖括号就是表示跨页输入和输出:箭头指向网络标号表示输入到网络标号,箭头指向标号另一侧表示从网络标号输出
4、I/O引脚
关于芯片中IO引脚功能设置主要分以下四种:上拉、下拉、推挽输出、开漏输出,主要区别如下:
(1)上下拉
主要指的是在引脚内部存在上拉/下拉电阻,避免做输入悬空时无法确定电平状态出错
(2)开漏输出
本质就是在芯片内部,给IO引脚提供了一个三极管或者MOS管。一般在硬件电路中都是使用高低电平代表逻辑1、0,但是有时候高低电平只是一个统称,具体多高的电平算是高电平,多低的电平是低电平并不是固定的,那么有了开漏输出之后就可以通过外加上拉电阻实现,具体原理结构如下:
悬空时,整个电路处于断路,检测到的信号必定是高电平,而且实际高电平值受上拉电阻控制,当三极管导通,此时外设检测到的电信号必定是低电平。
(3)推挽输出
推挽输出是让整个引脚输出的电信号是确定的,具体原理结构如下:
不论哪一个三极管断路,这个引脚输出的信号必定是确定的。
问题:在使用GZIP压缩和解压缩时可能会出现java.util.zip.ZipException: Not in GZIP format异常。
原因:在使用GZIP进行压缩时,创建GZIPOutputStream对象时,会调用一个writeHeader方法,此方法会在输出流中写入GZIP的头信息。代码如下:
private void writeHeader() throws IOException { out.write(new byte[] { (byte) GZIP_MAGIC, // Magic number (short) (byte)(GZIP_MAGIC >> 8), // Magic number (short) Deflater.DEFLATED, // Compression method (CM) 0, // Flags (FLG) 0, // Modification time MTIME (int) 0, // Modification time MTIME (int) 0, // Modification time MTIME (int) 0, // Modification time MTIME (int) 0, // Extra flags (XFLG) 0 // Operating system (OS) }); } 头部信息中前两个字节用于存储魔数,GZIP_MAGIC值为35615,第一个字节存储低位,第二个字节存储高位。在解压缩时GZIPInputStream会调用readheader读取头信息。代码如下:
背景说明:通过pip安装了GraphViz模块后,在对着sklearn的决策树文档操作输出决策树模型结果时,报错了:InvocationException: GraphViz’s executables not found 在网上找了一下,终于解决此问题,特此记录下来。 1、下载安装GraphViz(这是一个独立软件) https://graphviz.gitlab.io/_pages/Download/Download_windows.html 下载完后解压缩后,复制bin文件夹的路径。例如:
将GraphViz安装目录的bin目录放到环境变量的path路径中 windows下: 不过我手工在环境变量中添加了bin路径不行,还是运行下边这个语句好。
import os os.environ["PATH"] += os.pathsep + 'C:/Program Files (x86)/Graphviz2.38/bin/' #注意修改你的路径
分享一个UGUI根据自动改变长度的,主要用在有滑动列表的里面,还有就是可以控制字体的大小。
其中 (str.Length / 10+1) * 16 10为一行可容纳的10个汉字。16为一行所占的高,自行测试你的字体。
有任何问题直接留言,看到会回复 QQ791719266 备注“CSDN text文本转换”
Text text; RectTransform recttrans; private void Start() { text = GetComponent<Text>(); recttrans = GetComponent<RectTransform>(); string str = text.text; Debug.Log(str.Length); recttrans.sizeDelta = new Vector2(recttrans.sizeDelta.x, (str.Length / 10+1) * 16); }
Question:最近做一个在微信和支付宝内置浏览器中运行的移动web界面,前几个月ios微信更新之后,微信将后退的按钮移至了底部横栏,遮挡住了原先底部的操作按钮。由于之前的页面设计是整屏显示禁止触摸滚动效果的,就想着是不是可以隐藏微信内置的底部横栏。
Answer:
1. 经过查资料,很多人说可以调用Weixin为H5应用提供开放原生能力的JS接口来隐藏/显示底部的状态栏。代码如下:
document.addEventListener('WeixinJSBridgeReady', function onBridgeReady() { WeixinJSBridge.call('hideToolbar'); // 隐藏底部状态栏 WeixinJSBridge.call('hideOptionMenu'); // 隐藏右上角的三个点的选项 WeixinJSBridge.call('showToolbar'); // 显示底部状态栏 WeixinJSBridge.call('showOptionMenu'); // 显示右上角的三个点的选项 }); 但是实际使用过程中,发现无效,使用微信开发者工具调试,发现报错:“error:WeixinJSBridge.call方法无效”,在微信公众平台的企业微信中发现,该方法适用于企业微信,而在订阅号或者服务号的开发文档中暂未发现这个方法。
// 接口调用代码(JavaScript) --- from 微信公众平台-企业微信开发文档 function onBridgeReady(){ WeixinJSBridge.call('hideToolbar'); } if (typeof WeixinJSBridge == "undefined"){ if( document.addEventListener ){ document.addEventListener('WeixinJSBridgeReady', onBridgeReady, false); }else if (document.attachEvent){ document.attachEvent('WeixinJSBridgeReady', onBridgeReady); document.attachEvent('onWeixinJSBridgeReady', onBridgeReady); } }else{ onBridgeReady(); } // 返回说明 // 隐藏底部导航栏没有返回值。(需要显示顶部导航栏,请把hideToolbar换成showToolbar) 2. 暂且将页面调整为可以滚动的状态==!!!目前没有看到合适的方法撒,于是,还是来个滚动条吧
其实利用python实现汉字的简体和繁体相互转早有人做过,并发布到github上了,地址:https://github.com/skydark/nstools/tree/master/zhtools
该项目还有其他很多跟汉字相关的功能,本文只介绍繁体和简体相互转换
具体方法很简单,下载该项目中的 zh_wiki.py 和 langconv.py 两个文件,放到python代码目录下就可以了.
我的python是3.5版本,所以在字符串的decode上和python2.x 有所不同,demo:
from langconv import * import sys print(sys.version) print(sys.version_info) # 转换繁体到简体 def cht_to_chs(line): line = Converter('zh-hans').convert(line) line.encode('utf-8') return line # 转换简体到繁体 def chs_to_cht(line): line = Converter('zh-hant').convert(line) line.encode('utf-8') return line line_chs='<>123asdasd把中文字符串进行繁体和简体中文的转换' line_cht='<>123asdasd把中文字符串進行繁體和簡體中文的轉換' ret_chs = "%s\n"%cht_to_chs(line_cht) ret_cht = "%s\n"%chs_to_cht(line_chs) print("chs='%s'",ret_cht) print("cht='%s'",ret_cht) file = open('ret.txt','w',encoding='utf-8') file.write(ret_chs) file.write(ret_cht) file.close() ret.txt文件内容
<>123asdasd把中文字符串进行繁体和简体中文的转换 <>123asdasd把中文字符串進行繁體和簡體中文的轉換 转载自:https://www.jianshu.com/p/c3fd8629a0cc
python3中urllib.request模块提供的urlretrieve()函数。urlretrieve()方法直接将远程数据下载到本地。
urlretrieve(url, filename=None, reporthook=None, data=None)
参数url:下载链接地址参数filename:指定了保存本地路径(如果参数未指定,urllib会生成一个临时文件保存数据。)参数reporthook:是一个回调函数,当连接上服务器、以及相应的数据块传输完毕时会触发该回调,我们可以利用这个回调函数来显示当前的下载进度。参数data:指post导服务器的数据,该方法返回一个包含两个元素的(filename, headers) 元组,filename 表示保存到本地的路径,header表示服务器的响应头 将baidu的html抓取到本地,保存在''./baidu.html"文件中,同时显示下载的进度。
#!/usr/bin/env python # coding=utf-8 import os from urllib.request import urlretrieve def cbk(a,b,c): '''''回调函数 @a:已经下载的数据块 @b:数据块的大小 @c:远程文件的大小 ''' per=100.0*a*b/c if per>100: per=100 print('%.2f%%' % per) url='http://www.baidu.com' dir=os.path.abspath('.') work_path=os.path.join(dir,'baidu.html') urlretrieve(url,work_path,cbk) 下面是urlretrieve()下载文件的实例,可以显示下载进度。
#!/usr/bin/env python # coding=utf-8 import os import urllib def cbk(a,b,c): '''回调函数 @a:已经下载的数据块 @b:数据块的大小 @c:远程文件的大小 ''' per=100.0*a*b/c if per>100: per=100 print '%.2f%%' % per url='http://www.python.org/ftp/python/2.7.5/Python-2.7.5.tar.bz2' dir=os.path.abspath('.') work_path=os.path.join(dir,'Python-2.7.5.tar.bz2') urllib.urlretrieve(url,work_path,cbk) 复杂点可以参考https://blog.csdn.net/zzc15806/article/details/79636417,作者: zzc15806
下载cifar-10数据集为例,理解urlretrieve的用法
其它:Spring 中 Environment 的用法
一、Commons-Email 的使用:
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-email</artifactId>
<version>1.4</version>
</dependency>
/**
* 邮件信息类
* @author fmr
*/
public class EmailInfo {
//发件人
private String fromAddress;
//发件人昵称
private String fromNickName;
// 收件人
private List<String> toAddress = null;
// 抄送人地址
private List<String> ccAddress = null;
// 密送人
private List<String> bccAddress = null;
// 附件信息
private List<EmailAttachment> attachments = null;
// 邮件主题
private String subject;
// 邮件的文本内容
private String content;
}
在使用nuxt之前,我们正常的route控制语法如下:
const route = new Router({ routes:{ [...] } }) route.beforeEach(to,from,next){ //进行路由权限校验等方法 } 而使用nuxt,路由默认会根据页面的路径规则自动生成,所以乍一看根本没有配置的地方,所以当我们想要使用类似beforeEach功能的时候,我们就需要自己定义一个小插件啦。步骤如下: 1、首先在plugins目录下创建文件route.js
export default ({ app }) => { app.router.afterEach((to, from) => { console.log(to.path) }) } 2、在nuxt.config.js中plugins数组增加'~/plugins/route' 这样就搞定啦。
开发十年,就只剩下这套Java开发体系了 >>> 场景:接着笔记(三)的鉴权,需要先调用第三方服务进行鉴权,第三方对应的浏览器需要导入证书,否则就会报400错误,只有当鉴权成功后才能往下进行反向代理,此处就不强调如何生成证书,如何生成证书可以自行百度,此文关注点在如何配置ssl,以及配置验证浏览器的证书后如何获取浏览器证书的信息。
笔记(一)中介绍的是nginx源码安装,此处介绍个Openresty安装。
Centos7安装Openresty通过yum安装
在 /etc/yum.repos.d/ 下新建 OpenResty.repo 内容
[openresty] name=Official OpenResty Repository baseurl=https://copr-be.cloud.fedoraproject.org/results/openresty/openresty/epel-$releasever-$basearch/ skip_if_unavailable=True gpgcheck=1 gpgkey=https://copr-be.cloud.fedoraproject.org/results/openresty/openresty/pubkey.gpg enabled=1 enabled_metadata=1 yum install openresty -y
默认会安装到 /usr/local/openresty/ 目录下, 目录下包含了 luajit, lualib, nginx, openssl, pcre, zlib 这些组件。
到此就安装好了,简单吧,比源码安装简单多了。
1、nginx 配置
# HTTPS server # server { listen 443 ssl; server_name proxy.ztns.com; ssl on; # 证书公钥 它会被发送到连接服务器的每个客户端 ssl_certificate /usr/local/openresty/nginx/conf/ssl/proxy.server.crt; # 私钥是用来解密的 ssl_certificate_key /usr/local/openresty/nginx/conf/ssl/proxy.server.key; # CA签发机构证书 ssl_client_certificate /usr/local/openresty/nginx/conf/ssl/ca.crt; # 开启浏览器证书验证 ssl_verify_client on; ssl_session_cache shared:SSL:1m; ssl_session_timeout 5m; ssl_ciphers HIGH:!
Python中使用pyinstaller将pyqt所写的程序打包为exe文件 前言 最近需要写一些小工具来辅助工作,其中一些想了想如果有一个简单的界面的话应该使用起来更方便一些,由于python的方便性,大概试了一下python中的几个常用的图形库,如wxPython与Tkinter等,通过比较,感觉还是pyqt做出来的界面美观性要强一些,而且可移植性较好。
在写完程序的大概之后,即在IDE里运行程序可以出现想要的界面了,现在的一个问题是,以后打开这些程序的时候,若要每次都要先打开IDE然后运行程序,这个过程未免太过繁琐,所以想要将所写的程序打包为exe文件,这样今后打开的时候会方便许多,在其它机器上工作的时候移植也要方便。
本文就主要介绍如何将用pyqt所写的程序打包为exe程序。
环境准备 1、 anaconda下2与3共存的方式与在3的环境中安装包的方法 在本次尝试中遇到了许多问题,其中绝大部分问题最后归论起来还是pyqt环境安装的有问题,所以在安装pyqt的过程中一定要注意。
我的python的版本为2.7,是用anaconda2安装的环境。但是pyqt5对于python2的支持并不好,我在多次尝试后,始终没有找到合适的安装方法,因此最后还是在python3的环境中进行的操作。但是,如果只是想要在程序中实现界面的话,2.7是没有任何问题的,这里只是在打包exe过程中遇到了问题。
简单说一下anaconda,anaconda是一种集成了大多数常用的库的python环境,对于python的安装来说是一种非常方便的方式,anaconda的2与3两个版本便对应着python的2与3。在anaconda中2是可以与3共存的,安装的方法也比较简单,我是先安装的2,在安装3的时候需要主要要装到2的envs这个文件夹中新建的文件夹,如C:\Users\xxx\Anaconda2\envs\python3,再有就是安装的时候在这个界面最好两个选项都不要打勾:
其余的基本一路默认就可以,安装完成之后,python3便可以作为一个独立的环境来进行使用了,在IDE中可以选择…/envs/python3这个文件夹下的python3的解释器,即调用了python3的环境。而在控制台中,默认的初始情况下,直接输入python,进入的是默认的python2.7的环境(因为之前的系统变量中为2.7的环境,而安装anaconda3的时候并没有修改系统变量),使用python3 的方法为输入语句activate python3(这里的python3即为上面envs里面新建的文件夹的名称),此时系统默认的python的环境即更改为了python3,此时的pip也会将包装到3的环境中。此时,若输入python则会进入python环境并显示目前的python版本为python3.6:
而这里的第二行的开头可以看到括号里的python3,这里说明默认环境已经更改到了python3。而之后的说明若无特殊说明均默认为在已经进入了默认python3的环境。
2、 配置SIP 我们要利用PyQt5来写界面,所需的一个依赖库便是sip,sip是RiverBank(也就是PyQt的开发商)开发的用于PyQt的Python/C++混合编程解决方案。SIP是一种工具,可以将Python与C和C++的库进行绑定,它包括代码生成器和python等模块,这使得Python等解释性编程环境可以开发现有的C或者C++的库。
在这里,sip属于python的一个依赖库,可以直接使用命令进行安装
pip install sip ###3、 配置PyQt5
接下来便就是主角PyQt5了,在python3中可以直接使用pip进行安装:
pip install PyQt5 当然这里第二步和第三步会出现许多错误,我在后面会提到。
###4、 配置pyinstaller
这里网上许多资料里都使用下载包然后安装的方式,但是我也是简单地采用了pip的方式进行的安装,并没有出现问题。
pip install pyinstaller 测试 这里是测试的时候用的代码,可以显示出一个简单的界面:
import sys from PyQt5 import QtCore, QtWidgets app = QtWidgets.QApplication(sys.argv) widget = QtWidgets.QWidget() widget.resize(320, 240) widget.setWindowTitle("Hello, PyQT!") widget.show() sys.exit(app.exec()) 将代码写完后将其保存为hello_PyQt.py文件。
之后打开控制台,输入activate python3将默认的python环境设置为python3,然后输入cd 路径进入刚刚的.py文件所在的路径:
然后输入pyinstaller -F -w hello_PyQt.py将代码打包为exe文件(可以在网上查询各种不同参数含义,这里的-F与-w分别为保存为一个文件与运行exe文件时不显示控制台):
最后可以看见此时便保存成功了,在刚刚的路径中的多出来几个文件夹与文件,在build文件夹中可以查看pyinstaller运行时的一些信息,而在另一个dist文件夹中便有着hello_PyQt.exe文件了,即为我们需要的exe文件。此时运行该文件:
可以看到出现了我们代码中所实现的窗口,此时便运行成功。
过程中遇到的问题 1、 在配置sip时报错 在配置sip时报错:
一、引入Groovy依赖 <dependency> <groupId>org.codehaus.groovy</groupId> <artifactId>groovy-all</artifactId> <version>2.4.7</version> </dependency> 二、自定义脚本 package com.epf.activiti.utils; import groovy.lang.Script; import java.lang.reflect.Method; /** * 自定义脚本 * @author GZEPF * @date 2018 2018年8月28日 下午7:56:15 */ public class ExprBasicScript extends Script { @Override public Object run() { //show usage Method[] methods = ExprBasicScript.class.getDeclaredMethods(); StringBuilder sb=new StringBuilder(); for (Method method : methods) { sb.append(method); } return sb.substring(0, sb.length()-1); } public static Object nvl(Object str, Object val) { return str == null || "
机房是网络设备存放的地方,关系着网络系统的稳定。机房的网络设备需要经常维护保养,才能保证正常的用网需求,下面简要介绍机房网络设备保养的六点注意内容。
(机房)
对各个系统实施严格管理,现场设常驻维保人员,建立完整的值班制度和维修保养规则,值班人员应认真监测系统运行状况,随时记录异常情况,及时报修。
1、按国家有关规范和要求派专业人员对系统定期检查,测试,保养,维修,确保设备正常运行。
(1)对维保项目每周不低于1次进行检测。并填写巡查记录,发现故障及时排除或修复,并作为考核维保工作的依据。
(2)每月1次系统状态进行检查,每年12次。
(3)每季度不低于1次对维保项目进检测。如出现故障或问颗,要及时排除修复。
2、须提供24小时维保电话,24*365天随时接受业主的服务请求;接到业主服务请求后,现场驻地人员及时现场维护,若仍未解决,将会派专业工程师8小时内到达现场。
(1)维保技术人员对故障进行诊断后,按紧急程度不同划分,最迟在8小时内提交解决方案。
(2)维保技术人员到达现场后需持续工作直到设备正常运行,一般故障应当在24小时内修复;如需等待购买配件或因设备本身等原因不能及时修复的,要立即向业主报告,并采取相应的应急措施,在此期间,系统中断运行不得超过12小时。
(3)系统或设备修复后必须由乙方相关人员确认。
3、设备更换:维护保养过程中需购买、更换设备或配件的,应事先向业主报告,由业主代表签字确认后,方可进行维修或更换,此部分费用不在乙方范围。若乙方为了确保系统或设备正常运行,应急修复需立即更换设备或配件的,必须在事后及时向业主报告,更换后的损坏件应交由甲方查验。更换的设备(或器件)的型号参数不得低于原设备(或器件)型号参数,并记入设备维修(更换)记录单。
4、维保单位应向业主提交详细的工作计划与工作安排,对每次检修、保养工作要认真做好记录,并交业主相关人员签字。
5、维保单位应切实加强现场管理,确保安全生产,在检修保修中发生人身、设备及第三者事故,乙方不承担任何责任。
6、维保单位不得对相关信息进行查询、下载,不得泄露乙方工作秘密。维保单位工作人员进入业主单位展开维保工作,必须遵守业主的相关规章制度,服从业主单位的管理。
以上就是全部内容了,做好这六点可以让机房运行稳定,满足企业发展需求。
NodeManager
NodeManager会执行健康检查,可以是检查磁盘或者任意用户指定的检查脚本,如果检查失败,则标记此节点为unhealthy并且报告给ResourceManager,然后停止分配容器到此节点。
磁盘检查
磁盘检查两个目录(local-dirs和log-dirs)分别由yarn.nodemanager.local-dirs和yarn.nodemanager.log-dirs指定,检查包括权限和磁盘空间剩余量。同时检查文件系统不是只读状态。默认检查间隔时间为2Min,如果磁盘检查失败,NodeManager停止使用那部分磁盘,仍旧报告节点状态为healthy。如果许多磁盘检查失败,检查的磁盘数量可以配置,则报告节点状态为unhealthy,并且新的容器不会被调度到这个节点上。
下面的配置参数可以用于修改磁盘检查:
yarn.nodemanager.disk-health-checker.enable:是否开启磁盘健康检查。
yarn.nodemanager.disk-health-checker.interval-ms:磁盘检查间隔。
yarn.nodemanager.disk-health-checker.min-healthy-disks:浮点数,0-1之间,默认为0.25,必须通过多少检查,才认为是healthy
yarn.nodemanager.disk-health-checker.max-disk-utilization-per-disk-percentage:浮点数,0-100之间,默认值为90,磁盘被标记为unhealthy之前的最大使用率。
yarn.nodemanager.disk-health-checker.min-free-space-per-disk-mb:默认值为0。
扩展检查脚本
用户可以指定自己的健康检查脚本,它会被健康检查服务调起。用户也可以指定一个超时时间。如果脚本以非0码退出,超时,或者结果抛出异常,则节点被标记为unhealthy。如果因为权限或者不正确的路径,脚本不能执行,它会被标记为失败。指定健康检查脚本是必须的。如果没有健康检查脚本,则只有磁盘检查,确定节点的状态。
可以通过下面的参数配置健康检查。
yarn.nodemanager.health-checker.interval-ms:检查间隔,单位为毫秒,默认值为10min
yarn.nodemanager.health-checker.script-timeout-ms:健康检查脚本的超时时间,默认为20min
yarn.nodemanager.health-checker.script.path:脚本路径
yarn.nodemanager.health-checker.script.opts:脚本选项。
NodeManager Restart
在不丢失已经运行的激活的容器重启NodeManager。默认,NM存储必要的state在一个local state-store。当NM重启时,它会加载这些文件,然后进行恢复。
Step 1.开启NM Restart 功能:
yarn.nodemanager.recovery.enabled
Step 2.配置NM存储状态文件的本地目录
yarn.nodemanager.recovery.dir:默认值为$hadoop.tmp.dir/yarn-nm-recovery
Step 3.配置一个对于NodeManager合法的RPC地址
yarn.nodemanager.address:
Step 4. Auxilliary services
在YARN集群中,NodeManager可以被配置为运行auxilliary services,对于一个完整功能的NM restart,YARN依赖任何辅助服务支持恢复。
一个简单的例子是ShuffleHandler for MapReduce。
Auxiliary Service Classpath Isolation
如果需要运行辅助服务,系统管理员需要把jar包直接放置到NodeManager的类路径。如果存在多版本,则无法控制哪个版本会被加载。如果辅助服务和节点管理器存在依赖冲突,则会使辅助服务和节点管理器同时崩溃。为了解决这个问题,我们可以设置辅助服务使用单独的类路径。
在yarn-site.xml中配置下列选项。
yarn.nodemanager.aux-services.%s.classpath:指定本地jar和依赖jar的目录
yarn.nodemanager.aux-services.%s.remote-classpath:指定远程jar和依赖jar的目录
yarn.nodemanager.aux-service.%s.system-classes:
配置案例:
<property> <name>yarn.nodemanager.aux-services</name> <value>mapreduce_shuffle,CustomAuxService</value> </property> <property> <name>yarn.nodemanager.aux-services.CustomAuxService.classpath</name> <value>${local_dir_to_jar}/CustomAuxService.jar</value> </property> <!-- <property> <name>yarn.nodemanager.aux-services.CustomAuxService.remote-classpath</name> <value>${remote-dir_to_jar}/CustomAuxService.jar</value> </property> --> <property> <name>yarn.nodemanager.aux-services.CustomAuxService.class</name> <value>org.aux.CustomAuxService</value> </property> <property> <name>yarn.
初次接触Elasticsearch的同学经常会遇到分词相关的难题,比如如下这些场景:
1.为什么命名有包含搜索关键词的文档,但结果里面就没有相关文档呢?
2.我存进去的文档到底被分成哪些词(term)了?
3.我得自定义分词规则,但感觉好麻烦呢,无从下手
如果你遇到过类似的问题,希望本文可以解决你的疑惑。
1.上手
让我们从一个实例出发,如下创建一个文档:
PUT test/doc/1
{
msg:Eating an apple a day keeps doctor away
}
然后我们做一个查询,我们试图通过搜索eat这个关键词来搜索这个文档
POST test/_search
{
query:{
match:{
msg:eat
}
}
}
ES的返回结果为0。这不太对啊,我们用最基本的字符串查找也应该能匹配到上面新建的文档才对啊!
各位不要急,我们先来看看什么是分词。
2.分词
搜索引擎的核心是倒排索引(这里不展开讲),而倒排索引的基础就是分词。所谓分词可以简单理解为将一个完整的句子切割为一个个单词的过程。在 es 中单词对应英文为term。我们简单看个例子:
ES 的倒排索引即是根据分词后的单词创建,即我、爱、北京、天安门这4个单词。这也意味着你在搜索的时候也只能搜索这4个单词才能命中该文档。
实际上 ES 的分词不仅仅发生在文档创建的时候,也发生在搜索的时候,如下图所示:
读时分词发生在用户查询时,ES 会即时地对用户输入的关键词进行分词,分词结果只存在内存中,当查询结束时,分词结果也会随即消失。而写时分词发生在文档写入时,ES 会对文档进行分词后,将结果存入倒排索引,该部分最终会以文件的形式存储于磁盘上,不会因查询结束或者 ES 重启而丢失。
ES 中处理分词的部分被称作分词器,英文是Analyzer,它决定了分词的规则。ES 自带了很多默认的分词器,比如Standard、Keyword、Whitespace等等,默认是Standard。当我们在读时或者写时分词时可以指定要使用的分词器。
3.写时分词结果
回到上手阶段,我们来看下写入的文档最终分词结果是什么。通过如下 api 可以查看:
POST test/_analyze
{
field: msg,
text: Eating an apple a day keeps doctor away
}
其中test为索引名,_analyze为查看分词结果的endpoint,请求体中field为要查看的字段名,text为具体值。该 api 的作用就是请告诉我在 test 索引使用 msg 字段存储一段文本时,es 会如何分词。
在dedecms发布文章的时候,偶然遇到以下问题,看提示明显是数据库问题,运行一个SQL语句轻松解决
ALTER TABLE `#@__archives` ADD COLUMN `voteid` int(10) NOT NULL DEFAULT 0 AFTER `mtype`;
1.url: 要求为String类型的参数,(默认为当前页地址)发送请求的地址。
2.type: 要求为String类型的参数,请求方式(post或get)默认为get。注意其他http请求方法,例如put和delete也可以使用,但仅部分浏览器支持。
3.timeout: 要求为Number类型的参数,设置请求超时时间(毫秒)。此设置将覆盖$.ajaxSetup()方法的全局设置。
4.async: 要求为Boolean类型的参数,默认设置为true,所有请求均为异步请求。如果需要发送同步请求,请将此选项设置为false。注意,同步请求将锁住浏览器,用户其他操作必须等待请求完成才可以执行。
5.cache: 要求为Boolean类型的参数,默认为true(当dataType为script时,默认为false),设置为false将不会从浏览器缓存中加载请求信息。
6.data: 要求为Object或String类型的参数,发送到服务器的数据。如果已经不是字符串,将自动转换为字符串格式。get请求中将附加在url后。防止这种自动转换,可以查看 processData选项。对象必须为key/value格式,例如{foo1:"bar1",foo2:"bar2"}转换为&foo1=bar1&foo2=bar2。如果是数组,JQuery将自动为不同值对应同一个名称。例如{foo:["bar1","bar2"]}转换为&foo=bar1&foo=bar2。
7.dataType: 要求为String类型的参数,预期服务器返回的数据类型。如果不指定,JQuery将自动根据http包mime信息返回responseXML或responseText,并作为回调函数参数传递。可用的类型如下:
xml:返回XML文档,可用JQuery处理。
html:返回纯文本HTML信息;包含的script标签会在插入DOM时执行。
script:返回纯文本JavaScript代码。不会自动缓存结果。除非设置了cache参数。注意在远程请求时(不在同一个域下),所有post请求都将转为get请求。
json:返回JSON数据。
jsonp:JSONP格式。使用SONP形式调用函数时,例如myurl?callback=?,JQuery将自动替换后一个“?”为正确的函数名,以执行回调函数。
text:返回纯文本字符串。
8.beforeSend:
要求为Function类型的参数,发送请求前可以修改XMLHttpRequest对象的函数,例如添加自定义HTTP头。在beforeSend中如果返回false可以取消本次ajax请求。XMLHttpRequest对象是惟一的参数。
function(XMLHttpRequest){
this; //调用本次ajax请求时传递的options参数
}
9.complete:
要求为Function类型的参数,请求完成后调用的回调函数(请求成功或失败时均调用)。参数:XMLHttpRequest对象和一个描述成功请求类型的字符串。
function(XMLHttpRequest, textStatus){
this; //调用本次ajax请求时传递的options参数
}
10.success:要求为Function类型的参数,请求成功后调用的回调函数,有两个参数。
(1)由服务器返回,并根据dataType参数进行处理后的数据。
(2)描述状态的字符串。
function(data, textStatus){
//data可能是xmlDoc、jsonObj、html、text等等
this; //调用本次ajax请求时传递的options参数
}
11.error:
要求为Function类型的参数,请求失败时被调用的函数。该函数有3个参数,即XMLHttpRequest对象、错误信息、捕获的错误对象(可选)。ajax事件函数如下:
function(XMLHttpRequest, textStatus, errorThrown){
//通常情况下textStatus和errorThrown只有其中一个包含信息
this; //调用本次ajax请求时传递的options参数
}
12.contentType:
要求为String类型的参数,当发送信息至服务器时,内容编码类型默认为"application/x-www-form-urlencoded"。该默认值适合大多数应用场合。
13.dataFilter:
要求为Function类型的参数,给Ajax返回的原始数据进行预处理的函数。提供data和type两个参数。data是Ajax返回的原始数据,type是调用jQuery.ajax时提供的dataType参数。函数返回的值将由jQuery进一步处理。
function(data, type){
//返回处理后的数据
return data;
}
15.global:
要求为Boolean类型的参数,默认为true。表示是否触发全局ajax事件。设置为false将不会触发全局ajax事件,ajaxStart或ajaxStop可用于控制各种ajax事件。
16.ifModified:
要求为Boolean类型的参数,默认为false。仅在服务器数据改变时获取新数据。服务器数据改变判断的依据是Last-Modified头信息。默认值是false,即忽略头信息。
17.jsonp:
要求为String类型的参数,在一个jsonp请求中重写回调函数的名字。该值用来替代在"callback=?"这种GET或POST请求中URL参数里的"callback"部分,例如{jsonp:'onJsonPLoad'}会导致将"onJsonPLoad=?"传给服务器。
18.username:
js
1、标签(不推荐,要将script放在页面最后且不能onload)
<body> <button onclick="clickEvent()">click</button> </body> <script> function clickEvent() { alert('hello world!'); } </script> 2、函数赋值
<body> <button id="btn">click</button> </body> <script> window.onload=function(){ var btn=document.getElementById('btn'); // btn.onclick = function(){ // clickEvent() // }; // function clickEvent() { // alert('hello world'); // } btn.onclick=function(){ alert('hello world'); }; } </script> 3、事件监听( 传入的是函数 不是函数值 )
<body> <button id="btn">click</button> </body> <script> window.onload=function(){ var btn=document.getElementById('btn'); btn.addEventListener('click',function(){ alert('hello world!'); }) } </script> 移除addEventListener添加的事件:
ele.removeEventListener('click',myFunction); addEventListener方法特点:
1、同一事件多个句柄(不会覆盖已存在事件)
ele.addEventListener("click", myFunction); ele.
v=20; t=[0:0.01*pi:50*pi]; alpha=pi/6; omega=pi/6; x=v*sin(alpha)*t.*cos(omega*t); y=v*sin(alpha)*t.*sin(omega*t); z=v*cos(alpha)*t; plot3(x,y,z,'r','linewidth',2) grid on 转载于:https://www.cnblogs.com/Airboy1/p/9535283.html
mixin.styl:
bg-image($url)//默认2x图,dpr为3则使用3x图 background-image: url($url+"@2x.png") @media (-webkit-min-device-pixel-ratio: 3),(-min-device-pixel-ratio: 3) background-image: url($url+"@3x.png") header.vue:
<template> <div class="title"> <span class="brand"></span> <span class="name">{{seller.name}}</span> </div> </template> <style lang='stylus'> @import '../../common/stylus/mixin.styl'//使用前需要导入 ... .title margin: 2px 0 8px 0 .brand display: inline-block vertical-align: top width: 30px height: 18px bg-image('brand') background-size: 30px 18px background-repeat: no-repeat .name margin-left: 6px font-size: 16px font-weight: bold line-height: 18px </style>
前记
python中什么对象不能作为字典的key:有__hash__方法可以做字典的key,没有则不能作为字典的key;
除了list、dict、set和内部至少带有上述三种类型之一的tuple之外,其余对象均可作为字典的key;
一、list做key示例:
a = [1,2,3]
d = {a:a}
报错:
TypeError: unhashable type: 'list'
报错信息,list类型不可哈希;
查看源码object对象定义了__hash__方法,list、set、dict把__hash__赋值为None;
通过help(list/set/dict)也可看到__hash__赋值为None;
# 部分源码
class object:
""" The most base type """
def __hash__(self, *args, **kwargs): # real signature unknown
""" Return hash(self). """
pass
class list(object):
__hash__ = None
class set(object):
__hash__ = None
class dict(object):
__hash__ = None
二、实验
修改__hash__方法;
class Mylist(list):
def __hash__(self):
return hash(self[0])
l1=Mylist([1,2])
d={l1:"can?"}
print(d)
l1.append(3)
print(d)
今天,我们主要来聊聊Python开发环境的搭建。在程序猿的世界里,最痛苦的事情一般来说都不是敲代码本身,而是各种环境的搭建。今天我们要讨论的第一个主题就是Python开发环境的搭建。环境搭建分为两个部分,一部分是Python的安装,另一部分是开发工具(IDE)的选择及安装。
首先,咱们来说说第一部分:Python的安装。打开你的网页浏览器,在地址栏输入www.python.org,你将会看到一个纯英文的网站。如下图所示:
不要怕,一切尽在掌握,本猿来慢慢教你。点击Downloads 下面的 "All releases" 点击后会跳转到下载页面,下面的步骤要注意啦,关于Python版本的选择。
Python目前有两个大版本Python2和Python3。Python2系列中目前更新比较稳定的是Python2.7,Python3系列也在持续更新,相比Python2有一个较大的升级,且没有考虑向下兼容的问题,这里面一般来说可以跟随官方最新的小版本,在本猿写这篇文章时Python2的最新版是Python2.7.13,Python3的最新版是3.7.0,本猿常用的版本是2.7和3.6。
在这里新来的朋友就要问啦,你这有两个版本我们学习哪个呢?其实两个大版本之间的区别不是特别大,至于学习哪个版本,本猿推荐入门的朋友直接选择最新的Python3.x系列,小版本就比较随意啦,咱们就指定一个版本,免得选择困难症的出现,Python 3.6.6。点击下图中的 "Download" 按钮。
网页跳转后不要犹豫,直接往最下面拉。看到下面的表格以后咱们只关注红色框内的内容
Windos x86-64 executable installer 这个是64位Windows系统的安装包,Windows x86 executable installer这个是32位Windows系统的安装包。下面问题来了,怎么查看自己电脑操作系统是多少位的呢?进入自己的电脑桌面,右键点击“我的电脑”---“属性”,查看下图中的内容:
好了,这里咱们就知道自己的操作系统类型了。点击对应的下载链接即可下载自己需要的版本哦。如果下载速度太慢的话就用迅雷下吧!
下载完成后,双击我们下载好的安装包,可以看到如下界面:
选中上图中指示的"Add python 3.6 to PATH"(这点很重要),然后点击箭头2所示的位置“Customize installation”,就可以看到如下界面
这一页默认,直接点击"Next"按钮
在这个页面上,点选箭头1所示的框框,点击箭头2所示的按钮,选择你要安装Python的路径,笔者在这里选了C盘下的Python3.6文件夹,然后点击箭头3所示的Install 按钮,中间如果弹出什么窗口需要确认,那就允许吧!这时候咱们要做的事情就是等待程序安装完成啦~~~等程序运行完成后点击Close就可以啦!
如果到这里,那么恭喜你,你的Python已经安装完成啦。
下面我们来测试一下是否安装成功了。按下键盘上的Win键+R键,在弹出的运行框内输入“cmd”,如下图所示:
点击确定后,会弹出一个命令行窗口。这个界面下输入python,如下图所示:
敲回车键后,如果看到如下界面,那么恭喜你,你的环境已经搭建成功啦!
如果你看到的是如下界面
那么说明你在执行前面步骤的时候少勾选了红色字体标示的那个框框。本质上是你少配置了环境变量。关于这个问题,本猿会在下一篇文章中来提出解决方案。
好了,关于Python环境搭建的第一部分就聊到这里啦,我们将在接下来的一篇文章中讲述Python环境搭建的第二部分:编程工具篇。
如果觉得本文可以帮到你,欢迎关注哦~
长按关注哦~
由于Python的去重方式比较多,本人在项目中总结了几种常用方法,欢迎补充。 一、对列表去重 1.用循环查找的方式 li = [1,2,3,3,4,2,3,4,5,6,1]
news_li = []
for i in li:
if i not in news_li:
news_li.append(i)
print (news_li)
2.用集合的特性set() li1 = [1,4,3,3,4,2,3,4,5,6,1]
new_li1 = list(set(li1))
3.使用itertools模块的grouby方法 import itertools
li2 = [1,4,3,3,4,2,3,4,5,6,1]
li2.sort() # 排序
it = itertools.groupby(li2)
for k, g in it:
print (k)
4.运用while循环遍历的方式 def quchong(lb):
for x in lb:
while lb.count(x)>1:
del lb[lb.index(x)]
return lb
li3 = [1,4,3,3,4,2,3,4,5,6,1]
quchong(li3)
5.使用keys()方式 li4 = [1,0,3,7,7,5]
formatli = list({}.
项 目 经 验
项目一 客户关系管理系统(CRM)
项目描述
整个项目是基于B/S模式,应用Struts Spring Hibernate DWR和ExtJS五个框架实现了一个绚丽的客户关系管理系统。分为View层(显示层)、Control层(控制层)、Service层(业务逻辑层)、DAO层(数据库访问对象层)。利用Spring的依赖注入和面向切面特性,hibernate的数据持久化技术、Struts的控制器、ExtJS用于View层实现了用户权限管理、日程安排、客户关系管理、销售管理、档案管理、统计数据、商务联系管理等模块。
责任描述
在项目中作为组长,规划整个项目的需求分析,系统数据库设计,分配其他几位组员的模块,使每人在项目中各尽其职。在项目期间,充分发挥我的特长,耐心的和组员讨论项目中所遇到的问题,并在短时间内解决问题。我负责的是客户和潜在客户模块,
这两个模块主要用的ExtJS来实现用户界面,使Ajax和SSH的结合得到淋漓尽致的体现。最后负责各个模块的整合和测试。
项目总结
团队合作,使个人在团队合作能力、沟通能力、协调能力、技术方面都得到了很大的提高,同时能很好的为整个团队提出建议和自己的想法,能很好的协调好整个团队,团队之间的合作很愉快。
开发工具及技术
Windows XP professional、JDK1.5、MyEclipse6.5、Tomcat6.0、SQLServer2000、Struts1.2.9、Spring2.5.5、Hibernate3.3、Ext js2.0、DWR2.0
项目二 某房屋出租中介公司租房管理系统
项目描述
租房管理系统是B/S模式,该系统采用Struts Spring Hibernate框架整合应用同时加入DWR框架的应用,严格按照MVC的标准,实现了View层(显示层)、Control层(控制层)、Service层(业务逻辑层)、DAO层(数据库访问对象层)的多层架构。利用JSP作为显示层、Action作为控制层、Service层和DAO层处理业务逻辑。DTO、POJO作为传值组件。整个项目通过Spring的Ioc技术实现组件之间的依赖关系注入,View层通过采用javascript进行简单表单验证,利用struts标签,hibernate数据持久化技术,实现了用户登录注册、发布租房信息(登录的用户)、 编辑房屋信息(此房屋信息的发布者)、删除房屋信息(此房屋信息的发布者)、多条件查询房屋信息(一般查询和高级搜索)、用户权限管理等功能。
责任描述
独立完成项目的整个开发。体验到SSH框架应用的妙处和MVC思想在软件开发中的好处。
项目总结
能够安全高效的处理用户的所有功能需求,并巩固了自己的技术。
开发工具及技术
Windows XP professional、JDK1.5、MyEclipse6.5、Tomcat6.0、SQLServer2000、Struts1.2.9、Spring2.5.5、Hibernate3.3、DWR2.0
项目三 在线考试系统
项目描述
在线考试系统是为了提高考试效率,规范考试流程而设计的。系统是B/S模式,分为题型管理、题库管理、试卷管理、考试管理、阅卷管理、员工管理、在线考试(随机出题)、成绩查询等模块。其根据MVC设计思想,手写配置文件、解析配置文件,利用HTML、JSP作为View层,DTO作为传值组件,利用Action作为控制器,应用SQL Sever 2000作为数据库。满足用户需求同时,完成了分页、多条件查询、人阅和机阅的试卷等功能。
责任描述
在该项目中担当项目组长职责,负责需求分析和数据库设计,分配其他组员的任务,融洽团队的气氛,并把一些好的想法向团队提出一起讨论,最后完成两个模块的程序,和其他组员一起解决遇到的困难。
项目总结
能够安全高效的处理用户的所有功能需求。团队开发,充分发挥开发优势,感受到集体的力量,更加巩固了自己的技术。
开发工具
Windows XP professional、JDK1.5,Eclipse3.2.GA、Tomcat5.5、SQLServer2000。
项目四 人力资源管理系统(HRMS)
项目描述
本人力资源管理系统主要是为了方便企业筛选和储备人才,合理利用人力资源而设计。系统基于B/S模式,采用自己手写的MVC框架。从功能上分为简历管理,渠道管理,项目管理,系统管理,数据统计五个大模块。其中简历管理尤为重要,该模块采用了工作流的方式,从简历录入到初选,复选,再到人才的预约和面试,到最后的入职。真实地反映了企业吸纳人才的整个过程。我在项目中担任核心成员,负责并完成了其中最复杂的简历管理模块。
责任描述
在项目中担任核心成员,负责并完成了其中最复杂的简历管理模块,并且协调各组员之间的关系,让大家在一个紧张而又活泼的环境下完成。
项目总结
在组队完成项目中,对实现项目所用到的一些框架、技术等都有了更深的理解,在团队合作上也很成功,跟组员相处融洽,从其他组员哪里也学到了很多知识。
开发工具
Windows XP professional、JDK1.5,Eclipse3.2.GA、Tomcat5.5、SQLServer2000。
项目五 MailServer邮件服务器
项目描述
该项目是有个人独立开发的项目该系统是基于SMTP协议和POP3协议的电子邮件收发服务器系统,通过严格遵循简单邮件传输协议和邮局协议管理来保证收发功能的正常运行。实现了邮件自发,转发,多发等功能,并通过OUTLOOK、FOXMAIL等邮件收发工具测试成功。负责收发邮件信息,其中可以发送、接收邮件,并可对每个客户的邮件进行分类整理,并且提供给客户暂时缓存的功能
责任描述
负责整个项目代码编写及调试。
项目总结
老规矩废话不多说 直接上效果图可以支持多个选项
对话框的类结构
工程基于本人的GameFrame框架 主要逻辑如下
void ChangeScence() { Singleton<SceneManager>.GetInstance().LoadScene("Login", () => { Singleton<WindowManager>.GetInstance().OpenWindow("Dialogue",true,true,new DialogueContent("dialoguedata.json","node1")); }); } UI框架的DialogueContent的类结构如下: 支持当前对话 的模型头像的一些支持 比如当前说话的角色头像模型变大之类的
public class DialogueContent : WindowContext { public string FileName ; public string StartNode; public Sprite LeftIcon; public GameObject LeftModel; public Sprite RightIcon; public GameObject RightModel; public int ShowType = 0;// 不显示 1 显示ICON 2 显示 MODEL public DialogueContent(string file,string node,Sprite lefticon = null ,Sprite righticon = null,GameObject leftmodle = null,GameObject rightmodel = null,int show = 0) { FileName = file; StartNode = node; LeftIcon = lefticon; RightIcon = righticon; LeftModel = leftmodle; RightModel = rightmodel; ShowType = show; } } //初始化按钮的监听事件 for (int i = 0; i < 4; i++) { Answers[i] = CacheTransform.
这篇文章我们将使用 requests 和 xpath 爬取豆瓣电影 Top250,下面先贴上最终的效果图:
1、网页分析 (1)分析 URL 规律 我们首先使用 Chrome 浏览器打开 豆瓣电影 Top250,很容易可以判断出网站是一个静态网页
然后我们分析网站的 URL 规律,以便于通过构造 URL 获取网站中所有网页的内容
首页:https://movie.douban.com/top250
第二页:https://movie.douban.com/top250?start=25&filter=
第三页:https://movie.douban.com/top250?start=50&filter=
…
不难发现,URL 可以泛化为 https://movie.douban.com/top250?start={page}&filter=,其中 page 代表页数
最后我们还要验证一下首页的 URL 是否也满足规律,经过验证,很容易可以发现首页的 URL 也满足上面的规律
核心代码如下:
import requests # 获取网页源代码 def get_page(url): # 构造请求头部 headers = { 'USER-AGENT':'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36' } # 发送请求,获得响应 response = requests.get(url=url,headers=headers) # 获得网页源代码 html = response.text # 返回网页源代码 return html (2)分析内容规律 接下来我们开始分析每一个网页的内容,并从中提取出需要的数据
1 transform属性 在CSS3中,可以利用transform功能实现文字或图像的旋转、缩放、倾斜、移动这4中类型的变形处理。
(1)浏览器支持
到目前为止:Safari3.1以上、Chrome8以上、Firefox4以上、Opera10以上浏览器支持该属性。 2 旋转 使用rotate方法,在参数中加入角度值,角度值后面跟表示角度单位的“deg”文字即可,旋转方向为顺时针方向。
transform:rotate(45deg);
3 缩放 使用scale方法来实现文字或图像的缩放处理,在参数中指定缩放倍率。
transform:scale(0.5);//缩小一半
(1)可以分别指定元素的水平方向的放大倍率与垂直方向的放大倍率
transform:scale(0.5,2);//水平方向缩小一半,垂直方向放大一倍。
4 倾斜 使用skew方法实现文字或图像的倾斜处理,在参数中分别指定水平方向上的倾斜角度与垂直方向上的倾斜角度。
transform:skew(30deg,30deg);//水平方向上倾斜30度,垂直方向上倾斜30度。
(1)只使用一个参数,省略另一个参数
这种情况下视为只在水平方向上进行倾斜,垂直方向上不倾斜。
transform:skew(30deg);
5 移动 使用translate方法来移动文字或图像,在参数中分别指定水平方向上的移动距离与垂直方向上的移动距离。
transform:translate(50px,50px);// 水平方向上移动50px,垂直方向上移动50px
(1)只使用一个参数,省略另一个参数
这种情况下视为只在水平方向上移动,垂直方向上不移动。
transform:translate(50px);
6 对一个元素使用多种变形的方法 transform:translate(150px,200px) rotate(45deg) scale(1.5);
7 指定变形的基准点 在使用transform方法进行文字或图像变形的时候,是以元素的中心点为基准点进行变形的。
transform-origin属性 使用该属性,可以改变变形的基准点。
transform:rotate(45deg);
transform-origin:left bottom;//把基准点修改为元素的左下角
(1)指定属性值
基准点在元素水平方向上的位置:left、center、right
基准点在元素垂直方向上的位置:top、center、bottom
8 3D变形功能 (1)旋转
分别使用rotateX方法、rotateY方法、rotateZ方法使元素围绕X轴、Y轴、Z轴旋转,在参数中加入角度值,角度值后面跟表示角度单位的deg文字即可,旋转方向为顺时针旋转。
transform:rotateX(45deg);
transform:rotateY(45deg);
transform:rotateZ(45deg);
transform:rotateX(45deg) rotateY(45deg) rotateZ(45deg);
transform:scale(0.5) rotateY(45deg) rotateZ(45deg);
(2)缩放
分别使用scaleX方法、scaleY方法、scaleZ方法使元素按X轴、Y轴、Z轴进行缩放,在参数中指定缩放倍率。
transform:scaleX(0.5);
transform:scaleY(1);
transform:scaleZ(2);
transform:scaleX(0.5)scaleY(1);
transform:scale(0.5) rotateY(45deg);
(3)倾斜
分别使用skewX方法、skewY方法使元素在X轴、Y轴上进行顺时针方向倾斜(无skewZ方法),在参数中指定倾斜的角度
url请求流程图:
输入url请求地址 通过DNS服务查询目标IP 浏览器发送请求 浏览器与服务器完成三次握手,建立链接 socket作为网络通信的基本操作单元,负责完成数据传输 浏览器发送http请求 服务器处理http请求,并返回http响应 浏览器解析渲染html页面,转换成人类易懂内容 浏览器与服务器完成四次挥手,断开链接
前记
事务隔离性由锁实现;原子性、一致性、持久性由数据库redo log和undo log完成。redo log重做日志,保证事务原子性和持久性,undo log保证事务一致性;redo和undo都可视为一种恢复操作,redo恢复提交事务修改的页操作,undo回滚行记录到某个特定版本;redo是物理日志,记录的是页的物理操作,undo是逻辑日志,根据每行记录进行记录;redo log基本是顺序写,数据库运行时不需要对redo log file进行读取操作,undo log需要随机读写;InnoDB存储引擎启动时,不管上次数据库是否正常关闭,都会尝试进行恢复操作。redo log记录的是物理日志,恢复速度比逻辑日志快; redo
实现事务的持久性。由两部分组成,内存中重做日志缓存redo log buffer,易失;重做日志文件redo log file,持久的;通过Force Log at Commit机制实现事务的持久性,即事务提交commit时,需将该事务所有日志写入到redo log file进行持久化,待事务commit操作完成才算完成;每次将redo log buffer写入redo log file,InnoDB调用一次fsync操作;innodb_flush_log_at_trx_commit参数控制redo log刷新到磁盘的策略; 1:事务提交时必须调用一次fsync;
0:事务提交时不进行写入redo log操作,该操作仅在master thread中完成,master thread中每1秒进行一次redo log file的fsync操作;
2:事务提交时将redo log写入redo log file,但仅写入文件系统的缓存中,不进行fsync;
redo log vs binlog redo log是在InnoDB层,binlog是MySQL数据库上层产生;binlog是逻辑日志,记录的是对于的SQL语句;redo log是物理日志,记录的是对每个页的修改;binlog在事务commit完成后进行一次写入;redo log在事务中不断的被写入,不是随事务提交顺序写入的; log block
Innodb中,redo log以512字节存储的,即redo log buffer、redo log file都是以block方式保存,称为redo log block,大小为512字节;redo log block=log block header(12字节) + log body(492字节) + log tailer(8字节);redo log格式InnoDB引擎的存储管理基于页,所以redo log格式也是基于页;格式=redo_log_type + space + page_no + redo log body; redo_log_type:redo log的类型;
一、默认安装包已上传到虚拟机 默认上传解压过了 /opt/module/jdk1.8.0_144 这种只需要修改配置
1.编辑配置文件 [root@hadoop102 jdk1.8.0_144]# vim /etc/profile 2.尾部添加内容 export JAVA_HOME=/opt/module/jdk1.8.0_144 export PATH=$PATH:$JAVA_HOME/bin 3.source 文件 [root@hadoop102 jdk1.8.0_144]# source /etc/profile 4.测试 [root@hadoop102 jdk1.8.0_144]#java 二、linux环境下下载并安装jdk1.8 环境
Oracle VM VirtualBox、centOs7
1、下载安装包,需要在虚拟机能链接外网的情况下,否则需要自己上传安装包
1.下载命令 wget --no-check-certificate --no-cookies --header "Cookie: oraclelicense=accept-securebackup-cookie" http://download.oracle.com/otn-pub/java/jdk/8u181-b13/96a7b8442fe848ef90c96a2fad6ed6d1/jdk-8u181-linux-x64.tar.gz 2.有可能虚拟机没有安装 wget包,无法执行此命令,则需要先下载wget包 方式一: yum -y install wget 方式二:有可能没有 yum安装包 rpm ivh wget-1.12-1.4.el6.x86_64.rpm 3.开始下载 2、开始安装,自己上传的安装包也是一样的安装方式
2.1 解压命令:tar zxvf 安装包名称 2.2 进入解压后文件夹,获取路径用户配置环境 获取当前路径:pwd 2.3.1 查看未配置前的情况,确定未安装jdk java -version 2.3.2确定未安装,vi 编辑 /etc/profile 文件配置环境 方式一: JAVA_HOME=/usr/java/jdk1.8.0_25 JRE_HOME=/usr/java/jdk1.
众联社保本位码匹配工具2018版操作说明
一: HIS药品目录准备工作 从医保业务系统导出HIS药品目录
二:打开 众联社保本位码匹配工具 点击导入
三: 开始本位码和ypid 码的维护比对工作
第一步 选择左边待匹配的HIS药品目录 第二步 右边将根据药品名称自动刷新符合条件的数据 第三步 选择符合条件的记录 第四步 点击打勾按钮 第五步 点击是 完成本位码和ypid 码维护
四: 如需重新维护本位码和ypid 码 则选择匹配完成 查找需要重新维护逇记录,点击取消匹配,即可重新匹配 五:完成好所有的药品本位码和ypid 码的维护工作后 点击导出 生成excel 文件 六:在医保业务系统维护界面 点击导入 七: 完成导入后开始匹配2018年新药品目录
安装文件下载地址 百度网盘
https://pan.baidu.com/s/18xCpKpbcqHYxsAOpYu4XiQ
删除隐藏目标文件 本章节内容为删除目标文件以及隐藏的文件;还有一些是乱码或者标点符号命名的文件,通过 “ rm -f ” 进行删除的效果不太理想,必须得通过查询文件的号码才能进行删除;做起来的话还是相当麻烦的呢,所以我们开发的这个脚本就用的上场了;对于想删除文件我们只需要输入“序号” 就能将其删除…
脚本代码…
[root@deng-131 order]# vim srm.sh #!/bin/bash #用途:用于删除复杂隐藏的文件 #开发者:酋长rosen #联系方式:https://blog.csdn.net/weixin_42867972/ #版本信息:2.0.10 ls -lia | cat -n | tail -n +2 | awk '{print}' #把要当前目录下全部文件以列表的形式显示出来 read -p "请输入要删除文件的序号:" num #输入要删除的文件序号 if [[ $num =~ ^[0-9]{1,4}$ ]] #序号必须是数字输错就直接退出 then id=`ls -lia | cat -n | tail -n +2 | awk '$1=='$num'{print $2}'` #查找删除文件ID号,进行准确删除 find . -inum $id -exec rm {} \; #通过ID号对目标文件执行删除工作 echo -e "
菜单栏中选择 Files->witch workspace->other...,然后选择要切换的工作空间,点击launch即可
1、异常java.lang.NoClassDefFoundError: org/apache/poi/UnsupportedFileFormatException
解决方法:使用的poi的相关jar包一定版本一定要相同!!!!!
2、maven所使用jar包,没有使用maven的话,就用poi-3.9.jar和poi-ooxml-3.9.jar(这个主要是用于Excel2007以后的版本)两个jar包就行()
<dependency> <groupId>org.apache.poi</groupId> <artifactId>poi</artifactId> <version>3.9</version> </dependency> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi-ooxml</artifactId> <version>3.9</version> </dependency> 3、java导入Excel
先上传Excel
//上传Excel @RequestMapping("/uploadExcel") public boolean uploadExcel(@RequestParam MultipartFile file,HttpServletRequest request) throws IOException { if(!file.isEmpty()){ String filePath = file.getOriginalFilename(); //windows String savePath = request.getSession().getServletContext().getRealPath(filePath); //linux //String savePath = "/home/odcuser/webapps/file"; File targetFile = new File(savePath); if(!targetFile.exists()){ targetFile.mkdirs(); } file.transferTo(targetFile); return true; } return false; } 在读取Excel里面的内容
public static void readExcel() throws Exception{ InputStream is = new FileInputStream(new File(fileName)); Workbook hssfWorkbook = null; if (fileName.
一、应用场景 1.linux机器都禁止使用root远程登陆,需要ansible来实现切换用户文件分发。
二、实验步骤 1、配置资源清单hosts文件
[root@master playbook]# cat /etc/ansible/hosts [test_su] 192.168.1.232 ansible_ssh_user=saas ansible_ssh_pass='xE#bH2bmot3sz' ansible_become_pass='9Cg6Rxjlvtfx^' 192.168.1.233 ansible_ssh_user=saas ansible_ssh_pass='xE#bH2bmot3sz' ansible_become_pass='9Cg6Rxjlvtfx^' 注意: 密码部分要加单引号在2.5版本,变量也做了变化,ansible_become_pass替换了之前的ansible_sudo_pass or ansible_su_passAnsible普通用户sudo执行指令需要sshpass,使用过程中发现sshpass和synchronize模块冲突,可以使用copy模块代替。 2、Ansile客户端禁止root直接远程登陆,并创建普通用户saas
[root@master playbook]# grep -i “^PermitRootLogin” /etc/ssh/sshd_config PermitRootLogin no [root@master playbook]# systemctl restart sshd
3、Ansible服务端分发文件
[root@master playbook]# ansible test_su -S -R root -m copy -a “src=/etc/hosts dest=/etc/hosts”
4.Ansible普通用户sudo执行指令 [root@master playbook]# ansible test_su -S -R root -m shell “whoami”
5.参数解读 -S, –su run operations with su (deprecated, use become) -R SU_USER, –su-user=SU_USER run operations with su as this user (default=root) (deprecated, use become)
最近刚学完基础部分,写个爬虫充实一下自己。
#!/usr/bin/python #coding:utf-8 ''' 爬某小说网站 ''' import urllib2 import re from bs4 import BeautifulSoup #根据指定url获取服务器端响应 def OpenPage(url): Myheaders = {} #urllib2.Request 构造请求 req = urllib2.Request(url,headers=Myheaders) #相当于,在浏览器的地址栏,输入了网址 #激活请求,获取响应 f = urllib2.urlopen(req) #服务器端响应类文本对象,通过read()方法读取响应内容 data = f.read() #三种处理方式ignore replace xml..replace return data.decode("GBK",errors="ignore").encode("utf-8") def Test1(): url = "http://www.shengxu6.com/book/2967.html" print OpenPage(url) #从主页解析数据,获取各个章节的跳转链接url def ParseMainPage(page): #调用爬虫库提供的相关方法,进行数据分析 #html.parser python自带的html解析引擎 soup = BeautifulSoup(page,"html.parser") #find_all方法在全文内容里搜索符合内容的标签,返回一个列表 #检索所有的href属性值中包含read字符串的标签 GetA = soup.find_all(href=re.compile("read")) #因为标签内部属性是键值对的方式href="" #UrlList = [] #for item in GetA: # UrlList.
1.编写一个小程序:你好!
首先创建Java项目project->创建包package ->类class ->编写类,实现提示
例如:JSNU2018 ->cn.edu.jsnu.www(小写) -> DomoJsnu
项目名推荐英文大写
各种方法和属性(属性没有小括号-名词,方法有)
package cn.edu.jsnu.www;
public class Demo2 {
public static void main(String[] args) {
// TODO Auto-generated method stub
//通过类中的主方法
System.out.println("hello");//输出
}
}
//类的第一个字母大写
2.启动eclipse,设定工作空间
3.通过右侧open perspective,显示java 和javaee;(选择Java)
编程包括:
J2SE -Java To Standard Environment
J2EE-Java To Enterprise Environment
J2ME-Java To Mobile Environment
F2 -重命名(改项目,包,类名,方法名,属性)
F5 -刷新
【注意】类名必须与Java源代码名字相同。
如:DEMOJANU -DEMOJANU.JAVA
格式问题:
Java源代码:*.Java(星号代码任意字符)
Java编译类格式:*.class
Java的包格式:*.jar ->*.war *.exe
编写->完成编译(run as java1 )->在控制台console显示结果
【ECLIPSE优化】
1.字体调整
一.基本工具的使用
1.下载编码神器 SUBLIME TEXT
2.掌握SUBLIME常用快捷键
ctrl + shift + d ---------复制这行文本
Ctrl+ Shift+ v 进行自适应缩进的粘贴
ctrl + shift + P ------------------命令模式
ctrl + / ---------------------注释
ctrl+shift+/----------------多行注释
ctrl + 滚动 --------------字体变大/缩小
ctrl + N-------------------新建
ctrl + d ---------------多行游标选择 可以搭配 ctrl + K取消选择部分游标
产生游标的另外一种方式,按住Shift + 鼠标右键拖动光标
ctrl+光标 ---------------快速复写
ctrl+o --------------打开
ctrl+h --------------替换
ctrl+a --------------全选
alt+f3----------------光标在单词后,多选这个单词
eclipse alt +/------------代码提示
[Sublime配置流程]:
下载Sublime->解压->添加或删除右键菜单->添加成功->找到"s"标志的主程序-> 右击发送到桌面“快捷方式” ->通过桌在启动程序->通过“首选项”调整色彩方案(Color Scheme)
->通过“查看”调整布局 ->通过“文件”,设置文件编码和保存编码 ->采用UTF8或GBK编码。
UTF-8或UTF8 -万国码 -世界通用编码格式,支持全球主要语言(含中文)
GBK或GB2312 -中国标准码 -GBK(国标扩-中国国家标准扩展集)中国常用的新标准字符集
1.关键词volatile的理解 首先我们看看如下代码:
public class Voliate { private static int MAX_VALUE = 5; private static int init_value = 0; public static void main(String[] args) { new Thread(()->{ int localValue = init_value; while (localValue <= MAX_VALUE){ if(init_value != localValue){ System.out.println("the init_value is updated : " + init_value); localValue = init_value; } } },"Reader").start(); new Thread(()->{ int localValue = init_value; while (localValue <= MAX_VALUE){ System.out.println("the init_value is changed : " + localValue ++); init_value = localValue; try { TimeUnit.
目录
问题
解决 安装Visual C++ Redistributable for Visual Studio 2015 组件
注意(删除已有dll文件)
问题 安装软件过程中,系统弹出"无法启动此程序,因为计算机中丢失 api-ms-win-crt-runtime-l1-1-0.dll",尝试重新安装该程序来解决此问题
解决 安装Visual C++ Redistributable for Visual Studio 2015 组件 api-ms-win-crt-runtime组件为 MFC 的运行时环境的库,是用微软的visual studio C++编译的,底层也会用到微软提供的C++库和runtime库,安装Visual C++ Redistributable for Visual Studio 2015 组件即可解决此问题
注意(删除已有dll文件) 安装前必须先删掉C:\Windows\System32和C:\Windows\SysWOW64 下,Windows中已有的api-ms-win-crt-runtime-l1-1-0.dll组件,因为VC redit.exe 安装完成会重新生成该组件。如果有就直接删除,如果不放心的话,可以先备份
高斯消元
总结:概率和期望问题的求解都要依靠递推式,概率问题按照递推式进行dp,期望问题根据递推式化简的难易程度通过化简再dp或高斯消元求解,该类问题大部分仍属于各个类型的dp求解问题
2018.9.3-概率与期望dp学习
Discovering Gold
一排1到n的格子,每个格子上有黄金 ai ,你最开始在 1 号,每一次投骰子决定到哪一个格子,超出1~n范围则重新投掷,你到了哪个格子就得到哪个格子的金币,问最终在n 能得到金币的期望
#include<stdio.h> #include<string.h> const int MAX=1e2+5; int a[MAX]; double dp[MAX]; int t,n; int main() { scanf("%d",&t); for(int tc=1;tc<=t;++tc) { memset(dp,0,sizeof(dp)); scanf("%d",&n); for(int i=1;i<=n;++i) scanf("%d",&a[i]); dp[1]=1.0; for(int i=1;i<n;++i) { for(int j=1;j<=6&&i+j<=n;++j) { int tmp=6; if(i+6>n) tmp=n-i; dp[i+j]+=dp[i]/tmp; } } double ans=0; for(int i=1;i<=n;++i) ans+=dp[i]*a[i]; printf("Case %d: %f\n",tc,ans); } return 0; } HDU3366 Passage
有n扇门和m枚金币,每扇门后有3种可能:1.出路概率p,2.另一扇门概率1-p-q,3.失去一枚金币并且出现另一扇门概率q,门可选择,求在最优选择情况下找到出路得概率
根据p/q从大到小对每扇门排序即为最优策略,注意q可能的值为0,需eps处理
#include<stdio.h> #include<string.h> #include<algorithm> using namespace std; const int MAX=1e3+5; const double eps=1e-16; double dp[MAX][15],ans; int t,n,m; struct P { double p,q; }a[MAX]; inline bool cmp(P& x,P& y) { return (x.
课程大纲:
HTML基础列表,表格,框架表单初始CSSCSS美化页面元素制作完成项目 <strong><strong/>
<em><em/>
<hr/>
<br/>
 
此时将a01格子跨列成两格
此时将b01格子跨列成两格
锚:<a name="top"></a>
<p><a href="#top">返回顶部</a></p>
<!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8"> <title>这是我的第一个标题</title> </head> <body> <a name="top"></a> 这是我的第一个网页 <h1>这是标题一</h1> <h2>这是标题二</h2> <hr> <p><strong>加粗</strong><em>斜体</em><strong><em>加粗斜体</em></strong>这是  一个段落<br/>这是一个段落这是一个段落这是一个段落</p> <p>这是一个段落这是一个段落这是一个段落这是一个段落这是一个段落这是一个段落这是一个段落这是一个段落这是一个段落</p> <p> <a href="#i2">查看第二张图片</a> </p> <h2> <a name="i1">第一张图片</a></h2> <img src="img/1.jpg" alt="图片的替换文字" title="图片的悬停文字1"/> <h2> <a name="i2">第二张图片</a></h2> <img src="../img2/1.jpg" alt="图片的替换文字" title="图片的悬停文字2"/> <h2> <a name="i3">第三张图片</a></h2> <img src="file:///D://实训/img2/1.jpg" alt="图片的替换文字" title="图片的悬停文字3"/> <h2> <a name="i4">第四张图片</a></h2> <img src="http://p3.so.qhmsg.com/t01ddba1ee73a096568.jpg" alt="图片的替换文字" title="图片的悬停文字4"/> <h4>Disc 项目符号列表:</h4> <ul type="disc"> <li>苹果</li> <li>香蕉</li> <li>柠檬</li> <li>桔子</li> </ul> <h4>Circle 项目符号列表:</h4> <ul type="
步骤如下:
1、点击开始,点击控制面板;
2、点击windows防火墙;
3、点击高级设置;
4、点击出站规则,点击新建规则;
5、点击程序,点击下一步;
6、输入ie浏览器所在位置,例如%ProgramFiles% (x86)\Internet Explorer\iexplore.exe,点击下一步;
7、点击阻止连接,点击下一步;
8、勾选域、专用和公用,点击下一步;
9、输入名称,点击完成即可。
在浏览网站的过程中,我们经常会遇到需要登录的情况,有些页面只有登录之后才可以访问,而且登录之后可以连续访问很多次网站,但是有时候过一段时间就需要重新登录。还有一些网站,在打开浏览器时就自动登录了,而且很长时间都不会失效,这种情况又是为什么?其实这里面涉及会话和Cookies的相关知识,本节就来揭开它们的神秘面纱。
1. 静态网页和动态网页 在开始之前,我们需要先了解一下静态网页和动态网页的概念。这里还是前面的示例代码,内容如下:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>This is a Demo</title> </head> <body> <div id="container"> <div class="wrapper"> <h2 class="title">Hello World</h2> <p class="text">Hello, this is a paragraph.</p> </div> </div> </body> </html> 这是最基本的HTML代码,我们将其保存为一个.html文件,然后把它放在某台具有固定公网IP的主机上,主机上装上Apache或Nginx等服务器,这样这台主机就可以作为服务器了,其他人便可以通过访问服务器看到这个页面,这就搭建了一个最简单的网站。
这种网页的内容是HTML代码编写的,文字、图片等内容均通过写好的HTML代码来指定,这种页面叫作静态网页。它加载速度快,编写简单,但是存在很大的缺陷,如可维护性差,不能根据URL灵活多变地显示内容等。例如,我们想要给这个网页的URL传入一个name参数,让其在网页中显示出来,是无法做到的。
因此,动态网页应运而生,它可以动态解析URL中参数的变化,关联数据库并动态呈现不同的页面内容,非常灵活多变。我们现在遇到的大多数网站都是动态网站,它们不再是一个简单的HTML,而是可能由JSP、PHP、Python等语言编写的,其功能比静态网页强大和丰富太多了。
此外,动态网站还可以实现用户登录和注册的功能。再回到开头提到的问题,很多页面是需要登录之后才可以查看的。按照一般的逻辑来说,输入用户名和密码登录之后,肯定是拿到了一种类似凭证的东西,有了它,我们才能保持登录状态,才能访问登录之后才能看到的页面。
其实它就是会话和Cookies共同产生的结果,下面我们来一探究竟。
2. 无状态HTTP 在了解会话和Cookies之前,我们还需要了解HTTP的一个特点,叫作无状态。
HTTP的无状态是指HTTP协议对事务处理是没有记忆能力的,也就是说服务器不知道客户端是什么状态。当我们向服务器发送请求后,服务器解析此请求,然后返回对应的响应,服务器负责完成这个过程,而且这个过程是完全独立的,服务器不会记录前后状态的变化,也就是缺少状态记录。这意味着如果后续需要处理前面的信息,则必须重传,这导致需要额外传递一些前面的重复请求,才能获取后续响应,然而这种效果显然不是我们想要的。为了保持前后状态,我们肯定不能将前面的请求全部重传一次,这太浪费资源了,对于这种需要用户登录的页面来说,更是棘手。
这时两个用于保持HTTP连接状态的技术就出现了,它们分别是会话和Cookies。会话在服务端,也就是网站的服务器,用来保存用户的会话信息;Cookies在客户端,也可以理解为浏览器端,有了Cookies,浏览器在下次访问网页时会自动附带上它发送给服务器,服务器通过识别Cookies并鉴定出是哪个用户,然后再判断用户是否是登录状态,然后返回对应的响应。
我们可以理解为Cookies里面保存了登录的凭证,有了它,只需要在下次请求携带Cookies发送请求而不必重新输入用户名、密码等信息重新登录了。
因此在爬虫中,有时候处理需要登录才能访问的页面时,我们一般会直接将登录成功后获取的Cookies放在请求头里面直接请求,而不必重新模拟登录。
好了,了解会话和Cookies的概念之后,我们在来详细剖析它们的原理。
(1) 会话 在Web中,会话对象用来存储特定用户会话所需的属性及配置信息。这样,当用户在应用程序的Web页之间跳转时,存储在会话对象中的变量将不会丢失,而是在整个用户会话中一直存在下去。当用户请求来自应用程序的Web页时,如果该用户还没有会话,则Web服务器将自动创建一个会话对象。当会话过期或被放弃后,服务器将终止该会话。
(2) Cookies Cookies指某些网站为了辨别用户身份、进行会话跟踪而存储在用户本地终端上的数据。
会话维持
那么,我们怎样利用Cookies保持状态呢?当客户端第一次请求服务器时,服务器会返回一个请求头中带有Set-Cookie字段的响应给客户端,用来标记是哪一个用户,客户端浏览器会把Cookies保存起来。当浏览器下一次再请求该网站时,浏览器会把此Cookies放到请求头一起提交给服务器,Cookies携带了会话ID信息,服务器检查该Cookies即可找到对应的会话是什么,然后再判断会话来以此来辨认用户状态。
在成功登录某个网站时,服务器会告诉客户端设置哪些Cookies信息,在后续访问页面时客户端会把Cookies发送给服务器,服务器再找到对应的会话加以判断。如果会话中的某些设置登录状态的变量是有效的,那就证明用户处于登录状态,此时返回登录之后才可以查看的网页内容,浏览器再进行解析便可以看到了。
反之,如果传给服务器的Cookies是无效的,或者会话已经过期了,我们将不能继续访问页面,此时可能会收到错误的响应或者跳转到登录页面重新登录。
所以,Cookies和会话需要配合,一个处于客户端,一个处于服务端,二者共同协作,就实现了登录会话控制。
属性结构
接下来,我们来看看Cookies都有哪些内容。这里以知乎为例,在浏览器开发者工具中打开Application选项卡,然后在左侧会有一个Storage部分,最后一项即为Cookies,将其点开,如图所示,这些就是Cookies。
可以看到,这里有很多条目,其中每个条目可以称为Cookie。它有如下几个属性。
Name:该Cookie的名称。一旦创建,该名称便不可更改。Value:该Cookie的值。如果值为Unicode字符,需要为字符编码。如果值为二进制数据,则需要使用BASE64编码。Domain:可以访问该Cookie的域名。例如,如果设置为.zhihu.com,则所有以zhihu.com,结尾的域名都可以访问该Cookie。Max Age:该Cookie失效的时间,单位为秒,也常和Expires一起使用,通过它可以计算出其有效时间。Max Age如果为正数,则该Cookie在Max Age秒之后失效。如果为负数,则关闭浏览器时Cookie即失效,浏览器也不会以任何形式保存该Cookie。Path:该Cookie的使用路径。如果设置为/path/,则只有路径为/path/的页面可以访问该Cookie。如果设置为/,则本域名下的所有页面都可以访问该Cookie。Size字段:此Cookie的大小。HTTP字段:Cookie的httponly属性。若此属性为true,则只有在HTTP头中会带有此Cookie的信息,而不能通过document.cookie来访问此Cookie。Secure:该Cookie是否仅被使用安全协议传输。安全协议有HTTPS和SSL等,在网络上传输数据之前先将数据加密。默认为false。 会话Cookie和持久Cookie
从表面意思来说,会话Cookie就是把Cookie放在浏览器内存里,浏览器在关闭之后该Cookie即失效;持久Cookie则会保存到客户端的硬盘中,下次还可以继续使用,用于长久保持用户登录状态。
其实严格来说,没有会话Cookie和持久Cookie之分,只是由Cookie的Max Age或Expires字段决定了过期的时间。因此,一些持久化登录的网站其实就是把Cookie的有效时间和会话有效期设置得比较长,下次我们再访问页面时仍然携带之前的Cookie,就可以直接保持登录状态。
3. 常见误区 在谈论会话机制的时候,常常听到这样一种误解“只要关闭浏览器,会话就消失了”,这种理解是错误的。可以想象一下会员卡的例子,除非顾客主动对店家提出销卡,否则店家绝对不会轻易删除顾客的资料。对会话来说,也是一样,除非程序通知服务器删除一个会话,否则服务器会一直保留。比如,程序一般都是在我们做注销操作时才去删除会话。
参考:https://blog.csdn.net/jiangxinnju/article/details/26081963
https://blog.csdn.net/qq_29883591/article/details/69183999
因为在调试时候往往有大量输入不方面,因此引入输入重定向。
除了在VS项目属性,调试里更改,还可以在源代码中main函数前加入:
freopen("in.txt","r",stdin);
freopen("out.txt","w",stdout);
(注意该文件输入输出都存在与.c/.cpp相同的目录下。)
1. rpm包的管理
介绍:
一种用于互联网下载包的打包及安装工具,它包含在某些Linux分发版中,它生成具有RPM扩展名的文件,RPM是RedHat Package Manager(RedHat软件包管理工具)的缩写,类似windows的setup.exe,这一文件格式名称虽然打上了RedHat的标志,但理念是通用的
Linux的分发版本都有采用(suse,redhat, centos 等等),可以算是公认的行业标准了
2. rpm包的简单查询指令:
查询已安装的rpm列表 rpm –qa | grep xx(q表示query,a表示查询所有,grep表示过滤)
例如:查询Linux中是否安装有firefox
rpm -qa | grep firefox
rpm包名基本格式:
一个rpm包名:firefox-45.0.1-1.el6.centos.x86_64.rpm
名称:firefox
版本号:45.0.1-1
适用操作系统: el6.centos.x86_64 表示centos6.x的64位系统
如果是i686、i386表示32位系统,noarch表示通用
rpm包的其它查询指令:
rpm -qa:查询所安装的所有rpm软件包
rpm -qa | more :查询所安装的所有rpm软件包 并且分页显示
rpm -qa | grep X [rpm -qa | grep firefox ] :查询是否安装有某个软件(火狐的软件)
rpm -q 软件包名 :查询软件包是否安装 rpm -q firefox
rpm -qi 软件包名 :查询软件包信息
rpm -ql 软件包名 :查询软件包中的文件的安装位置
rpm -qf 文件全路径名:查询文件所属的软件包 ,例如:rpm -qf /etc/passwd 3.
flask 考虑到模板代码的重用性,Jiaja2提供了块 (Block)和宏 (Macro)来提高代码的继承和复用性。其中块 (Block)的使用可以极大精简代码,可以通过继承(extend)扩展让大量代码重复使用,并在Block自由定制替换内容块;而宏 (Macro) 的使用更可以极大的提高模板的复用性,减少复杂度,类似于函数,可以传入参数。这篇我们就来学习下 块 (Block)和宏 (Macro)的用法。
块 (Block) 关于模板的继承,我们可以在子模板的顶部使用如”{% extend ‘base.html’ %}”语句来声明继承。而子模板中由”{% block block_name %}”和”{% endblock %}”所包括的语句块,将会替换父模板中同样由”{% block block_name %}”和”{% endblock %}”所包括的语句块。
这就是块的功能,模板语句的替换。这里要注意几个点:
模板不支持多继承,也就是子模板中定义的块,不可能同时替换两个父模板的块。模板中不能定义同名的块,因为这样无法确认替换块的内容。 建议在”endblock”关键字后也加上块名,比如”{% endblock block_name %}”,增加可读性。
使用父模板块 (Block)的内容 如果子模板想使用父模板中的块里的内容,请使用{{ super() }}。请看下面例子:
<!doctype html> <head> {% block head %} <link rel="stylesheet" href="{{ url_for('static', filename='style.css') }}"> <title>{% block title %}{% endblock %}</title> {% endblock %} </head> <body> <div class="page"> {% block body %} {% endblock %} </div> </body> 上面是父模板,我要在子模板里使用”head”块的css文件并增加新的文件,如下: