javascript unit test

javascript unit test http://blog.sina.com.cn/s/blog_6768f2290100ubw5.html 最近由于工作和个人兴趣的关系,有幸研究了一下javascript的unit test,市面上常见且比较易用的javascript的unit test的framework有三个: jsunit, qunit和yuitest,虽然出处不同,但是本质上,使用方法都大同小异。 jsunit: http://www.jsunit.net/ 最早开发自2001年,是第一个实用的javascript的unit test framework (那时候TDD还远未流行) ,其完全遵循junit的xunit pattern, 有setup, teardown, 有testsuit概念,还有若干种assert方法,不过因为其诞生早,对非同步的ajax测试支持不够,因而有市场占有率渐低的趋势。 qunit: http://docs.jquery.com/Qunit 个人极其欣赏的一个framework,隶属于大名鼎鼎的jquery,但是又无需依赖于jquery的库可单独运行, 方法轻量易学,且具有异步测试的功能。可惜在公司没有被官方支持,只能自己玩。 yui test: http://developer.yahoo.com/yui/yuitest/ 著名的yahoo web js toolkit library中的ut子项目,使用方法和qunit极其相似,也具有异步测试功能,在本人公司被官方支持,最大的缺点是使用时要调用其他诸多的yui模块用来显示结果,不够独立。 以下以qunit为例子,介绍这些unit test framework的使用方法: 1 ) 下载qunit的测试驱动程序js文件和对应显示结果用的css文件 (分别为qunit.js 和qunit.css ) 2 ) 将这两个文件保存在某个目录,并在同一目录建立一个简单的html文件,包含该两个文件以及jquery.js 3 ) 将我们需要测试的js代码的文件也包含入该简单html中(该例中为mycode.js)。 4 ) 将我们要测试的js代码的依赖库也加入该html中(如ExtJS或者其他库) 5 ) 在html中添加script的测试代码 (test suit和assert部分) 6 ) 在浏览器中载入该html文件,页面会自动显示运行结果。 值得一提的是,网上有qunit-CLI的项目,其用rhino解释器来代替浏览器做unit test js的运行环境,提高了测试的效率,有兴趣的朋友可以去google搜索看看。 代码如下: mycode.js function (a, b) { return a + b; } test.html <!- js to be tested -> ...

2014-08-25 · 1 min · 92 words · -

原子操作

原子操作 CAS(Compare And Swap/Set) Fetch And Add Test And Set 原子操作-无锁多线程编程 翻译:Xiaobo 原文链接: Lock-free multithreading with atomic operations 推荐:之前读《程序员的自我修养》一书中有关于多线程的讲解非常好;但最近读到这几篇文章对于多线程的讲解,个人认为比前者(书)更加的清晰、易懂、全面。每篇文章的内容安排也很合理,非常感谢作者TRIANGLES和他优秀的文章,这里是他的个人站点。 相关系列译文 「译文」带你慢慢的了解多线程 「译文」线程同步 「译文」原子操作-无锁多线程编程 (本篇) 「译文」内存重排对无锁多线程的影响 译文正文部分 在希腊语中,原子 (ἄτομος; atomos) 的意思是不可切割。当计算机执行的每个任务无法再细分的时候(无法拆分为更小的子任务),这就是一个原子的任务。 在多线程编程中,原子是一个重要的属性:因为原子操作不可再细分,一个线程就无法闯入到另一个线程正在执行的原子操作中。假如,写入数据操作是原子的,那么其他线程就无法在另一个线程写入未完成的时候进行数据读取。反过来,读取数据也一样。换句话说,原子操作中,不存在数据竞争。 前一篇内容中,已经介绍了所谓的同步原语的概念,还有常见的实现线程同步的工具。它们也经常被用来在多线程中提供原子操作。但实现的方式仅仅是让单线程访问,阻塞其他线程,直到第一个线程完成操作。基于它们有能力冻结线程,同步原语也被称为阻塞机制。 前一篇提到的阻塞机制,在大部分情况下都能很好的工作。只有使用正确,它们也是可靠和快速的。然后,它们也有一些缺点需要注意: 1、休眠的线程除了等待,什么也做不了。 2、它们可以挂起你的应用程序——如果一个持有同步原语锁的线程由于某种原因崩溃,锁本身将永远不会被释放,等待的线程将永远被卡住; 3、开发者无法控制哪些线程将被休眠——一般这是被操作系统控制的,这就有可能引发优先级反转:执行重要任务的线程被迫等待那些执行不重要任务的线程。 大部分情况下,你可能也不会关心这些问题,因为它们似乎不会影响程序执行的正确性。但也有可能,为了充分利用多核 CPU,让一些线程一直保持运行也是可行的,此时如果因为优先级反转而引起系统假死,这就是个大问题了。 无锁编程 好消息是:我们还有其他方式控制多线程的并发任务。这个方式就是无锁编程,这是一种不使用锁机制来保证多线程安全的技术。 坏消息是:这是一种很底层的方式,这种方式,离硬件更近了一步。同时,使用无锁编程是对自己的智力挑战,也是我们了解计算机到底如何工作的好机会。 无锁编程依赖原子指令,这些原子指令是直接被 CPU 执行的。所以,我们需要先了解一些原子指令,然后我会告诉你如何使用这些执行进行并发控制。 什么是原子指令 当计算机显示一张图片到屏幕上的时候,实际上是由若干子任务组成:从存储单元中读取图片,解码图片,渲染像素点等等…,如果我们再放大每个子任务去看,每个子任务又能划分出更多的子任务。一直拆分到最小,对人类可见的被处理器直接执行的操作叫“机器指令”。下图中,虚线框属于软件层,实线框属于硬件层: 不同的 CPU 架构中,都有各自不同的机器指令,其中有些机器指令是原子的,这些指令的执行是单独的,不能分割,也不能被打断。也有一些指令不是原子的:这些指令在执行的时候,会被处理器在划分为多个更细微的操作在后台执行,也被称为微操作(micro-operations) ;我们暂时把焦点放到前边那一类,即原子指令上。原子指令可以分类两个大类: 1、存储/装载指令 (store-load) 2、RMW 指令 (read-modify-write) 存储装载原子指令 (store-load) 这些指令被用来从内存中存储和读取(装载)数据。大多数的 CPU 架构在设计时,都会确保这些操作在一些特定情况下是原子操作。比如基于 X86 架构实现的处理器,都会有MOV指令,用来从内存中读取字节数据交于 CPU,如果对字节对齐(aligned data) 的数据执行MOV操作,CPU 就会确保该操作是原子的。(aligned data:存储在内存中的信息,方便CPU轻松快速的读取)。 RMW (read-modify-write) 原子指令 一些复杂点的操作,仅仅通过存储和读取是无法完成的,比如自增操作(++x),至少需要 3个存储和读取的原子指令,这就会整个操作变的非原子化 。RMW 原子指令正是用来填补这种问题,它能让多次复杂操作变为一整个原子操作。这类指令非常多。一些 CPU 架构实现了它们,主要的分类如下,其他的都是这些指令的子集: ...

2014-08-20 · 2 min · 326 words · -

摄影构图

摄影构图 在《辞海》中是这样解释“构图”的,“构图"为艺术家为了表现作品的主题思想和美感效果,在一定的空间,安排和处理人、物的关系和位置,把个别或局部的形象组成艺术的整体。 https://zhuanlan.zhihu.com/p/52292163 https://zhuanlan.zhihu.com/p/21261635 中心构图, 中心构图是将主体放在画面中心构图,也是比较保险和常用的构图方法。这种方式的优点是能突出主体、明确,而且能够找到画面平衡点。 三分法, 三分法也是比较常见的构图方法。画面一般是横竖各两条线,形成“井”字排布,将画面分为九等分。很多手机和相机都会带这种构图参考线。交叉点是画面最吸引人的地方,将主体放在这个位置也是三分构图的基本原则。 水平线构图, 水平伸展的直线,可以让画面看起来比较宽阔、稳定、和谐。比如地平线和水平面,将两个空间分隔开,给人更多的想象空间。那么,水平线居于什么位置才是好的呢?这也要看情况。比如你想让画面和谐,可以选择三分之一的视觉兴趣线。如果你天空云比较艳丽,你可以多拍天空,如果云颜色单调,你想突出地上的景物,就多拍地面。另外,如果你想拍水面或湖面镜面倒影的感觉,也可以将水平线放在中间,增强对称感。 对称式构图, 说到对称,这里要介绍第4种构图方法。对称式构图。想起小时候学的轴对称图形,这里的对称就是让图像景物按对称或对称中心来构图。常与中心构图联合使用,主体位于画面中心。 框架式构图, 框架式构图,利用前景框架产生遮挡,增加画面的深度。当前景景物和主体有区别度时,通过前后的明显对比也更能突出主体,从更加新颖的角度去观察事物,让普通的风景变得与众不同。 引导线, 画面中出现清晰的线条可以引起关注,起到“吸睛”效果。引导线是画面中任何形式的线条,像直线、曲线、汇聚线、平行线、螺旋线等都可以对观众视线引导。它可以用于创造、增强纵深感等。另外,引导线也不一定是具体的线条,比如排列的或者有明显方向延伸趋势的物体,比如墙壁、道路,还有相同的颜色或者阴影等。 对角线和三角形, 构图中,也经常会用到对角线和三角形的构图。这不仅能够强化几何的美感,还可以带来一种动感的张力。 S型构图(曲线构图), 在自然界有变化万千的形状,其中S型曲线总会给人一种柔和、优雅的美感。让人看上去是延长的,变化的,非常有节奏和韵律。像一些风光大片中,道路、小溪、河流是比较常见的。S型构图也可以用在一些弧度小的曲线元素,像在拍摄美女时,可以利用S展示女性身材特有的魅力。 前景与纵深感, 前景在风光摄影中的作用还是比较强大的。前景掩映后是主体,整个空间被拉长,变得更加立体,更具有纵深感和层次感。 利用空白空间, “画留三分空,生气随之发”。画面中留出空白,通过简单的背景突出主体。可以为画面增加更多的深邃意味。这种留白也可以结合简约主义的构图,通过画面比较少的内容,来给观者更多的想象空间。 黄金三角形构图, 黄金三角形构图和三分法相似。只不过这里的直线是从四个角出发的,在图像左右两边形成两个直角三角形。我们要将画面的元素放在交叉位置。这样可以使画面更加丰富,多个三角形相互关联,相互呼应,更具趣味性。 黄金比例构图, 黄金分割的比例原是一个数学规律,也是在自然界中大量存在的。这个比例被更多地运用在绘画和设计中。黄金分割的比例是1:0.618。在摄影构图中比较高级,黄金分割点表现在对角线上的某条垂直线上的点,还是正方形边长为半径延伸出的螺旋线。但在拍摄时,如果你很难找到这个位置,可以利用九宫格构图,其实是黄金分割的简化版。 填满画面, 将主体填满整个画面,不为周围预留空间,可以让观众目光集中在主体,去排除干扰,更多地记住细节。 重复构图法, 重复构图,一般是在特定的情况下。比如水果摊、花丛、或者一面全是窗的墙。画面的内容是不断地重复要拍摄的主体,单调重复的方式来占据画面,这样也能够突出主体。 改变视角, 们经常看到很多摄影师在拍摄时会趴在地上,或者也有的站在楼顶或者更高的位置去拍摄。这其实是想以人眼高度之外的视角去拍摄物体。现在很多相机可以翻转屏幕,你可以试试仰拍。降低或者提高视角,或许会发现拍摄主体不同的美。

2014-08-13 · 1 min · 34 words · -

kindle

kindle 把pdf 发送到 kindle 把电子书比如 pdf 格式的文档 作为附件发送到 xxx@kindle.cn 设置/查看 amazon账号配置的kindle 邮箱地址 https://www.amazon.cn/hz/mycd/myx#/home/settings/payment 账户列表》 数字内容和设备》内容和设备》首选项》个人文档设置》〖发送至Kindle〗电子邮箱 注意!!! 记得设置白名单: “已认可的发件人电子邮箱列表”

2014-08-13 · 1 min · 18 words · -

linux tty

linux tty pts(pseudo-terminal slave) 用tty命令看看当前bash关联到了哪个tty tty 看 tty 都被哪些进程打开了 lsof /dev/pts/1 往tty里面直接写数据跟写标准输出是一样的效果 echo foo > /dev/pts/1 下面是 tty 和进程以及 I/O 设备交互的结构图: Input +--------------------------+ R/W +------+ ----------->| |<---------->| bash | | pts/1 | +------+ <-----------| |<---------->| lsof | Output | Foreground process group | R/W +------+ +--------------------------+ 两个pts间发送消息 echo "foo" > /dev/pts/2 # 红色字体, 颜色代码参照ANSI控制码 echo -e "\033[31mFoo\033[0m" > /dev/pts/2 列出系统支持的所有终端类型 toe -a 比较两个终端的区别 infocmp infocmp vt100 vt220 TTY历史 支持多任务的计算机出现之前 在计算机出来以前,人们就已经在使用一种叫teletype的设备,用来相互之间传递信息,看起来像下面这样: ...

2014-08-11 · 6 min · 1251 words · -

语法糖

语法糖 语法糖 (Syntactic sugar) ,也译为糖衣语法,是由英国计算机科学家彼得·约翰·兰达 (Peter J. Landin) 发明的一个术语,指计算机语言中添加的某种语法,这种语法对语言的功能并没有影响,但是更方便程序员使用。通常来说使用语法糖能够增加程序的可读性,从而减少程序代码出错的机会。 举个例子: 在C语言里用a[i]表示*(a+i),用a[i][j]表示*(*(a+i*数组a第二维的长度)+j),看来语法糖不是"现代语言"才有啊,连我们的老大哥C也有,而且这种写法简洁明了,也更好懂了。 实际上从面向过程到面向对象也是一种语法糖啊,C语言可以通过它的指针、类型转换,结构实现面向对象的编程风格,但是C++更进一步的推广了这种风格,更好用了,不过到了C#把OO的风格发挥得淋漓尽致。OO的编程风格对于面向过程来说是不是一种语法糖呢?如果生硬地照此理解,只有计算机硬件指令才不算语法糖,而其他一切利用编译器、汇编器将代码抽象,和自然语言更相近的手段都算语法糖。 现在很多很多编程思想,编程理论层出不穷,当然,对于学习来说我们是要抓住技术的核心,但对于工程来说如何提高工程质量,如何提高工程效率也是我们要关注的,既然这些语法糖能辅助我们以更好的方式编写代码为什么要"抵制"呢? 我想语法糖和其他编程思想一样重要,什么duck type,人本接口,最小接口,约定优于配置,其实不都是一些思想上的"语法糖"? 不过也并不是没有反对的声音,这其中就有图灵奖的第一个获得者: Alan Perlis。.net从2.0到3.0到3.5底层CLR并没有做更新,没有添加任何新的IL指令,所以C#从2.0到3.0中所有的特性都是语法糖,就算从1.0到2.0,也只有一个泛型不是语法糖,其余的新特性也都是如此,但是每一次C#发布新特性的时候我们不得不为之而鼓舞,为之而喝彩。新的语法可以酿造更好的编程风格,以前一些难以实现的方面现在也轻而易举了。 需要声明的是"语法糖"这个词绝非贬义词,它可以给我带来方便,是一种便捷的写法,编译器会帮我们做转换;而且可以提高开发编码的效率,在性能上也不会带来损失。

2014-08-10 · 1 min · 19 words · -

闭包, closure

闭包, closure 何为闭包 闭包是由函数及其相关的引用环境组合而成的实体(即:闭包=函数+引用环境) 闭包(Closure) 是一种函数(或函数和其相关的变量环境的组合),它不仅包含函数的定义,还“记住”了创建该函数时的 作用域中的变量。 通俗解释: 闭包就是一个函数 “带着”它所需要的外部变量一起打包起来使用。即使这些外部变量在函数外部已经不存在了,闭包仍然可以访问它们。 函数嵌套:闭包一定是函数内部的函数。 访问外部变量:内部函数访问了外部函数的局部变量。 变量生命周期延长:被闭包引用的外部变量不会在外部函数结束后立即销毁。 java内部类 wiloon.com/inner-class golang 闭包 func outer() func() int { x := 0 return func() int { x++ return x } } Javascript function outer() { let count = 0; return function inner() { count++; console.log(count); }; } const counter = outer(); counter(); // 输出 1 counter(); // 输出 2 python def outer(): x = 10 def inner(): print(x) return inner f = outer() f() # 输出 10 我们知道这个返回的闭包中包含了 Add 函数中提供的变量 y (也就是闭包产生的环境) 也就是说这个闭包包含了函数本身,以及一个对局部变量y的引用。 这里特别需要注意的一点是,如果y是定义在函数Add的调用栈里的一个变量,那么当Add()函数被调用完毕后,y就销毁了,这时候再用原来的指针去访问y就会出问题,因此这里就出现了一个原则: 闭包中引用的外部变量必须是在堆上分配的 实际上Go的编译器在处理到这个闭包时,会使用escape analyze来识别变量y的作用域,当发现变量y被一个闭包所引用时,就会把y转移到堆中 (这一过程称为变量逃逸)。 总结一下,闭包从底层理解,就是函数本身和其所需外部变量的引用,用R大的话来形容闭包的创建过程就是: ...

2014-08-10 · 5 min · 968 words · -

Git Stash

Git Stash 比如当前分支是 branch0, 新建了一个文件, 之后发现分支不对, 应该是在 branch1 上添加, 这时就可以用 git stash 暂存当前修改, 切换到 branch1 再 git stash pop. git stash # 如果有新添加的文件,那么就需要添加 -a 参数 git stash save -a "msg0" git stash list git stash pop git stash pop 开启某个修改暂存后,会在 stash list 里面将最近一次的修改暂存记录删除掉,而 git stash apply stash@{0} 则不会。 https://blog.csdn.net/daguanjia11/article/details/73810577 Git Stash用法 最近在使用Git管理项目工程的时候,遇到了很多问题,也学习到了很多关于Git常见使用的技巧,下面就其中关于Git Stash的用法和大家分享下。 首先,简单介绍下Git Stash命令的用法,详细的用法在man文档中有相关介绍,下面我来说明常见的使用。 git stash: 备份当前的工作区的内容,从最近的一次提交中读取相关内容,让工作区保证和上次提交的内容一致。同时,将当前的工作区内容保存到Git栈中。 git stash pop: 从Git栈中读取最近一次保存的内容,恢复工作区的相关内容。由于可能存在多个Stash的内容,所以用栈来管理,pop会从最近的一个stash中读取内容并恢复。 git stash list: 显示Git栈内的所有备份,可以利用这个列表来决定从那个地方恢复。 git stash clear: 清空Git栈。此时使用gitg等图形化工具会发现,原来stash的哪些节点都消失了。 ...

2014-08-09 · 1 min · 106 words · -

ssh 跳板(Jump Host)的使用

ssh 跳板(Jump Host)的使用 ProxyJump Host hostB HostName 10.124.44.91 User root Host arch-vm HostName 192.168.122.2 User root ProxyJump hostB # jump0: 跳板机 # server0: 目标服务器 host jump0 HostName 192.168.0.1 User user0 Host server0 HostName 192.168.0.2 User user0 ProxyCommand ssh -q -W %h:%p jump0 # %h: ~/.ssh/config 的语法, 代表主机名, 执行的时候会用 HostName 的值替换 # %p: 端口 # https://linux.die.net/man/5/ssh_config # -q 表示代理命令工作在静默模式下,而 -W 则表示 stdio 转发 这里说的 ssh 跳板,是指我们通过一个中继服务器其访问另一台内网服务器。典型的应用场景是在 VPN 网络中,我们进入了 VPN 服务器之后再访问另一个网段的内网服务器。 ...

2014-08-08 · 1 min · 171 words · -

委托模式

委托模式 http://blog.sina.com.cn/s/blog_5f13e9910100g3ob.html http://www.iteye.com/topic/29541 委托模式是软件设计模式中的一项基本技巧。在委托模式中,有两个对象参与处理同一个请求,接受请求的对象将请求委托给另一个对象来处理。委托模式是一项基本技巧,许多其他的模式,如状态模式、策略模式、访问者模式本质上是在更特殊的场合采用了委托模式。委托模式使得我们可以用聚合来替代继承,它还使我们可以模拟mixin。 “委托"在C#中是一个语言级特性,而在Java语言中没有直接的对应,但是我们可以通过动态代理来实现委托!代码如下: Java代码 收藏代码 import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; /* @author Liusheng 实现"委托"模式,用户需要实现InvocationHandler接口; 参考: http://www.uml.org.cn/j2ee/200411036.htm */ public abstract class Delegator implements InvocationHandler { //RelegateTo针对每个对象都要生成一个实例,因而非Static的log,代价比较高。 //protected Log _log = LogFactory.getLog(this.getClass()); //private static Log _log = LogFactory.getLog(RelegateTo.class); //————— protected Object obj_orgin = null; //原始对象 protected Object obj_proxy = null; //代理对象 //————— public Delegator() { //空 } public Delegator(Object orgin){ this.createProxy(orgin); } //————— protected Object createProxy(Object orgin) { obj_orgin = orgin; obj_proxy = Proxy.newProxyInstance( orgin.getClass().getClassLoader(), //加载器 ...

2014-08-08 · 2 min · 267 words · -

adb command

adb command pacman -S android-tools 在手机上打开USB调试 adb help adb kill-server sudo adb start-server adb devices #这个命令将登录设备的shell adb shell # adb push <本地路径> <远程路径> adb push <本地路径> <远程路径> #列出手机装的所有app 的包名 adb shell pm list packages 查看设备 –查看当前连接的设备, 连接到计算机的android设备或者模拟器将会列出显示 adb reboot bootloader adb pull Copies a specified file from an emulator/device instance to your development computer. 从电脑上发送文件到设备 –用push命令可以把本机电脑上的文件或者文件夹复制到设备(手机) adb push Copies a specified file from your development computer to an emulator/device instance. ...

2014-08-07 · 1 min · 153 words · -

EOF

EOF EOF(End of File),是ASCII码中的替换字符(Control-Z,代码26) EOF不是特殊字符,而是定义在 <stdio.h> 中的一个常量,一般等于-1。#define EOF (-1) 以EOF作为文件结束标志的文件,必须是文本文件。在文本文件中,数据都是以字符的ASCII代码值的形式存放。ASCII代码值的范围是0~127,不可能出现-1,因此可以用EOF作为文件结束标志。 ———————————————— 版权声明:本文为CSDN博主「咕咕怪」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。 原文链接:https://blog.csdn.net/weixin_38911591/article/details/89605221 EOF (as defined in the C language) is not a character/not an ASCII value. That’s why getc returns an int and not an unsigned char - because the character read could have any value in the range of unsigned char, and the return value of getc also needs to be able to represent the non-character value EOF (which is necessarily negative). ...

2014-07-31 · 1 min · 81 words · -

经度, 纬度, lng, lat

经度, 纬度, lng, lat 经度 longitude lng 116.677 纬度 latitude lat 39.86864

2014-07-31 · 1 min · 12 words · -

缓冲IO, 缓冲I/O, buffered I/O

缓冲IO, 缓冲I/O, buffered I/O 在系统调用的函数中有 STDIN_FILENO 和 STDOUT_FILENO, STDERR_FILENO, 分别对应标准输入(一般使键盘),标准输出 (一般使显示器),标准错误,(他们都是非负整数,属于文件描述符)。一般在老程序中也将他们分别用 0,1,2 代替,但建议还是使用他们的别名。 在标准IO函数中还有stdin,stdout,stderr等是 FILE * 类型,是属于文件指针,属于标准I/O,高级的输入输出函数。在<stdio.h>中。 而STDIN_FILENO等是文件描述符,是非负整数,一般定义为0, 1, 2,属于没有buffer的I/O,直接调用系统调用, 在<unistd.h>zh 。 stdin是文件指针,是FILE *类型 STDIN_FILENO是文件描述符,是int类型的 stdout和STDOUT_FILENO同样。 所以使用fread(,,stdin),而read(STDOUT_FILENO),因为函数的参数类型是不一样的 二. 下面使网上的一篇文章,讲解缓冲IO和不带缓冲IO 首先,先稍微了解系统调用的概念: 系统调用,英文名system call,每个操作系统都在内核里有一些内建的函数库,这些函数可以用来完成一些系统系统调用把应用程序的请求传给内核,调用相应的的内核函数完成所需的处理,将处理结果返回给应用程序,如果没有系统调用和内核函数,用户将不能编写大型应用程序,及别的功能,这些函数集合起来就叫做程序接口或应用编程接口(Application Programming Interface,API),我们要在这个系统上编写各种应用程序,就是通过这个API接口来调用系统内核里面的函数。如果没有系统调用,那么应用程序就失去内核的支持。 现在,再聊不带缓存的I/O操作: linix对IO文件的操作分为不带缓存的IO操作和标准IO操作 (即带缓存),刚开始,要明确以下几点: 1:不带缓存,不是直接对磁盘文件进行读取操作,像read()和write()函数,它们都属于系统调用,只不过在用户层没有缓存,所以叫做无缓存IO,但对于内核来说,还是进行了缓存,只是用户层看不到罢了。如果这一点看不懂,请看第二点; 2:带不带缓存是相对来说的,如果你要写入数据到文件上时 (就是写入磁盘上),内核先将数据写入到内核中所设的缓冲储存器,假如这个缓冲储存器的长度是100个字节,你调用系统函数: ssize_t write (int fd,const void * buf,size_t count); 写操作时,设每次写入长度count=10个字节,那么你几要调用10次这个函数才能把这个缓冲区写满,此时数据还是在缓冲区,并没有写入到磁盘,缓冲区满时才进行实际上的IO操作,把数据写入到磁盘上,所以上面说的“不带缓存不是就没有缓存直写进磁盘”就是这个意思。 那么,既然不带缓存的操作实际在内核是有缓存器的,那带缓存的IO操作又是怎么回事呢? 带缓存IO也叫标准IO,符合ANSI C 的标准IO处理,不依赖系统内核,所以移植性强,我们使用标准IO操作很多时候是为了减少对read()和write()的系统调用次数,带缓存IO其实就是在用户层再建立一个缓存区,这个缓存区的分配和优化长度等细节都是标准IO库代你处理好了,不用去操心,还是用上面那个例子说明这个操作过程: 上面说要写数据到文件上,内核缓存 (注意这个不是用户层缓存区)区长度是100字节,我们调用不带缓存的IO函数write()就要调用10次,这样系统效率低,现在我们在用户层建立另一个缓存区 (用户层缓存区或者叫流缓存),假设流缓存的长度是50字节,我们用标准C库函数的fwrite()将数据写入到这个流缓存区里面,流缓存区满50字节后在进入内核缓存区,此时再调用系统函数write()将数据写入到文件 (实质是磁盘)上,看到这里,你用该明白一点,标准IO操作fwrite()最后还是要掉用无缓存IO操作write,这里进行了两次调用fwrite()写100字节也就是进行两次系统调用write()。 如果看到这里还没有一点眉目的话,那就比较麻烦了,希望下面两条总结能够帮上忙: 无缓存IO操作数据流向路径:数据——内核缓存区——磁盘 标准IO操作数据流向路径:数据——流缓存区——内核缓存区——磁盘 三. 下面是一个网友的见解,以供参考: 不带缓存的I/O对是文件描述符操作,下面带缓存的I/O是针对流的。 标准I/O库就是带缓存的I/O,它由ANSI C标准说明。当然,标准I/O最终都会调用上面的I/O例程。标准I/O库代替用户处理很多细节,比如缓存分配、以优化长度执行I/O等。 标准I/O提供缓存的目的就是减少调用read和write的次数,它对每个I/O流自动进行缓存管理 (标准I/O函数通常调用malloc来分配缓存)。它提供了三种类型的缓存: 1) 全缓存。当填满标准I/O缓存后才执行I/O操作。磁盘上的文件通常是全缓存的。 2) 行缓存。当输入输出遇到新行符或缓存满时,才由标准I/O库执行实际I/O操作。stdin、stdout通常是行缓存的。 3) 无缓存。相当于read、write了。stderr通常是无缓存的,因为它必须尽快输出。 ...

2014-07-28 · 1 min · 133 words · -

CSS DIV居中

CSS DIV居中 CSS 如何使DIV层水平居中 今天用CSS碰到个很棘手的问题,DIV本身没有定义自己居中的属性, 网上很多的方法都是介绍用上级的text-align: center然后嵌套一层DIV来解决问题. 可是事实上这样的方法科学吗? 经过网络搜索和亲自实验得出以下结论: 正确的也是对页面构造没有影响的设置如下: 对需要水平居中的DIV层添加以下属性: margin-left: auto; margin-right: auto; 经过这么一番设置问题似乎解决了,在FF中已经居中了,可是在IE中看竟然还是没有居中! 郁闷了一下午,就是找不出问题所在,还特地比较了网上的文章竟然一模一样. 问题到底出在哪里呢? 感谢网友乐天无用帮忙找出了这个邪门问题的原因. 原来是L-Blog默认没有在HTML前加上DTD,于是IE就以HTML而不是XHTML来解释文档. 问题并不在CSS而在XHTML网页本身. 需要加上这样的代码才能使得上述设置有效果: 如果您希望更为严格的XHTML 1.0 Strict或者XHTML 1.1请查阅相关文档. 以上测试均基于Windows XP SP2版IE6和FireFox 1.0最终版. 如何使DIV居中 主要的样式定义如下: body {TEXT-ALIGN: center;} #center { MARGIN-RIGHT: auto; MARGIN-LEFT: auto; } 说明: 首先在父级元素定义TEXT-ALIGN: center;这个的意思就是在父级元素内的内容居中;对于IE这样设定就已经可以了。但在mozilla中不能居中。解决办法就是在子元素定义时候设定时再加上"MARGIN-RIGHT: auto;MARGIN-LEFT: auto; " 需要说明的是,如果你想用这个方法使整个页面要居中,建议不要套在一个DIV里,你可以依次拆出多个div,只 要在每个拆出的div里定义MARGIN-RIGHT: auto;MARGIN-LEFT: auto; 就可以了。 如何使图片在DIV 中垂直居中,用背景的方法。举例: body{BACKGROUND: url(http://www.w3cn.org/style/001/logo_w3cn_194x79.gif) #FFF no-repeat center;} 关键就是最后的center,这个参数定义图片的位置。还可以写成"top left"(左上角)或者"bottom right"等,也可以直接写数值"50 30" 如何使文本在DIV中垂直居中 如果是文字,便不能用背景方法,可以用增高行距的办法变通实现垂直居中,完整代码如下: ...

2014-06-25 · 1 min · 73 words · -

子查询

子查询 子查询是多表查询的一种形式。子查询就是次要查询,它返回的结果数据被用 于主查询的条件中。它返回的结果可以是一行或多行。比如: 例1//返回一条记录 select * from emp where deptno=(select deptno from dept where dept_name=‘SALES’) 例2//返回多条记录 select * from emp where deptno in (select deptno from dept where dept_addr=‘北京’) 由上例可以看出,子查询并不要求两个表有相关字段,只要得到子查询的结果集 就行,用于主查询,而连接查询,则必须要求两个表有相关字段。 2.连接查询是对两个表逐记录 (一行一行地) 进行相关查询,例1可写为连接查询 ,例2不可以写为连接查询,因为子查询返回多行记录。 select * from emp a, dept b where a.deptno= b.deptno and b.dept_name=‘SALES’ 上述形式为内连接,还有外连接 oracle中的字段后面有加号是什么意思,多说一点详细一点 a.emp_no = b.emp_no (+) 不论把(+)写在等号左边项还是右边项,统称为外连接 在内连接中,只返回那些在连接表中有匹配数据的数据行 外连接即在被连接的表中加入一个空行来与没有匹配行的数据进行匹配 比如查询员工所属的部门,总裁不属于任何部门, (老板不属于任何部门,dname 项是空的) select e.emp_name ename,d.dept_name dname from emp e, dept d where e.dept_no=d.dept_no(+) ename dname —————————— sam SALES ...

2014-06-19 · 1 min · 81 words · -

Chrome浏览器运行参数的方法来模拟手机

Chrome 浏览器运行参数的方法来模拟手机 http://www.weste.net/2014/3-26/96040.html 以前我们介绍过如何通过修改Chrome浏览器运行参数的方法来模拟手机访问网站,但是在Chrome 32和33版本以后增加了更加便捷的方法,在开发者工具中只需要设置一下就能方便的模拟各种手机型号的访问效果了。 以前我们介绍过如何通过修改Chrome浏览器运行参数的方法来模拟手机访问网站,但是在Chrome 32和33版本以后增加了更加便捷的方法,在开发者工具中只需要设置一下就能方便的模拟各种手机型号的访问效果了。 方法如下: 打开Chrome浏览器,需要32以后版本的。笔者使用的是Chrome 33版本。 打开"开发者工具",快捷键 (F12或者Ctrl+Shift+i) 。 \ 在"开发者工具"界面的右侧有个"Show drawer"按钮,点击后在"drawer"界面再点击"Emulation"。 \ 这个界面就一目了然了,Device里面可以选择各种手机或者平板设备,大概有20种之多。User Agent和Sensors显示了模拟的数据。点击"Emulate"按钮就可以生效了。 \ 然后就在地址栏里面输入网址吧!看看模拟的效果怎么样? 谷歌Chrome浏览器模拟手机浏览器的方法 (修改启动参数的方法) : http://www.weste.net/2013/5-25/91691.html

2014-06-17 · 1 min · 25 words · -

HashSet, TreeSet, LinkedHashSet

HashSet, TreeSet, LinkedHashSet 在一个set中,是没有重复元素的。这也是使用set最主要的原因之一。Set的实现类有三个: HashSet,TreeSet,LinkedHashSet。什么时候使用哪一种实现类?。简单地说,如果我们想要一个快速的set,那么我们应该使用HashSet;如果我们需要一个已经排好序的set,那么TreeSet应该被使用;如果我们想一个可以根据插入顺序来读取的set,那么LinkedHashSet应该被使用。 接口 Set接口继承了Collection接口。在set中,不允许有重复的元素。每一个元素在set中都是唯一的。我们可以简单地添加元素至一个set中,最后,我们会得到一个自动删除重复元素的set。 HashSet vs. TreeSet vs. LinkedHashSet HashSet 是使用一个哈希表实现的。元素是无序的。add、remove 及contains 方法的时间复杂度是一个常量 O(1)。 TreeSet 是使用红黑树 来实现的。元素在set中被排好序,但是add、remove及contains方法的时间复杂度为O(log(n))。它提供了几个方法用来处理有序的set,比如first(),last(),headSet(),tailSet()等等。 LinkedHashSet LinkedHashSet介于HashSet与TreeSet之间。它由一个执行hash表的链表实现,因此,它提供顺序插入。基本方法的时间复杂度为O(1)。 HashMap和HashSet的区别是Java面试中最常被问到的问题。如果没有涉及到Collection框架以及多线程的面试,可以说是不完整。而Collection框架的问题不涉及到HashSet和HashMap,也可以说是不完整。HashMap和HashSet都是collection框架的一部分,它们让我们能够使用对象的集合。collection框架有自己的接口和实现,主要分为Set接口,List接口和Queue接口。它们有各自的特点,Set的集合里不允许对象有重复的值,List允许有重复,它对集合中的对象进行索引,Queue的工作原理是FCFS算法(First Come, First Serve)。 首先让我们来看看什么是HashMap和HashSet,然后再来比较它们之间的分别。 什么是HashSet HashSet实现了Set接口,它不允许集合中有重复的值,当我们提到HashSet时,第一件事情就是在将对象存储在HashSet之前,要先确保对象重写equals()和hashCode()方法,这样才能比较对象的值是否相等,以确保set中没有储存相等的对象。如果我们没有重写这两个方法,将会使用这个方法的默认实现。 public boolean add(Object o)方法用来在Set中添加元素,当元素值重复时则会立即返回false,如果成功添加的话会返回true。 什么是HashMap HashMap实现了Map接口,Map接口对键值对进行映射。Map中不允许重复的键。Map接口有两个基本的实现,HashMap和TreeMap。TreeMap保存了对象的排列次序,而HashMap则不能。HashMap允许键和值为null。HashMap是非synchronized的,但collection框架提供方法能保证HashMap synchronized,这样多个线程同时访问HashMap时,能保证只有一个线程更改Map。 public Object put(Object Key,Object value)方法用来将元素添加到map中。 HashSet和HashMap的区别 对于HashSet而言,它的底层是基于HashMap实现的。HashSet底层使用HashMap来保存所有元素。 HashSet的实现其实非常简单,它只是封装了一个HashMap对象来存储所有的集合元素。所有放入HashSet中的集合元素实际上由HashMap的key来保存,而HashMap的value则存储了一个PRESENT,它是一个静态的Object对象。 HashSet的绝大部分方法都是通过调用HashMap的方法来实现的,因此HashSet和HashMap两个集合在实现本质上是相同的。 注意:由于HashSet的add()方法添加集合元素实际上转变为调用HashMap的put()方法来添加key-value对,当新放入HashMap的Entry中key与集合中原有Entry的key相同 (hashCode()返回值相等,通过equals比较也返回true)时,新添加的Entry的value将覆盖原来Entry的value,但key不会有任何改变。因此,如果向HashSet中添加一个已经存在的元素,新添加的集合元素 (底层由HashMap的key保存)不会覆盖已有的集合元素。 ———————————————— 版权声明:本文为CSDN博主「bear_wr」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。 原文链接:https://blog.csdn.net/bear_wr/article/details/52275874

2014-06-17 · 1 min · 53 words · -

MQ JMS

MQ JMS http://blog.csdn.net/xyw_blog/article/details/9128165 MQ简介: MQ全称为Message Queue, 消息队列 (MQ) 是一种应用程序对应用程序的通信方法。应用程序通过写和检索出入列队的针对应用程序的数据 (消息) 来通信,而无需专用连接来链接它们。消息传递指的是程序之间通过在消息中发送数据进行通信,而不是通过直接调用彼此来通信,直接调用通常是用于诸如远程过程调用的技术。排队指的是应用程序通过队列来通信。队列的使用除去了接收和发送应用程序同时执行的要求。其中较为成熟的MQ产品有IBMWEBSPHERE MQ。 MQ特点: MQ的消费-生产者模型的一个典型的代表,一端往消息队列中不断的写入消息,而另一端则可以读取或者订阅队列中的消息。MQ和JMS类似,但不同的是JMS是SUN JAVA消息中间件服务的一个标准和API定义,而MQ则是遵循了AMQP协议的具体实现和产品。 使用场景: 在项目中,将一些无需即时返回且耗时的操作提取出来,进行了异步处理,而这种异步处理的方式大大的节省了服务器的请求响应时间,从而提高了系统的吞吐量。 JMS简介: JMS即Java消息服务 (Java Message Service) 应用程序接口是一个Java平台中关于面向消息中间件 (MOM) 的API,用于在两个应用程序之间,或分布式系统中发送消息,进行异步通信。Java消息服务是一个与具体平台无关的API,绝大多数MOM提供商都对JMS提供支持。 定义: JMS (Java Messaging Service) 是Java平台上有关面向消息中间件(MOM)的技术规范,它便于消息系统中的Java应用程序进行消息交换,并且通过提供标准的产生、发送、接收消息的接口简化企业应用的开发,翻译为Java消息服务。 简介: JMS是一种与厂商无关的 API,用来访问消息收发系统消息。它类似于JDBC(Java DatabaseConnectivity): 这里,JDBC 是可以用来访问许多不同关系数据库的 API,而 JMS 则提供同样与厂商无关的访问方法,以访问消息收发服务。许多厂商目前都支持JMS,包括 IBM 的 MQSeries、BEA的 Weblogic JMS service和 Progress 的 SonicMQ,这只是几个例子。 JMS 使您能够通过消息收发服务 (有时称为消息中介程序或路由器) 从一个 JMS 客户机向另一个JMS客户机发送消息。消息是 JMS 中的一种类型对象,由两部分组成: 报头和消息主体。报头由路由信息以及有关该消息的元数据组成。消息主体则携带着应用程序的数据或有效负载。根据有效负载的类型来划分,可以将消息分为几种类型,它们分别携带: 简单文本(TextMessage)、可序列化的对象 (ObjectMessage)、属性集合 (MapMessage)、字节流 (BytesMessage)、原始值流 (StreamMessage),还有无有效负载的消息 (Message)。 JMS和MQ的关系: JMS是一个用于提供消息服务的技术规范,它制定了在整个消息服务提供过程中的所有数据结构和交互流程。而MQ则是消息队列服务,是面向消息中间件 (MOM) 的最终实现,是真正的服务提供者;MQ的实现可以基于JMS,也可以基于其他规范或标准。 支持JMS的开源MQ: 目前选择的最多的是ActiveMQ。 ...

2014-06-11 · 1 min · 178 words · -

JSR168

JSR168 JSR168是Java 规范要求 (Java Specification Request ,JSR) 的缩写,它为创建Portlet建立标准的API。很多重量级的Portal开发商和开源项目组参与了Java标准化组织 (Java Community Process) 创建JSR168标准的过程,并且很多Portal产品开始支持JSR 168。JSR168在2003年10月正式发布。最主要的Portal开发商已经宣布计划支持JSR 168标准,查看JSR 168站点 (http://www.jcp.org/en/jsr/detail?id=168 ) 可以得到目前为止JSR 168支持者的完整列表。 按照Java标准化组织 (Java Community Process) 所述,JSR 168 portlet拥有一个适用于所有Portal客户端的简单的、标准的API,支持多种类型的客户端 (多设备、多浏览器) ,支持本地化和国际化,允许门户应用程序的热部署和重新部署,并且包含声明性安全 (与servlet和企业JavaBean规范中使用的机制相同) 。 现在开发商只需要支持一种Portlet集。结果,更多的ISV提供他们自己的通用的、开箱即用 (out-of-the-box) 的Portal集成构件。这是值得客户高兴的时刻,因为开箱即用的应用程序集成现在无需考虑选择那个Portal开发商就可以使用。 JSR 168意味着在Portal市场上,争夺主导地位的优势不再是哪个开发商拥有最多数目ISV的开箱即用集成。相反,标准化通过使ISV支持他们自己的Porlet统一了这一领域。客户的风险和成本降低,并且不再根据重建Portlet的业务量来选择门户开发商。在选择Portal开发商的时候,主要的决定性因素将是Portal产品与客户企业体系结构的适应程度。 对程序员简而言之,开发符合JSR168规范的Portlet将可以顺利移植到符合该规范的不同Portal平台上!

2014-06-11 · 1 min · 36 words · -