记微信小程序 利用canvas压缩图片 并进行base64

最近做一个小程序 上传图片时进行base64 总是报上传图片失败 究其原因是图片过大 需要进行压缩 废话不多说 上代码 选择图片后利用canvas重新绘制图片大小 利用绝对定位 隐藏canvas <image class="uploader_input_icon" src="/images/wy/uploader9@3x.png" /> <canvas canvas-id="canvas" style="width:{{cWidth}}px;height:{{cHeight}}px;position: absolute;left:-1000px;top:-1000px;"></canvas> 因为这里有多处需要上传代码并压缩,所以抽取出来作为公共方法 const chooseImage = (_this) => { wx.chooseImage({ count: 1, // 默认9 sizeType: ['compressed'], // 指定只能为压缩图,首先进行一次默认压缩 sourceType: ['album', 'camera'], // 可以指定来源是相册还是相机,默认二者都有 success: photo => { //将tempFilePaths[0]加入到images数组 作为展示 _this.data.images.push(photo.tempFilePaths[0]) _this.setData({ images: _this.data.images }) //-----返回选定照片的本地文件路径列表,获取照片信息----------- wx.getImageInfo({ src: photo.tempFilePaths[0], success: res => { //---------利用canvas压缩图片-------------- var ratio = 2; var canvasWidth = res.width //图片原始长宽 var canvasHeight = res.

Orchestrator MySQL主库故障切换的几种类型

Orchestrator 对MySQL主库的故障切换分为自动切换和手动切换。 手动切换又分为recover、force-master-failover、force-master-takeover以及graceful-master-takeover. 1.自动切换 自动切换是主库出现故障后,自动提升新主库,进行故的障切换。 自动切换受到以下条件限制和约束: 主库是downtime的集群不进行故障切换。如果希望忽略集群故障,可以设置downtime。处于故障活跃期的集群不进行故障切换(即in_active_period=1)只对配置项RecoverMasterClusterFilters匹配的集群进行故障切换 会周期检测主库状态。 自动切换,会周期进行故障扫描,如果发现故障,条件满足就会进行故障切换。 故障检测和切换具体由CheckAndRecover()实现,具体调用: GetReplicationAnalysis(),进行故障扫描executeCheckAndRecoverFunction(),进行故障恢复 2.手动切换 手动切换包括: recover、force-master-failover, force-master-takeover以及graceful-master-takeover。 手动切换不受自动切换中提到的条件限制和约束。 2.1 recover recover 以故障主库以及候选实例candiateKey为参数,调用CheckAndRecover(),进行故障切换。 指定的故障主库必须是故障的,也就是已确认发生故障,如果不是故障的,不进行切换。 2.2 force-master-failover 不论集群主库是否故障,都会进行后续切换操作,需要用户确认已发生故障。 具体步骤: (1) 故障扫描 forceAnalysisEntry()-->GetReplicationAnalysis()(2) 故障恢复ForceExecuteRecovery(analysisEntry, nil,false)-->executeCheckAndRecoverFunction(),不指定候选主库 最后,老主库成为单独的DB 实例。 2.3 force-master-takeover 同上,需要用户自己判定故障。 force-master-takeover,唯一不同于force-master-failover的点是,force-master-takeover带候选主库(即candidate),并且候选主库必须是集群主库的直连从库。 其他同force-master-failover。 2.3 graceful-master-takeover 这种切换方式针对的是:老主库是正常的,需要提升新主库,老主库可作为从库。 具体操作步骤包括: (1)检查候选主库 候选主库必须是集群的主库的直连从库候选主库,没有被禁止提升为主库(即promotion rule 不是must not)候选主库,没有延迟过大(超过20s) (2) 故障扫描,forceAnalysisEntry()-->GetReplicationAnalysis() (3) 调用hooks:PreGracefulTakeoverProcesses (4) 如果集群中不只一个副本,将老主库的从库移动到候选主库之下 (5) 停止候选主库的复制,在候选主库上执行stop slave (6) 设置老主库只读 (7) 使候选主库追上老主库(start slave until) (8) 进行故障恢复,新主库形成ForceExecuteRecovery(analysisEntry, &destination.Key, false)-->executeCheckAndRecoverFunction() (9) 将老主库变成新主库的从库 (10) 调用hooks: PostGracefulTakeoverProcesses

tomcat查看部署的所有项目,以及运行状态,可视化工具的使用

用Tomcat可视化工具 1. 修改E:\apache-tomcat-8.5.43\conf 的tomcat-users.xml的文件 tomcat 默认采用文件安全域,也就是以文件存放用户名和密码,tomcat的用户由conf路径下的 tomcat-users.xml文件控制,打开该文件,发现除了注释差不多就只剩下一对标签了,对于普通开发者来说,也就是只访问/status/*这些资源,配置一个manager-gui角色就可以了 2.

在百度或者淘宝搜索时,每次输入字符串都会出现搜索建议,例如输入北京,在搜索输入框下面会以北京为前缀,展示北京爱情故事,北京公交,北京医院等搜索词,实现这类技术所采用的数据结构是什么

在百度或者淘宝搜索时,每次输入字符串都会出现搜索建议,例如输入"北京",在搜索输入框下面会以北京为前缀,展示"北京爱情故事",“北京公交”,"北京医院"等搜索词,实现这类技术所采用的数据结构是什么? Trie树,又称为单词查找树,字典树,是一种树形结构,是一种哈希树的变种,是一种快速检索的多叉树结构,单行应用就是用于统计和排序大量的字符串(但不仅限于字符串),所以经常被搜索引擎系统用于文本词频统计. 他的优点是:最大限度的减少无谓字符串的比较,查询效率比哈希表高. Trie树的核心思想是:空间换时间,利用字符串的公共前缀降低查询时间的开销以达到提高效率的目的. 对于搜索引擎,一般会保留一个单词查找树前N个字(全球或最近热门使用的),对于每个用户,保持Trie树最近前N个字为该用户使用的结果. 用户点击任何搜索结果后,Trie树可以非常迅速并一步获取完整的部分/模糊查询,然后预取数据,再用一个Web应用程序发送一个较小的组结果到浏览器.

[20190823]关于CPU成本计算2.txt

[20190823]关于CPU成本计算2.txt --//前几天探究CPU cost时遇到的问题,获取行成本时我的测试查询结果出现跳跃,不知道为什么,感觉有点奇怪,分析看看。 --//ITPUB原始链接已经不存在,我的日记本还有记录,现在想想当时的记录思路很乱,不过这些都是猜测的过程,以前思路混乱也是正常的。 --//顺便做一些必要补充。 1.环境: SCOTT@test01p> @ ver1 PORT_STRING VERSION BANNER CON_ID -------------------- ---------- ---------------------------------------------------------------------------- ------ IBMPC/WIN_NT64-9.1.0 12.2.0.1.0 Oracle Database 12c Enterprise Edition Release 12.2.0.1.0 - 64bit Production 0 2.测试: SCOTT@test01p> create table t as select rownum a1 , rownum a2 ,rownum a3 from dual connect by level<=100 ; Table created. --//分析略. select 'explain plan set statement_id='''||lpad(rownum,3,'0')||''''||' for select 1 from t where rownum<='||rownum||';' c80 from t; --//把以上的输出保存一个文件执行,然后执行如下: select STATEMENT_ID,CPU_COST,lead(cpu_cost ) over ( order by STATEMENT_ID ) N1,lead(cpu_cost ) over ( order by STATEMENT_ID )- cpu_cost N2 from ( select STATEMENT_ID,OPERATION, OPTIONS, COST, CPU_COST, IO_COST, TIME from plan_table where options='FULL'); STATEMENT_ CPU_COST N1 N2 ---------- -------- ----- ---- 001 7271 7421 150 002 7421 7571 150 003 7571 7721 150 004 7721 7871 150 005 7871 8021 150 006 8021 8321 300 007 8321 8321 0 008 8321 8471 150 009 8471 8621 150 010 8621 8771 150 011 8771 8921 150 012 8921 9071 150 013 9071 9371 300 014 9371 9371 0 015 9371 9521 150 016 9521 9671 150 017 9671 9821 150 018 9821 9971 150 019 9971 10121 150 020 10121 10271 150 021 10271 10421 150 022 10421 10571 150 023 10571 10721 150 024 10721 10871 150 025 10871 18143 7272 026 18143 18293 150 027 18293 18593 300 028 18593 18593 0 029 18593 18743 150 030 18743 18893 150 031 18893 19043 150 032 19043 19193 150 033 19193 19343 150 034 19343 19493 150 035 19493 19643 150 036 19643 19793 150 037 19793 19943 150 038 19943 20093 150 039 20093 20243 150 040 20243 20393 150 041 20393 20543 150 042 20543 20693 150 043 20693 20843 150 044 20843 20993 150 045 20993 21143 150 046 21143 21293 150 047 21293 21443 150 048 21443 21593 150 049 21593 21743 150 050 21743 29014 7271 051 29014 29164 150 052 29164 29314 150 053 29314 29464 150 054 29464 29914 450 055 29914 29914 0 056 29914 29914 0 057 29914 30064 150 058 30064 30214 150 059 30214 30364 150 060 30364 30514 150 061 30514 30664 150 062 30664 30814 150 063 30814 30964 150 064 30964 31114 150 065 31114 31264 150 066 31264 31414 150 067 31414 31564 150 068 31564 31714 150 069 31714 31864 150 070 31864 32014 150 071 32014 32164 150 072 32164 32314 150 073 32314 32464 150 074 32464 32614 150 075 32614 39886 7272 076 39886 40036 150 077 40036 40186 150 078 40186 40336 150 079 40336 40486 150 080 40486 40636 150 081 40636 40786 150 082 40786 40936 150 083 40936 41086 150 084 41086 41236 150 085 41236 41386 150 086 41386 41536 150 087 41536 41686 150 088 41686 41836 150 089 41836 41986 150 090 41986 42136 150 091 42136 42286 150 092 42286 42436 150 093 42436 42586 150 094 42586 42736 150 095 42736 42886 150 096 42886 43036 150 097 43036 43186 150 098 43186 43486 300 099 43486 43486 0 100 43486 100 rows selected.

faiss安装方法:anaconda安装和swig安装

方法一:通过anaconda安装 1、下载anaconda 2、bash下载的anaconda.sh,一路回车,默认安装 3、修改环境变量: <1>vim /etc/profile <2>添加 export PATH="$HOME/anaconda2/bin:$PATH" (假设你的anaconda为anaconda2,在$HOME路径下) <3>启用 source /etc/profile 4、通过conda list 命令查看anaconda是否能正常使用 5、下载faiss安装包 6、将下载的faiss安装包放至anaconda/pkgs/ 下 7、faiss安装:conda install 相应的faiss包,直接安装 8、安装完成后,运行python,import faiss可以正常使用 方法二:通过swig将faiss的C++编译为py文件的安装方式 1、下载faiss,并解压 2、下载安装numpy 3、安装swig(swig为c/c++和python的“粘合剂”): <1>下载swig,并解压 <2>安装:a) ./configure (可通过./configure --prefix=your安装路径 // 指定安装目录) b) make //编译 c)make install //安装 4、安装OpenBLAS(faiss依赖的数学库) <1>下载OpenBLAS包,并解压(https://github.com/xianyi/OpenBLAS 选择合适的版本) <2>安装:a)make //编译 b)make install (可通过make PREFIX=your安装路径 install 进行指定目录安装) <3>修改环境变量: a)vim /etc/profile b)添加:export OpenBLAS_PATH=/opt/OpenBLAS/lib/ export LIBRARY_PATH=$OpenBLAS_PATH:$LIBRARY_PATH (g++进行.o文件生成时,需要openblas相应的库文件) c)启用:source /etc/profile 5、编译.so 及py文件 <1>进入到faiss文件夹,执行make命令进行编译 生成相应的.so文件 <2>修改环境变量: a)vim /etc/profile

c语言练习15——条件运算符的嵌套

#include<stdio.h> #include<stdlib.h> /*题目:利用条件运算符的嵌套来完成此题:学习成绩>=90分的同学用A 表示,60-89 分之间的用B 表示,60分以下的用C表示*/ int main() { system("color 1F"); // 设定显示框为蓝底白字 system("mode con cols=80 lines=30"); //固定显示框尺寸 /******************************************程序主体分割线(顶部)*************************/ int num; while(1){ printf("请输入分数:"); scanf("%d",&num); if(num>=90) printf("等次A\n"); else if(num>=60) printf("等次B\n"); else printf("等次C\n"); } /******************************************程序主体分割线(底部)***************************/ return 0; } 转载于:https://www.cnblogs.com/gougouwang/p/11401710.html

身为一个小白,看到一篇值得看的文章。讲述小白学习python的6个方法。

01. Python怎么学? Python虽然号称非常简单,功能强大!但是再简单,它也是一门编程语言,任何一个编程语言都会包含: 内功,心法和招式,内功心法就是指的算法,数据结构; 招式就是任何一门语言都有的,变量(int/string/float),条件判断(if/else), 循环(for/while),函数(fun),模块(import),文件(I/O),并发(多进程,多线程)等等; 这些招数无论你学C,C++,Java,Python都会有的,只是语法不一样而已 所以学语言需要遵循一点的逻辑,循序渐进,不要上来就啃硬骨头!从容易到难,不要语法都不太熟悉,就去看爬虫,hello world还没有写好,就去看数据分析!最后就是欲速则不达! 那既然学编程有一个过程,有没有什么好的方法? 1).建议一开始的是照着敲代码 就是把别人的例子一个字一个字敲一边,主要选的例子不要太长,以20行内的例子比较适合。 2).开始改代码 等你一个字一个字敲一边之后,要开始改代码,比如把把100改为200,比如把for循环的变量改改,然后等你熟悉了,可以改一下结构,改一下顺序。 3).擦掉重来 等你完成了上面2步,把代码全部删除,然后自己重头开始写出来,一行一行用自己的方法写出来。 所有的作品都是先模仿->再修改->再创造的流程,这招看起来很笨,但是非常有效果!尤其是对初学者! 02. 现在学Python是不是有点晚了? 一点都不晚,目前全民编程的趋势越来越明显!无论是文科,还是理科,无论是运营还是产品,很多岗位都要求懂编程!打个比分,很多金融保险行业的,普通的员工,放在10年前跟编程八杆子打不到一块去,现在都要懂编程! 为啥呢,因为现在各行各业的数据越来越多,行业竞争越来越激烈,需要提高效率,优化流程,而编程是一个非常好的途径!那为啥是Python呢,因为Python目前是所有的主流语言里面最简单的,最容易上手的语言,C,C++,JAVA,PERL,RUBY,JS这些语言不是太复杂就是太笨重,学习的成本太高了。 网上有一些对比的分析,同样的一个问题,要C要100行,Java 要10行,Python 只要1-2行!听起来有点夸张,但是确实是实话,Python把很多复杂的东西都隐藏了起来,你不需要考虑烦人的指针,不需要考虑垃圾回收机制,更不需要去考虑复杂的语法,因为Python本身的语法有点类似英语。 现在K12的青少年都开始学Python,所以全民编程的趋势风口已经来了,不要在犹豫中错过! 学Python 不敢保证你大赚很多,但是一定不吃亏,绝对是加分项。 03. 资料一堆,网盘都放不下了, 怎么看啊? 很多时候不是我们没有选择,而且选择太多。好比你下班回家饥肠辘辘,家里只有一碗泡面,你不会考虑吃什么,直接端起来就吃了,而且吃的一干二净!为啥你没有选择,饿呀! 但是你走进一家大的自助餐,面对上百种的各种各样的美味菜肴,你的选择太多了,吃海鲜还是烤肉,先吃鸡腿还是先吃牛肉,我是喝橙汁还是西瓜汁,结果每一盘菜都有剩下,每一种都没有吃干净!最后的结果就是小猴子掰玉米,一个都没有学好! focus很重要 建议是根据自己的爱好和工作情况,一个时期选择一个方向研究起来: 我要入门,那么就先看入门的书 我是准备自动化测试的,那么我啃CI方面的书 我是准备要数据分析,做增长黑客的,那么我就开始研究数据驱动运营,研究数据分析, 我是准备进军AI领域,那么就一头专心研究机器学习 但是也有人天生博爱,就是都有兴趣,也可以的如果你的时间和精力都允许的话,你可以先入一个方向,然后再横向扩展到多个方向! 04. 为啥我学了3个月, 还是毫无进展? 学3个月还是毫无进展的人,并不是在少数。这样的情况,主要是因为一般工作中并不直接用到Python,或者不是直接从事Python相关的岗位!或者是没有很强的需求,比如我要找工作,比如我要考证书等等!毕竟没有需求就没有动力,如果现在老板跟你说我们要开发一个新的产品,比如要用某种技术,或者你马上要转岗,对方的岗位明确要求必须会Python,相信你的动力会强很多! 每个人都是有惰性的,编程又是非常枯燥的一件事情,很多事情都是被逼出来的,人只有在有压力的情况下才会跑的更快! 05. 学Python到底能不能找到工作啊? 学Python能找到工作,但是并不是充分必要条件,公司里的工作并不是只要求会Python,只会一门语言,现在大部分的岗位都要求精通一到两门语言,git版本控制,linux的基本操作等等! 你做后端的,我希望你懂Javascript,我希望你懂数据库。 你做自动化测试的,我希望你懂linux,我希望你了解shell 你做数据分析的,我希望你不仅懂Python,还要懂数据库,还要懂很多可视化的工具比如Tableau,excel,还有统计学! 一个工作不是一个单能力组成的,而是要求复合的能力!更不要说你的团队合作,沟通能力,责任心等。所以如果你真的功夫练到家了,你真的懂的很深很多,我相信你一定能找到工作的! 06. 学Python应该怎么看, 怎么练才比较快? 建议以始为终,以目的驱动学习!什么意思,就是完全以需求和目的出发,来反过来指导你的学习! 比如我就是要学会爬豆瓣,我做一个电影排行榜; 比如我就是要搭建一个网站,用Python后端搭起来; 比如我就是要做一篇文章是研究北京的二手房的数据; 比如我就是要做一个简单的推荐系统! 然后把这个任务总体分析需要学哪些内容,需要看什么书,什么资料找到,再把任务分割到每一个小块,并设定目标每天看几个小时,每周完成多少,细化任务!相信这样的科学备战,绝对不会出现,3个月过去,还是在Hello world! 转载于:https://www.cnblogs.com/zfb123-/p/11398851.html

建议看一下,零基础学Python都想问的6个问题,老司机给你两千字解答

最近我们知识星球(千人Python知识星球)里面来了很多小伙伴,来自五湖四海,很都是零基础的同学,非常捉急,想学Python,有很多问题想问,我觉得这些内容非常有用,这里也在公众号里面发一下,希望能帮助到更多的小伙伴! 01. Python怎么学? Python虽然号称非常简单,功能强大!但是再简单,它也是一门编程语言,任何一个编程语言都会包含: 内功,心法和招式,内功心法就是指的算法,数据结构; 招式就是任何一门语言都有的,变量(int/string/float),条件判断(if/else), 循环(for/while),函数(fun),模块(import),文件(I/O),并发(多进程,多线程)等等; 这些招数无论你学C,C++,Java,Python都会有的,只是语法不一样而已 所以学语言需要遵循一点的逻辑,循序渐进,不要上来就啃硬骨头!从容易到难,不要语法都不太熟悉,就去看爬虫,hello world还没有写好,就去看数据分析!最后就是欲速则不达! 那既然学编程有一个过程,有没有什么好的方法? 1).建议一开始的是照着敲代码 就是把别人的例子一个字一个字敲一边,主要选的例子不要太长,以20行内的例子比较适合。 2).开始改代码 等你一个字一个字敲一边之后,要开始改代码,比如把把100改为200,比如把for循环的变量改改,然后等你熟悉了,可以改一下结构,改一下顺序。 3).擦掉重来 等你完成了上面2步,把代码全部删除,然后自己重头开始写出来,一行一行用自己的方法写出来。 所有的作品都是先模仿->再修改->再创造的流程,这招看起来很笨,但是非常有效果!尤其是对初学者! 02. 现在学Python是不是有点晚了? 一点都不晚,目前全民编程的趋势越来越明显!无论是文科,还是理科,无论是运营还是产品,很多岗位都要求懂编程!打个比分,很多金融保险行业的,普通的员工,放在10年前跟编程八杆子打不到一块去,现在都要懂编程! 为啥呢,因为现在各行各业的数据越来越多,行业竞争越来越激烈,需要提高效率,优化流程,而编程是一个非常好的途径!那为啥是Python呢,因为Python目前是所有的主流语言里面最简单的,最容易上手的语言,C,C++,JAVA,PERL,RUBY,JS这些语言不是太复杂就是太笨重,学习的成本太高了。 网上有一些对比的分析,同样的一个问题,要C要100行,Java 要10行,Python 只要1-2行!听起来有点夸张,但是确实是实话,Python把很多复杂的东西都隐藏了起来,你不需要考虑烦人的指针,不需要考虑垃圾回收机制,更不需要去考虑复杂的语法,因为Python本身的语法有点类似英语。 现在K12的青少年都开始学Python,所以全民编程的趋势风口已经来了,不要在犹豫中错过! 学Python 不敢保证你大赚很多,但是一定不吃亏,绝对是加分项。 03. 资料一堆,网盘都放不下了, 怎么看啊? 很多时候不是我们没有选择,而且选择太多。好比你下班回家饥肠辘辘,家里只有一碗泡面,你不会考虑吃什么,直接端起来就吃了,而且吃的一干二净!为啥你没有选择,饿呀! 但是你走进一家大的自助餐,面对上百种的各种各样的美味菜肴,你的选择太多了,吃海鲜还是烤肉,先吃鸡腿还是先吃牛肉,我是喝橙汁还是西瓜汁,结果每一盘菜都有剩下,每一种都没有吃干净!最后的结果就是小猴子掰玉米,一个都没有学好! focus很重要 建议是根据自己的爱好和工作情况,一个时期选择一个方向研究起来: 我要入门,那么就先看入门的书 我是准备自动化测试的,那么我啃CI方面的书 我是准备要数据分析,做增长黑客的,那么我就开始研究数据驱动运营,研究数据分析, 我是准备进军AI领域,那么就一头专心研究机器学习 但是也有人天生博爱,就是都有兴趣,也可以的如果你的时间和精力都允许的话,你可以先入一个方向,然后再横向扩展到多个方向! 04. 为啥我学了3个月, 还是毫无进展? 学3个月还是毫无进展的人,并不是在少数。这样的情况,主要是因为一般工作中并不直接用到Python,或者不是直接从事Python相关的岗位!或者是没有很强的需求,比如我要找工作,比如我要考证书等等!毕竟没有需求就没有动力,如果现在老板跟你说我们要开发一个新的产品,比如要用某种技术,或者你马上要转岗,对方的岗位明确要求必须会Python,相信你的动力会强很多! 每个人都是有惰性的,编程又是非常枯燥的一件事情,很多事情都是被逼出来的,人只有在有压力的情况下才会跑的更快! 05. 学Python到底能不能找到工作啊? 学Python能找到工作,但是并不是充分必要条件,公司里的工作并不是只要求会Python,只会一门语言,现在大部分的岗位都要求精通一到两门语言,git版本控制,linux的基本操作等等! 你做后端的,我希望你懂Javascript,我希望你懂数据库。 你做自动化测试的,我希望你懂linux,我希望你了解shell 你做数据分析的,我希望你不仅懂Python,还要懂数据库,还要懂很多可视化的工具比如Tableau,excel,还有统计学! 一个工作不是一个单能力组成的,而是要求复合的能力!更不要说你的团队合作,沟通能力,责任心等。所以如果你真的功夫练到家了,你真的懂的很深很多,我相信你一定能找到工作的! 06. 学Python应该怎么看, 怎么练才比较快? 建议以始为终,以目的驱动学习!什么意思,就是完全以需求和目的出发,来反过来指导你的学习! 比如我就是要学会爬豆瓣,我做一个电影排行榜; 比如我就是要搭建一个网站,用Python后端搭起来; 比如我就是要做一篇文章是研究北京的二手房的数据; 比如我就是要做一个简单的推荐系统! 然后把这个任务总体分析需要学哪些内容,需要看什么书,什么资料找到,再把任务分割到每一个小块,并设定目标每天看几个小时,每周完成多少,细化任务!相信这样的科学备战,绝对不会出现,3个月过去,还是在Hello world! 当你有很明确的target,会进步很快很快,当然也欢迎加入我们的组织(Python知识星球),里面有很多小伙伴一起学习,会少走一些弯路,短期内也会成长的更快! 一个人学习太枯燥,不如结伴而行! 近期热门: 廖雪峰大神的“大数据分析全栈工程师”课程第8期开始招生 Python心得和技巧: 零基础学了8个月的Python,到底有啥感悟 我珍藏的一些好的Python代码,技巧

LVS的FULLNAT模式

LVS的FULLNAT模式 fullnat模式原理: fullnat模式和nat模式比较类似,客户端的请求和响应都会经过lvs,不同的是nat模式下转换仅存在于目的方向,也就是说客户端的发来的请求经过lvs后,请求的目的ip会转化成rs的ip地址,目的端口会转化成rs的目的端口,而在fullnat模式下,客户端发来的请求的源ip和源端口都会被转换成lvs的内网ip地址和端口,同理对于rs回复的响应,nat模式下,响应的目的ip和目的端口均为客户端的,而fullnat模式下,响应的目的ip和目的端口均为lvs内网的,这样lvs收到这个响应后会将源ip和源端口转换成vip的地址和端口,目的ip和目的端口会被转换成客户端的ip地址和端口,也就是说在nat模式下对于客户端的请求仅发生DNAT转换,对于RS的响应仅发生SNAT转换,而fullnat模式下,在请求和响应上都会发生SNAT和DNAT转换;另一点不同是nat模式下要求lvs的内网ip和rs的ip地址在同一网段,lvs和rs之间需要二层交换设备,而fullnat对于请求和响应都会发生DNAT和SNAT所以lvs的内网ip地址可以和rs不再同一网段,这样lvs和rs之间就需要三层交换设备,所以相对于nat模式,fullnat的部署会更加灵活,它不要求lvs的内网ip和rs的ip在同一网段,下边做实验来模拟一下fullnat模式的过程: 安装过程: fullnat模式的内核版本比较低,所以安装最好在centos6下进行,这里不能使用原来的通过yum安装的ipvsadm,而是需要编译安装经过阿里改造后的,所以需要卸载原来的ipvsadm 1. 下载内核rpm包 wget ftp://ftp.redhat.com/pub/redhat/linux/enterprise/6Server/en/os/SRPMS/kernel-2.6.32-220.23.1.el6.src.rpm 2. 在root目录下 vim ~/.rpmmacros; 并添加 %_topdir /home/pukong/rpms %_tmppath /home/pukong/rpms/tmp %_sourcedir /home/pukong/rpms/SOURCES %_specdir /home/pukong/rpms/SPECS %_srcrpmdir /home/pukong/rpms/SRPMS %_rpmdir /home/pukong/rpms/RPMS %_builddir /home/pukong/rpms/BUILD 这样可以把rpm安装到/home/pukong路径下 3. 安装rpm包,安装rpm-build rpm -ivh kernel-2.6.32-220.23.1.el6.src.rpm cd /home/pukong/rpms/SPECS yum install rpm-build rpmbuild -bp kernel.spec 这样就可以在/home/pukong/rpms/BUILD目录里看到内核的源码了 4. 安装lvs补丁 从http://kb.linuxvirtualserver.org/images/a/a5/Lvs-fullnat-synproxy.tar.gz下载Lvs-fullnat-synproxy.tar.gz然后解压,将解压后的里边的lvs-2.6.32-220.23.1.el6.patch补丁拷贝到/home/pukong/rpms/BUILD/路径下,并执行patch -p1<lvs-2.6.32-220.23.1.el6.patch命令 5. 安装依赖并在/home/pukong/rpms/BUILD目录里编译安装内核 yum install -y xmlto gcc-c++ rpm-build patchutils asciidoc elfutils-libelf-devel zlib-devel binutils-devel newt-devel python-devel hmaccalc perl\(ExtUtils::Embed\) rng-tools lrzsz openssl-devel popt-devel make

LVS的NAT模式

上次总结了DR模式的转发流程这次模拟一下LVS的NAT模式来抓包分析一下流程 LVS NAT原理 类似于防火墙的私有网络结构,Director Server作为所有服务器节点的网关,即作为客户端的访问入口,也是各节点回应客户端的访问出口,其外网地址作为整个群集的VIP地址,其内网地址与后端服务器Real Server在同一个物理网络,Real Server必须使用私有IP地址。 数据包流向分析: 用户发送请求到Director Server,请求的数据报文(源IP是CIP,目标IP是VIP)到达内核空间。 内核空间判断数据包的目标IP是本机,此时IPVS比对数据包请求的服务是否为集群服务,若是,修改数据包的目标IP地址为后端服务器IP,重新封装数据包(源IP为CIP,目标IP为RIP),然后选路将数据包发送给Real Server。 Real Server比对发现目标IP是本机的IP,重新封装报文(源IP为RIP,目标IP为CIP)发回给Director Server。 Director Server重新封装数据包,将源IP地址修改为自己的VIP地址,然后响应给客户端。 此时报文的源IP为VIP,目标IP为CIP。 NAT模型的特点 (1)RS必须使用私有IP地址,网关指向DIP。 (2)DIP与RIP必须在同一网段内。 (3)DS作为所有服务器节点的网关,也就是说请求和响应报文都需要经过Director Server。 (4)支持端口映射,高负载场景中,Director Server压力比较大,易成为性能瓶颈。 实验环境:GNS3 实验拓扑: 本拓扑中,内网网段是192.168.1.0/24,外网网段是192.168.2.0/24两个RS的ip地址分别是192.168.1.2和192.168.1.3,lvs的内网ip地址为192.168.1.1,外网ip是192.168.2.1,client的ip为192.168.2.2 环境搭建: 1. 按照拓扑所示在各个虚拟机上配置ip地址 lvs RS1 RS2 client 2. 在lvs上配置用iptables配置nat转发 192.168.1.0/24是内网网段,ens37是连接外网的网卡 3. 用ipvsadm添加服务 这里采用简单的轮询算法,-m表示使用nat模式 4. 在RS上添加路由并开启http服务 在client上使用curl命令查看效果 抓包分析过程:(以请求到web2上为例) 在lvs的两侧进行抓包来分析这个过程,在client和lvs之间的链路上抓包结果如下 前三个包是tcp连接建立的三次握手的过程,来看一下第一个syn数据包 可以看到这个数据包的源ip是client的IP,源mac是client的mac,目的ip是lvs的公网ip,目的mac是lvs的外网网卡的mac地址,这个syn数据包在lvs的另一个链路上的结果为 可以看到这个syn数据包的源ip和源端口同样是client的ip,但是目的ip被lvs转换成了web2的IP地址,源mac是lvs的连接内网的网卡的mac地址,目的mac是web2的mac地址,这样交换机会把这个数据包转发给web2,web2收到这个数据包后会返回syn,ack数据包 可以看到这个数据包的源ip是web2的IP地址目的ip是client的ip地址,源mac是web2的mac,目的mac是lvs的内网网卡的mac地址,这个数据包经过lvs后会变成这样 可以看到源ip地址变成了lvs的外网ip地址,目的ip还是client的IP,源mac是lvs的外网网卡的mac地址,目的mac是client的mac地址,这样这个syn,ack数据包就会返回给client,client收到这个数据包后发发送第三次握手请求,整个过程和刚才的过程一样,都是经过lvs后,目的ip地址会变成RS的IP地址,而请求的响应经过lvs后源ip会变成lvs的ip地址,所以整个总结起来如下: (1)客户端请求lvs的公网ip(即VIP) (2)所有的请求经过lvs后目的ip会变成内网RS的ip地址,源ip不变(源ip是客户端的ip),即发生DNAT (3)所有的响应经过lvs后源ip会变成lvs的公网ip地址,目的ip不变(目的ip是客户端的ip),即发生SNAT (4)对于MAC地址的更新过程和三层交换一样,都是经过lvs后把对链路层解封装,然后根据各主机的mac地址对mac地址重新封装,因此可以把lvs比作一个三层交换设备 所以从这个过程来看,lvs的功能=三层交换+对源ip或者目的ip的转换 端口转换: 另外,lvs的nat模式同样支持端口转换,在刚才的实验环境基础上做出如下改变 1. 修改/etc/httpd/conf/httpd.conf改变web1和web2的http服务的端口 然后用systemctl restart httpd命令重启http服务 2. 改变ipvsadm注册的服务,将vip的80端口关联到RS的8080端口 改变之后,在client上使用curl进行请求发现还是可以进行的 这说明lvs的nat模式支持端口转换,来抓包看一下这个过程,同样以请求到web2为例,首先client还是发送syn数据包 这个数据包和没有使用端口转换的情况是一样的,经过lvs的转换后数据包会变成这样 可以看到这个数据包的源ip还是不变,目的ip变成了web2的ip地址,源端口不变还是客户端的端口,但是目的ip已经转换成了8080,也就是变成了RS的开放的http服务的端口,这样这个数据包可以被RS来处理,RS收到这个syn数据包后会返回如下syn,ack数据包

LVS的DR模式

一、负载均衡LVS基本介绍 LVS是 Linux Virtual Server 的简称,也就是Linux虚拟服务器。这是一个由章文嵩博士发起的一个开源项目,它的官方网站是 http://www.linuxvirtualserver.org。 LVS是Linux内核标准的一部分。LVS是一个实现负载均衡集群的开源软件项目,通过 LVS 的负载均衡技术和 Linux操作系统可以实现一个高性能高可用的 Linux 服务器集群,它具有良好的可靠性、可扩展性和可操作性。 LVS架构从逻辑上可分为调度层、Server集群层和共享存储。LVS实际上相当于基于IP地址的虚拟化应用。 二、LVS的组成 LVS 由2部分程序组成,包括 ipvs 和 ipvsadm。 ipvs(ip virtual server):工作在内核空间,是真正生效实现调度的代码。 ipvsadm:工作在用户空间,负责为ipvs内核框架编写规则,定义谁是集群服务,而谁是后端真实的服务器(Real Server) 三、LVS相关术语 DS:Director Server, 指的是前端负载均衡器节点。 RS:Real Server, 后端真实的工作服务器。 VIP:向外部直接面向用户请求,作为用户请求的目标的IP地址。 DIP:Director Server IP, 前端负载均衡器IP地址,主要用于和内部主机通信。 RIP:Real Server IP, 后端服务器的IP地址。 CIP:Client IP, 访问客户端的IP地址 四、LVS的工作模式介绍 LVS负载均衡常见的有三种工作模式,分别是地址转换(简称NAT模式)、IP隧道(简称TUN模式)和直接路由(简称DR模式),其实企业中最常用的是 DR 实现方式,下面总结 DR模式的原理和特点 五、LVS的DR模式 DR模式是通过改写请求报文的目标MAC地址,将请求发给真实服务器的,而真实服务器响应后的处理结果直接返回给客户端用户。但是要求调度器LB与真实服务器RS都有一块网卡连接到同一物理网段上,必须在同一个局域网环境。DR模式是互联网使用比较多的一种模式。 Director Server作为群集的访问入口,但不作为网关使用,后端服务器池中的Real Server与Director Server在同一个物理网络中,发送给客户机的数据包不需要经过Director Server。为了响应对整个群集的访问,DS与RS都需要配置有VIP地址。 数据包流向分析 用户发送请求到Director Server,请求的数据报文(源IP是CIP,目标IP是VIP)到达内核空间。由于DS和RS在同一个网络中,所以是通过二层数据链路层来传输。 内核空间判断数据包的目标IP是本机IP,此时IPVS比对数据包请求的服务是否为集群服务,若是,重新封装数据包,修改源MAC地址为DIP的MAC地址,目标MAC地址为RIP的MAC地址,源IP地址与目标IP地址没有改变,然后将数据包发送给Real Server。 RS发现请求报文的MAC地址是自己的MAC地址,就接收此报文,重新封装报文(源IP地址为VIP,目标IP为CIP),将响应报文通过lo接口传送给eth0网卡然后向外发出。 RS直接将响应报文传送到客户端。 LVS-DR模型的特点 1.RS和DS必须在同一个物理网络中。 2.RS可以使用私有地址,也可以使用公网地址,如果使用公网地址,可以通过互联网对RIP进行直接访问。 3.所有的请求报文经由Director。 Server,但响应报文必须不能经过Director Server。

基于DPDK实现二层交换

上次分析了DPDK的l2fwd的源码,l2fwd实现了相邻两个端口之间的二层交换,入端口和出端口的关系是通过一个数组来实现的,从某一个端口进只能从一个固定的端口出。于是想到对其转发的规则做出修改就能实现一个二层交换机,也就是说在l2fwd中创建一个mac表,这个表中存储了每一个端口上的主机的mac地址,然后当l2fwd收到一个数据包的时候就能够根据mac表将数据包从对应的端口转发出去从而实现了二层交换的功能,当然这个mac表的内容是需要l2fwd根据实际网络来自学习的,结合上次总结的两个主机在二层交换情况下的通信过程可以知道,交换机是根据主机的ARP数据包的源mac地址来学习主机的位置的,所以只要按照这样的逻辑对l2fwd改造就能实现一个二层交换机。 实现步骤 1. 创建mac表 mac表主要记录了每一个端口上的主机的mac地址,因此可以创建如下的结构体来实现 // 添加结构体 #define MAX_HOST_PER_PORT 100 struct host_in_this_port{ unsigned nb_host; // host的数量 struct ether_addr host_list[MAX_HOST_PER_PORT]; // mac地址的数组 }; struct host_in_this_port all_port_host[RTE_MAX_ETHPORTS];// 创建一个host_in_this_port结构体数组 存放这个端口的host列表 并且要初始化这个结构体的一个全局的数组来存放每一个端口上的主机的mac地址 2. 交换机自学习过程 自学习过程也就是填充刚刚创建的all_port_host数组的过程,根据二层交换的过程,对主机的位置的学习主要是根据ARP包的源地址来实现的,也就是说在哪个端口上收到了ARP包,那么这个ARP包的源MAC所对应的主机的位置就在这个端口上,代码如下 struct ether_addr eth_src = eth->s_addr; struct ether_addr eth_dst = eth->d_addr; uint16_t type = eth->ether_type; struct host_in_this_port *this_port = NULL; if (type = 0x0806) { // 根据数据链路层的源mac学习每一个主机的位置 // 将这个源mac添加到portid的host_in_this_port的结构体中 this_port = &all_port_host[portid]; int host_nb = this_port->nb_host; int count = 0; int exist = 0; for (count = 0; count < host_nb; count++) { if (isMacAddrEqual(this_port -> host_list[count], eth_src)) { exist = 1; break; } } if (exist == 0) { this_port->host_list[this_port->nb_host] = eth_src; this_port->nb_host++; } else { exist = 0; } } 首先从数据链路层的头部获取ethernet的类型,如果是ARP包就执行这个学习的过程,首先取出这个数据包的源MAC地址,然后从对应的端口的host_in_this_port结构体中去寻找是否之前已经学习到了这个mac地址,如果没有的话就将这个mac地址添加到这个结构体中

安装软件时提示“此产品的配置信息已损坏。请联系您的技术支持”的解决办法

实例 比如安装深容医学文献的SCITranslate v11.0时,由于先前一直在用V8.0,先前直接删除安装文件夹想安装V10.0,即便卸载并清空了注册表里面的所有与SCITranslate 有关的项目一直没法安装上,V11.0也无法安装,点老用户直接运行的SCITranslate11.exe无法安装, 点新用户的安装程序msi显示如下: 解决方案 查看系统日志:双击控制面板图标,打开控制面板,选择管理工具 → 打开管理工具---组件服务→打开 组件服务---事件查看器(本地)---window 日志→点开应用程序里面日志列表 查看系统日志----应用程序里面的日志列表。打开你安装SCITranslate时出现的错误。可以看到里面的确切消息。如下图,我这里提示的是:在项 HKU\S-1-5-21-272378374-3645185259-3561292323-7292\Software\Microsoft\Installer\Products\A789085C0BA9B6A4B9A8C7A9857FC2DA\SourceList 中出现意外值或缺少值: (名称: PackageName,值: )。那么你就可以根据你的相关提示删除错误的注册表项。就是注册表里搜索“A789085C0BA9B6A4B9A8C7A9857FC2DA”,我这里删除了A789085C0BA9B6A4B9A8C7A9857FC2DA这个注册表项就可以正常安装了。

基于docker使用elasticsearch-dump,es数据导入导出

1.拉去dump镜像 [root@localhost ~]# docker pull taskrabbit/elasticsearch-dump 2.相关实例 1.创建文件存放路径 [root@localhost ~]# mkdir -p /data/ 2.将索引数据备份到文件 [root@localhost ~]# docker run --rm -ti -v /data/:/tmp taskrabbit/elasticsearch-dump --input=http://192.168.1.2:9200/my_index --output=/tmp/dump.json --type=data 3.将旧环境数据导入到新环境 [root@localhost ~]# docker run --rm -ti elasticsearch-dump --input=http://192.168.1.2:9200/my_index --output=http://192.168.1.2:9200/my_index --type=data 3.将文件导入到es数据库中 [root@localhost ~]# docker run --rm -ti -v /data:/tmp taskrabbit/elasticsearch-dump --input=/data/dump.json --output=http://192.168.1.2:9200/my_index --type=data 官方文档:https://github.com/taskrabbit/elasticsearch-dump?utm_source=dbweekly&utm_medium=email

java与c语言的内存对比

问题来源 由于本人经常用java进行开发,对c语言的开发不是很熟悉,在用c语言写一个返回数组的函数的时候踩到了坑,具体问题如下: 这是一个普通的java函数,用来返回一个数组:用java语言在一个方法中创建一个数组,并进行初始化,编译以后可以运行通过 public class GetArray { public static int[] getArray(){ int[] a = {1,2,3,4,5}; return a; } public static void main(String[] args){ int[] ret = getArray(); for(int i = 0;i<5;i++){ System.out.println(i); } } } 用c语言写同样类似的函数,在函数中创建并初始化一个数组,编译完成后运行这个程序会发生段错误: #include<stdio.h> int* getArray(){ int a[] = {1,2,3,4,5}; return a; } void main(){ int *ret = getArray(); for(int i = 0; i < 5 ;i ++){ printf("%d\n",ret[i]); } } 这个问题产生的原因是java内存和c内存的布局以及每个区域存放的内容的不同而造成的,为了探明原因,首先来回顾一下java内存和c内存的布局。 Java内存: 由于Java程序是交由JVM执行的,所以我们在谈Java内存区域划分的时候事实上是指JVM内存区域划分。下图是java程序的执行流程。 首先Java源代码文件(.java后缀)会被Java编译器编译为字节码文件(.class后缀),然后由JVM中的类加载器加载各个类的字节码文件,加载完毕之后,交由JVM执行引擎执行。在整个程序执行过程中,JVM会用一段空间来存储程序执行期间需要用到的数据和相关信息,这段空间一般被称作为Runtime Data Area(运行时数据区),也就是我们常说的JVM内存。因此,在Java中我们常常说到的内存管理就是针对这段空间进行管理(如何分配和回收内存空间)。Runtime Data Areas的分区如下:

利用Ajax与后台传输数据的三种方式

1.把数据放到url中传递 js: <code> var id = $("#id").val(); $.ajax({ type: "POST", url: "/IFTree/people/getPeopleById/"+id,//参数放在url中 success:function(data){ alert(data); }, error:function(xhr, textStatus, errorThrown) { } }); </code> 后台: <pre><code> @RequestMapping(value = "getPeopleById/{id}") @ResponseBody public Map<String, Object> getPeopleById(@PathVariable("id") int id) { //@PathVariable("id") 如果参数名与url定义的一样注解可以不用定义("id") System.out.println(id); Map<String, Object> map = new HashMap<String, Object>(); return map; } } </code></pre> 2.把数据放到data中 js: <code> var id = $("#id").val(); $.ajax({ type: "POST", url: "/IFTree/people/getPeopleById", data: {id:id}, success:function(data){ alert(data.result); }, error:function(xhr, textStatus, errorThrown) {

【C++ 语言】异常 ( 抛出字符串异常 | 抛出异常对象 | 抛出任意对象 | 抛出自定义异常 )

文章目录 I 异常处理II 字符串异常III 异常对象IV 抛出任意类型对象V 自定义异常VI 异常相关代码 I 异常处理 1. 异常处理 : 使用 " try{}catch(){} " 将抛出异常的代码包起来 , 注意将可能抛出异常的代码包裹在 try 后的大括号中 , 将异常处理逻辑放在 catch 后的大括号中 ; ① 包含可能出现异常的代码 : 在 try 代码块中编写可能抛出异常的代码 ;② 捕获异常 : catch 后的括号中注明可能捕获的异常类型 ;③ 针对捕获的异常进行处理 : 在 catch() 后的代码块中编写异常处理代码 ; 2. 异常处理代码示例 : // 2. 捕获异常对象 // 其中调用 exception 的 what() 方法即可获得异常信息 // 可以获取异常信息 , 即构造函数中传入的字符串 try { throwException(); } catch (exception &e) { cout << "

vue.js element-ui动态改变组件placeholder的值

element-ui根据条件动态改变组件placeholder的值 假设有一个需求,一个下拉框select,如果无选项,则显示 暂无可用VPC,请先申请 ,如果有选项, 则显示 请选择 利用vue.js 的v-bind属性,将placeholder绑定一个动态参数,如下: :placeholder="vpcPlaceholder" 该动态参数通过某个条件计算而来,因此将该参数写到computed()中最为合理,如下代码: // placeholder动态绑定 <el-select v-model="form.vpc" :placeholder="vpcPlaceholder" @change="changeVPC"> <el-option v-for="item in attrs.vpc" :key="item.value" :label="item.label" :value="item.value"> </el-option> </el-select> // placeholder文字根据条件生成 computed: { vpcPlaceholder() { return this.attrs.vpc.length ? "请选择" : "暂无可用VPC,请先申请" } }

Latex两端对齐

在使用minipage环境的时候,发现centerline在子图情况下不会自动换行。如果将centerline换做center,倒是能够自动换行了,但正如其名字所体现的,其会自动居中,在子图解释文字无法写满一行的情况下,这样会显得很难看。如果换做 \begin{flushleft} 左齐正文 \end{flushleft} 则能够左对齐,但是每行右端又有可能出现空格。最终比较完美的解决方案是使用\usepackage{ragged2e},然后在需要两端对齐的文字前面添加\justifying即可。亲测可行。

Django-Migration admin.0001_initial is applied before its dependency accounts.0001_initial on....

错误: django.db.migrations.exceptions.InconsistentMigrationHistory: Migration admin.0001_initial is applied before its dependency accounts.0001_initial on database ‘default’. 如果我们一开始使用的是django原生模型User,在后来的开发中,我们在其他app中想使用自己的User模型,在我们makemigrations时,就会出现以上错误 解决方法: 一: 删除除了auth_user表以外的所有数据库删除与用户有关app下的migrations文件夹重新makemigrations + migrate 缺点:这个方法相当于从头到尾更新重建了我们的数据模型,需要我们备份数据库中的数据 二: 在setttings文件中注释掉:django.contrib.admin在urls文件中注释掉:path('admin/', admin.site.urls)重新migrate将刚才注释的代码加回去重新migrate

分组序列@GroupSequenceProvider、@GroupSequence控制数据校验顺序,解决多字段联合逻辑校验问题【享学Spring MVC】

每篇一句 不要像祥林嫂一样,天天抱怨着生活,日日思考着辞职。得罪点说一句:“沦落”到要跟这样的人共事工作,难道自己身上就没有原因? 前言 本以为洋洋洒洒的把Java/Spring数据(绑定)校验这块说了这么多,基本已经算完结了。但今天中午一位热心小伙伴在使用Bean Validation做数据校验时上遇到了一个稍显特殊的case,由于此校验场景也比较常见,因此便有了本文对数据校验补充。 关于Java/Spring中的数据校验,我有理由坚信你肯定遇到过这样的场景需求:在对JavaBean进行校验时,b属性的校验逻辑是依赖于a属性的值的;换个具象的例子说:当且仅当属性a的值=xxx时,属性b的校验逻辑才生效。这也就是我们常说的多字段联合校验逻辑~ 因为这个校验的case比较常见,因此促使了我记录本文的动力,因为它会变得有意义和有价值。当然对此问题有的小伙伴说可以自己用if else来处理呀,也不是很麻烦。本文的目的还是希望对数据校验一以贯之的做到更清爽、更优雅、更好扩展而努力。 需要有一点坚持:既然用了Bean Validation去简化校验,那就(最好)不要用得四不像,遇到问题就解决问题~ 热心网友问题描述 为了更真实的还原问题场景,我贴上聊天截图如下: 待校验的请求JavaBean如下: 校需求描述简述如下: 这位网友描述的真实生产场景问题,这也是本文讲解的内容所在。 虽然这是在Spring MVC条件的下使用的数据校验,但按照我的习惯为了更方便的说明问题,我会把此部分功能单摘出来,说清楚了方案和原理,再去实施解决问题本身(文末)~ 方案和原理 对于单字段的校验、级联属性校验等,通过阅读我的系列文章,我有理由相信小伙伴们都能驾轻就熟了的。本文给出一个最简单的例子简单"复习"一下: @Getter @Setter @ToString public class Person { @NotNull private String name; @NotNull @Range(min = 10, max = 40) private Integer age; @NotNull @Size(min = 3, max = 5) private List<String> hobbies; // 级联校验 @Valid @NotNull private Child child; } 测试: public static void main(String[] args) { Person person = new Person(); person.

java代码实现向有kerberos认证的kafka中发送数据

java代码实现向有kerberos认证的kafka中发送avro格式数据 1.在idea中创建一个maven工程 1.1 pom.xml 内容 <dependencies> <dependency> <groupId>org.apache.kafka</groupId> <artifactId>kafka_2.11</artifactId> <version>1.0.0</version> </dependency> <dependency> <groupId>org.apache.avro</groupId> <artifactId>avro</artifactId> <version>1.8.0</version> </dependency> </dependencies> <build> <plugins> <plugin> <artifactId>maven-compiler-plugin</artifactId> <configuration> <source>1.8</source> <target>1.8</target> <encoding>utf8</encoding> </configuration> </plugin> <plugin> <artifactId>maven-assembly-plugin</artifactId> <configuration> <appendAssemblyId>false</appendAssemblyId> <descriptorRefs> <descriptorRef>jar-with-dependencies</descriptorRef> </descriptorRefs> <archive> <manifest> <!-- 此处指定main方法入口的class --> <mainClass>com.test.kafkaProducer</mainClass> </manifest> </archive> </configuration> <executions> <execution> <id>make-assembly</id> <phase>package</phase> <goals> <goal>assembly</goal> </goals> </execution> </executions> </plugin> </plugins> </build> 1.2 创建一个AvroKafkaProducter的类 package com.test; import org.apache.avro.Schema; import org.apache.avro.generic.GenericData; import org.apache.avro.generic.GenericDatumWriter; import org.apache.avro.generic.GenericRecord; import org.apache.avro.io.BinaryEncoder; import org.

解决1235 - This version of MySQL doesn't yet support 'LIMIT & IN/ALL/ANY/SOME subquery'

出现场景:使用子查询时 这版本的 MySQL 不支持使用 LIMIT 子句的 IN/ALL/ANY/SOME 子查询 意味着下列查询不能正确的执行 select * from my_table where id in (select id from my_table limit 10) 解决方案: select * from my_table where id in (select t.id from (select * from my_table limit 10)as t) 再套一次查询就OK了 说在最后的话:编写实属不易,若喜欢或者对你有帮助记得点赞+关注或者收藏哦~

概率笔记12——多维正态分布的最大似然估计

我们在前面的章节中见识过二维正态分布,(X,Y)服从参数为μ1, μ2, σ1, σ2, ρ的二维正态分布,记作(X, Y)~N(μ1, μ2, σ1, σ2, ρ),它的密度函数: 其中μ1是第1维度的均值,σ12是第1维度的方差,ρ是将两个维度的相关性规范到-1到+1之间的统计量,称为样本的相关系数,定义为: 对于二维正态随机变量(X,Y),X和Y相互独立的充要条件是二者的协方差为0,也就是参数ρ=0。由于一维随机变量没有是否独立一说,ρ一定是0,因此没有在一维随机变量的正态分布中体现ρ。 下图是一个标准二维正态分布和其在x-z,y-z平面的投影: 多维正态分布 现在推广到多维,为了便于表达,我们用向量的形式表示随机变量和参数,对于n维随机变量: 这里只考虑所有维度变量互相独立的情况,即ρ=0的情况,此时密度函数可表示为: 上面的结果告诉我们,在各维度相互独立的情况下,多维正态分布的概率密度其实就是各个维度的正态分布密度函数的乘积。 在①中: σi2表示xi的方差,如此看来,中间那个矩阵实际上是协方差矩阵的逆矩阵: 根据行列式的性质,上三角矩阵的行列式等于主对角线所有元素的乘积,斜对角矩阵当然也是一个上三角矩阵,因此协方差矩阵的行列式是: 将②、③代入①中,得到最终结果: 最大似然估计量 n维相互独立的随机变量x服从正态分布: 在求最大似然估计量时和一维随机变量有所区别,根据上一节的最终结果: 假设有m个可观察样本,那么最大似然函数是: 其对数似然函数是: 其中m和n是已知的,C 是一个常数。 求极值需要对μ和∑求偏导: μ和∑是矩阵,涉及到矩阵的求导法则。先看对μ的求导,lnL由3个因子组成,只有一个因子含有μ,因此: 其中: 上式中: 因此: 将该结论代入∂lnL/∂μ中: μ和∑是矩阵,根据矩阵的求导法则: 因为∑-1是一个对称矩阵,因此: 根据矩阵的求导法则: 将a1,a2代入∂lnL/∂μ 中: 再看对∑求偏导: ∑和∑-1都是实对称矩阵,根据矩阵的求导法则,当A是实对称矩阵时: 再看b2。设ωpq是∑第p行第q列的元素,Epq是一个第p行第q列元素为1,其它元素全为0的矩阵,E与∑-1同阶。根据矩阵的求导公式: 已经知道了∑-1是一个对称矩阵,矩阵乘法满足结合律,在不改变矩阵顺序的条件下可以任意加括号: 其中(∑-1(x(i)-μ))T是一个1*n的矩阵,(∑-1(x(i)-μ))Tp表示矩阵中的第p个元素;∑-1(x(i)-μ)是一个n*1的矩阵,(∑-1(x(i)-μ))q表示矩阵中的第q个元素。将该结论推广到矩阵对矩阵的的求导,根据矩阵对矩阵的求导公式: 其中: 在A1中,(∑-1(x(i)-μ))T是一个1*n的矩阵,(∑-1(x(i)-μ))Ti表示矩阵中的第i个元素,是一个标量;∑-1(x(i)-μ)是一个n*1的矩阵,(∑-1(x(i)-μ))i表示矩阵中的第i个元素,也是一个标量,因此: 终于可以求得b2了: 现在可以看看最终的似然函数: I是单位矩阵,∑-1I=∑-1: 等号两侧同时左乘∑: 两侧同时右乘∑: 最终解得: 最终结论,多维正态分布的最大似然估计量是: 作者:我是8位的 出处:http://www.cnblogs.com/bigmonkey 本文以学习、研究和分享为主,如需转载,请联系本人,标明作者和出处,非商业用途! 扫描二维码关注公作者众号“我是8位的”

java内存分配参数设置

#heap 内存 JAVA_OPTS="$JAVA_OPTS -Xmx14336m —最大堆容量 -Xms14336m —堆内存初始大小(最大堆容量和初始堆容量大小相等则表示java堆不可扩展) -XX:PermSize=256m —方法区初始容量 -XX:MaxPermSize=512m —最大方法区容量 (可以通过PermSize和MaxPermSize限制方法区大小) -XX:MaxDirectMemorySize=256m” — 直接内存(不指定时默认与最大堆容量Xmx一样) (直接内存并不是虚拟机运行时数据区的一部分,也不是java虚拟机规范中定义的内存区域。) nohup java -Xms800m -Xmx2048m -XX:PermSize=256m -XX:MaxPermSize=2048m -XX:MaxNewSize=512m -jar xxxx.jar 转载于:https://my.oschina.net/u/2842177/blog/3094600

SpringBoot+Shiro权限控制

最近一段时间刚好遇到了权限控制的问题,今天写一下自己的感悟与理解。 首先说一下什么是Shiro,ApacheShiro是一个功能强大、灵活的,开源的安全框架,它内部集成了很多安全机制,只需要我们配置,利用就好。下面说一下Shiro架构的三个主要的理念: Subject:当前用户,Subject 可以是一个人,但也可以是第三方服务、守护进程帐户、时钟守护任务或者其它–当前和软件交互的任何事件。 SecurityManager:管理所有Subject,SecurityManager 是 Shiro 架构的核心,配合内部安全组件共同组成安全伞。 Realms:用于进行权限信息的验证,我们自己实现。Realm 本质上是一个特定的安全 DAO:它封装与数据源连接的细节,得到Shiro 所需的相关的数据。在配置 Shiro 的时候,你必须指定至少一个Realm 来实现认证(authentication)和/或授权(authorization) 了解了这三个重要的理念之后就开始说一下项目的整体思路吧: 项目通过赋予角色权限增加角色的访问权利,又通过赋予用户不同的角色来控制登录用户所拥有的权限。 首先肯定是必须要用到shiro框架给我集成好的一些方法和技术,所以就开始shiro的配置,shiro对权限的控制使用的是过滤器,还必须实现登录认证、权限控制的方法以及通过realm来获取数据。配置好这些之后呢,就可以开始代码的编写了,这里还需要强调几个点: 第一呢,为了保证框架的性能,使用的是redis进行缓存, 第二呢,给密码加密的方法是使用了MD5,为了保证登录的时候顺利通过登录认证,必须在用户增加的时候给密码进行加密,在登录认证的时候也需要给密码加密以验证数据库中的密码。 Shiro能做的东西很多,这里我只是进行了简单的登录认真和权限控制,下面详细说一下代码吧,相信结合上面我的思路大家可以更清晰的学习代码。 `首先是pom依赖,里面有挺多不认识的依赖的话,多上网查一下,有助于理解代码 <?xml version="1.0" encoding="UTF-8"?> 4.0.0 <groupId>com.study</groupId> <artifactId>springboot-shiro</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>jar</packaging> <name>springboot-shiro</name> <description>Demo project for Spring Boot</description> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.5.2.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <java.version>1.8</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency> <dependency> <groupId>com.

【C++ 语言】vector 容器 ( 容器分类 | vector 声明 | vector 初始化 | vector 容器元素增删查改 )

文章目录 序列式容器vector 简介vector ( 向量 ) 头文件vector ( 向量 ) 声明及初始化vector ( 向量 ) 添加元素vector ( 向量 ) 查询元素vector ( 向量 ) 删除元素vector ( 向量 ) 容量改变vector ( 向量 ) 涉及到的运算符重载vector ( 向量 ) 相关源码 序列式容器 1. 常用的数据结构 ( 容器 ) 及分类 : 数组 , 链表 , 树 , 栈 , 队列 ; 容器可以分为序列式 , 与关联式 两种 ; 2. 序列式容器 : 序列式容器的元素排列的顺序与元素本身无关 , 其先后顺序由元素添加到容器中的顺序决定 ; 3. 常用的序列式容器 : C++ 的 STL ( 标准模板库 ) , 包括 vector ( 向量 ) , list ( 列表 ) , queue ( 队列 ) , dequeue ( 双向队列 ) , stack ( 栈 ) , priority_queue ( 优先队列 ) ;

如何判断一维数据集服从何种分布

KL散度 KL 散度是一种衡量两个概率分布的匹配程度的指标,两个分布差异越大,KL散度越大。 定义: 其中 p(x) 是真实分布,q(x)是目标分布(建模目标分布),如果两个分布完全匹配,那么 第一组:数据集为采集100个人的年龄,为以下表格所示,我们使用KL散度去研究最符合的分布类型。 age012345678910总数count3671113181511754100 尝试1:使用均匀分布建立模型 可视化为:黄色的为建立的目标均匀分布模型,与蓝色真实分布的对比。 尝试2:使用高斯分布建立模型 可视化为:(红色虚线是相同与拟合的一条正态分布曲线,蓝色条形图为概率密度): 计算分析 : 如何判断真实分布更接近均匀分布还是高斯分布,用肉眼看是很不准确的,用KL散度来衡量真实分布去匹配目标分布所损失的信息量。所以能够将模型量化去比较从而判断出接近哪种分布。 1、计算与均匀分布的KL散度: import numpy as np import math count=np.array([3,6,7,11,13,18,15,11,7,5,4]) count_rate=count/100 balance_rate=1/11 sum=0 for i in range(11): sum+=count_rate[i]*math.log(count_rate[i]/balance_rate) print(sum) 计算结果为:0.12899493763053263 2、计算与高斯分布的KL散度: def gaosi(x): mu=5.03 sigma=2.4349743325135895 t1=1/(sigma*math.sqrt(2*math.pi)) t2=((x-mu)**2)/(2*sigma*sigma) return math.exp(-1*t2)*t1 count=np.array([3,6,7,11,13,18,15,11,7,5,4]) count_rate=count/100 sum=0 for i in range(11): sum+=count_rate[i]*math.log(count_rate[i]/gaosi(i)) print(sum) 计算结果为:0.03997441345364968 结论: 在只考虑均匀分布模型与高斯分布模型的情况下,用本身去拟合目标模型时,匹配高斯分布所损失的信息量最少,计算发现该数据集的分布更符合高斯分布。

数据链路层和传输层可靠传输

一个ip包经过的数据链路层实际上是分成很多段的,数据链路层的纠错只能逐端纠错,而在中间点(路由器、三层交换机)上丢弃的包是不能被数据链路层发现的。

Python核心编程正则表达式练习题1-1 识别后续的字符串:“bat”、“bit”、“but”、“hat”、“hit”或者“hut”...

# 1-1 识别后续的字符串:“bat”、“bit”、“but”、“hat”、“hit”或者“hut”。 1 import re 2 3 # 正则表达式,|元字符表示选择“或” 4 # character = 'bat|bit|but|hat|hit|hut' # 方法一 5 # character = '[bh][aiu]t' # 方法二 6 character = '(b|h)(a|i|u)t' # 方法三 7 8 # 测试数据 9 data = 'bat' 10 data1 = 'bit' 11 data2 = 'but' 12 data3 = 'hat' 13 data4 = 'hit' 14 data5 = 'hut' 15 16 # 测试开始 17 m = re.match(character, data) 18 m1 = re.

安卓开发 自定义TextView 去除默认内边距

一.搜到的大部分的解决办法 1.网上方法的效果 在xml文件中对TextView设置: includeFontPadding=false 加上以上属性之后,文本的高度明显变小了,但是没有达到我们预想的效果(文字紧贴边框),而是在上下留了一部分距离。 具体效果可以查看第二部分中的对比图 2.失效的原因 在了解这个原因前需要对TextView中文本的绘制有一点了解,具体查看文末参考文章中启航大佬的介绍文章。 对应下图,top和bottom之间的高度,就是默认的TextView的高度。 includeFontPadding=false属性取消的是top和ascent之间,bottom和descent之间的两个空白区域。 但是也看的出来,在ascent和descent中间的文字,距离两条线还是有一定距离,这也就是在设置includeFontPadding=false属性后继续留着的空白部分。 (图来自启航大佬的文章) 具体从源码中可以看出这个过程 查看TextView的源码中查找mIncludePad属性,发现都是进到一个BoringLayout中 在其中查找includepad,在其init()方法中找到以下部分。 其中metrics为系统提供的用于查询top,ascent,descent,bottom四个属性的一个对象 二.自定义view实现效果 1.最终效果对比图 中间的为普通的TextView 2 自定义的思路 首先系统提供了一个用于检测包裹住的文字所需最小的矩形的方法。 /** * 获取指定字符串所对应的最小矩形,以(0,0)点所在位置为基线 * @param text 要测量最小矩形的字符串 * @param start 要测量起始字符在字符串中的索引 * @param end 所要测量的字符的长度 * @param bounds 接收测量结果 */ public void getTextBounds(String text, int start, int end, Rect bounds); 自定义View onMeasure 中把宽高设置为上述最小矩形的宽高 onDraw 由于宽高被重新设置了,所以canvas中原点要进行位移,才能使得文本正常显示。 3 具体代码 public class MyNoPaddingTextView extends android.support.v7.widget.AppCompatTextView { private Rect minRect; public MyNoPaddingTextView(Context context) { super(context); } public MyNoPaddingTextView(Context context, @Nullable AttributeSet attrs) { super(context, attrs); } public MyNoPaddingTextView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.

超级强大的五个资源网站 想要的资源都有

还在为找不到资源而烦恼吗,今天在这里和大家分享几个资源超丰富的网站,什么电影、音乐、学习资源,你想要的这里都有。 1、草名电影 宅人必备的影视资源,你除了可以看到最新的电视剧,刚上映没几天的电影也可以看,一个更新频率比较高的在线影院,网站内的影视资源免费可以选择在线观看和下载。 2、91听歌网 有不少小伙伴比较喜欢一些比较经典的歌,但是现在要找的话也是很难了。在这个网站里我们就可以轻易的找到自己想要听的经典老歌,很是方便。 3、Wiki How 这是一个可以找到很多自学资源网站,这里的学习资源不仅有工作方面的,还有很多关于生活方面的,比如一些常用的生活技巧、冷门有趣的知识讲解等等;你可以在这里学习到任何你想要学习的内容,网站是全英文的,全英文不方便浏览的话,直接开启网页翻译即可看到全中文内容。 4、迅捷屏幕录像工具 可以录制各种屏幕视频,录制直播、录制游戏视频、录制教学视频。对这方面感兴趣的朋友可以试一下。 5、Soogif 这个网站除了是一个营销型的网站,其实是一个很好的gif素材网站,会给用户更新最新的表情包,可免费使用,也可以选择自己在下制作表情包,十分有趣。

Fastboot的使用简单教程

大家都知道HTC手机重新启动进入所谓的project模式,就是HBOOT,然后能够进入FASTBOOT界面,在这个界面。我们能够在电脑端能够做非常多事,特别是HBOOT被改动过,假设是ENG S-OFF的能够做的很多其它。就是利用FASTBOOT能够刷入一些分区。 可是有些分区不建议大家使用FASTBOOT。你也刷不进。 手机端分区: 这里的分区主要就是我们常常会使用的分区: 开机启动画面区(splash1):开机第一屏就是这个 数据恢复区(recovery):Recovery所在的分区 内核区(boot):引导分区。就是ROM包boot.img刷入的分区 系统区(system):就是系统存放的分区,也就是ROM包相应的SYSTEM分区,这个分区出厂设置会比較大。可是这个空间是死的,你改动不了。就是说,你400M和100M的ROM包存放的空间都是一样大的。机型不同这个分区厂商设置的不同。 数据缓存区(cache):手机执行后存放缓存的分区 用户数据区(userdata):手机执行后存在的数据分区 FASTBOOT帮助: usage: fastboot [ <option> ] <command> commands: update <filename> reflash device from update.zip flashall "flash boot" + "flash system" flash <partition> [ <filename> ] write a file to a flash partition erase <partition> erase a flash partition getvar <variable> display a bootloader variable boot <kernel> [ <ramdisk> ] download and boot kernel flash:raw boot <kernel> [ <ramdisk> ] create bootimage and flash it devices list all connected devices reboot reboot device normally reboot-bootloader reboot device into bootloader options: -w erase userdata and cache -s <serial number> specify device serial number -p <product> specify product name -c <cmdline> override kernel commandline -i <vendor id> specify a custom USB vendor id 复制代码

display切换元素的可见状态

toggle() 方法切换元素的可见状态。 如果被选元素可见,则隐藏这些元素,如果被选元素隐藏,则显示这些元素。 <ul id="appDown" style="display: none; position: fixed;"> <img src="index/images/androiddownload.png" class="img-rounded" style="width:60px;height:60px;" alt=""> </ul> //APP下载的二维码显示和隐藏切换 function showApp(){ $("#appDown").toggle(); } 转载于:https://my.oschina.net/u/2842177/blog/3093511

使用Adobe Acrobat为PDF文件添加签名(图片+签名)

1、使用Adobe Acrobat打开PDF文件,并切换到工具页,点击证书 2、选择数字签名,然后在文档中要签名的位置上单击并绘制一个区域 3、创建签名证书,点击“签名为:”下拉框,选择 “新建ID” 4、 创建签名图片,点击“外观:”下拉框,并选择“创建新外观” 5、输入第3步创建的证书密码,并选择签名即可。

调制方式OOK

数字调制方式中有一种最简单的调制方式为OOK,on-off keying。通断键控调制方式,也称二进制开关键控,调制原理为根据发射幅度来控制发射的频率,如发射幅度高时,发射载波频率,反之,发射幅度低时,则不发射载波频率,所以这种调制方式的一大特点是低功耗,主要应用在需要电池供电的移动式设备上。仅供参考。

关于kafka的topic的授权和消费的问题汇总

关于kafka的topic的授权问题的汇总 在具有kerberos的集群上对其他用户相应的topic授权的时候主要有以下几点 如果超级用户为kafka这时候需要切换到kafka安装的一个节点上,进行kinit验证的操作 例如:kinit –kt /etc/kafka/conf/kafka.keytab kafka 需要创建要对topic进行操作的用户(读,写或者读和写都具备) 1.1添加的一个普通用户: 在管理员的状态下使用addprinc,delprinc,modprinc,listprincs命令。使用?可以列出所有的命令。 kadmin.local: addprinc –pw 111111 user01 kadmin.local: delprinc user01 kadmin.local: listprincs 说明: addprinc :生成kerberos用户,语法为addprinc –pw 密码用户名 delprinc:删除kerberos用户,语法为delprinc 用户名 listprincs : 查看kerberos用户列表 1.2 生成keytab文件:使用xst命令或者ktadd命令 kadmin.local: ktadd -kt /xxx/xxx/user01.keytab –norandeky user01 kadmin.local: xst -k /xxx/xxx/user01.keytab –norandeky user01 注意:加上–norandeky表示生成keytab后,原用户密码不失效,否则密码失效 1.3 创建需要授权的topic如果topic已经存在这时候不需要创建 创建topic的时候先认证到kafka的超级用户 kinit –kt /etc/kafka/conf/kafka.keytab kafka 接下来进行topic的创建 kafka-topics --create --zookeeper node01:2181/kafka --replication-factor 1 --partitions 2 --topic test01 随后对用户user01对test01的topic授予读写的权限 kafka-acls --authorizer-properties zookeeper.connect=node01:2181/kafka --add --allow-principal User:use01 --operation Read --topic test01 对用户user01对test01的topic授予group读权限 kafka-acls --authorizer-properties zookeeper.

Data Manipulation Language

数据操作语言DML操作的是对象中的数据insert,update ,delete 1.insert;向表中插入数据(注册,添加) 语法: insert into 表名(列名2,列名1,列名4) values(值2,值1,‘值4’) 注意: 插入时要遵守约束列的顺序任意,但是values后面值的顺序要和前面列的顺序对应当值是字符串或时间类型时使用引号若插入所有列,可以简化语法:insert into 表名(值1,值2,值3…简化了要插入所有列的值) 2.update:更新,修改表中的数据 语法: update 表名 set 列名 = 值, 列名 = ‘值’ [where条件] 危险操作: update 表名 set 列名1= 值1,列名2 = 值2 上面的语句更新的是对应列的所有值 update 表名 set 列名 = 值,列名 = 值 where 条件 (主键列名=‘值’) update empl set job = ‘PG’ where emplNo = ‘10005’ where条件:列名 比较运算符 =、 >、<、>= <= <> 过个条件使用and 或:or update emp set Sal=Sal+7000 where empDept = '1' and Sal < 8000 【注意】在数据库中可以通过update来修改主键的值

通过feign调用微服务传递header

由于我们项目开发中前台调用后台接口是要在请求头中携带token令牌的,但是通过feign调用其他微服务时敏感头信息是不会向下游微服务传递的,这时就要配置拦截器实现header的传递,代码如下: package com.cyclothes.interceptor; import feign.RequestInterceptor; import feign.RequestTemplate; import org.springframework.stereotype.Component; import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.context.request.ServletRequestAttributes; import javax.servlet.http.HttpServletRequest; import java.util.Enumeration; /** * spirng cloud feign传递header * * @author 梁建朝 * @date 2019/4/3 */ @Component public class FeignHeaderInterceptor implements RequestInterceptor { @Override public void apply(RequestTemplate template) { /** * 获取头部带盐的token */ HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest(); Enumeration<String> headerNames = request.getHeaderNames(); if (headerNames != null) { while (headerNames.hasMoreElements()) { String name = headerNames.nextElement(); String values = request.

jsonrpc-c编译

for X86 1、#autoreconf -i 如果报错连续执行两次,执行后会产生configure文件。 2、打开configure文件,在12658行附近的内容,更改如下: # Check whether --with-libev was given. if test "${with_libev+set}" = set; then : withval=$with_libev; WITH_LIBEV=$withval else WITH_LIBEV=yes fi WITH_LIBEV="/home/jcy/HuiTu/libev/libev-4.24-X86/libev-4.24/x86" LIBEV_CFLAGS="-I$WITH_LIBEV/include" LIBEV_LIBS="-L$WITH_LIBEV/lib -lev" ac_config_headers="$ac_config_headers config.h" ac_config_files="$ac_config_files Makefile include/Makefile src/Makefile example/Makefile" 备注:/home/jcy/HuiTu/libev/libev-4.24-X86/libev-4.24/x86是的libev编译目录 3、执行#./configure 备注:如果是嵌入式编译,则configure命令为"#./configure --host=arm-linux" 4、执行#make 编译不会出错,并在example目录产生文件server执行文件

MATLAB中改变默认工作路径的方法

文章目录 1. 按2. 操作步骤 1. 按 老版本如2009可以通过设置userpath来修改默认的工作路径,但新版本如2019的则不行。本文介绍的通过修改MATLAB启动时自动运行的文件的方式可以解决新版本的设置工作路径的问题,启动matlab时会自动运行 X:\Program Files\Polyspace\R2019a\toolbox\local\matlabrc.m文件,因此我们只需要在这个文件的末尾中加入一条cd指令用于切换工作目录就可以了。 2. 操作步骤 用记事本或者MATLAB或者VSCode打开X:\Program Files\Polyspace\R2019a\toolbox\local\matlabrc.m文件。 即打开安装路径下的matlabrc.m文件(注:最开头的“X”是你所安装的位置盘符)。 在最后一行加入这条语句: cd 'D:\0COCO\Sys\Documents\MATLAB' 注意一:需要在英文输入法下输入代码; 注意二:cd命令之后有一个空格,将D:\0COCO\Sys\Documents\MATLAB这里换成你自己的路径。 3. 重启MATLAB就可以看到效果了。

深度学习计算机视觉学习流程

怎么入门机器/深度学习? 回答这个问题,最先要考虑的问题是:你有多少时间? 准备用三个月入门,和想要一个月速成,肯定是截然不同的路径。当然我建议大家稳扎稳打,至少可以拿出五个月的时间来学好机器学习的基础知识。 基础很重要,知其所以然很重要。毕竟工具总在进步,每个月都会出现更好的深度学习技术,但基础知识是不变的。 如何用五个月时间入门?下面分三个部分,详细指南。(以及,如果你确实时间有限,最后还有一个速成指南) 五个月入门 Part 1:从机器学习开始(两个月) 最好的入门教程,就是吴恩达讲授的机器学习。吴恩达这套课程发布很久了,虽然有些地方稍微过时,但相信我,现在没有任何公开的课程,能比吴恩达讲得更好。真的,课程结束时我几乎哭了出来。 这个课程可以说适合任何水平的学生,当然,你最好还是得知道两个矩阵如何相乘,以及对编程有一些基本的了解。 这套课程可以前往Coursera学习,传送门: https://www.coursera.org/learn/machine-learning 也可以上网易公开课收看,传送门: http://open.163.com/special/opencourse/machinelearning.html 如果你有时间,一定要听完全部的课程。如果时间紧张,至少要听完前五节课程,后面的可以暂时跳过。 吴恩达的机器学习课程深入讲解了经典的机器学习模型,如线性回归、逻辑回归、神经网络、支持向量机、PCA、无监督学习等等。大部分重要概念,都以简单易懂的方式进行了介绍。 课程延伸 当你学习到第五节课,也就是开始讲述神经网络时,建议开始查看与课程平行的外部资料。比方3bule1brown推出的神经网络讲解视频。推荐必看。 YouTube传送门: https://youtu.be/aircAruvnKk?list=PLZHQObOWTQDNU6R1_67000Dx_ZCJB-3pi 或者可以前往B站查看: http://space.bilibili.com/88461692/#/ 以及,我觉得吴恩达在讲神经网络时有点快,所以建议补充阅读一些资料。比如有关神经网络和深度学习的在线书籍,免费的就很好了。 传送门: http://neuralnetworksanddeeplearning.com/ 作者Michael A. Nielsen以一种简单直观的方式,深入探究了神经网络的每个细节。建议阅读这本书的前两章,与吴恩达的课程并行。当你熟悉更多概念后,开始搞深度学习时,可以再看书中的其余部分。 如果你英文不好,这本《神经网络与深度学习》也有中文翻译版本,可以免费在线查看。 传送门在此: https://tigerneil.gitbooks.io/neural-networks-and-deep-learning-zh/content/ 这个部分的学习结束之后,你就能明白机器/深度学习的许多概念。最后推荐阅读Christopher Olah的博客,很有意思。 传送门: http://colah.github.io/ Part 2:涉足深度学习(1个月) 开始研究深度学习之前,最好重温一下大学数学。Ian Goodfellow传奇般的“花书”《深度学习》,简明扼要的概括了大部分重要主题。 建议大家尽可能深入地阅读线性代数、概率、信息理论的章节。每当读论文遇到深度学习概念时,都可以在书中找到参考。 以及,这本书有在线的版本。 例如英文版在此: https://github.com/janishar/mit-deep-learning-book-pdf/blob/master/complete-book-bookmarked-pdf/deeplearningbook.pdf 。 而中文翻译版本在此: https://github.com/exacity/deeplearningbook-chinese 关于深度学习的在线资料有很多,你可能会挑花了眼。 再一次,我觉得最好的选择,还是听吴恩达的《深度学习专项系列课程(Deep Learning Specialization)》。 Coursera传送门: https://www.coursera.org/specializations/deep-learning 网易云课堂的传送门: https://mooc.study.163.com/smartSpec/detail/1001319001.htm/ 这门课程包括五大章节。其实不是免费的,你可以按照50美元/月购买。当然,如果你负担不起,还能申请“助学金”。申请时请详细阐明理由,处理的时间大概需要15天左右。 当然不付费,大部分内容都是可以看的。以及视频的部分,在很多地方也能免费收看。 这五门课程主要讲的是: 1、神经网络和深度学习(4周) 2、改善深度神经网络(3周) 3、结构化机器学习项目(2周) 4、卷积神经网络(4周) 5、序列模型(3周) 前三门课程涉及一般的神经网络和深度学习,第四、第五门课程涉及特定主题。如果你打算搞视觉,第四课必听;如果你搞NLP、音频等,第五课必听。但如果你需要听第五课,那么建议也把第四课好好听一下。 这里鼓励大家一下,课程里每周的内容,实际上一两天就能学完,所以不要被课程表吓倒。劳逸集合、提升效率。 学到这个地步,其实就可以再去http://neuralnetworksanddeeplearning.com/ ,查看第三到第六章的内容,来强化你的概念。如果你有什么还没搞懂的,请前往Olah的博客。 以及,这时候你要开始看深度学习的论文了,从中学习知识。深度学习有个强烈的特点,那就是内容都非常新,阅读论文是跟上时代唯一的方法。不想被抛下,那么还是养成阅读论文的好习惯吧。 Part 3:深度学习上手练(两个月) 学到这里,你应该对机器学习和深度学习中的大多数概念有了正确的理解,现在是时候投入沸腾的实际生活中了。

相互依赖的so库,在编译时如何解耦

有时候,我们写的程序,会涉及到相互引用的问题。比如frameworks\av\media\libstagefright下的这个libstagefright,被frameworks\av\media\libstagefright\codecs\avienc我们这个新增的avienc引用到了,而反过来,libstagefright在录制avi视频时,又用到了我们的avienc.so这个库。看Android.mk: libstagefright.so的Android.mk里 ...... LOCAL_SHARED_LIBRARIES := \ avienc ...... avienc.so的Android.mk里 ...... LOCAL_SHARED_LIBRARIES := \ libstagefright ...... 像这种情况,在编译时,肯定是通过不了的。因为在编译libstagefright的时候,要用到avienc,而去编译avienc时又需要到libstagefright,这样就造成了一个相互依赖的死结。 处理这种情况,最常用的办法是将avienc里要用到的libstagefright里的文件,全部拷贝到avienc里来,这样就达到了单方向的解耦。但是这样无疑会增加avienc的代码量。有没有一种,在不影响libstagefright和avienc的代码结构、不增加它们代码量的情况下,解决这个问题的方法呢?答应是有的。 动态库dlopen、dlsym、dlclose这三个函数就可以实现这个功能。其实在android里,我们framework层去调用hal层的库时,用的hw_get_module这个函数,只要大家跟时去看,就会发现,实际上它用的也就是动态库的这三板斧。先来介绍下这三个函数: dlopen 基本定义 功能:打开一个动态链接库 包含头文件: #include <dlfcn.h> 函数定义: void * dlopen( const char * pathname, int mode ); 函数描述: 在dlopen的()函数以指定模式打开指定的动态连接库文件,并返回一个句柄给调用进程。使用dlclose()来卸载打开的库。 mode:分为这两种 RTLD_LAZY 暂缓决定,等有需要时再解出符号 RTLD_NOW 立即决定,返回前解除所有未决定的符号。 RTLD_LOCAL RTLD_GLOBAL 允许导出符号 RTLD_GROUP RTLD_WORLD 返回值: 打开错误返回NULL 成功,返回库引用 编译时候要加入 -ldl (指定dl库) dlsym() 功能: 根据动态链接库操作句柄与符号,返回符号对应的地址。 包含头文件: #include <dlfcn.h> 函数定义: void*dlsym(void* handle,const char* symbol) 函数描述: dlsym根据动态链接库操作句柄(handle)与符号(symbol),返回符号对应的地址。使用这个函数不但可以获取函数地址,也可以获取变量地址。 handle是由dlopen打开动态链接库后返回的指针,symbol就是要求获取的函数或全局变量的名称。 dlclose() dlclose用于关闭指定句柄的动态链接库,只有当此动态链接库的使用计数为0时,才会真正被系统卸载。 介绍完这三个函数后,再来看我们是如何来解耦的。我们在avienc文件夹里增加一个头文件avidef.

4、H3C交换机AAA本地用户

//添加本地用户,并进入本地用户视图 [switch] local-user user-name class manage //设置本地用户的密码 [switch-local-user] password [ { hash | simple } password ] //设置本地用户可以使用的服务类型 [switch-local-user] service-type [ ssh | terminal ] ----------------------------------------------------------------------------------------- //为AAA用户添加三员 //使能缺省用户角色授权功能 [switch] role default-role enable [ role-name ] //进入本地用户视图 [switch] local-user user-name class manage [switch-local-user] authorization-attribute user-role role-name 注:其中role-name为(三员) 1、network-operator 2、network-admin 3、security-audit

Linux下编写C++服务器(HTTP服务器)

今天使用Makefile写一个HTTP的服务器,之前没有接触过Makefile,需要探索一下。 VS2015下测试Makefile 新建一个Makefile Project(Linux),这里名为HTTPTest; 添加新建项, 添加C ++文件(.cpp),名为main.cpp, 内容如下: #pragma once #pragma execution_character_set("utf-8") #include <stdio.h> int main() { printf("HttpServer启动\n"); int count = 0; while (count<3) { count++; printf("hello %d\n",count); } printf("HttpServer关闭\n"); return 0; } 在main.cpp的同级目录下创建一个Makefile的空文件,注意文件名的大小写,并添加到HTTPTest项目中, 写入如下内容: build: gcc -gdwarf-2 -o HTTPTest main.cpp clean: rm -rf HTTPTest 右键项目,选择属性,在General的Remote Build Root Directory中写入Linux上的项目目录, 在Remote Build四项中分别写入 cd $(RemoteRootDir)/$(ProjectName); make build cd $(RemoteRootDir)/$(ProjectName); make clean build cd $(RemoteRootDir)/$(ProjectName); make clean $(RemoteRootDir)/$(ProjectName)/HTTPTest 如图: 在main.cpp的其中一行打上断点,按F5调试,测试成功了。 安装libevent HTTP服务器我们选择libevent库实现。

基于LQR的一阶倒立摆控制仿真

(1)LQR简介 LQR(linear quadratic regulator)即线性二次型调节器,其对象是现代理论中以状态空间形式给出的线性系统。LQR最优设计是指设计出的状态反馈控制器 K要使二次型目标函数J 取最小值,而 K由权矩阵Q 与 R 唯一决定,故此 Q、 R 的选择尤为重要。 (2)LQR的特点 LQR理论是现代控制理论中发展最早也最为成熟的一种状态空间设计法。特别可贵的是 ,LQR可得到状态线性反馈的最优控制规律 ,易于构成闭环最优控制。而且 Matlab 的应用为LQR 理论仿真提供了条件 ,更为我们实现稳、准、快的控制目标提供了方便。 (3)LQR针对的问题 LQ问题的几种特殊情况 1、状态调节器问题:用不大的控制能量,使系统状态X(t)保持在零值附近 2、输出调节器问题:用不大的控制能量,使系统输出Y(t)保持在零值附近 3、跟踪问题:用不大的控制量,使系统输出Y(t)紧紧跟随Yr(t)的变化 (4)LQR应用原理 线性二次型是指系统的状态方程是线性的,指标函数是状态变量和控制变量的二次型。考虑线性系统的状态方程为: 找一状态反馈控制律: 使得二次型性能指标最小化: 其中,x(t)为系统的状态变量;t0,tf 为起始时间与终止时间;S为终态约束矩阵;Q(t)为运动约束矩阵;R(t)为约束控制矩阵。其中Q(t)、R(t)决定了系统误差与控制能量消耗之间的相对重要性。为使J最小,由最小值原理得到最优控制为: 则 式中,矩阵P(t)为微分Riccatti方程的解对于最优反馈系数矩阵,使用Matlab中专门的求解工具lqr()来求取。 [K,P]=lqr(A,B,Q,R). 以下是以一阶倒立摆为研究对象,使用LQR算法实现倒立摆的稳定。 步骤一:将倒立摆系统表达为状态间的形式,详细的推导可参考其他资料。 步骤二:利用matlab的lqr函数求解K。 步骤三:将输入u(t)=-K*x(t)带入系统中。 (下方第一幅图为输入力的大小,断点为添加的干扰,第二幅图的为位置x的变化,第三幅图为摆杆与垂直方向的夹角随时间的变化,初始倒立摆的角度为10°) 仿真源码

如何遍历newtonsoft.json的JObject里的JSON数据

这种问题,在网上搜,居然没有答案,又是一堆垃圾,连谷歌上都搜不到。老实说,我喜欢这边的工作环境,可以上谷歌,毕竟是大公司,有自己的VPN 。……(不可说,非常不可说,此处省略一千字)……居然连谷歌都会被禁,让人无语。 还是经过自己摸索,有代码有J8: JObject json = //获得一个JObject对象 /* { "records": [ { "ID": "ABC", "OperationPatchID": "1", "s05055396": "120.93900", "s05055099": "14.44790", "s04026131": "Open lot", "s04020195": "3334", "s03006029": "2014/7/23 0:00:00", "s03006045": "BAC" } ], "count": 1 } Newtonsoft.Json.Linq.JObject */ StringBuilder sb = new StringBuilder("<div>"); JToken record = json["records"][0]; foreach(JProperty jp in record) { sb.Append(String.Format(@"<span>{0}</span>:<span>{1}</span>" ,jp.Name ,jp.Value)); } sb.Append("</div>");

instanceof关键字进行类型判断

如何才知道一个父类引用的对象,本来是什么子类? 格式: 对象 instanceof 类名称 这将会得到一个Boolean值结果,也就是判断前面的对象能不能当作后面的实例 //动物类 public abstract class Animal { public abstract void eat(); } //猫类 public class Cat extends Animal { @Override public void eat() { System.out.println("猫吃鱼!"); } //猫的特有方法 public void catchMouse(){ System.out.println("猫捉老鼠"); } } //狗 public class Dog extends Animal{ @Override public void eat() { } public void watchHouse(){ System.out.println("狗看门"); } } public class DemoInstanceof { public static void main(String[] args) { Animal animal = new Dog(); //本来是一只猫 animal.