TCODE: MASS
对于批量修改主数据如客户,供应商等,可以试用一下Mass , 它所能修改的范围如下:
选定要修改的对象后,点击运行,会要求选择需要修改的表和字段,
然后填写过滤出要修改数据的条件
随后会显示所有需要修改的数据:
可以在下方表格里一个一个输入要修改的值,如果是统一修改成相同的值,可以填写在上方表格的新值行里,然后点批量更改,
会将下方表格的值统一改为相同一个值,确定所有要修改项正确后,点击保存按钮,会更新到sap数据库。
退出后查看一下修改的主数据是否已改确认无误 .
补充:对于各类主数据一般有相应更快捷的批修改tcode,其实都是调用这个只是默认选好了对象。如:
XK99 批量维护供应商.
MM17 批量维护物料。
XD99 批理维护客户.
OB_GLACC11 批量维护科目数据
OB_GLACC12 批量维护公司代码数据
KE55 批量维护利润中心主数据
然后填写过滤出要修改数据的条件
随后会显示所有需要修改的数据:
可以在下方表格里一个一个输入要修改的值,如果是统一修改成相同的值,可以填写在上方表格的新值行里,然后点批量更改,
会将下方表格的值统一改为相同一个值,确定所有要修改项正确后,点击保存按钮,会更新到sap数据库。
退出后查看一下修改的主数据是否已改确认无误 .
补充:对于各类主数据一般有相应更快捷的批修改tcode,其实都是调用这个只是默认选好了对象。如:
XK99 批量维护供应商.
MM17 批量维护物料。
XD99 批理维护客户.
OB_GLACC11 批量维护科目娄据
OB_GLACC12 批量维护公司代码数据
KE55 批量维护利润中心主数据
题目描述
输入3个整数,将它们从大到小输出。思路提示:假设输入a b c三个数,可以先找出最大数和a交换,确保a最大; 然后剩下两数中找出最大数和b交换,确保b最大;剩下的c就是最小数;输出a b c就是从大到小排列了(注意:自己和自己不交换,如a本身就是最大,就不需要和a交换的)。
输入
输入3个整数,
输出
从大到小输出,中间用空格隔开
样例输入 Copy
2 5 1
样例输出 Copy
5 2 1
#include <stdio.h> int main() { int a,b,c,max; scanf("%d %d %d",&a,&b,&c); if(a<b) { max=a,a=b,b=max; } if(a<c) { max=a,a=c,c=max; } if(b<c) { max=b,b=c,c=max; } if(a<b) { max=a,a=b,b=max; } printf("%d %d %d\n",a,b,c); return 0; }
有更好的可以分享一下,如果玩的在高级一点,可以用aop
Mybatis的分页插件简单好用,话不多说直接上代码(使用的lombok,你要是不会你就太落后了): <!-- 分页查询插件 --> <dependency> <groupId>com.github.pagehelper</groupId> <artifactId>pagehelper-spring-boot-starter</artifactId> <version>1.2.5</version> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> import lombok.Data; /** * @program: mqdemo * @description: 分页实体 * @author: shenning * @create: 2020-10-09 11:18 */ @Data public class PagePaging { /** * 当前页码 */ private int pageNum = 1; /** * 每页数量 */ private int pageSize = 10; /** * 页码总数 */ private int pages; /** * 记录总数 */ private Long total; } import com.
在我们使用Jupyter Notebook写代码时,启动后总是需要导入一些库并进配置,尤其是用来做数据分析时,打开后肯定是光速键入下面的代码
import pandas as pd import numpy as np import matplotlib.pyplot as plt from sklearn import svm, tree, linear_model, neighbors, naive_bayes, ensemble, discriminant_analysis, gaussian_process from xgboost import XGBClassifier from sklearn.preprocessing import OneHotEncoder, LabelEncoder from sklearn import feature_selection from sklearn import model_selection ....... 虽然代码量不大,但是每打开一次notebook都要输入一次,总是感觉很繁琐,如果再用上pyecharts等其他库那么光导入各种包就要消耗很多时间,并且还有可能手滑输错了。
那么有什么办法能让jupter notebook/ipython在启动时自动加载一段我们需要的代码呢?
在Mac下你可以进入~/.ipython/profile_default文件夹(Windows下也可以在安装目录中找到对应的文件夹),
如上图所示,在该文件夹下新建一个名为startup的文件夹(如果有则不用新建),之后进入startup文件夹新建一个Python脚本start.py
现在你可以在start.py中尽情的添加你每次启动jupyter notebook后都需要手动敲入的那段代码,之后保存即可,再次打开jupyter notebook并新建一个notebook后就可以直接使用pandas、numpy等我们配置好的库!
最近项目启动时出现一个异常问题:
重要日志信息内容如下:
Bean with name ‘aService’ has been injected into other beans
[bService] in its raw version as part of a circular reference, but has
eventually been wrapped. This means that said other beans do not use
the final version of the bean. This is often the result of over-eager
type matching - consider using ‘getBeanNamesOfType’ with the
‘allowEagerInit’ flag turned off, for example.
相关代码内容如下:
(1)AService
public class AService { @Autowired BService bService; @Async public void aMathod(){ } } (2)BService
随着国内对集成电路,特别是存储芯片的重视,前来咨询我们关于NOR Flash,NAND Flash,SD NAND, eMMC, Raw NAND的客户越来越多了。这里我们专门写了这篇文章:1,把常用的存储产品做了分类; 2把一些产品的特点做一个描述。
在正式开始介绍之前,我们给大家推(an)荐(li)一款非常易用稳定的Flash产品:CS品牌的SD NAND。具备如下特点:
1,免驱动使用;2,可机贴;3,尺寸小巧。6*8mm,LGA-8封装;
4,擦写寿命长;5,耐高低温冲击;6,容量适宜(128MB~4GB)
具体可以可以看链接:http://www.longsto.com/product/31.html
我们把存储产品大概分为E2PROM,NOR,NAND 3类,他们框架如下:
一,E2PROM
容量非常小,目前存在于一些MCU内部,遥控器,电风扇等小家电里。用来存储一些基础信息。用户基本不关心这个。因此这里不做详细描述。
二,NOR Flash
是目前应用领域最广泛的一种存储芯片了.基本上主流的电子产品里都有使用。甚至我们手机摄像头内部,屏幕驱动电路板上都会用到。主要用来存储代码和一些比较小的数据文件。主流是SPI NOR接口; 主流容量:1Mbit~128Mbit; 封装:SOP-8居多,也有更小的;尺寸也都比较小。
NOR Flash架构决定了它的容量不能做大,而且读取速度比较慢。好处在于比较简单易用。甚至可以直接用地址访问到数据,不需要建立文件系统。(这点攻城狮朋友们比较喜欢)
三,NAND Flash
应该是目前最热门的存储芯片了。因为我们生活中经常使用的电子产品都会涉及到它。比如你买手机,肯定会考虑64GB,还是256GB?买笔记本是买256GB,还是512GB容量的硬盘呢?(目前电脑大部分采用了基于NAND Flash产品的固态硬盘)。这里我们从如下几方面做一个分类:
3.1 内部材质
NAND FLASH从材质上可以分为SLC/MLC/TLC/QLC,本质区别就是在最小的存储单元内能存放多少bit的信息。SLC(2bit)/MLC(4bit)/ TLC(8bit)/ QLC(16bit). 这样晶圆的存储密度会翻倍。这4种晶圆的特点如下:
可以看到从SLC 到QLC 擦写寿命越来越短,性能和品质越来越差。目前我们主流的消费类电子产品使用的大容量产品,基本都是TLC/QLC了。比如手机,笔记本里的固态硬盘。
3.2 生产工艺
目前主要有2D和3D。主流生产工艺已经升级到3D了。2D和3D区别可以看如下的示意图:
可以理解2D工艺就是老的砖瓦房,3D工艺就是摩天大楼。带来的最大好处就是存储密度N倍的增长。最近几年手机,笔记本的主流容量都在变大跟产业使用了3D工艺有直接关系。
3.3 使用特点/管理机制
NAND Flash产品本身存在一定的特性,要正常使用,必须配备对应的管理机制。主要有:
1,NAND Flash存在位翻转和位偏移。本来存储的是0101的数据,有一定概率会变成1010。这个时候就需要配备EDC/ECC机制;
2,NAND Flash出厂时会有坏块(不用惊讶,原厂出厂的时候都会标识出来,而且比例是很低),在使用当中也可能产生坏块。因此需要配备 动态和静态坏块管理机制;
3,NAND Flash有写入寿命的限制。每个块都有擦写寿命。因此需要配备 平均读写机制。让整体的块能够均衡的被使用到;
4,NAND Flash是先擦后写,集中擦写的强电流会对周边块有影响等。需要配备 垃圾回收,均衡电荷散射机制等。
CS品牌的SD NAND把这些算法都集成到内部了。示意图如下
3.4 产品分类
Raw NAND本质上是把NAND Flash晶圆的Pad点引出来,封装成TSOP48/BGA等颗粒。 由于里面不带控制器,针对NAND Flash的各种管理算法都需要在CPU端来做,一来会涉及到写驱动的问题;二来会增加CPU的负荷。
带控制器的产品,我们分为芯片类和模组类两种。由于产品的设计初衷不一样,导致两类产品的品质要求有很大区别。具体我们曾经写了一篇文章专门讲过这个:http://www.longsto.com/news/25.html。
芯片类产品有SD NAND,eMMC, SPI NAND.
import requests if __name__ == '__main__': #step1:指定url url='https://www.sogou.com/' #step2:发起请求 #get方法会返回一个响应对象 res=requests.get(url=url) #step3:获取相应数据.text返回的是以字符串形式的 page=res.text print(page) #step4:持久化存储 with open('./sogou.html','w',encoding='utf-8')as fp: fp.write(page) print("爬取数据结束") 简单的网页采集器 搜索引擎 import requests if __name__ == '__main__': url='https://www.sogou.com/sie?' #处理url携带的参数:封装到字典中 kw=input('enter a word:') param={ 'query':kw } #对指定url发起的请求是携带参数的url是携带参数的 res=requests.get(url=url,params=param) passs=res.text print(passs) fileName=kw+'.html' with open(fileName,'w',encoding='utf-8') as fp: fp.write(passs.text) print(fileName,'保存成功!!!!') ps:输入空姐,则在网页中搜索空姐
搞定百度翻译 ajax 前端局部刷新
百度翻译,是post请求携带的参数
响应的是json数据
post请求要携带参数
json数据
import requests import json if __name__ == '__main__': #指定url链接 post_url='https://fanyi.baidu.com/sug' #post请求参数处理(同get请求一致) data={ 'kw':'dog' } # 伪装一下浏览器 headers={'User-Agent': 'Mozilla/5.
1.ios 通过重写样式控制: body { /* IOS禁止微信调整字体大小 */ -webkit-text-size-adjust: 100% !important; text-size-adjust: 100% !important; -moz-text-size-adjust: 100% !important; } 2.android 通过重写事件控制: <script> (function() { if (typeof WeixinJSBridge == "object" && typeof WeixinJSBridge.invoke == "function") { handleFontSize(); } else { if (document.addEventListener) { document.addEventListener("WeixinJSBridgeReady", handleFontSize, false); } else if (document.attachEvent) { document.attachEvent("WeixinJSBridgeReady", handleFontSize); document.attachEvent("onWeixinJSBridgeReady", handleFontSize); } } function handleFontSize() { // 设置网页字体为默认大小 WeixinJSBridge.invoke('setFontSizeCallback', { 'fontSize' : 0 }); // 重写设置网页字体大小的事件 WeixinJSBridge.on('menu:setfont', function() { WeixinJSBridge.
学习手撸dpdk,从写最简单的例子开始。
功能说明 数据包: ETHER HEADER | TYPE | LENGTH | VALUE
TYPE = 0x03 write req
TYPE = 0x04 write reply
收到write req的单播请求,保存value, 回复write reply消息。
测试客户端 利用python3 scapy库来构造符合规则的二层数据包
[root@localhost ~]# python3 Python 3.6.8 (default, Apr 2 2020, 13:34:55) [GCC 4.8.5 20150623 (Red Hat 4.8.5-39)] on linux Type "help", "copyright", "credits" or "license" for more information. >>> >>> from scapy.all import * >>> pkt1 = Ether(dst='00:0C:29:0D:CD:6C', src='00:0c:29:0d:cd:62')/'\3\5'/"Hello" >>> pkt2 = Ether(dst='00:0C:29:0D:CD:6C', src='00:0c:29:0d:cd:62')/'\3\25'/"
package main import ( "database/sql" "fmt" _ "github.com/go-sql-driver/mysql" //只导入初始化方法 ) const ( _selectUser = "select id,name,age from student where id = ?" _selectUserAll = "select id,name,age from student" _updateUser = "update student set name = ? where id = ?" _insertUser = "insert student (name,age) values (?,?)" _deleteUser = "delete from student where id = ?" ) func main() { //Go标准库中没有数据库驱动 //第⼀步:打开数据库,格式是 ⽤户名:密码@/数据库名称?编码⽅式 db, err := sql.Open("mysql", "root:shenning@tcp(127.0.0.1:3306)/test?charset=utf8") //判断是否空 if err !
给你一个字符串 s ,请你根据下面的算法重新构造字符串:
从 s 中选出 最小 的字符,将它 接在 结果字符串的后面。
从 s 剩余字符中选出 最小 的字符,且该字符比上一个添加的字符大,将它 接在 结果字符串后面。
重复步骤 2 ,直到你没法从 s 中选择字符。
从 s 中选出 最大 的字符,将它 接在 结果字符串的后面。
从 s 剩余字符中选出 最大 的字符,且该字符比上一个添加的字符小,将它 接在 结果字符串后面。
重复步骤 5 ,直到你没法从 s 中选择字符。
重复步骤 1 到 6 ,直到 s 中所有字符都已经被选过。
在任何一步中,如果最小或者最大字符不止一个 ,你可以选择其中任意一个,并将其添加到结果字符串。
请你返回将 s 中字符重新排序后的 结果字符串 。
C++ //桶计数 class Solution { public: int h[26]; inline bool haveChar(){//判断是否桶里还有字符 for(int i = 0; i < 26; i++){ if(h[i]){ return true; } } return false; } string sortString(string s) { string res = "
我做PCB设计时,常采用AD18这个软件,使用过程中经常碰到一些问题,遇到查了半天解决了。后来又碰到了,索性记一下吧,以后碰到的也陆陆续续记上来,图片不一定用自己的了,可能随便去哪里找一个。
原理图网络关联 在同一个工程中,可能会画多个原理图,并且用相同的网络标签,如电源部分,这样我们需要进行关联:
工程——》工程选项——》Options
铺铜: 先铺铜,然后点击铺铜的属性
覆完铜后把网络设置为GND,但是板子变绿色了:
解决方法:
右键选择优先选项:
在打开的对话框左侧选择PCB editor—general,将铺铜重建打上勾即可。
要是还是绿色,就把铺铜删除,重新画一下就可以了
要去除死铜的话,就在属性里设置一下:
布线检查: 画完PCB时候,需要检查是线否漏布了。
把线路信息勾选:
然后它点击报告即可查看布线率:
过孔设置: 画线的时候,按住shift+ctrl,滚动滚轮即可换层并自动添加过孔。
大小可以在生成过孔时按tab键调整,或者在属性里边调整:
我们还可以给过孔添加上泪滴:
工具(Tools)-> 泪滴(E…)
添加logo 首先需要一张图片,用“画图”导出二值图:
然后利用PCB Logo Creator生成一个logo,没有这个工具的自己去下载,下载完放到一个目录里。
在AD左上角的search里输入run:
找到运行脚本:
点击浏览:
点击来自文件之后,选择刚刚下载好的LOGO脚本文件。
打开以后:
运行脚本文件后,点击LOAD选项。
选择logo二值图文件:
在哪一个层,大小什么的可以自己调,然后点击convert即可。
LOGO就生成完了,这个脚本文件运行后会直接自行创建一个新的PCB图,并不是在原本创建的PCB图中生成,把LOGO选中CTRL + C,粘贴到自己的PCB图中就可以了。
查找相似对象 我们需要批量修改某类对象,比如固定元件,修改过孔之类的。可以用查找相似对象:
1、选中对象,右键,选择查找相似对象:
对象无法选中 比如当你PCB中的线、器件、过孔、铺铜无法选中时,打开properties看一下,是否都选上了
锁定对象还能移动 当对象(元器件)无法被锁定时,即锁定的对象没有被保护:
找到优先选项
开启锁定对象保护
导出BOM清单 1、去报告里找:
2、然后:
然后导出:
自定义规则 新建规则
设置名称和自定义
然后进入下面页面:
比如我们要设置过孔到走线的间距:
第一个选择过孔:
第二个选择走线:
secureFTP 连接到远程服务器,alt+p,进入sftp,
使用的命令与linux命令相同,另外增加的命令有lcd/lpwd/lls等,在前面添加字母l,local表示本地的操作,
put 文件名 上传
get 文件名 下载
==============================================================
yum install -y lrzsz
随便拖拽上传功能
rz 选中文件 上传 sz 文件名 下载
在引入矢量图层以后筛选指定属性信息的数据 在引入矢量图层以后,gee用户往往会选择矢量图层中的某一小块来做研究,(比如引入中国分省的矢量图层,但是研究区只是涉及到安徽省)这就要用到筛选功能,将安徽省从中国矢量图层里面筛选出来。
当然比较简单的方法是从ArcGIS或者其他软件中,将安徽省单独筛选出来并且导出,再引入到Geemap里面,但是这样做比较耗费时间和人力。
一般用户的需求有两种:
①是从大区域中筛选一个小区域作为实验区;
②是从一个大区域中筛选多个小区域作为实验区
衡阳市的属性表信息: (这里以从湖南省衡阳市中筛选衡南县为例子)
一、从大区域中筛选一个小区域作为实验区 1、第一种方法: 使用.filterMetadata(‘PYNAME’,‘equals’,‘Hengnan Xian’)命令:
指的是筛选元数据PYNAME等于Hengnan Xian的矢量区域。
当然也可以用其他属性信息筛选,只需要更换函数里面的字段名称
var HengYangShi= ee.FeatureCollection(HY); var HengnanXian= HengYangShi.filterMetadata('PYNAME','equals','Hengnan Xian'); 其中的HY是引入的衡阳市的矢量图层。
2、第二种方法: 事先查询Hengnan Xian的点的位置,引入衡南县境内的一个点,
var Roi_HengnanXian = ee.Geometry.Point(114,30) 或者用Geemap里面的手绘方式绘制一个衡南县境内的点
然后用下面的命令(点包含在面里)从衡阳市中筛选衡南县的矢量区域。
//用point筛选HengYangShi var HY = table.filterBounds(Roi_HengnanXian).geometry(); 结果如下图所示
3、其他方法 如果使用第一种方法会节省很多工作,除了以上两种方法以外,还有其他方法。
二、从一个大区域中筛选多个小区域作为实验区 1、使用属性信息筛选多个区域 下图的table就是上图中导入的衡阳矢量图
var HengYangShi = ee.FeatureCollection(table); var Name_List = ee.List( ['Hengdong Xian','Hengyang Xian','Qidong Xian','Hengnan Xian'] ); var Inlist_Filter = ee.Filter.inList( 'PYNAME', Name_List); var List_Features = HengYangShi.filter( Inlist_Filter ); Map.
系统环境:
Kubernetes 版本:1.19.2kubernetes-dashboard 版本:v2.0.3 兼容性 Kubernetes版本1.131.141.151.161.171.18兼容性?????✓ ✕ 不支持的版本范围。✓ 完全支持的版本范围。? 由于Kubernetes API版本之间的重大更改,某些功能可能无法在仪表板中正常运行。 1、Dashboard RBAC 创建 Dashboard RBAC 部署文件
k8s-dashboard-rbac.yaml
apiVersion: v1 kind: ServiceAccount metadata: labels: k8s-app: kubernetes-dashboard name: kubernetes-dashboard namespace: kube-system --- apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: labels: k8s-app: kubernetes-dashboard name: kubernetes-dashboard namespace: kube-system rules: - apiGroups: [""] resources: ["secrets"] resourceNames: ["kubernetes-dashboard-key-holder", "kubernetes-dashboard-certs", "kubernetes-dashboard-csrf"] verbs: ["get", "update", "delete"] - apiGroups: [""] resources: ["configmaps"] resourceNames: ["kubernetes-dashboard-settings"] verbs: ["get", "update"] - apiGroups: ["
变量和常量 1.常量
常量:不能被改变的数据。
如:1,e1,077,true,false,“哇塞”,null
2.变量
变量:程序运行过程中值可以发生改变的量。
2.1定义变量的方式
var 变量名 = 值 ;变量名 = 值 ;var 变量名 ;字符串型:var str = " 华晨宇好牛逼!";布尔型: var b = true ;数值型: var n = 10 ;复合型: var obj = new Object ( ) ; 2.2 变量命名
变量命名必须是以下划线或者字母开头(数字开头的不行),后面可以跟下划线或者数字,但不能使用特殊符号(比如:$ #)
2.3 变量的用途
用于计算的结果,存储用户输入的数据。可作为对象的引用,通过变量来操作对象的内容或者调用对象。例如:
var ChenyuHua = new Array( "花花","Mars", "歌手"); document.write("<b>华晨宇:</b>"); for( n in ChenyuHua ) { document.write( "<li>" + ChenyuHua[n] ); } 结果如图:
管理距离(AD值)是指一种路由协议的路由可信度。每一种路由协议按可靠性从高到低,依次分配一个信任等级,这个信任等级就叫管理距离。AD值越低,则它的优先级越高。 一个管理距离是一个从0~255的整数值,0是最可信赖的,而255则意味着不会有业务量通过这个路由。
思科路由器(默认) 路由源AD值直连接口0静态路由1EIGRP汇总路由5EBGP20EIGRP(内部)90IGRP100OSPF110ISIS115RIP(V1&V2)120EGP140ODR160EIGRP(外部)170IBGP200NHRP(下一跳解析协议)250通过DHCP学习到的默认静态路由254未知255 华为路由器(默认) 路由源AD值直连路由0OSPF10ISIS15静态路由60IGRP80RIP100OSPF(域外路由)150BGP255
我的SQL自学文档 数据库可视化操作工具:sequelpro 链接
基本操作 网页练习题
命令行操作
#链接数据库
mysql -u root -p # u 是用户名,p 需要用密码登录数据库
#查看数据库
show databases; #选择数据库
use database_name; #查看数据库中的table表
show table; #查看表格的结构
desc table; #查看表中(一定量)的数据
select * from table_name (limit 10); #条件查询
select * from table_name where condition and/or condition #通配符%
%AT% 代表AT前后可以有任意字符
#查询结果过滤和排序
distinct 属性列唯一返回,直接删除重复行
select distinct column from table_name where condition(s); group by返回唯一行,按某个col_name对数据进行分组
SELECT AGG_FUNC(column_or_expression) AS aggregate_description, … FROM mytable WHERE constraint_expression GROUP BY column; order by 对结果的属性列进行排序
magoshare data rescovery
下载地址
https://www.lanzoux.com/iRbrJgk1did
参考
https://xclient.info/s/magoshare-data-recovery.html
应用介绍
Magoshare Data Recovery Mac是一款出色的数据恢复软件,能从Mac计算机、HDD、SSD、外部硬盘驱动器、USB驱动器、数码相机、音乐播放器、存储卡、SD卡和其他存储媒体设备中恢复丢失的数据。并恢复所有类型的丢失文件,包括照片、绘图、视频、音频、语音备忘录、文档、文件夹、档案、电子邮件等。
功能最强大的Mac数据恢复软件,可以完全从任何灾难中恢复丢失的数据
Magoshare Data Recovery for Mac提供完整的数据恢复解决方案,可帮助从任何类型的硬盘驱动器或外部存储设备中恢复已删除,格式化,损坏或无法访问的数据。
Mac删除文件恢复
由于意外删除,清空垃圾箱,命令+删除,永久删除等,轻松恢复已删除的文件。
Mac格式化恢复
从已擦除,格式化,重新格式化的Mac硬盘驱动器或外部存储设备中完全恢复丢失的数据。
适用于Mac的原始恢复
安全地恢复原始数据,从HDD / SSD和外部存储介质设备恢复不可访问,损坏的数据。
完整数据恢复
您还可以恢复因系统崩溃,病毒感染,逻辑错误,人为错误,电源故障,操作系统升级等原因丢失的数据。
恢复所有类型的文件
恢复所有类型的丢失文件,包括照片,绘图,视频,音频,语音备忘录,文档,文件夹,档案,电子邮件等。
恢复所有设备
从Mac计算机,HDD,SSD,外部硬盘驱动器,USB驱动器,数码相机,音乐播放器,存储卡,SD卡和其他存储媒体设备中恢复丢失的数据。
更新日志
激活方法
直接安装
解压密码
本站所有dmg、zip 打开密码均为 xclient.info
目录 1、树的定义1.1、树结点分类1.2、树的结点之间的关系1.3、树的其他概念 2、树的存储结构2.1、双亲表示法2.2、孩子表示法2.3、孩子兄弟表示法 3、二叉树的定义3.1、二叉树的特点3.2、特殊的二叉树3.2.1、斜树3.2.2、满二叉树3.2.3、完全二叉树 4、二叉树的五大性质5、二叉树的存储结构5.1、二叉树的顺序存储结构5.2、二叉树的链式存储结构(二叉链表) 6、二叉树的遍历方法6.1、前序遍历6.2、中序遍历6.3、后序遍历6.4、层序遍历 7、构建一颗二叉树8、树、森林与二叉树的转换8.1、树转换为二叉树8.2、森林转换为二叉树8.3、二叉树转换为树8.4、二叉树转换为森林 9、赫夫曼树 1、树的定义 树(Tree)是n(n>=0)个结点的有限集。当n=0时,称为空树。
在任意一棵非空树种:
(1)、有且仅有一个特定的称为根的结点(Root);
(2)、当n>1时,其余结点可分为m(m>0)个互不相交的有限集T1、T2、…、Tm,其中每一个集合本身又是一棵树,并且称为根的子树(SubTree)。
如下图所示:
本书中还是少了一些有关红黑树的概念。
树有很多概念和定义需要我们去理解记忆。
1.1、树结点分类 树的结点包含一个数据元素及若干指向其子树的分支。结点拥有的子树称为结点的度(Degree)。度为0的结点称为叶结点(Leaf)或终端结点;
度不为0的结点称为非终端结点或分支结点。除根结点之外,分支结点也称为内部结点。
树的度是树内各结点的度的最大值。如下图所示,这棵树结点的度的最大值是结点D的度,为3,所以这颗树的度是3。
1.2、树的结点之间的关系 结点的子树的根称为该结点的孩子(Child),该结点称为孩子的双亲(Parent)。
同一个双亲的孩子之间互称为兄弟(Sibling)。
结点的祖先是从根到该结点所经分支上的所有结点。反之,以某结点为根的子树中的任一结点都称为该结点的子孙。如下图所示:
1.3、树的其他概念 结点的层次(Level)从根开始定义起,根为第一层,根的孩子为第二层。
其双亲在同一层的结点互为堂兄弟。
树中结点的最大层次称为树的深度(Depth)或高度。
如下图所示:
如果将该树中的各子树看成从左到右是有秩序的 ,不能互换的,则称该树为有序树,否则称为无序树。
森林(Forest)是m(m>=0)棵互不相交的树的集合。
2、树的存储结构 不能使用简单的顺序存储结构和链式存储结构进行概况了 ,树是一种比较特殊的结构。
本节后面的表示法,都是基于这张图的:
2.1、双亲表示法 树这种结构除了根节点之外,其余每个结点,它不一定有孩子,但是一定有且仅一个双亲。
一个结点:包含一个数据域data,存储数据元素,一个parent指针域,存储该结点的双亲在数组中的下标。
如下图所示:
2.2、孩子表示法 由于树中每个结点可能有多棵子树,可以考虑用多重链表,即每个结点有多个指针域,其中每个指针指向一棵树的根节点,我们把这种方法叫作多重链表表示法。
下面有两种方案:
方案1:
上面这种方法存在很多空间上的浪费。
方案2:
这种方法克服了浪费空间的缺点,对空间利用率很高,但是由于各个结点的链表是不相同的结构,加上要维护结点的度的数值,在运算上就会带来时间上的损耗。
最终我们找到了解决方案,也就是孩子表示法:
具体操作是,把每个结点的孩子结点排列起来,以单链表的作为存储结构,则n个结点有n个孩子的链表,如果是叶子结点则此单链表为空。然后n个头指针又组成一个线性表,采用顺序存储结构,存放进一个一维数组。如下图所示:
这样的结构对于我们要查找某个结点的某个孩子,或者找某个结点的兄弟,只需要查找这个结点的孩子单链表即可,对于遍历整棵树也是很方便的,对头结点的一维数组循环即可。
2.3、孩子兄弟表示法 刚才我们从双亲和孩子的角度去探讨了数据结构,我们现在以兄弟的角度去考虑。
任意一棵树,它的结点的第一个孩子如果存在就是唯一的,它的右兄弟如果存在也是唯一的,因此我们设置两个指针,分别指向该结点的第一个孩子和此结点的右兄弟。
所以我们定义结点结构如下:
实现示意图如下:
引出二叉树
3、二叉树的定义 二叉树(Binary Tree)是n(n>=0)个结点的有限集合,该集合或者为空集(称为空二叉树),或者由一个根节点或两棵互不相交的、分别称为根节点的左子树和右子树组成。
来一张认识一下:
是一种很特殊的树结构。
3.1、二叉树的特点 包括三个特点和五种形态:
三个特点:
1、每个结点最多只有两棵子树,所以二叉树中不存在度大于2的结点;
2、左子树和右子树是由顺序的,次序不能任意颠倒;
3、即使树种某结点只有一棵子树,也要区分它是左子树和右子树。
五种形态:
1、空二叉树;
训练TF模型时发现电脑内存太小了,无法处理一万张720p的图片(VOC格式数据集),于是改用Sequence进行训练迭代,有效减少内存的要求。代码如下:
from tensorflow.python.keras.utils.data_utils import Sequence # 定义在C:\ProgramData\Anaconda3\envs\tf\Lib\site-packages\tensorflow_core\python\keras\utils\data_utils.py import random, os, gc, cv2 import numpy as np from xml.dom.minidom import parse from sklearn.preprocessing import MultiLabelBinarizer from sklearn.model_selection import train_test_split from tensorflow.keras.preprocessing.image import img_to_array, load_img seed = 295 random.seed(seed) class SequenceData(Sequence): ''' xmlPath, imgPath, cutSize=(0,0.7), batch_size=32, size=(720,1280) xml文件路径, img文件路径, 训练集切分起始比例, 批次大小, 图片大小 ''' def resize_img_keep_ratio(self, img_name,target_size): ''' 1.resize图片,先计算最长边的resize的比例,然后按照该比例resize。 2.计算四个边需要padding的像素宽度,然后padding ''' img = cv2.imread(img_name) old_size = img.shape[0:2] ratio = min(float(target_size[i])/(old_size[i]) for i in range(len(old_size))) new_size = tuple([int(i*ratio) for i in old_size]) img = cv2.
原文地址: 数据链路层和TCP传输层的迷思
关于数据链路层和传输层提供的可靠传输的疑问和回答 传输层协议UDP,书上说不必事先建立连接,是无连接的不可靠的协议,只是尽最大努力交付,但UDP仅是传输层协议,下面还有数据链路层协议啊,该层中有超时重传,差错重传的ARQ协议,这样,原始的数据帧就能可靠通信了,上层数据也是通过下层数据表现的,不同样也能保证可靠通信吗?为什么说UDP是不可靠的? 数据链路层可以实现无差错的数据帧的交付,但是并不一定一定要实现,这个实现是需要有代价的,比如HDLC协议等等。
HDLC采用CRC校验,并且对所有的帧进行编号,通过序和确认机制,可以防止漏发和重发。事实上,HDLC是互联网初期的时候较常使用的数据链路层的协议,因为那个时候数据链路层的传输不是非常可靠。
现在使用的大部分是PPP协议,PPP协议只提供差错检测但不提供纠错,他同样使用的也是CRC校验,只能够保证无差错接收,但是由于不适用序列号和确认机制,所以无法检测重发和漏发。
如果对于所有的数据帧都使用可靠的数据链路层协议来保证数据链路层的可靠传输的话,那么无疑会极大地增加网络的负担。事实上,网络中许多的数据并不一定都需要保证可靠传输,因此随着网络的发展,数据链路层将保证数据可靠传输交由上层的传输层来控制(UDP和TCP等等)。而数据链路层大部分使用不一定可靠的PPP协议等等。
最最重要的是:传输层是端到端的,数据链路层是点到点的,想要保证端到端的可靠传输就必须在传输层做文章,仅仅在保证数据链路层各个点之间的可靠传输也不能保证上层数据的可靠性,依然会出现丢包等情况的出现。
如果有数据链路层的差错重传和超时重传,还要TCP的的重传机制干嘛? 数据链路层有差错重传和超时重传功能,但是不是所有的数据帧都需要可靠的传输。
数据链路层和传输层的TCP都有滑动窗口,这不重复了吗?为什么 在数据链路层,由于收发双方是点到点的连接,其流量控制策略相对较为简单,接收窗口和发送窗口即为固定大小的缓冲区的个数,发送方的窗口调整,即缓冲区的覆盖依赖于确认帧的到达,由于信号传播延时和CPU的处理时间等都对相对较为稳定,所以发送方的数据帧和接收方的确认帧,其发送和接收时间是可估计的。在TCP层,由于一个TSAP可同时与多个TSAP建立连接,每个连接都将协商建立一个窗口(即一对发送和接收缓冲区),所以窗口的管理较为复杂,其流量控制策略是通过窗口公告来实现的,当接收方收到数据后发送的确认中将通报剩余的接收缓冲区大小,发送方的发送窗口调整是根据接收方的窗口公告进行的,也就是即使收到接收方的确认也不一定就能对发送窗口进行调整,一旦发送方收到一个零窗口公告,必须暂停发送并等待接收方的下一个更新窗口公告,同时启动一个持续定时器。 其它层的首部我看都有长度字段,但TCP的首部中没有长度字段,那怎么知道该报文到哪里结束? TCP的报文封装在IP内部,在IP头部中,有两个字段,分别是IP头部长和IP总长,因此,总长减去头部长就可以得到数据部分的长度,也就是传输层封装的数据的长度,TCP的首部中包含有头部的长度,因此可以得到TCP报文的数据的部分的长度。
目录 前言文章内容一、文章介绍1.目的2.背景 二、十个建模技巧1.模板选择2.阅读发表的相应模板三维结构的文章3.去除不必要的元素、溶剂、配体和离子4.优化3D结构,如果氢丢失要补回氢5.留意比对过程的gaps6. 进行loop建模时要考虑loop大小以及残基组成7.在进行计算分析前,进行结构最小化是必不可少的8.使用多种策略进行三维结构的验证和评估9.考虑氨基酸质子化作用10.了解拓扑结构建模非蛋白质分子案例研究 最后说两句 前言 博主刚把脚踏进生物物理和生物信息这领域,本身没有坚实的生物基础,也没有专门去学计算机,所以在这领域中撞墙碰壁,苟延残喘。如今想要开始通过写博客的方式,在平台上向各位大佬各位学者学习。我觉得知识是要拿出来分享,不仅帮助了他人,也充实着自己。
我打算隔一段时间写一篇博客关于生信中同源建模相关(或是其他)的文献,我也是第一次解读文章编写博客,会有很多不足的地方,各位看官若能够指出我哪些做得不够的地方,或是指出文献解读方面不足之处,那就再好不过了,这对我的帮助很大,在这先谢谢大家了哈!
今天要讲内容的是一篇入门蛋白质同源建模的文献——《Ten quick tips for homology modeling of high-resolution protein 3D structures》。这篇文献偏介绍性,例如建模的基本流程,在各步骤需要留意的点或处理技巧,以及介绍在建模过程中哪些地方可以使用哪些软件。整篇来说,概念性较强,对初学同源建模的同学还是有帮助的。
下面要讲的这篇文章是《Ten quick tips for homology modeling of high-resolution protein 3D structures》,链接[https://doi.org/10.1371/journal.pcbi.1007449]
文章内容 接下来将要对文献进行简要讲解,我会挑出每个Tip中我觉得有帮助的点,并且尝试去多讲一些。
一、文章介绍 1.目的 文章作者想给初学建模的人通过介绍的系统实践的方法来建模出高分辨率的蛋白质3D结构。建模者要学会能够访问和使用原子坐标来构建同源模型。另外想要提供一个原理就是在建模的基础上制作一个简单的原子坐标列表,用于符合物理原理的计算分析。后面还有一部分内容是关于建模非蛋白分子和同源建模的例子实践。
2.背景 根据蛋白质能量景观漏斗假说:蛋白质native结构应该在漏斗低端具有最低的自由能,即全局能量最小。如今就有很多计算策略通过查找势能景观来确定蛋白质native构象,这些想法被分为两种算法:一种是确定性的(deterministic),一种是启发式的(heuristic)。区别是搜索构象空间的coverage的不同。
确定性方法扫描整个或者大部分构象空间,基于先验知识排除掉子空间,(举例:同源建模允许修改同源结构来预测蛋白质3D结构,这样就可以消除掉大量的构象。)注意:大师兄说现如今好像没有可以扫描搜索整个构象空间的方法,即使是同源建模。其实我觉得构象空间这个概念很抽象,感觉言语上说不清。
启发式方法只搜索构象空间一小部分,但有一组代表性的构象,例如MD应用能量函数研究力,求解运动方程,并预测原子轨迹。尽管c空间覆盖有限,MD提供了关于折叠和展开路径的信息。这些方法常用于工业酶以及药物制造中。
同源建模工作流程分为以下几个步骤,开始于选择最佳模板3D结构,第一次的序列比对通常使用BLOcks替换矩阵执行。第二次序列比对(也称为比对校正)用于构建骨干三维结构。然后对无模板区域或者相似性比较低的区域进行loop建模。最高精度可达12~13个残基。接着是侧链重建,通过依赖主链的旋转体库进行构象搜索。接下来应该通过各种质量评估工具对结构进行改进和验证。注意:序号代表的是在哪几个Tip有提及到。
在同源建模中五类导致建模不准确的原因:1.模板选择不当。2.比对出错,可以用多序列比对降低错误率。3.在正确对齐的区域中的出现shift错误。通常是由模板结构失调引起的,可以通过使用多个模板结构来补偿。4.给定序列与同源模板三维结构之间有差异,导致侧链堆积有误。5.低同源性区域或缺乏合适的同源三维模板,这通常可以通过loop建模来解决。注意:第三点比较难以理解,shift errors 一开始理解成即使比对正确,也发生了错误,是在序列上出错。但是师兄说在模板结构上的出错而不是序列上出错。这里还需要进一步去研究。
附注:从一篇有关MODELLER同源建模的文献提到了这五类原因,仔细研读了下发现shift/distortion是指结构上的出错, 具体说法是这样的: 由于序列差异, 有可能会导致主链构象变化, 但整体上的fold保持不变。也就是说部分片段在比对正确情况下, 模板和靶标局部不同, 导致该区域构象上还是有差异。
有两个比赛或项目可供建模者跟踪学习:
在最新的CASP(The Critical Assessment of protein Structure Prediction)比赛中,同源建模主要在四个领域有不错进展:序列-结构对齐,结合多个三维结构模板,loop建模和蛋白质组装。同源性建模精度显著的提高,主要归因于使用多个模板,从头建模缺失部分,改进了优化,提高了模型精度的评估。
CAMEO(Continuous Automated Model EvaluatiOn :www.cameo3d.org)项目为三个建模服务器组提供每周跟踪:(1)同质建模,(2)模型质量估计,(3)接触预测。
另外介绍常用的同源建模软件:SWISS-MODEL,Robetta,Protein Homology/AnalogY
Recognition Engine 2,RaptorX,Position Specific Iterated-BLAST–based secondary structure PREDiction,MODELLER,SCWRL。根据学者自身情况选择所需软件建模。
详解卡尔曼滤波原理 在网上看了不少与卡尔曼滤波相关的博客、论文,要么是只谈理论、缺乏感性,或者有感性认识,缺乏理论推导。能兼顾二者的少之又少,直到我看到了国外的一篇博文,真的惊艳到我了,不得不佩服作者这种细致入微的精神,翻译过来跟大家分享一下,原文链接:http://www.bzarg.com/p/how-a-kalman-filter-works-in-pictures/ 我不得不说说卡尔曼滤波,因为它能做到的事情简直让人惊叹!意外的是很少有软件工程师和科学家对对它有所了解,这让我感到沮丧,因为卡尔曼滤波是一个如此强大的工具,能够在不确定性中融合信息,与此同时,它提取精确信息的能力看起来不可思议。
什么是卡尔曼滤波? 你可以在任何含有不确定信息的动态系统中使用卡尔曼滤波,对系统下一步的走向做出有根据的预测,即使伴随着各种干扰,卡尔曼滤波总是能指出真实发生的情况。 在连续变化的系统中使用卡尔曼滤波是非常理想的,它具有占用内存小的优点(除了前一个状态量外,不需要保留其它历史数据),并且速度很快,很适合应用于实时问题和嵌入式系统。 在Google上找到的大多数关于实现卡尔曼滤波的数学公式看起来有点晦涩难懂,这个状况有点糟糕。实际上,如果以正确的方式看待它,卡尔曼滤波是非常简单和容易理解的,下面我将用漂亮的图片和色彩清晰的阐述它,你只需要懂一些基本的概率和矩阵的知识就可以了。
我们能用卡尔曼滤波做什么? 用玩具举例:你开发了一个可以在树林里到处跑的小机器人,这个机器人需要知道它所在的确切位置才能导航。 我们可以说机器人有一个状态 ,表示位置和速度: 注意这个状态只是关于这个系统基本属性的一堆数字,它可以是任何其它的东西。在这个例子中是位置和速度,它也可以是一个容器中液体的总量,汽车发动机的温度,用户手指在触摸板上的位置坐标,或者任何你需要跟踪的信号。 这个机器人带有GPS,精度大约为10米,还算不错,但是,它需要将自己的位置精确到10米以内。树林里有很多沟壑和悬崖,如果机器人走错了一步,就有可能掉下悬崖,所以只有GPS是不够的。 或许我们知道一些机器人如何运动的信息:例如,机器人知道发送给电机的指令,知道自己是否在朝一个方向移动并且没有人干预,在下一个状态,机器人很可能朝着相同的方向移动。当然,机器人对自己的运动是一无所知的:它可能受到风吹的影响,轮子方向偏了一点,或者遇到不平的地面而翻倒。所以,轮子转过的长度并不能精确表示机器人实际行走的距离,预测也不是很完美。 GPS 传感器告诉了我们一些状态信息,我们的预测告诉了我们机器人会怎样运动,但都只是间接的,并且伴随着一些不确定和不准确性。但是,如果使用所有对我们可用的信息,我们能得到一个比任何依据自身估计更好的结果吗?回答当然是YES,这就是卡尔曼滤波的用处。
卡尔曼滤波是如何看到你的问题的 下面我们继续以只有位置和速度这两个状态的简单例子做解释。 我们并不知道实际的位置和速度,它们之间有很多种可能正确的组合,但其中一些的可能性要大于其它部分: 卡尔曼滤波假设两个变量(位置和速度,在这个例子中)都是随机的,并且服从高斯分布。每个变量都有一个均值 μ,表示随机分布的中心(最可能的状态),以及方差 ,表示不确定性。 在上图中,位置和速度是不相关的,这意味着由其中一个变量的状态无法推测出另一个变量可能的值。下面的例子更有趣:位置和速度是相关的,观测特定位置的可能性取决于当前的速度: 这种情况是有可能发生的,例如,我们基于旧的位置来估计新位置。如果速度过高,我们可能已经移动很远了。如果缓慢移动,则距离不会很远。跟踪这种关系是非常重要的,因为它带给我们更多的信息:其中一个测量值告诉了我们其它变量可能的值,这就是卡尔曼滤波的目的,尽可能地在包含不确定性的测量数据中提取更多信息! 这种相关性用协方差矩阵来表示,简而言之,矩阵中的每个元素 表示第 i 个和第 j 个状态变量之间的相关度。(你可能已经猜到协方差矩阵是一个对称矩阵,这意味着可以任意交换 i 和 j)。协方差矩阵通常用“”来表示,其中的元素则表示为“ ”。 使用矩阵来描述问题 我们基于高斯分布来建立状态变量,所以在时刻 k 需要两个信息:最佳估计 (即均值,其它地方常用 μ 表示),以及协方差矩阵 。 (1) (当然,在这里我们只用到了位置和速度,实际上这个状态可以包含多个变量,代表任何你想表示的信息)。接下来,我们需要根据当前状态(k-1 时刻)来预测下一状态(k 时刻)。记住,我们并不知道对下一状态的所有预测中哪个是“真实”的,但我们的预测函数并不在乎。它对所有的可能性进行预测,并给出新的高斯分布。 我们可以用矩阵 来表示这个预测过程: 它将我们原始估计中的每个点都移动到了一个新的预测位置,如果原始估计是正确的话,这个新的预测位置就是系统下一步会移动到的位置。那我们又如何用矩阵来预测下一个时刻的位置和速度呢?下面用一个基本的运动学公式来表示: 现在,我们有了一个预测矩阵来表示下一时刻的状态,但是,我们仍然不知道怎么更新协方差矩阵。此时,我们需要引入另一个公式,如果我们将分布中的每个点都乘以矩阵 A,那么它的协方差矩阵 会怎样变化呢?很简单,下面给出公式: 结合方程(4)和(3)得到: 外部控制量 我们并没有捕捉到一切信息,可能存在外部因素会对系统进行控制,带来一些与系统自身状态没有相关性的改变。 以火车的运动状态模型为例,火车司机可能会操纵油门,让火车加速。相同地,在我们机器人这个例子中,导航软件可能会发出一个指令让轮子转向或者停止。如果知道这些额外的信息,我们可以用一个向量来表示,将它加到我们的预测方程中做修正。 假设由于油门的设置或控制命令,我们知道了期望的加速度,根据基本的运动学方程可以得到: 以矩阵的形式表示就是: 称为控制矩阵,称为控制向量(对于没有外部控制的简单系统来说,这部分可以忽略)。让我们再思考一下,如果我们的预测并不是100%准确的,该怎么办呢?
外部干扰 如果这些状态量是基于系统自身的属性或者已知的外部控制作用来变化的,则不会出现什么问题。 但是,如果存在未知的干扰呢?例如,假设我们跟踪一个四旋翼飞行器,它可能会受到风的干扰,如果我们跟踪一个轮式机器人,轮子可能会打滑,或者路面上的小坡会让它减速。这样的话我们就不能继续对这些状态进行跟踪,如果没有把这些外部干扰考虑在内,我们的预测就会出现偏差。 在每次预测之后,我们可以添加一些新的不确定性来建立这种与“外界”(即我们没有跟踪的干扰)之间的不确定性模型: 原始估计中的每个状态变量更新到新的状态后,仍然服从高斯分布。我们可以说的每个状态变量移动到了一个新的服从高斯分布的区域,协方差为。换句话说就是,我们将这些没有被跟踪的干扰当作协方差为的噪声来处理。 这产生了具有不同协方差(但是具有相同的均值)的新的高斯分布。 我们通过简单地添加得到扩展的协方差,下面给出预测步骤的完整表达式: 由上式可知,新的最优估计是根据上一最优估计预测得到的,并加上已知外部控制量的修正。 而新的不确定性由上一不确定性预测得到,并加上外部环境的干扰。 好了,我们对系统可能的动向有了一个模糊的估计,用和来表示。如果再结合传感器的数据会怎样呢?
传统关系型数据库对关联关系的处理 对于传统关系型数据库而言,处理数据的关联关系时比较正规的设计是范式化设计与非范式化设计。
范式化 (Normalization) 范式化设计的主要⽬标是“减少不必要的更新”,一般有三段范式,其实就是本着将两个关联数据模型之间通过主键的处理去划分属性字段,减少不必要的更新处理。
关于范式化的概念可以自行去学习。
反范式化 (Denormalization) 范式化设计带来的一个弊端就是读操作可能会涉及很多表的处理,性能受影响,所以如果我们本来只需要关联对象的一个字段却还得去查询关联表一次,很不方便,于是便有了范式化设计,就是不使⽤关联关系,⽽是直接保存冗余的数据,减少join操作。
关于反范式化的概念可以自行去学习。
ElasticSearch 对关联关系的处理 在 ElasticSearch 中,对数据的关联关系的处理,其实也有参考范式化与反范式化的设计,并且针对这两中设计理念都有对应的实现方式。
嵌套对象(Nested Object) nested 是 ElasticSearch 处理关联关系时的一种范式化设计的数据模型,在索引时他们被存放到两个不同Lucene文档中,在查询的时候 join出来,将根父文档带出来。
允许嵌套对象中的数据被独⽴索引分成两个文档去存储,类似数据库的分表存放关键词 “type”: “nested” 指定 nested 数据类型 要想使用 nested,需要我们在设置mapping的时候将这个对象的数据类型设置成为 nested。
PUT blog { "mappings": { "properties": { "actors": { "type": "nested", "properties": { "name": { "type": "keyword" }, "sex": { "type": "keyword" }, "another": { "type": "nested", "properties": { "name": { "type": "keyword" } } } } } } } } 如上这个mapping的设置语义,就是将actors作者定义成为nested存储类型。
安装总结:
先启动http服务;按向导安装Microsoft .NET Framework 3.5.1。 具体:
安装Microsoft .NET Framework 3.5.1时需要启动HTTP服务(IIS服务中的一个组件)。
(1)使用Administrator帐号登录操作系统。
(2)选择“开始 > 所有程序 > 附件 > 命令提示符”(打开管理员命令窗口)。
(3)执行如下命令启动HTTP服务。
sc config http start= auto net start http start与“=”之间没有空格,而“=”与auto之间至少需要一个空格分隔。
(4)选择“开始 > 管理工具 > 服务器管理器”,选择“功能 > 增加功能 > .NET Framework 3.5.1”。
(5)按向导安装系统自带的Microsoft .NET Framework 3.5.1。
参考:https://info.support.huawei.com/network/ptmngsys/Web/tsrev_oss/cn/content/oss/install/cn_install_reference_2379.html
一、OSPF路由协议概述1.内部网关协议和外部网关协议2.OSPF的工作过程 二、OSPF的应用环境1.从以下几方面考虑OSPF的使用2.OSPF的特点 三、OSPF基本概念OSPF区域OSPF路由类型生成OSPF多区域的原因Router IDRouter ID选取规则选举DR和BDR1.自动选举DR和BDR2.手工选择DR和BDR3.DR和BDR的选举过程 OSPF的组播地址度量值OSPF的数据包类型OSPF协议7种状态分析OSPF协议6种LSA分析OSPF地址汇总的作用 四、OSPF配置命令示例1.通用配置2.优化配置3.验证命令4.查看LSA命令5.修改oSPF路由的接口优先集,缺省值为16.OSPF路由重分发配置命令7.区域间路由汇总配置8.虚链路配置 一、OSPF路由协议概述 1.内部网关协议和外部网关协议 自治系统(AS)内部网关协议(IGP) :rip、ospf等外部网关协议(EGP):bgp等 2.OSPF的工作过程 邻居列表链路状态数据库路由表
二、OSPF的应用环境 1.从以下几方面考虑OSPF的使用 网络规模网络拓扑其他特殊要求路由器自身要求 2.OSPF的特点 可适应大规模网络路由变化收敛速度快无路由环支持变长子网掩码VLSM支持区域划分支持以组播地址发送协议报 三、OSPF基本概念 OSPF区域 为了适应大型的网络,OSPF在AS内划分多个区域每个OSPF路由器只维护所在区域的完整链路状态信息 区域ID 区域ID可以表示成一个十进制的数字也可以表示成一个IP 骨干区域Area 0 负责区域间路由信息传播 非骨干区域 非晋干区域相互通信必须通过骨干区域
– 标准区域
– 末梢区域stub
– 完全末梢区域total stub
– 非纯末悄区域nssa OSPF路由类型 区域之间路由器: ABR自制系统边界路由器:ASBR
生成OSPF多区域的原因 改善网络的可扩展性快速收敛 Router ID OSPF区域内唯一标识路由器的IP地址
Router ID选取规则 选取路由器loopback接口上数值最高的IP地址如果没有loopback接口,在物理端口中选取IP地址最高的也可以使用router-id命令指定Router IDDR和BDR的选举方法 选举DR和BDR 1.自动选举DR和BDR 网段上Router lID最大的路由器将被选举为DR,第二大的将被选举为BDR 2.手工选择DR和BDR 优先级范围是0~255,数值越大,优先级越高,默认为1如果优先级相同,则需要比较Router ID如果路由器的优先级被设置为0,它将不参与DR和DBR的选举 3.DR和BDR的选举过程 路由器的优先级可以影响一个选举过程,但是它不能强制更换已经存在的DR或BDR路由器
OSPF的组播地址 224.0.0.5
224.0.0.6
DRothers向DR/BDR发送DBD、LASR或者Lsu时目标地址是224.0.0.6(AllDRouter)﹔或者理解为:DR/BDR侦224.0.0.6DR/BDR向DRothers发送更新的DBD、LSR或者Lsu时目标地址是224.0.0.5(AllSPFRouter),或者理解为:DRothers侦听224.0.0.5 度量值 OSPF度量值 cost(开销)=10OM/BW(端口带宽)
– 最短路径是基于接口指定的代(cost路径成本)计算的R工P是跳数 OSPF的数据包类型 承载在lIP数据包内,使用协议号89
apt-get install -d <软件包>
ls /var/cache/apt/archives/ #下载的包目录
一、 域名与 DNS 解析 域名主要是为了方便让人记住,而 IP 地址是机器间的通信的真正机制。以 time.geekbang.org 为例,最后面的 org 是顶级域名,中间的 geekbang 是二级域名,而最左边的 time 则是三级域名。点(.)是所有域名的根,所有域名都以点作为后缀。
把域名转换为 IP 地址的服务,就是域名解析服务(DNS)。对应的服务器就是域名服务器,网络协议则是 DNS 协议。DNS 协议在 TCP/IP 栈中属于应用层,不过实际传输还是基于 UDP 或者 TCP协议(UDP 居多) ,并且域名服务器一般监听在端口 53 上。
既然域名以分层的结构进行管理,相对应的,域名解析也是用递归的方式,发送给每个层级的域名服务器,直到得到解析结果。通常来说,每级 DNS 服务器都会有最近解析记录的缓存。当缓存命中时,直接用缓存中的记录应答;如果缓存过期或者不存在,才需要用刚刚提到的递归方式查询。
所以,系统管理员在配置 Linux 系统的网络时,除了需要配置 IP 地址,还需要配置DNS 服务器,这样才可以通过域名来访问外部服务。可以执行下面的命令来查询你的DNS配置
$ cat /etc/resolv.conf nameserver 114.114.114.114 另外,DNS 服务通过资源记录的方式,来管理所有数据,它支持 A、CNAME、MX、NS、PTR 等多种类型的记录。比如
A 记录,用来把域名转换成 IP 地址;CNAME 记录,用来创建别名; NS 记录,则表示该域名对应的域名服务器地址。
比如以 time.geekbang.org 为例,执行下面的 nslookup 命令,就可以查询到这个域名的 A 记录,可以看到,它的 IP 地址是 39.106.233.176:
$ nslookup time.geekbang.org # 域名服务器及端口信息 Server: 114.
我们知道数据链路层和传输层都提供可靠传输服务,传输层是一定要提供的,比如TCP就是可靠传输协议,保证了端到端的可靠传输,确保每一个报文段都能按序送达对方,如果下层传输丢失,也能及时通过ARQ协议来重传,那么为什么会丢失呢?
1.可能是因为网络层的路由器负载过高,导致后来的数据报被丢弃,那么传输层就需要重传了;
2.因为有定时器的存在,一段时间没收到确认就重传;
3.还有一种丢失的可能就是数据链路层检测数据帧传输出错,被丢弃了,因为我们知道数据链路层是提供节点到节点之间的可靠交付,那么这时候传输层的报文就没有正确传输到对方,也会重传。
所以传输层是保证传输无误的最高层次,任何下层导致的传输错误,传输层都要重传来处理,来达到让对方能正确接收数据的目的,传输层就是保证端到端的可靠传输,就是应用之间的通信可靠。
那么数据链路层提供的是什么呢?数据链路层也规定了可以提供可靠传输,但具体实不实现得按具体情况来分析,只是给出了这个框架说你可以这么去做,但具体实现得具体分析。
我们假设它是提供可靠传输的,而且是点对点的可靠传输,也就是两个网络节点,节点之间只有通信链路,没有其他节点。那么问题来了,它是为谁提供可靠传输的?是传输层吗,不对,传输层的报文都封装在IP数据报里,IP数据报又封装在数据链路层的数据帧里,那么链路层提供的可靠服务是为物理层来服务的!!因为最终数据还是要经过物理层来传输,而物理层的传输过程中是可能出错的,比如噪声的影响导致比特传输错误,传输到对面的节点还原链路层数据帧,发现出错,这时候链路层的可靠传输就体现出来了,数据帧会通过一些手段对数据进行校验,来发现数据帧是否错误,如果错误,可以检错重发,向前纠错,反馈校验,检错丢弃等手段来保证两个节点之间传输的数据帧向上层提供的数据是无差错的。
这样就从底层的传输又加了一层保险,数据链路层的差错控制是一定要的,不然上层不知道是否传输错误,但数据链路层的可靠传输不只是差错控制,还可以通过可靠交付,比如传输层的滑动窗口协议等都是适用于链路层的,但并不是所有数据链路层的协议都需要设计成可靠交付的,支持可靠交付的链路层协议里多应用于高出错率的链路中,对于低出错率,例如光纤、双绞线链路等,采用可靠交付似乎没有必要,因此,通常有线链路的数据链路层协议,不提供可靠交付服务,但是差错控制是要有的。
说到这里,就有个大概的了解了,数据链路层是为物理层提供可靠服务的,因为物理层可能导致比特传输差错,数据链路层保证向上层提供的数据是无差错的;传输层是为网络层提供可靠传输服务的,因为数据报在核心网传输过程中,可能会在路由器那里因负载过高导致丢弃,然后传输层重传,来保证可靠传输,这样传输层能保证向上层(也就是应用层)提供的数据是无误且按序交付的。
下面给出矩阵可相似对角化的充要条件:
摘自 Linear Algebra and its applications David C. Lay
Chapter 5.3 , page282
矩阵相似对角化示例1
矩阵相似对角化示例2
实对称矩阵的 P P P除了满足可逆之外,还是正交矩阵
特征值篇4——实对称矩阵的特殊性
正规矩阵的 P P P除了满足可逆之外,还是酉矩阵
酉相似于对角阵的充要条件
FileCoin常用命令 新建钱包
./lotus wallet new bls
抵押扇区
./lotus-miner sectors pledge
抵押扇区状态查询
./lotus-miner sectors list
启动miner
./lotus-miner run —nosync
初始化 owner和worker是钱包的值
./lotus-miner init --owner --worker
清理节点node
sh deploy.sh -c $PWD /var/tmp/123
启动节点node
./lotus daemon --genesis=genesis.car --bootstrap=false
钱包余额
./lotus wallet balance id
提现
./lotus-miner actor withdraw
查找miner
./lotus state list-miners
查询交易
./lotus client list-deals
发交易
./lotus client deal bafk2bzacedhn3djyudzvoupta4sthfgqn4tskq6ab7pbglic3rxp56ah5kci4 t01000 0.000005 600000
连接lotus node
./lotus net connect /ip4/192.168.31.166/tcp/55065/p2p/12D3KooWFi2e1iz2oKpWxju4gqYvS5HGEZUC8Wf2vwqsNLy33zzD
查看所有文件
ls -alRh
问题 今天使用python开发一个下工具,需要切换32位的python环境,使用如下命令
set CONDA_FORCE_32BIT=1 还是win-64!!切换失败了啊,然后就找到了如下解决措施
解决措施 因为使用set命令设置环境变量在powershell中无效,所以我们更换如下命令即可
$Env:CONDA_FORCE_32BIT=1 切换成功!!
今天老大提了一个需求,想要做一个按钮点击后出现一个类似于json.cn代码格式化,把后端返回给你的一个json数据格式化以后显示在页面上,经高人指点知道了这样一个jsoneditor模块
一.介绍 JSON编辑器是基于Web的工具,用于查看,编辑,格式化和验证JSON。 它具有多种模式,例如树编辑器,代码编辑器和纯文本编辑器。
该编辑器可以用作您自己的Web应用程序中的组件。 该库可以作为CommonJS模块,AMD模块或常规javascript文件加载。
支持的浏览器:Chrome,Firefox,Safari,Opera,Edge,Internet Explorer 11。
二.安装 npm install jsoneditor 可以npm安装,也可以直接引用cdn,或者下载下来再引用。
// 为了在我们的web应用中实现JSONEditor,我们需要载入css和js文件 <link href="https://cdn.bootcss.com/jsoneditor/5.13.1/jsoneditor.min.css" rel="stylesheet"> <script src="https://cdn.bootcss.com/jsoneditor/5.13.1/jsoneditor.min.js"></script> // 获取更多详细的错误信息 <script src="https://cdn.bootcss.com/ace/1.2.9/ace.js"></script> //上面提到支持多种modes,而其中的code mode比较特别,需要依赖于Ace editor, JSON Editor comes with a custom built version of Ace containing the ace modules ace.js, ext-searchbox.js, mode-json.js, theme-textmate.js, and a custom theme theme-jsoneditor.js。除了载入ace.js之外,我们还需要在js代码中设置mode,就像下面给出的实例中所示。 <script src="https://cdn.bootcss.com/jsonlint/1.6.0/jsonlint.min.js"></script> 三.react里使用 import React, { Component } from 'react'; import JSONEditor from 'jsoneditor'; import 'jsoneditor/dist/jsoneditor.min.css' import 'jsoneditor/dist/jsoneditor.min.js' export default class TopicCards extends Component { constructor(props) { super(props); this.
一,AFL简介 AFL(American Fuzzy Lop)是一款基于覆盖引导(Coverage-guided)的模糊测试工具,它通过记录输入样本的代码覆盖率,从而调整输入样本以提高覆盖率,增加发现漏洞的概率。
①从源码编译程序时进行插桩,以记录代码覆盖率(Code Coverage);
②选择一些输入文件,作为初始测试集加入输入队列(queue);
③将队列中的文件按一定的策略进行“突变”;
④如果经过变异文件更新了覆盖范围,则将其保留添加到队列中;
⑤上述过程会一直循环进行,期间触发了crash的文件会被记录下来。
开始Fuzzing前,首先要选择一个目标。 AFL的目标通常是接受外部输入的程序或库,输入一般来自文件。
AFL主要用于C/C++程序的测试,所以这是我们寻找软件的最优先规则。
2,AFL安装 从官网http://lcamtuf.coredump.cx/afl/ 下载最新版的源码(latest version),解压后进入所在目录。执行以下命令进行编译和安装:
make sudo make install 输入afl-fuzz测试安装是否成功;
查看AFL安装目录:
通过查阅资料我们大概知道AFL下一些文件的作用:
• afl-gcc 和afl-g++ 分别对应的是gcc 和g++ 的封装
• afl-clang 和afl-clang++ 分别对应clang 的c 和c++ 编译器封装À。
• afl-fuzz 是AFL 的主体,用于对目标程序进行fuzz。
• afl-analyze 可以对用例进行分析,通过分析给定的用例,看能否发现用例中有意义的字段。
• afl-qemu-trace 用于qemu-mode,默认不安装,需要手工执行qemu-mode 的编译脚本进行编译,后面会介绍。
• afl-plot 生成测试任务的状态图
• afl-tmin 和afl-cmin 对用例进行简化
• afl-whatsup 用于查看fuzz 任务的状态
• afl-gotcpu 用于查看当前CPU 状态
• afl-showmap 用于对单个用例进行执行路径跟踪
3,AFL使用 按照https://xz.aliyun.com/t/4314 的思路,我们也拿一个c语言程序来进行试用AFL-FUZZ;
文章目录 1、Spring框架概述2、Spring入门案例3、spring的体系结构4、面向切面编程AOP关于AOP的配置详解 5、注入其他类型数据6、依赖注入 1、Spring框架概述 什么是spring框架
spring是J2EE应用程序框架,是一个兴起于2003年左右的开源框架,是轻量级的IoC和AOP的容器框架,主要是针对javaBean的生命周期进行管理的轻量级容器,可以单独使用,也可以和Struts框架,ibatis框架等组合使用;
IoC和AOP是什么
首先Spring框架是基于Bean编程的,Spring框架会将所有的对象都集中起来管理,这个操作就是使用了IoC思想;IOC是spring框架的核心,容器将对象连接到了一起,并且配置、管理他们的生命周期;
IOC不是一种技术,只是一种思想:代码松耦合、结构灵活
1、很好的体现了面向对象的设计法则之一:“好莱坞法则:别找我们,我们找你”,这里的我们指的是Java中的对象;依赖容器给予你资源,控制权在容器身上,不主动new对象,哪里需要对象,向容器发出请求,让容器帮自己new一个对象;
2、依赖注入(DI):在IOC容器创建完对象后 ,处理对象之间的依赖关系;所需求的对象,需要依赖容器注入;
3、spring中有三种注入方式,一种是set注入,一种是接口注入,另一种是构造方法注入;
AOP面向切面编程
比如业务1和业务2都需要一个共同的操作,与其往每个业务中都添加同样的代码,不如写一遍代码,让两个业务共同使用这段代码;
面向对象的延续,spring框架的重要内容,是函数式编程的衍生泛型,利用AOP可以对业务逻辑整个部分之间的耦合度降低,提高程序的重用性与开发的效率;
spring中面向切面变成的实现有两种方式,一种是动态代理,一种是CGLIB,动态代理必须要提供接口,而CGLIB实现是有继承。
为什么使用spring框架
在不使用spring框架之前,我们的service层中要使用dao层的对象,不得不在service层中new一个对象,各个层之间的调用都是这样的;
这使得层与层之前存在耦合,代码冗余,并且对象创建好之后,只能等待垃圾回收器自动回收,这时内存的开销也很大;
2、Spring入门案例 1、创建普通项目,导入Spring框架需要依赖的jar包: 如果是创建Maven项目,需要依赖的jar包有:
<!-- Spring核心依赖 --> <!-- https://mvnrepository.com/artifact/org.springframework/spring-context --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>5.2.6.RELEASE</version> </dependency> <!-- https://mvnrepository.com/artifact/org.springframework/spring-core --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>5.2.8.RELEASE</version> </dependency> <!-- https://mvnrepository.com/artifact/org.springframework/spring-beans --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-beans</artifactId> <version>5.2.7.RELEASE</version> </dependency> 2、编写Java实体类: public class HelloSpring { private String str; public void print() { System.out.println(str + "======Spring======"); } public String getStr() { return str; } //创建SET访问器,用于Spring注入值 public void setStr(String str) { this.
来自:宋天龙《PYTHON数据分析与数据化运营》,以下内容比较简陋,方便日后翻阅。
1. 业务场景 业务部门希望数据部门能对流失用户做分析,找到流失用户的典型特征,例如:到底流失用户的哪些特征最显著,当客户在哪些特征的什么条件下比较容易发生流失行为,并送到业务部门。
分析:
1.这是关于特征提取的分析工作,目标是交付特征重要性和特征规则;
2.该需求可以通过决策树实现,本例使用XGBoost
3.必须给业务部门提供规则图
4.数据集样本不平衡,因为流失用户是少量的,即使CGBoost对缺失值不敏感,但是过采样不允许有空值,故需要对缺失值处理。
2. python实现 1.导包,数据读取、预处理 # 导入库 import pandas as pd from sklearn.model_selection import train_test_split # 数据分区库 import xgboost as xgb from sklearn.metrics import accuracy_score, auc, confusion_matrix, f1_score, \ precision_score, recall_score, roc_curve # 导入指标库 from imblearn.over_sampling import SMOTE # 过抽样处理库SMOTE import matplotlib.pyplot as plt import prettytable # 导入表格库 # 读取准备 raw_data = pd.read_csv('classification.csv', delimiter=',') # 读取数据文件 X,y = raw_data.iloc[:, :-1],raw_data.iloc[:, -1] # 分割X,y n_samples, n_features = X.
lotus 区块高度 导出快照 1,导出快照lotus 1.1.0lotus 1.1.2lotus version 1.2.2lotus version 1.4.0lotus version 1.5.0lotus version 1.6.0lotus version 1.8.0 2,导入快照安全导入快照 3,减少lotus磁盘占用空间 1,导出快照 找一个已经同步完区块高度的节点
lotus chain export --recent-stateroots=900 --skip-old-msgs snapshot.car 导出时间大概30分钟,快照3.9GB
# ls -lh | grep snapshot.car -rw-r--r-- 1 root root 3.9G 9月 28 10:50 snapshot.car 3分钟导出来 # lotus chain export --recent-stateroots=900 --skip-old-msgs snapshot.car +++2020-10-01T17:32:07.675+0800 INFO rpc go-jsonrpc@v0.1.2-0.20200822201400-474f4fdccc52/client.go:213 rpc output message buffer {"n": 2} 4.7G snapshot.car 4分钟导出 lotus chain export --recent-stateroots=900 --skip-old-msgs snapshot.car 4.
静态的调用方式是指客户所采用的对象构件中明确定义了调用接口,客户程序可直接访问到某 远程调用对象的属性和方法;动态调用方式是指客户程序在构造和生成时并未确切规定远程调用对象,而是在运行时,动态地确定所需访问的对象及其访问途径。
目录 Go语言环境搭建 下载地址在线编译地址在线常用包查询安装注意事项环境变量CMD检测参数查看创建文档Go语言变量和常量 标识符关键字变量 标准声明批量声明变量初始化常量iotaGo语言基本数据类型 整型特殊整型浮点数复数布尔值字符串字符串转义多行字符串字符串常用操作byte和rune类型修改字符串使用rune判断是否为回文类型转换Go语言运算符 算数运算符关系运算符逻辑运算符位运算符赋值运算符Go语言数组 Array定义值类型初始化遍历多维数组Go语言切片 切片定义长度和容量基于数组的切片切片再切片使用make构造切片切片的本质切片不能直接比较切片赋值拷贝切片遍历append添加方法append防止底层数组共享办法使用copy赋值切片从切片中删除元素Go语言map map定义map使用判断是否存在某个值map遍历使用delete删除按照指定顺序遍历元素为map的切片值为切片的mapGo语言指针 指针地址和类型指针取值new和makeGo语言流程控制 if elsefor无限循环for rangeswitch casegotobreakcontinueGo语言终端和文件读写 终端读写带缓存读写文件读写小文件全部读写io/ioutil读取压缩文件文件写入文件拷贝Go语言结构体 类型别名和自定义类型结构体定义、实例化匿名结构体创建指针类型结构体取结构体地址的实例化使用键值对初始化使用值列表初始化构造函数方法和接收者 指针类型接收者值类型接收者什么时候用指针类型接收者和值类型接收者任意类型添加方法结构体的匿名字段嵌套结构体嵌套匿名结构体嵌套结构体字段冲突结构体中的继承结构体字段可见性结构体与json序列化结构体tag标签Go语言接口 接口类型接口定义实现接口的条件接口类型变量Go中描述方法集 从接收者角度看方法集值接收者实现接口指针接收者实现接口一个类型实现多个接口多个类型实现同一个接口接口嵌套空接口空接口应用类型断言判断是否实现了接口Go语言反射 变量的内在机制反射的应用反射是把双刃剑反射-reflect转换关系TypeOftype name和type kindValueOf通过反射获取值通过反射设置变量的值isNil和isValid结构体反射StructFile类型结构体反射实例Go语言并发编程 并行与并发goroutine匿名函数使用goroutineGolang调度器之GMP模型GOMAXPROCSchannel无缓冲通道有缓冲通道for range从通道中取值单项通道worker poolselect多路复用并发安全和锁互斥锁读写互斥锁sync.Oncesync.Map原子操作Go语言网络编程 socket编程之TCP通信解决TCP粘包socket编程之UDP通信Go语言http编程 go的http编程 http serverhttp clienthttp head请求http panic处理表单处理http_template模板Go语言ini文件操作Go语言使用mysqlGo语言使用redis获取本机ip示例kafka环境搭建kafka简单示例tail简单应用Go语言标准库之fmtGo语言标准库之timeGo语言标准库之stringsGo语言标准库之contextGo语言标准库之Strconv
一、样式
* Description:查询客户订单信息 <br> * * @author li.xueru<br> * @param request <br> * @return String <br> * @throws BaseAppException <br> */ @ApiOperation(value = "查询客户订单信息") @RequestMapping(value = "/custOrderInfo", method = RequestMethod.GET) public String queryCustOrderInfo( @ApiParam(value = "查询客户订单信息请求信息") @ModelAttribute QueryCustOrderInfoReq request) throws BaseAppException { return orderDetailService.queryCustOrderInfo(request.getPartyType(), request.getPartyCode()); } 二、说明
1、@ApiOperation不是spring自带的注解是swagger里的com.wordnik.swagger.annotations.ApiOperation;
2、@ApiOperation和@ApiParam为添加的API相关注解,个参数说明如下:
@ApiOperation(value = “接口说明”, httpMethod = “接口请求方式”, response = “接口返回参数类型”, notes = “接口发布说明”);其他参数可参考源码;@ApiParam(required = “是否必须参数”, name = “参数名称”, value = “参数具体描述”)。 三、注意
HTML 标签 <img class="weui-uploader__file" style="background-image: url('+ window.location.protocol + "//" + window.location.host +"/utils/fileStream?imgUrl=" + encodeURIComponent(imgList[j]) +')" ></img> JAVA Controller /** * 根据图片地址获取图片文件流 * * @param request * @param response * @param imgUrl */ @RequestMapping(value = "/fileStream") @ResponseBody public void fileStream(HttpServletRequest request, HttpServletResponse response, String imgUrl) { try { InputStream is = getInputStream(kehuApiConfig.getKehuApiUrlByImage() + URLEncoder.encode(imgUrl, "utf-8")); ByteArrayOutputStream baos = new ByteArrayOutputStream(); OutputStream os = response.getOutputStream(); int ch = 0; while (-1 !
Mysql报错Operand should contain 1 column(s) 1.报错 ERROR 1241 (21000): Operand should contain 1 column(s)
2. 报错原因 这个语句的出现多是因为将select 的结果集用()包住了。使用()将select 括注是正常的,但是可能是字段使用不当,如下面的SQL: select pit_key ,employee_code ,department_id ,value_date from pit_employee_department ped where ped.employee_code = 'GSCQ3349' and ped.value_date < date_format(date_sub(curdate(), interval day(curdate()) - 1 day),'%Y%m%d') and ped.pit_key not in ( select pit_key ,value_date from pit_employee_department ped_1 inner join ( select max(value_date) as max_date from pit_employee_department ped where ped.value_date <= date_format(date_sub( date_sub(curdate(), interval day(curdate()) - 1 day),interval 1 month),'%Y%m%d') and employee_code = 'GSSH0039' )ped_2 on ped_1.
269. 火星词典 问题: 现有一种使用字母的全新语言,这门语言的字母顺序与英语顺序不同。
假设,您并不知道其中字母之间的先后顺序。但是,会收到词典中获得一个 不为空的 单词列表。因为是从词典中获得的,所以该单词列表内的单词已经 按这门新语言的字母顺序进行了排序。
您需要根据这个输入的列表,还原出此语言中已知的字母顺序。
示例 1:
输入: [ "wrt", "wrf", "er", "ett", "rftt" ] 输出: "wertf" 示例 2:
输入: [ "z", "x" ] 输出: "zx" 示例 3:
输入: [ "z", "x", "z" ] 输出: "" 解释: 此顺序是非法的,因此返回 “”。
提示:
你可以默认输入的全部都是小写字母
若给定的顺序是不合法的,则返回空字符串即可
若存在多种可能的合法字母顺序,请返回其中任意一种顺序即可
解决: class Solution: def alienOrder(self, words: List[str]) -> str: # 每个字母代表图的一个顶点 # 邻接表表示有向图 graph = {} # 构建图顶点 for word in words: for w in word: if w not in graph: graph[w] = [] # 两两单词进行比较,确定图的方向 for i in range(len(words) - 1): j = 0 while j < len(words[i]) and j < len(words[i + 1]): if words[i][j] !
1.查看文件 ls:显示没有隐藏的文件和文件夹ls -a:显示当前目录下的所有文件和文件夹,包括隐藏的文件ls -l:显示没有隐藏的文件和文件夹的详细信息ls -al:显示当前目录下的所有文件和文件夹的详细信息 2.文件详细信息解读 第1列:代表文件的类型。我们常见的是d和-。d代表是目录文件。-代表是普通文件。其他不常见的有。l代表链接文件,b代表块设备。c代表字符设备文件。第2-10列:代表该文件的权限。三个为一组。第一组代表文件所有者的权限,第二组代表同用户组的权限,第三组代表其他用户非本用户组的权限。
每组权限中的rwx,分别代表读,写,可执行的意思。第11列数字,图中的2,1,3,9这列,代表有多少文件名连接到此节点。
每个文件都会将它的权限与属性记录到文件系统的i-node中,不过我们使用的目录树却是使用文件名来记录,因此每个文件名就会连接到一个i-node,这个属性记录的就是有多少不同的文件名连接到相同的一个i-node号码。第12列的root:所属者用户名第13列的root:所属用户组第14列:容量大小,默认为B后面为创建或修改日期,最后为文件名。 3.文件权限介绍 每一文件或目录的访问权限都有三组,每组用三位表示,分别为文件属主的读、写和执行权限;与属主同组的用户的读、写和执行权限;系统中其他用户的读、写和执行权限。
如之前的图所示,-代表空许可,r代表只读,w代表只写,x代表可执行。
4.chmod命令重写权限 该命令用于改变文件或目录的访问权限。
该命令有两种写法:1、文字设定法(包含字母和操作符的方式)。2、数字设定法(包含数字的设定方式)。
5.文字设定法 (1)命令:chmod [who] [+ | - | =] [mode] 文件名
who:包含以下: u 表示“用户(user)”,即文件或目录的所有者。 g 表示“同组(group)用户”,即与文件属主有相同组ID的所有用户。 o 表示“其他(others)用户”。 a 表示“所有(all)用户”。它是系统默认值。 操作符 +添加某个权限。
-取消某个权限。 =赋予给定权限并取消其他所有权限(如果有的话)。 mode r 可读。 w 可写。 x 可执行。 u 与文件属主拥有一样的权限。
g 与和文件属主同组的用户拥有一样的权限。
o 与其他用户拥有一样的权限。
文件名 以空格分开的要改变权限的文件列表,支持通配符。 (2)举个栗子:
给当前用户增加对startup.sh的执行权限。 chmod u+x startup.sh
使同组和其他用户对文件example 有读权限。chmod g+r,o+r example
6.数字设定法 (1)命令:chmod [mode] 文件名
我们将之前的rwx用数字进行替代。
0表示没有权限,1表示可执行权限,2表示可写权限,4表示可读权限。
数字之和,即为该文件的权限。
大家好,之前说过由于和LeetCode结了梁子,所以周末的LeetCode专题取消了,给大家写点其他专题的算法问题。目前选择的是国外著名的编程竞赛平台——codeforces。它在竞赛圈名气比较大,对于普通大学生而言可能了解不多。所以今天这篇文章简单和大家介绍一下codeforces这个网站,以及它的使用方法。
链接:codeforces.com
codeforces简介 简单介绍一下codeforces这个网站,codeforces位于宇宙编程最强的毛国。据说最早是由俄罗斯的一群大学生维护的,它最大的特点就是代码和题解的公开。所有人都可以随意查看其它大牛的代码,可以说是非常具有开源精神了。
codeforces很大的特点就是题目兼容并蓄,什么难度等级的题目都可以找到。并且题目很有意思,往往思维陷阱比较多,也就是思维题比较多。对于数据结构以及算法的考察相对弱一些,更多的时候往往是告诉你用什么算法你也不知道怎么做……
codeforces另外一个很大的特点就是它有自己的上分系统,基本上每周会举办一到两次在线的算法比赛。一般的比赛时长是两个小时,只要注册账号就可以免费参加。我记得当年第一次参加比赛会获得一个初始分是1500,然后根据你在比赛当中的表现上分或者减分。由于参加的选手水平实力强度不一,所以它开设了好几个档次(div),不同层次的选手面对的题目难度也不一样,这样保证了大家都可以愉快地参赛。
这块内容比较重要,我们放在后面详细介绍。
基本功能 简介介绍一下codeforces当中的功能以及页面,这个是首页的banner,我们挑几个比较重要的来介绍一下。
TOP 首先是Top,top里基本上是大牛放出来的一些资料、博客和题解什么的。比如下图就是一个大牛整理的一些算法和数据结构的经典问题整理。
这里面干货还是很多的,但是由于是国外的网站,所以显然肯定是全英文的。不过也不要惧怕,大家都是技术男,而且大多数不是native。描述一个问题或者是算法的时候也不会使用太晦涩的单词,所以还是蛮好懂的。另外现在在线翻译功能也很发达,我当年英语很差的时候都没什么压力,所以大家也不要担心。
contest 第二个重要的栏目是contest,里面是正在进行以及过去举办过的线上比赛。
比如上图就是目前的一个比赛安排计划,即将开始的比赛会多出来一个register按钮,让大家注册参加。
比赛名称后面括号里div表示的是难度等级,div1是最高难度。需要有1900以上的rating才可以报名。div2难度会简单很多,基本上学过算法和数据结构都可以进去做个一两题。div2的比赛前两题基本上都不涉及什么算法,主要是考验思维。一般到了C题之后才会考察一些算法和数据结构。
这张图是之前举办过的比赛,我们也可以点进去练习,它还提供replay功能,可以模拟当时的比赛的情况。
gym gym英文是健身房的意思,这里顾名思义可以理解成练习题。
gym栏目下的一般是一些专业的比赛题以及acm的练习题,和contest里面的题比起来gym里面的题难度会更大一些。并且也会有各种算法和数据结构的专题。虽然看起来难度更大,但是里面的题目也是有区分度的,并不是每一题都很难,即使水平一般也是可以做一两道的。
首页当中比较常用的功能就是这些,后面还有像是小组、天梯、日历等一些功能,由于不是非常常用,这里就不多赘述了。
比赛 最后介绍一下codeforces当中的比赛,这个是它起家的核心功能,不能不提。
codeforces当中的比赛一般有六道题,由于只有两个小时的时间,我们一般也很难把6道题都做完。基本上能做出来三题,rating就不会跌了。当然rating的涨跌情况也和你现在的rating有关,系统会根据你现在的rating对你的表现有一个期望,你最终的涨跌就是你实际表现和这个期望的差值。菜鸟做两题可能就可以涨分,但如果你现在rating已经很高的话,你也做了两题,那你肯定是跌的。
我们在比赛的时候可以实时看到每一道题过了多少人,这个有助于帮助我们选择题目。一般来说越前面的题目越简单,但是也有例外,比如有些题藏了一些陷阱,虽然简单,但是很多人没想到都挂在上面,这是常有的事。
当我们比赛的时候,经常会出现一种情况,就是我们做了3题之后还有时间,但是后面的题目一时想不出来了。这个时候多了时间可以干嘛呢,可以查看其它选手的代码。我们可以看到这里有一个栏目叫Room,在比赛的时候系统会随机分配房间。你可以查看同房间内通过了同样问题的人的代码。
codeforces在比赛的时候只会测试一小部分数据,真正的测试集会放到赛后进行测试。所以在比赛中测试通过的代码,只是通过了小数据验证,很有可能有隐藏的问题没被发现。当你通过了这道题之后,你就可以去查看其他通过人的代码,去分析它们有没有问题,如果发现了bug,可以构造一份数据hack掉他的提交。hack成功之后,你会获得分数的奖励。
你可以双击打开其他人的提交记录,去阅读他们的代码。到了比赛后期,能做的问题做的差不多了之后,就进入了紧张刺激的互相hack阶段。讲道理,这比只是单纯做题的竞赛要有趣多了。
以前我们acm集训队经常晚上一起打codeforces的比赛,有时候看到队友在一个房间里,还会互相关注一下近况,互相hack一把,不得不说现在怀念起来还是非常有意思的。
好了,关于codeforces网站就介绍到这里了,如果你也对算法感兴趣的话,不妨试着用一下它吧,相信你也会找到算法的乐趣。
衷心祝愿大家每天都有所收获。如果还喜欢今天的内容的话,请来一个三连支持吧~(点赞、关注、转发)
原文链接,求个关注
https://www.infoq.cn/article/Q0o*QzLQiay31MWiOBJH/
一、背景 2019年快手Kafka集群日消息处理量为数万亿级别,峰值超过1亿/s。
在快手,Kafka集群被分成3类:
在线集群:作为消息中间件,为不同在线业务之间提供异步的消息通知服务Log集群:业务集群直接将log打给Kafka,并通过Kafka进行传输和收集,由于数据在业务应用层不落地,所以这个过程不能出现由于Kafka问题导致业务受到影响,这对Kafka可用性要求很高;Log集群还为重要的实时计算或模型训练提供数据源离线集群:Log数据的最终汇聚点,数据被dump到HDFS中,做离线处理。离线集群为次要的实时计算、实时训练提供数据源。 此外,也提供了Mirror服务,用于将数据从在线集群、Log集群传输到离线集群。
之所以将Kafka集群做物理划分,是为了保证服务质量,控制Kafka集群问题的影响面
业务规模:
二、技术演进 第一阶段:为了支持业务快速发展,做了多集群建设,并增加了Kafka平滑扩容功能。
第二阶段:为了保证业务稳定,对Kafka可用性优化:将单点宕机发现与恢复的时间从91s优化到6s,提升了15倍
第三阶段:为了增加可维护性及提升系统运维效率,对数据Mirror服务做了集群化,并开发了资源管理平台
第四阶段:为了进一步提升Kafka稳定性与性能,做了资源隔离,对cache进行改造,并对消费者进行了智能限速。
2.1、平滑扩容 先看原生Kafka的扩容流程:
1、假如集群有3个broker,4个TP(topic partition),每个3副本,均匀分布。
2、现在要扩容一台机器,新broker加入集群后,需要通过工具进行topic partition迁移。
3、一共迁移3个topic partition的副本到新broker上。
4、等迁移结束后,会重新进行leader balance。
最终topic partition分布如下图:
从微观角度看,TP从1台broker迁移到另1台broker的过程是怎样的呢?
以TP3的第三个副本,从broker1迁移到broker4来看:
broker4作为TP3的follower,从broker1上最早的offset进行获取数据,
直到追平offset为止,新副本被放入ISR中,并移除broker1上的副本,迁移完毕。
但原生Kafka扩容流程存在如下问题:
数据迁移从TP3的最初Offset开始copy数据,回导致大量的读磁盘,消耗大量的IO资源,导致磁盘繁忙,从而造成produce操作延迟变长。所以说迁移过程不够“平滑”。
优化思考:Kafka理论上是个消息缓存系统,不需要永久存储数据,很有可能费了很多工作迁移过来的数据,根本就不会被使用,甚至马上就被删除了。从这个角度来说,迁移数据时,为什么一定要从partition的最初offset开始迁移呢?仔细想想,实际不需要这样。
所以,平滑扩容的思路:在迁移TP时,直接从partition最新的offset开始迁移,但要同步保持一段时间,主要是确保所有consumer都已经跟上了。如上图所示,再来看这个TP3的第三个副本从broker1迁移到broker4的过程:
这次broker4从broker1最新的offset开始迁移,即transfer start这条竖线。此时,因为consumer1还没能跟上(可能有的consumer有消息积压,没有消费到consumer start),所以整个迁移过程需要保持一段时间,直到transfer end这个点。这时候,可以将TP3的新副本放到ISR中,同时去掉broker1上的副本,迁移过程完毕。
从这次迁移看,因为都是读最新的数据,不会出现源broker读大量磁盘数据的问题,仅仅多了一个副本的流量,基本对系统无影响。
基于这样的过程,我们就可以在晚高峰期间做扩容,从Kafka整体服务质量上看,对业务没有任何影响。
这个策略是Kafka官方的patch: https://issues.apache.org/jira/browse/KAFKA-8328
2.2、Mirror集群化 接下来看如何改进Mirror服务,使其具备较好的管理性,提升运维效率。
如上图所示,目前Kafka多集群之间的数据同步,采用的事MirrorMaker,这个架构存在2个问题:
1)被Mirror的topic是静态管理的,运维成本很高,且容易出错;
2)一旦有topic增加或减少,以及机器的加入或退出,都会导致原有正在Mirror的数据断流,这主要是因为经历了“停止服务,再启动服务”的过程。
为了解决这个问题,快手基于UReplicator,开发了KReplcator服务,并替换掉了现有的MirrorMaker服务。UReplicator是Uber开源的Kafka数据Mirror同步服务。
如上图所示,在部署的时候,快手部署了多个KReplicator cluster,主要是为了保证数据同步的稳定性。
在实现细节上,我们对UReplicator进行了扩展,使其可以动态感知不同的Kafka集群。这样只需要部署一个Mirror集群,就可以进行不同源集群及不同目标集群的数据同步,而不再需要部署多个Mirror集群。
KReplicator集群包括三个模块:
1、Controller:
用于动态管理topic, worker的增减
负责TP的分配策略,支持部分partition的迁移,这样新增节点或节点宕机会触发部分TP的迁移,不会造成Mirror服务的整体断流,仅仅是一小部分有抖动。
2、Worker:
支持动态增减与减少topic,这样增加或减少topic,避免了对已有TP传输的影响。
吃吃同时传输多个源集群到多个目标集群的数据传输能力
支持将数据dump到HDFS中
3、Zookeeper:
负责协调controller与worker
有了KReplicator cluster管理Kafka多集群间数据Mirror,极大地减少了我们的运维成本,以及出错的情况。此外,由于集群化管理的存在,我们可以快速地对Mirror服务进行扩缩容,以便对应业务的突发流量。
总结:KReplicator主要用于解决TP动态变更导致Mirror服务断流的问题。
2.3、资源隔离 问题1、不同业务线之间的topic会相互影响。
如下图,这个broker服务两个业务线的TP,不同业务线的TP会共享一块磁盘。如果此时,consumer出现问题,导致消费产生lag,而lag积累会导致读取磁盘中的数据,进而造成磁盘繁忙。最终,会影响在同一块磁盘的其他业务线TP的写入。
解决思路很简单,就是对不同业务的topic进行物理隔离。把不同业务线的topic放到不同的broker,如下图所示,这样任何业务线产生问题,不会影响其他业务线。这个改动需要对broker打上不同的标签,并在topic创建、TP迁移、宕机恢复流程中,增加按标签的TP分片算法就可以。
问题2、Kafka RPC队列缺少隔离,一旦某个topic处理慢,会导致所有请求hang住。
数据守护搭建
1.备份还原
1.1脱机备份,脱机还原
正常关库
脱机备份
./dmrman
BACKUP DATABASE ‘/home/dmdba/dmdbms/data/dmdb/dm.ini’ FULL TO BACKUP_FILE1 BACKUPSET ‘/home/dmdba/dmdbms/data/BACKUP_FILE_01’
拷贝备份文件到所在机器dm.ini dm.ctl
scp /home/dmdba/dmdbms/data/dmdb/dm.ini dmdba@192.168.6.67/home/dmdba/dmdbms/data/dmdb/dm.ini
脱机还原恢复
./dmrman
RESTORE DATABASE ‘/home/dmdba/dmdbms/data/dmdb/dm.ini’ FROM BACKUPSET ‘/home/dmdba/dmdbms/data/BACKUP_FILE_01’
RECOVER DATABASE ‘/home/dmdba/dmdbms/data/dmdb/dm.ini’ FROM BACKUPSET ‘/home/dmdba/dmdbms/data/BACKUP_FILE_01’
RECOVER DATABASE ‘/home/dmdba/dmdbms/data/dmdb/dm.ini’ UPDATE DB_MAGIC
1.2联机备份,脱机还原
对主库进行联机备份操作
SQL>BACKUP DATABASE BACKUPSET ‘/home/dmdba/dmdbms/data/BACKUP_FILE_01’
拷贝备份文件到所在机器dm.ini dm.ctl
scp /home/dmdba/dmdbms/data/dmdb/dm.ini dmdba@192.168.6.67/home/dmdba/dmdbms/data/dmdb/dm.ini
./dmrman
BACKUP DATABASE ‘/home/dmdba/dmdbms/data/dmdb/dm.ini’ FULL TO BACKUP_FILE1 BACKUPSET ‘/home/dmdba/dmdbms/data/BACKUP_FILE_01’
拷贝备份文件到所在机器dm.ini dm.ctl
scp /home/dmdba/dmdbms/data/dmdb/dm.ini dmdba@192.168.6.67/home/dmdba/dmdbms/data/dmdb/dm.ini
恢复
./dmrman
2.环境规划
两个机器事先安装DM和实例
安装路径为/home/dmdba/dmdbms/
数据库名字为/home/dmdba/dmdbms/dmdb
由于Springboot中默认的json对象序列化框架是Jackson,所以我们需要去了解一下Jackson框架是如何将java对象与json对象实现序列化与反序列化的。 jackson序列化的原理 根据java对象的getter和setter方法,与JSON对象的名字去一一对应,其中会将getter()方法中的属性名的第一个字母改成小写与JSON对象的属性去对象。 具体可看下面两个例子
json对象java getter/setter对象方法{“name”:“zhangsan”}setName()/getName(){“engineName”: “host1”}setEngineName()/getEngineName(){“primaryEngine”: true}setPrimaryEngine()/isPrimaryEngine() jackson忽略部分字段 比如说我现在有个User的Java类,有id, userName, password 和job四个属性字段,其中password字段不希望返回给客户端,则可通过如下两种方式实现。
1.在需要忽略的属性上增加@JsonIgnore注解
2.在类上增加需要忽略属性的注解
AFL-Fuzz介绍 Fuzzing是指通过构造测试输入,对软件进行大量测试来发现软件中的漏洞的一种模糊测试方法。在CTF中,fuzzing可能不常用,但在现实的漏洞挖掘中,fuzzing因其简单高效的优势,成为非常主流的漏洞挖掘方法。
AFL则是fuzzing的一个很好用的工具,全称是American Fuzzy Lop,由Google安全工程师Michał Zalewski开发的一款开源fuzzing测试工具,可以高效地对二进制程序进行fuzzing,挖掘可能存在的内存安全漏洞,如栈溢出、堆溢出、UAF、double free等。由于需要在相关代码处插桩,因此AFL主要用于对开源软件进行测试。当然配合QEMU等工具,也可对闭源二进制代码进行fuzzing,但执行效率会受到影响
工作原理:
通过对源码进行重新编译时进行插桩(简称编译时插桩)的方式自动产生测试用例来探索二进制程序内部新的执行路径。AFL也支持直接对没有源码的二进制程序进行测试,但需要QEMU的支持。
安装 直接去官网下载压缩包,解压后在目录中打开终端输入:
makesudo make install 输入以上命令后基本就能安装成功了,在终端输入afl-后tab,就能出现以下这些命令了
说明安装成功
使用AFL插桩程序(有源码) 这里就以一个简单的c语言的程序作为例子来试试
#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <string.h> #include <signal.h> int vuln(char *str) { int len = strlen(str); if(str[0] == 'A' && len == 66) { raise(SIGSEGV); //如果输入的字符串的首字符为A并且长度为66,则异常退出 } else if(str[0] == 'F' && len == 6) { raise(SIGSEGV); //如果输入的字符串的首字符为F并且长度为6,则异常退出 } else { printf("it is good!\n"); } return 0; } int main(int argc, char *argv[]) { char buf[100]={0}; gets(buf);//存在栈溢出漏洞 printf(buf);//存在格式化字符串漏洞 vuln(buf); return 0; } 总的流程概述: