SpringMVC

SpringMVC http://www.iteye.com/blogs/subjects/springmvc-explore 《Struts2技术内幕» 本文是专栏文章 (SpringMVC深度探险) 系列的文章之一,博客地址为: http://downpour.iteye.com/blog/1330537 在我们熟知的建立在三层结构 (表示层、业务逻辑层、持久层) 基础之上的J2EE应用程序开发之中,表示层的解决方案最多。因为在表示层自身的知识触角很多,需要解决的问题也不少,这也就难免造成与之对应的解决方案层出不穷。 笔者在很多讨论中经常可以看到类似"某某框架已死",或者"某某框架已经足以打败所有其他的框架"的言论。**事实上,每一种解决方案都有着自身独有的存在价值和历史背景。**如果单单从某一个方面或者某几个方面去看一个框架,那么评论难免有失偏颇。 所以,整个系列的第一篇文章,我们脱开SpringMVC框架本身,把SpringMVC放到一个更大的知识体系范围之中,讲一讲整个Web开发领域、尤其是MVC框架的发展历程。正如"认识历史才能看清未来",当我们能够正确审视整个MVC框架的发展历程,也就能够分析它的发展趋势,并且站在一个更高的高度来对所有的解决方案进行评价。 两种模型 从整个B/S程序的运行结构来看,J2EE的表示层解决方案实际上是对"请求-响应"模式的一种实现。既然谓之"请求-响应"也就势必存在着两大沟通角色: 由于这两大角色的承载载体和编程语言实现基础都不同,因而也就产生了两种截然不同的针对表示层的解决方案的设计思路: 以服务器端应用程序为主导来进行框架设计 以浏览器页面组件 (及其自身的事件触发模型) 为主导来进行框架设计 业界对于上述这两种不同的设计模型也赋予了不同的名词定义: 前一种被称之为MVC模型;后一种则被称之为组件模型,也有称之为事件模型。 **注: **笔者个人对于这两种模型的概念定义并不是非常认同。因为在笔者个人的观点认为,MVC模型的定义角度所针对的是编程元素的划分;而组件模型 (事件模型) 的定义角度是动态交互方式的表述。所以我们在这里强调的是解决方案自身所设立的基准和侧重点的不同。 从使用者的社区力量上来看,无疑MVC模型获得了更多程序员的青睐。这里面的原因很多,我们在这里也不想过多展开对两种不同编程模型之间的讨论。不过在这里,我们将针对同一个业务场景 (用户注册) 分别给出基于这两个编程模型的代码示例,帮助读者了解这两种编程模型在设计思想上的不同之处。 【MVC模型】 在MVC模型中,我们选取当前比较热门的两大框架Struts2和SpringMVC作为代码示例。 首先,我们将用户注册场景中最为核心的"用户类"定义出来: Java代码 <img src="http://downpour.iteye.com/images/icon_star.png" alt="收藏代码" /> public class User { private String email; private String password; // 省略了setter和getter方法 } 紧接着是一个简单的JSP表单: Html代码 <img src="http://downpour.iteye.com/images/icon_star.png" alt="收藏代码" /> <form method="post" action="/register"> <label>Email:</label><input type="text" name="email" /> <label>Password:</label><input type="password" name="password" /> <input type="submit" value="submit" /> </form> 上述这两段代码无论是SpringMVC还是Struts2,都可以共用。而在请求响应处理类 (也就是Controller) 上的设计差异是两个框架最大的不同。 ...

2012-11-30 · 2 min · 420 words · -

用 dbunit-maven-plugin 来管理你的测试数据

用 dbunit-maven-plugin 来管理你的测试数据 http://newwhx2011.iteye.com/blog/1089559 单元测试有人写过,也有人没做过,数据库的 dbunit 的用的人应该更少了,它可以用来给你做测试准备数据。一般我们做测试会在一个测试数据库中不停的测,自然会累积许多垃圾数据,给单元测试会造成不便,功能测试倒无太紧要。如果我们想在单元测试的时候有一份干净的数据,有个做法是搞个备用的数据库,测试前导到测试库的,或用某些数据库的导入导出功能。 这里我们来看 dbunit 怎么实现准备测试数据的,它可以用来导出数据库数据到数据文件中,从数据文件中导入干净的数据到数据库中,比较数据库与数据文件、或增量的插入记录等等。 dbunit 最初为 ant 提供了 antask,当然可以编程使用,如今 maven 大行其道,所以也就有了 maven 的 dbunit 插件,相似功能的插件有两个: dbunit-maven-plugin maven-dbunit-plugin 就是 maven 和 dbunit 倒了一下,别晕了,第二个似乎提供了更多的 goal,但运行 mvn dbunit:xxxx,指向的是第一个 dbunit-maven-plugin,看来第一个要正统些。本文也就介绍下dbunit-maven-plugin 的用法,测试数据库是 MySQL。

2012-11-30 · 1 min · 34 words · -

字符串匹配算法总结

字符串匹配算法总结 KMP虽然经典,但是理解起来极其复杂,好不容易理解好了,便起码来巨麻烦! 老子就是今天图书馆在写了几个小时才勉强写了一个有bug的、效率不高的KMP,特别是计算next数组的部分。 其实,比KMP算法速度快的算法大把大把,而且理解起来更简单,为何非要抓住KMP呢?笔试出现字符串模式匹配时直接上sunday算法,既简单又高效,何乐而不为? 说实话,想到sunday算法的那个人,绝对是发散思维,绝对牛。当我在被KMP折磨的够呛的时候,我就琢磨,有没有别的好算法呢??琢磨了半天也没想出个所以然来。笨啊,脑子不够发散。 下面贴上一位兄弟写的算法总结,很简单 (建议KMP部分就不用看了,看了费脑子) 。 参见: http://hi.baidu.com/willamette/blog/item/02bd0b5599c8b4c0b645ae06.html 趁着做Presentation的功夫,顺便做一个总结 字符串匹配: -willamette 在匹配串中寻找模式串是否出现,注意和最长公共子序列相区别(LCS: Longest Common Substring) **-: ** Brute Force(BF或蛮力搜索) **算法: ** 这是世界上最简单的算法了。 首先将匹配串和模式串左对齐,然后从左向右一个一个进行比较,如果不成功则模式串向右移动一个单位。 速度最慢。 那么,怎么改进呢? 我们注意到Brute Force 算法是每次移动一个单位,一个一个单位移动显然太慢,是不是可以找到一些办法,让每次能够让模式串多移动一些位置呢? 当然是可以的。 我们也注意到,Brute Force 是很不intelligent 的,每次匹配不成功的时候,前面匹配成功的信息都被当作废物丢弃了,当然,就如现在的变废为宝一样,我们也同样可以将前面匹配成功的信息利用起来,极大地减少计算机的处理时间,节省成本。^_^ 注意,蛮力搜索算法虽然速度慢,但其很通用,文章最后会有一些更多的关于蛮力搜索的信息。 **-: KMP算法 ** 首先介绍的就是KMP 算法。 原始论文: Knuth D.E., Morris J.H., and Pratt V.R., Fast pattern matching in strings, SIAM Journal on Computing, 6(2), 323-350, 1977. 这个算法实在是太有名了,大学上的算法课程除了最笨的Brute Force 算法,然后就介绍了KMP 算法。也难怪,呵呵。谁让Knuth D.E. 这么world famous 呢,不仅拿了图灵奖,而且还写出了计算机界的Bible ( 业内人士一般简称TAOCP). 稍稍提一下,有个叫H.A.Simon 的家伙,不仅拿了Turing Award ,顺手拿了个Nobel Economics Award ,做了AI 的爸爸,还是Chicago Univ 的Politics PhD ,可谓全才。 ...

2012-11-27 · 5 min · 898 words · lcf

Database

Database SQL tuning 类 列举几种表连接方式 等连接 (内连接) 、非等连接、自连接、外连接 (左、右、全) Or hash join/merge join/nest loop(cluster join)/index join ?? ORACLE 8i,9i 表连接方法。 一般的相等连接: select * from a, b where a.id = b.id; 这个就属于内连接。 对于外连接: Oracle中可以使用"(+) “来表示,9i可以使用LEFT/RIGHT/FULL OUTER JOIN LEFT OUTER JOIN: 左外关联 SELECT e.last_name, e.department_id, d.department_name FROM employees e LEFT OUTER JOIN departments d ON (e.department_id = d.department_id); 等价于 SELECT e.last_name, e.department_id, d.department_name FROM employees e, departments d WHERE e.department_id=d.department_id(+) 结果为: 所有员工及对应部门的记录,包括没有对应部门编号department_id的员工记录。 RIGHT OUTER JOIN: 右外关联 SELECT e.last_name, e.department_id, d.department_name FROM employees e RIGHT OUTER JOIN departments d ON (e.department_id = d.department_id); 等价于 SELECT e.last_name, e.department_id, d.department_name FROM employees e, departments d WHERE e.department_id(+)=d.department_id 结果为: 所有员工及对应部门的记录,包括没有任何员工的部门记录。 FULL OUTER JOIN: 全外关联 SELECT e.last_name, e.department_id, d.department_name FROM employees e FULL OUTER JOIN departments d ON (e.department_id = d.department_id); 结果为: 所有员工及对应部门的记录,包括没有对应部门编号department_id的员工记录和没有任何员工的部门记录。 ORACLE8i是不直接支持完全外连接的语法,也就是说不能在左右两个表上同时加上(+),下面是在ORACLE8i可以参考的完全外连接语法 select t1.id,t2.id from table1 t1,table t2 where t1.id=t2.id(+) union select t1.id,t2.id from table1 t1,table t2 where t1.id(+)=t2.id ...

2012-11-27 · 15 min · 3180 words · lcf

快速匹配字符串

快速匹配字符串 假设内存有一个大字符串集,里面含有约1000万个字符串,如何快速知道该字符串集是否含有某个指定的测试字符串 ? (假设内存能放下这么多字符串) 方法一: hashCode法 方法二: Trie树 http://zh.wikipedia.org/wiki/Trie HashCode法 01 def sampleHashMap(strSet: Set[String]): Map[Int, Set[String]]={ 02 strSet.groupBy{ 03 s => s.hashCode 04 } 05 } 06 07 def contain(str: String, sampleMap: Map[Int, Set[String]]): Boolean = { 08 sampleMap.getOrElse(str.hashCode, Set[String]()).exists(_ equals str) 09 } 10 11 // 测试 12 val sampleSet = Set("a","b","c","AA","Archer","Jack"); 13 val sampleMap = sampleHashMap(sampleSet); 14 println(contain("Archer", sampleMap)); // true 15 println(contain("A", sampleMap)); // false 16 println(contain("a", sampleMap)); // true Trie树法 01 sealed abstract class Trie { 02 def contains(msg: String): Boolean = contains(msg, this) 03 04 @scala.annotation.tailrec 05 private def contains(msg: String, trie: Trie): Boolean = (msg, trie) match { 06 case (null, _ ) | (_ , null ) => false 07 case (StringCase(head, tail), TrieNode(edges)) => edges.get(head) match { 08 case None => false 09 case Some(subTrie) => contains(tail,subTrie) 10 } 11 case (StringCase(_,_), TrieLeaf()) => false 12 case _ => true 13 } 14 } 15 16 case class TrieNode(edges: Map[Char, Trie]) extends Trie{ 17 assert(edges.size > ) 18 } 19 case class TrieLeaf extends Trie 20 21 object StringCase{ 22 def unapply(s: String): Option[(Char, String)] ={ 23 if (s == null || s == "" ) None 24 else Some(s.head, s.tail) 25 } 26 } 27 28 object Trie{ 29 30 def apply(strs: String*): Trie ={ 31 apply(strs.toSet); 32 } 33 34 def apply(strSet: Set[String]) : Trie = { 35 if (strSet.size == || strSet == Set("")) TrieLeaf() 36 else { 37 val char2TrieSet = strSet.filter(_.length > ).groupBy(_.head).mapValues{ 38 strs => strs.map(_.tail) 39 }.mapValues{ 40 strs => apply(strs) 41 } 42 TrieNode(char2TrieSet); 43 } 44 } 45 46 } 47 48 val trie= Trie("abc","ac","b") 49 println(trie) 50 assert(trie.contains("") == true); // true 51 assert(trie.contains(null) == false); //false 52 assert(trie.contains("a") == true); // true 53 assert(trie.contains("b") == true); // true 54 assert(trie.contains("ab") == true); //true 55 assert(trie.contains("ac") == true); //true 56 assert(trie.contains("abc") == true); //true 57 assert(trie.contains("acb") == false); // false 58 assert(trie.contains("abcd") == false); //false 59 assert(trie.contains("bc") == false); //false

2012-11-26 · 2 min · 328 words · lcf

what if

what if 如果…将会怎么样 例句与用法: What if it is true? 如果这是真的又该如何呢? What if he doesn’t agree? 如果他不同意该怎么办呢? What if he comes back now? 如果他现在回来怎么办? What if I fail! 即使我失败了又怎样!

2012-11-25 · 1 min · 28 words · -

citrix

citrix install, uninstall, and update dpkg --list | grep -i icaclient download https://www.citrix.com/downloads/workspace-app/linux/workspace-app-for-linux-latest.html for ubuntu 24.04 Support for Ubuntu 2404 To support Citrix Workspace app for Linux on Ubuntu 2404, backporting the webkit2gtk library is required. Follow the steps below to backport the library based on your architecture: For x64 architecture: Add the following packages for jammy: sudo apt-add-repository deb http://us.archive.ubuntu.com/ubuntu jammy main sudo apt-add-repository deb http://us.archive.ubuntu.com/ubuntu jammy-updates main sudo apt-add-repository deb http://us.archive.ubuntu.com/ubuntu jammy-security main ...

2012-11-25 · 1 min · 167 words · -

normalize.css 简介

normalize.css 简介 大部分情况下,我们在页面中使用 CSS Resets 解决不同浏览器对 HTML 元素的默认 CSS 设置的差异。CSS normalization 则与 CSS Resets 不同,为了页面具有相同的表现,CSS Resets 对大多元素的样式进行了复位操作,而 normalize.css 则在保留原有表现的基础上进行值的重设并修复一些浏览器的 Bug。

2012-11-24 · 1 min · 20 words · -

LESS CSS

LESS CSS 一种 动态 样式 语言 LESS 将 CSS 赋予了动态语言的特性,如 变量, 继承,运算, 函数. LESS 既可以在 客户端 上运行 (支持IE 6+, Webkit, Firefox),也可以借助Node.js或者Rhino在服务端运行 CSS (层叠样式表) 是一门历史悠久的标记性语言,同 HTML 一道,被广泛应用于万维网 (World Wide Web) 中。HTML 主要负责文档结构的定义,CSS 负责文档表现形式或样式的定义。 作为一门标记性语言,CSS 的语法相对简单,对使用者的要求较低,但同时也带来一些问题: CSS 需要书写大量看似没有逻辑的代码,不方便维护及扩展,不利于复用,尤其对于非前端开发工程师来讲,往往会因为缺少 CSS 编写经验而很难写出组织良好且易于维护的 CSS 代码,造成这些困难的很大原因源于 CSS 是一门非程序式语言,没有变量、函数、SCOPE (作用域) 等概念。LESS 为 Web 开发者带来了福音,它在 CSS 的语法基础之上,引入了变量,Mixin (混入) ,运算以及函数等功能,大大简化了 CSS 的编写,并且降低了 CSS 的维护成本,就像它的名称所说的那样,LESS 可以让我们用更少的代码做更多的事情。 http://www.ibm.com/developerworks/cn/web/1207_zhaoch_lesscss/index.html

2012-11-24 · 1 min · 57 words · -

SASS

SASS http://www.ruanyifeng.com/blog/2012/06/sass.html 作者: 阮一峰 日期: 2012年6月19日 学过CSS的人都知道,它不是一种编程语言。 你可以用它开发网页样式,但是没法用它编程。也就是说,CSS基本上是设计师的工具,不是程序员的工具。在程序员眼里,CSS是一件很麻烦的东西。它没有变量,也没有条件语句,只是一行行单纯的描述,写起来相当费事。 很自然地,有人就开始为CSS加入编程元素,这被叫做"CSS预处理器" (css preprocessor) 。它的基本思想是,用一种专门的编程语言,进行网页样式设计,然后再编译成正常的CSS文件。 各种"CSS预处理器"之中,我自己最喜欢SASS,觉得它有很多优点,打算以后都用它来写CSS。下面是我整理的用法总结,供自己开发时参考,相信对其他人也有用。 一、什么是SASS SASS是一种CSS的开发工具,提供了许多便利的写法,大大节省了设计者的时间,使得CSS的开发,变得简单和可维护。

2012-11-24 · 1 min · 15 words · -

自适应网页设计 (Responsive Web Design)

自适应网页设计 (Responsive Web Design) http://www.ruanyifeng.com/blog/2012/05/responsive_web_design.html 作者: 阮一峰 日期: 2012年5月 1日 随着3G的普及,越来越多的人使用手机上网。 移动设备正超过桌面设备,成为访问互联网的最常见终端。于是,网页设计师不得不面对一个难题: 如何才能在不同大小的设备上呈现同样的网页? 手机的屏幕比较小,宽度通常在600像素以下;PC的屏幕宽度,一般都在1000像素以上 (目前主流宽度是1366×768) ,有的还达到了2000像素。同样的内容,要在大小迥异的屏幕上,都呈现出满意的效果,并不是一件容易的事。 很多网站的解决方法,是为不同的设备提供不同的网页,比如专门提供一个mobile版本,或者iPhone / iPad版本。这样做固然保证了效果,但是比较麻烦,同时要维护好几个版本,而且如果一个网站有多个portal (入口) ,会大大增加架构设计的复杂度。 于是,很早就有人设想,能不能"一次设计,普遍适用",让同一张网页自动适应不同大小的屏幕,根据屏幕宽度,自动调整布局 (layout) ? 一、“自适应网页设计"的概念 2010年,Ethan Marcotte提出了"自适应网页设计” (Responsive Web Design) 这个名词,指可以自动识别屏幕宽度、并做出相应调整的网页设计。

2012-11-24 · 1 min · 31 words · -

lazygit

lazygit https://github.com/jesseduffield/lazygit go install github.com/jesseduffield/lazygit@latest

2012-11-23 · 1 min · 5 words · -

html 版权符号

html 版权符号 在页面里加上版权符号,HTML代码里对应输入© ©就是版权符号在HTML里的代码,但是很多页面在设计的时候,用的字体是宋体,就算没有设置字体,中文系统下默认用的还是宋体,那么就导致的显示出来的版权符号变形。让我们来看看用宋体显示出来的是什么样子,代码和效果: Copyright ©2009 www.fwl.name 看到了,版权符号变形了 让我们来看看用arial字体显示出来的是什么样子,代码和效果: Copyright ©2009 www.fwl.name 看,这样就正常了· 所以,要很好很完美的显示出版权符号,除了用©外,还得用对字体

2012-11-21 · 1 min · 14 words · -

autoHotKey

autoHotKey ^ ctrl shift ! alt ^!s:: {BS} backspace sleep 500 Send Hello{Enter} return //ctrl+alt+s

2012-11-19 · 1 min · 15 words · -

golang 方法, 接口, 继承

golang 方法, 接口, 继承 package main import "fmt" type Foo struct{ Field0 string Field1 string } type Bar struct{ Foo Field2 string Field3 string } func main(){ fmt.Println("hello") bar:=Bar{Field2: "f2",Field3: "f3"} bar.Field0="f0" fmt.Printf("%v",bar) } http://www.cnblogs.com/chenny7/p/4497969.html Go语言没有沿袭传统面向对象编程中的诸多概念,比如继承、虚函数、构造函数和析构函数、隐藏的 this 指针等。 go 方法 Go 语言中同时有函数和方法。方法就是一个包含了接收器 (receiver) 的函数,receiver 可以是内置类型或者结构体类型的一个值或者是一个指针。所有给定类型的方法属于该类型的方法集。 如下面的这个例子,定义了一个新类型Integer,它和int一样,只是为它内置的int类型增加了个新方法 Less() 接收器——方法作用的目标 接收器的格式如下: func (接收器变量 接收器类型) 方法名(参数列表) (返回参数) { 函数体 } type Integer int func (a Integer) Less(b Integer) bool { return a < b } func main() { var a Integer = 1 if a.Less(2) { fmt.Println("less then 2") } } 可以看出,Go语言在自定义类型的对象中没有 C++/Java 那种隐藏的 this指针,而是在定义成员方法时显式声明了其所属的对象。 ...

2012-11-18 · 5 min · 895 words · -

Filter FilterChain

Filter FilterChain http://blog.csdn.net/zhaozheng7758/article/details/6105749 一、Filter的介绍及使用**** 什么是过滤器? 与Servlet相似,过滤器是一些web应用程序组件,可以绑定到一个web应用程序中。但是与其他web应用程序组件不同的是,过滤器是"链"在容器的处理过程中的。这就意味着它们会在servlet处理器之前访问一个进入的请求,并且在外发响应信息返回到客户前访问这些响应信息。这种访问使得过滤器可以检查并修改请求和响应的内容。 过滤器适用于那些地方? l 为一个web应用程序的新功能建立模型(可被添加到web应用程序中或者从web应用程序中删除而不需要重写基层应用程序代码); l 向过去的代码添加新功能。 过滤器放在容器结构的什么位置? 过滤器放在web资源之前,可以在请求抵达它所应用的web资源(可以是一个Servlet、一个Jsp页面,甚至是一个HTML页面)之前截获进入的请求,并且在它返回到客户之前截获输出请求。Filter: 用来拦截请求,处于客户端与被请求资源之间,目的是重用代码。Filter链,在web.xml中哪个先配置,哪个就先调用。在filter中也可以配置一些初始化参数。 Java中的Filter 并不是一个标准的Servlet ,它不能处理用户请求,也不能对客户端生成响应。 主要用于对HttpServletRequest 进行预处理,也可以对HttpServletResponse 进行后处理,是个典型的处理链。 Filter 有如下几个用处: l 在HttpServletRequest 到达Servlet 之前,拦截客户的HttpServletRequest 。 l 根据需要检查HttpServletRequest ,也可以修改HttpServletRequest 头和数据。 l 在HttpServletResponse 到达客户端之前,拦截HttpServletResponse 。 l 根据需要检查HttpServletResponse ,可以修改HttpServletResponse 头和数据。 Filter 有如下几个种类: l 用户授权的Filter: Filter 负责检查用户请求,根据请求过滤用户非法请求。 l 日志Filter: 详细记录某些特殊的用户请求。 l 负责解码的Filter: 包括对非标准编码的请求解码。 l 能改变XML 内容的XSLTFilter 等。 一个Filter 可负责拦截多个请求或响应:一个请求或响应也可被多个请求拦截。 创建一个Filter 只需两个步骤: (1)创建Filter 处理类: (2)在web.xml 文件中配置Filter 。 创建Filter 必须实现javax.servlet.Filter 接口,在该接口中定义了三个方法。 • void init(FilterConfig config): 用于完成Filter 的初始化。 ...

2012-11-18 · 3 min · 558 words · -

python调用shell命令

python调用shell命令 http://blog.chinaunix.net/uid-16362696-id-3067891.html python调用shell命令的方法有许多 1.1 os.system(command) 在一个子shell中运行command命令,并返回command命令执行完毕后的退出状态。这实际上是使用C标准库函数system()实现的。这个函数在执行command命令时需要重新打开一个终端,并且无法保存command命令的执行结果。 1.2 os.popen(command,mode) 打开一个与command进程之间的管道。这个函数的返回值是一个文件对象,可以读或者写(由mode决定,mode默认是’r’)。如果mode为’r’,可以使用此函数的返回值调用read()来获取command命令的执行结果。 1.3** **commands.getstatusoutput(command) 使用os.popen()函数执行command命令并返回一个元组(status,output),分别表示command命令执行的返回状态和执行结果。对command的执行实际上是按照{command;} 2>&1的方式,所以output中包含控制台输出信息或者错误信息。output中不包含尾部的换行符。 2.1 subprocess.call([“some_command”,“some_argument”,“another_argument_or_path”]) subprocess.call(command,shell=True) 2.2 subprocess.Popen(command, shell=True) 如果 command 不是一个可执行文件,shell=True 不可省。 使用subprocess模块可以创建新的进程,可以与新建进程的输入/输出/错误管道连通,并可以获得新建进程执行的返回状态。使用subprocess模块的目的是替代os.system()、os.popen*()、commands.*等旧的函数或模块。 最简单的方法是使用class subprocess.Popen(command,shell=True)。Popen类有Popen.stdin,Popen.stdout,Popen.stderr三个有用的属性,可以实现与子进程的通信。 将调用shell的结果赋值给python变量 handle = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE) print handle.communicate()[0] 如果想获取执行命令的状态值,也就是$?, 可以用os.system( cmd ) 如果想获取执行命令的print内容, 可以用os.popen( cmd ).read() 既想获取状态值,也想获取打印的内容? import commands stat, content = commands.getstatusoutput( cmd ) stat is the exit code content is the content for printing

2012-11-17 · 1 min · 62 words · -

Lambda 表达式

Lambda 表达式 “Lambda 表达式"是一个匿名函数,它可以包含表达式和语句,并且可用于创建委托或表达式目录树类型。 所有 Lambda 表达式都使用 Lambda 运算符 =>,该运算符读为"goes to”。该 Lambda 运算符的左边是输入参数 (如果有) ,右边包含表达式或语句块。Lambda 表达式 x => x * x 读作"x goes to x times x"。 函数式接口functional interface, @FunctionalInterface 函数式接口(Functional Interface)是Java 8对一类特殊类型的接口的称呼。 这类接口只定义了唯一的抽象方法的接口 (除了隐含的Object对象的公共方法) , 因此最开始也就做SAM类型的接口 (Single Abstract Method) 。 为什么会单单从接口中定义出此类接口呢? 原因是在 Java Lambda 的实现中, 开发组不想再为Lambda表达式单独定义一种特殊的Structural函数类型,称之为箭头类型 (arrow type) , 依然想采用Java既有的类型系统(class, interface, method等), 原因是增加一个结构化的函数类型会增加函数类型的复杂性,破坏既有的Java类型,并对成千上万的Java类库造成严重的影响。 权衡利弊, 因此最终还是利用SAM 接口作为 Lambda表达式的目标类型。 JDK中已有的一些接口本身就是函数式接口,如Runnable。 JDK 8中又增加了java.util.function包, 提供了常用的函数式接口。 函数式接口代表的一种契约, 一种对某个特定函数类型的契约。 在它出现的地方,实际期望一个符合契约要求的函数。 Lambda表达式不能脱离上下文而存在,它必须要有一个明确的目标类型,而这个目标类型就是某个函数式接口。 方法引用 (method reference) 双冒号 “::” 是 Java 8 引入 Lambda 表达式后的一种用法,表示方法引用 (method reference) ,可以更加简洁的实例化接口 双冒号表达式返回的是一个 函数式接口对象 (用 @FunctionalInterface 注解的 interface 类型) 的实例,如下: ...

2012-11-17 · 5 min · 1020 words · -

数据库索引

数据库索引 数据库索引好比是一本书前面的目录,能加快数据库的查询速度。 例如这样一个查询: select * from table1 where id=44。如果没有索引,必须遍历整个表,直到ID等于44的这一行被找到为止;有了索引之后(必须是在ID这一列上建立的索引),直接在索引里面找44 (也就是在ID这一列找) ,就可以得知这一行的位置,也就是找到了这一行。可见,索引是用来定位的。 索引分为聚簇索引和非聚簇索引两种,聚簇索引 是按照数据存放的物理位置为顺序的,而非聚簇索引就不一样了;聚簇索引能提高多行检索的速度,而非聚簇索引对于单行的检索很快。为表设置索引要付出代价的: 一是增加了数据库的存储空间,二是在插入和修改数据时要花费较多的时间(因为索引也要随之变动)。 详述 创建索引可以大大提高系统的性能。第一,通过创建唯一性索引,可以保证数据库表中每一行数据的唯一性。第二,可以大大加快数据的检索速度,这也是创建索引的最主要的原因。第三,可以加速表和表之间的连接,特别是在实现数据的参考完整性方面特别有意义。第四,在使用分组和排序子句进行数据检索时,同样可以显著减少查询中分组和排序的时间。第五,通过使用索引,可以在查询的过程中,使用优化隐藏器,提高系统的性能。 也许会有人要问: 增加索引有如此多的优点,为什么不对表中的每一个列创建一个索引呢?因为,增加索引也有许多不利的方面。第一,创建索引和维护索引要耗费时间,这种时间随着数据量的增加而增加。第二,索引需要占物理空间,除了数据表占数据空间之外,每一个索引还要占一定的物理空间,如果要建立聚簇索引,那么需要的空间就会更大。第三,当对表中的数据进行增加、删除和修改的时候,索引也要动态的维护,这样就降低了数据的维护速度。 索引是建立在数据库表中的某些列的上面。在创建索引的时候,应该考虑在哪些列上可以创建索引,在哪些列上不能创建索引。一般来说,应该在这些列上创建索引: 在经常需要搜索的列上,可以加快搜索的速度; 在作为主键的列上,强制该列的唯一性和组织表中数据的排列结构; 在经常用在连接的列上,这些列主要是一些外键,可以加快连接的速度;在经常需要根据范围进行搜索的列上创建索引,因为索引已经排序,其指定的范围是连续的; 在经常需要排序的列上创建索引,因为索引已经排序,这样查询可以利用索引的排序,加快排序查询时间; 在经常使用在WHERE子句中的列上面创建索引,加快条件的判断速度。 同样,对于有些列不应该创建索引。一般来说,不应该创建索引的的这些列具有下列特点: 第一,对于那些在查询中很少使用或者参考的列不应该创建索引。这是因为,既然这些列很少使用到,因此有索引或者无索引,并不能提高查询速度。相反,由于增加了索引,反而降低了系统的维护速度和增大了空间需求。 第二,对于那些只有很少数据值的列也不应该增加索引。这是因为,由于这些列的取值很少,例如人事表的性别列,在查询的结果中,结果集的数据行占了表中数据行的很大比例,即需要在表中搜索的数据行的比例很大。增加索引,并不能明显加快检索速度。 第三,对于那些定义为text, image和bit数据类型的列不应该增加索引。这是因为,这些列的数据量要么相当大,要么取值很少,不利于使用索引。 第四,当修改性能远远大于检索性能时,不应该创建索引。这是因为,修改性能和检索性能是互相矛盾的。当增加索引时,会提高检索性能,但是会降低修改性能。当减少索引时,会提高修改性能,降低检索性能。因此,当修改操作远远多于检索操作时,不应该创建索引。可以基于数据库表中的单列或多列创建索引。多列索引可以区分其中一列可能有相同值的行。 如果经常同时搜索两列或多列或按两列或多列排序时,索引也很有帮助。例如,如果经常在同一查询中为姓和名两列设置判据,那么在这两列上创建多列索引将很有意义。 确定索引的有效性: 检查查询的WHERE和JOIN子句。在任一子句中包括的每一列都是索引可以选择的对象。 对新索引进行试验以检查它对运行查询性能的影响。 考虑已在表上创建的索引数量。最好避免在单个表上有很多索引。 检查已在表上创建的索引的定义。最好避免包含共享列的重叠索引。 检查某列中唯一数据值的数量,并将该数量与表中的行数进行比较。比较的结果就是该列的可选择性,这有助于确定该列是否适合建立索引,如果适合,确定索引的类型。根据数据库的功能,可以在数据库设计器中创建三种索引: 唯一索引、主键索引和聚集索引。有关数据库所支持的索引功能的详细信息,请参见数据库文档。 提示: 尽管唯一索引有助于定位信息,但为获得最佳性能结果,建议改用主键或唯一约束。 唯一索引 唯一索引是不允许其中任何两行具有相同索引值的索引。 当现有数据中存在重复的键值时,大多数数据库不允许将新创建的唯一索引与表一起保存。数据库还可能防止添加将在表中创建重复键值的新数据。例如,如果在employee表中职员的姓(lname)上创建了唯一索引,则任何两个员工都不能同姓。 主键索引 数据库表经常有一列或列组合,其值唯一标识表中的每一行。该列称为表的主键。 在数据库关系图中为表定义主键将自动创建主键索引,主键索引是唯一索引的特定类型。该索引要求主键中的每个值都唯一。当在查询中使用主键索引时,它还允许对数据的快速访问。 聚集索引 在聚集索引中,表中行的物理顺序与键值的逻辑 (索引) 顺序相同。一个表只能包含一个聚集索引。 如果某索引不是聚集索引,则表中行的物理顺序与键值的逻辑顺序不匹配。与非聚集索引相比,聚集索引通常提供更快的数据访问速度。 索引 uuid vs 自增 需要看你索引适应的形式,如果使用 b-tree 索引形式,有序 id 比无需 id 好,如果是 hash 索引,两个差别不大。主要原因是索引在磁盘上存储的形式,常用的 b-tree 索引如果 id 是连续的,那么数据存储在相邻的磁盘上,如果查询和写入操作的 id 连续,那么减少随机读写硬盘的几率,提升读写效率。所以看你的实际情况,如果你用的是 b-tree 索引,同时记录比较多,那么用有序 id 作为索引效率会高很多。 ...

2012-11-17 · 1 min · 87 words · -

MySQL 分页

MySQL 分页 一般MySQL最基本的分页方式: select * from content order by id desc limit 0, 10 在中小数据量的情况下,这样的SQL足够用了,唯一需要注意的问题就是确保使用了索引。随着数据量的增加,页数会越来越多,查看后几页的SQL就可能类似: select * from content order by id desc limit 10000, 10 一言以蔽之,就是越往后分页,LIMIT语句的偏移量就会越大,速度也会明显变慢。 此时,我们可以通过2种方式: 一,子查询的分页方式来提高分页效率,SQL语句如下: SELECT * FROM content WHERE id <= (SELECT id FROM content ORDER BY id desc LIMIT “.($page-1)*$pagesize.”, 1) ORDER BY id desc LIMIT $pagesize 为什么会这样呢?因为子查询是在索引上完成的,而普通的查询时在数据文件上完成的,通常来说,索引文件要比数据文件小得多,所以操作起来也会更有效率。 (via) 通过explain SQL语句发现: 子查询使用了索引! id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY content range PRIMARY PRIMARY 4 NULL 6264 Using where ...

2012-11-15 · 1 min · 170 words · lcf