Redis, Memcache, Guava, Ehcache 中的算法

Redis, Memcache, Guava, Ehcache 中的算法 缓存那些事,一是内存爆了要用LRU(最近最少使用, Least Recently Used)、LFU(最少访问次数, Least Frequently Used)、FIFO的算法清理一些;二是设置了超时时间的键过期便要删除,用主动或惰性的方法。 在看所有的细节之前,可以看一篇相当专业的《缓存算法》,世界真宽阔,算法真奇妙。 LRU 简单粗暴的Redis 今天看Redis3.0的发行通告里说,LRU算法大幅提升了,就翻开源码来八卦一下,结果哭笑不得,这旧版的"近似LRU"算法,实在太简单,太偷懒,太Redis了。 在Github的Redis项目里搜索lru,找到代码在redis.c的freeMemoryIfNeeded()函数里。 先看2.6版的代码: 竟然就是随机找三条记录出来,比较哪条空闲时间最长就删哪条,然后再随机三条出来,一直删到内存足够放下新记录为止…….可怜我看配置文档后的想象,一直以为它会帮我在整个Redis里找空闲时间最长的,哪想到我有一百万条记录的时候,它随便找三条就开始删了。 好,收拾心情再看3.0版的改进: 现在每次随机五条记录出来,插入到一个长度为十六的按空闲时间排序的队列里,然后把排头的那条删掉,然后再找五条出来,继续尝试插入队列………嗯,好了一点点吧,起码每次随机多了两条,起码不只在一次随机的五条里面找最久那条,会连同之前的一起做比较…… 中规中矩的Memcached 相比之下,Memcached实现的是再标准不过的LRU算法,专门使用了一个教科书式的双向链表来存储slab内的LRU关系,代码在item.c里,详见memcached源码分析–LRU队列与item结构体,元素插入时把自己放到列头,删除时把自己的前后两个元素对接起来,更新时先做删除再做插入。 分配内存超限时,很自然就会从LRU的队尾开始清理。 同样中规中矩的Guava Cache Guava Cache同样做了一个双向的Queue,见LocalCache中的AccessQueue类,也会在超限时从Queue的队尾清理,见evictEntries()函数。 和Redis旧版一样的Ehcache/Hazelcast 看文档,居然和Redis2.6一样,直接随机8条记录,找出最旧那条,刷到磁盘里,再看代码,Eviction类 和 OnHeapStore的evict()函数。 再看Hazelcast,几乎一样,随机取25条。 这种算法,切换到LFU也非常简单。 小结 不过后来再想想,也许Redis本来就不是主打做Cache的,这种内存爆了需要通过LRU删掉一些元素不是它的主要功能,默认设置都是noeviction——内存不够直接报错的,所以就懒得建个双向链表,而且每次访问时都要更新它了,看Google Group里长长的讨论,新版算法也是社区智慧的结晶。何况,Ehcache和Hazelcast也是和它的旧版一样的算法,Redis的新版还比这两者强了。 后来,根据@刘少壮同学的提示,JBoss的InfiniSpan里还实现了比LRU更高级的LIRS算法,可以避免一些冷数据因为某个原因被大量访问后,把热数据挤占掉。 过期键删除 如果能为每一个设置了过期的元素启动一个Timer,一到时间就触发把它删掉,那无疑是能最快删除过期键最省空间的,在Java里用一条DeplayQueue存着,开条线程不断的读取就能做到。但因为该线程消耗CPU较多,在内存不紧张时有点浪费,似乎大家都不用这个方法。 所以有了惰性检查,就是每次元素被访问时,才去检查它是否已经超时了,这个各家都一样。但如果那个元素后来都没再被访问呢,会永远占着位子吗?所以各家都再提供了一个定期主动删除的方式。 Redis 代码在redis.c的activeExpireCycle()里,看过文档的人都知道,它会在主线程里,每100毫秒执行一次,每次随机抽20条Key检查,如果有1/4的键过期了,证明此时过期的键可能比较多,就不等100毫秒,立刻开始下一轮的检查。不过为免把CPU时间都占了,又限定每轮的总执行时间不超过1毫秒。 Memcached Memcached里有个文不对题的LRU爬虫线程,利用了之前那条LRU的队列,可以设置多久跑一次(默认也是100毫秒),沿着列尾一直检查过去,每次检查LRU队列中的N条数据。虽然每条Key设置的过期时间可能不一样,但怎么说命中率也比Redis的随机选择N条数据好一点,但它没有Redis那种过期的多了立马展开下一轮检查的功能,所以每秒最多只能检查10N条数据,需要自己自己权衡N的设置。 Guava Cache 在Guava Cache里,同一个Cache里所有元素的过期时间是一样的,所以它比Memached更方便,顺着之前那条LRU的Queue检查超时,不限定个数,直到不超时为止。而且它这个检查的调用时机并不是100毫秒什么的,而是每次各种写入数据时的preWriteCleanup()方法中都会调用。 吐槽一句,Guava的Localcache类里面已经4872行了,一点都不轻量了。 Ehcache Ehcache更乱,首先它的内存存储中只有惰性检查,没有主动检查过期的,只会在内存超限时不断用近似LRU算法(见上)把内存中的元素刷到磁盘中,在文件存储中才有超时检查的线程,FAQ里专门解释了原因。 然后磁盘存储那有一条8小时左右跑一次的线程,每次遍历所有元素…..见DiskStorageFactory里的DiskExpiryTask。 一圈看下来,Ehcache的实现最弱。 文章持续修改,转载时请保留原链接: http://calvin1978.blogcn.com/articles/lru.html

2015-06-28 · 1 min · 56 words · -

Red-Black Tree,红黑树, R-B Tree

Red-Black Tree, 红黑树, R-B Tree https://github.com/julycoding/The-Art-Of-Programming-By-July/blob/master/ebook/zh/03.01.md 二叉查找树 由于红黑树本质上就是一棵二叉查找树,所以在了解红黑树之前,咱们先来看下二叉查找树。 二叉查找树 (Binary Search Tree) ,也称有序二叉树 (ordered binary tree) ,排序二叉树 (sorted binary tree) ,是指一棵空树或者具有下列性质的二叉树: 若任意结点的左子树不空,则左子树上所有结点的值均小于它的根结点的值; 若任意结点的右子树不空,则右子树上所有结点的值均大于它的根结点的值; 任意结点的左、右子树也分别为二叉查找树。 没有键值相等的结点 (no duplicate nodes) 。 因为,一棵由n个结点,随机构造的二叉查找树的高度为lgn,所以顺理成章,一般操作的执行时间为O (lgn) . (至于n个结点的二叉树高度为lgn的证明,可参考算法导论 第12章 二叉查找树 第12.4节) 。 但二叉树若退化成了一棵具有n个结点的线性链后,则此些操作最坏情况运行时间为O (n) 。后面我们会看到一种基于二叉查找树-红黑树,它通过一些性质使得树相对平衡,使得最终查找、插入、删除的时间复杂度最坏情况下依然为O (lgn) 。 红黑树 前面我们已经说过,红黑树,本质上来说就是一棵二叉查找树,但它在二叉查找树的基础上增加了着色和相关的性质使得红黑树相对平衡,从而保证了红黑树的查找、插入、删除的时间复杂度最坏为O(log n)。 但它是如何保证一棵n个结点的红黑树的高度始终保持在h = logn的呢?这就引出了红黑树的5条性质: 每个结点要么是红的,要么是黑的。 根结点是黑的。 每个叶结点 (叶结点即指树尾端NIL指针或NULL结点) 是黑的。 如果一个结点是红的,那么它的俩个儿子都是黑的。 对于任一结点而言,其到叶结点树尾端NIL指针的每一条路径都包含相同数目的黑结点。 正是红黑树的这5条性质,使得一棵n个结点是红黑树始终保持了logn的高度,从而也就解释了上面我们所说的"红黑树的查找、插入、删除的时间复杂度最坏为O(log n)“这一结论的原因。 红黑树是不符合AVL树的平衡条件的,即每个节点的左子树和右子树的高度最多差1的二叉查找树。但是提出了为节点增加颜色,红黑是用非严格的平衡来换取增删节点时候旋转次数的降低,任何不平衡都会在三次旋转之内解决,而AVL是严格平衡树,因此在增加或者删除节点的时候,根据不同情况,旋转的次数比红黑树要多。所以红黑树的插入效率更高!!! 这里引用一下知乎上的回答: Answer 1: 如果插入一个node引起了树的不平衡,AVL和RB-Tree都是最多只需要2次旋转操作,即两者都是O(1);但是在删除node引起树的不平衡时,最坏情况下,AVL需要维护从被删node到root这条路径上所有node的平衡性,因此需要旋转的量级O(logN),而RB-Tree最多只需3次旋转,只需要O(1)的复杂度。 其次,AVL的结构相较RB-Tree来说更为平衡,在插入和删除node更容易引起Tree的unbalance,因此在大量数据需要插入或者删除时,AVL需要rebalance的频率会更高。因此,RB-Tree在需要大量插入和删除node的场景下,效率更高。自然,由于AVL高度平衡,因此AVL的search效率更高。 map的实现只是折衷了两者在search、insert以及delete下的效率。总体来说,RB-tree的统计性能是高于AVL的。 作者: Acjx 链接: http://www.zhihu.com/question/20545708/answer/58717264 Answer 2 这个总结比较好: 红黑树的 查询性能略微逊色于AVL树,因为他比avl树会稍微不平衡最多一层,也就是说红黑树的查询性能只比相同内容的avl树最多多一次比较,但是,红黑树在插入和删除上完爆avl树, avl树每次插入删除会进行大量的平衡度计算,而红黑树为了维持红黑性质所做的红黑变换和旋转的开销,相较于avl树为了维持平衡的 开销要小得多 ...

2015-06-28 · 1 min · 148 words · -

Iterator, Enumeration

Iterator, Enumeration http://www.cnblogs.com/skywang12345/p/3311275.html Iterator和Enumeration区别 在Java集合中,我们通常都通过 “Iterator(迭代器)” 或 “Enumeration(枚举类)” 去遍历集合。今天,我们就一起学习一下它们之间到底有什么区别。 我们先看看 Enumeration.java 和 Iterator.java的源码,再说它们的区别。 Enumeration是一个接口,它的源码如下: package java.util; public interface Enumeration { boolean hasMoreElements(); E nextElement(); } Iterator也是一个接口,它的源码如下: package java.util; public interface Iterator { boolean hasNext(); E next(); void remove(); } 看完代码了,我们再来说说它们之间的区别。 (01) 函数接口不同 Enumeration只有2个函数接口。通过Enumeration,我们只能读取集合的数据,而不能对数据进行修改。 Iterator只有3个函数接口。Iterator除了能读取集合的数据之外,也能数据进行删除操作。 (02) Iterator支持fail-fast机制,而Enumeration不支持。 Enumeration 是JDK 1.0添加的接口。使用到它的函数包括Vector、Hashtable等类,这些类都是JDK 1.0中加入的,Enumeration存在的目的就是为它们提供遍历接口。Enumeration本身并没有支持同步,而在Vector、Hashtable实现Enumeration时,添加了同步。 而Iterator 是JDK 1.2才添加的接口,它也是为了HashMap、ArrayList等集合提供遍历接口。Iterator是支持fail-fast机制的: 当多个线程对同一个集合的内容进行操作时,就可能会产生fail-fast事件。 第2部分 Iterator和Enumeration实例 下面,我们编写一个Hashtable,然后分别通过 Iterator 和 Enumeration 去遍历它,比较它们的效率。代码如下: 按 Ctrl+C 复制代码 按 Ctrl+C 复制代码 ...

2015-06-27 · 1 min · 77 words · -

ReferenceQueue

ReferenceQueue 引用队列 ReferenceQueue 使用 SoftReference,WeakReference,PhantomReference 的时候,可以关联一个 ReferenceQueue。那么当垃圾回收器准备回收一个被引用包装的对象时,该引用会被加入到关联的 ReferenceQueue。程序可以通过判断引用队列中是否已经加入引用, 来了解被引用的对象是否被GC回收。 作者: leilifengxingmw 链接: https://www.jianshu.com/p/6ae4f53a4752 来源: 简书 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。 http://www.iflym.com/index.php/java-programe/201407140001.html 在java的引用体系中,存在着强引用,软引用,虚引用,幽灵引用,这4种引用类型。在正常的使用过程中,我们定义的类型都是强引用的,这种引用类型在回收中,只有当其它对象没有对这个对象的引用时,才会被GC回收掉。简单来说,对于以下定义: Object obj = new Object(); Ref ref = new Ref(obj); 在这种情况下,如果 ref 没有被 GC,那么 obj 这个对象肯定不会 GC 的。因为 ref 引用到了 obj。如果 obj 是一个大对象呢,多个这种对象的话,应用肯定一会就挂掉了。 那么,如果我们希望在这个体系中,如果obj没有被其它对象引用,只是在这个Ref中存在引用时,就把obj对象gc掉。这时候就可以使用这里提到的Reference对象了。 我们希望当一个对象被gc掉的时候通知用户线程,进行额外的处理时,就需要使用引用队列了。ReferenceQueue即这样的一个对象,当一个obj被gc掉之后,其相应的包装类,即ref对象会被放入queue中。我们可以从queue中获取到相应的对象信息,同时进行额外的处理。比如反向操作,数据清理等。 2 使用队列进行数据监控 一个简单的例子,通过往map中放入10000个对象,每个对象大小为1M字节数组。使用引用队列监控被放入的key的回收情况。代码如下所示: Object value = new Object(); Map<Object, Object> map = new HashMap<>(); for(int i = 0;i < 10000;i++) { byte[] bytes = new byte[_1M]; WeakReference<byte[]> weakReference = new WeakReference<byte[]>(bytes, referenceQueue); map.put(weakReference, value); } System.out.println("map.size->" + map.size()); 这里使用了weakReference对象,即当值不再被引用时,相应的数据被回收。另外使用一个线程不断地从队列中获取被gc的数据,代码如下: ...

2015-06-26 · 2 min · 262 words · -

CountDownLatch

CountDownLatch CountDownLatch是一个同步辅助类,在完成一组正在其他线程中执行的操作之前,它允许一个或多个线程一直等待。 CountDownLatch和CyclicBarrier的区别 (01) CountDownLatch的作用是允许1或N个线程等待其他线程完成执行;而CyclicBarrier则是允许N个线程相互等待。 (02) CountDownLatch的计数器无法被重置;CyclicBarrier的计数器可以被重置后使用,因此它被称为是循环的barrier。 下面通过CountDownLatch实现: “主线程"等待"5个子线程"全部都完成"指定的工作(休眠1000ms)“之后,再继续运行。 import java.util.concurrent.CountDownLatch; import java.util.concurrent.CyclicBarrier; public class CountDownLatchTest1 { private static int LATCH_SIZE = 5; private static CountDownLatch doneSignal; public static void main(String[] args) { try { doneSignal = new CountDownLatch(LATCH_SIZE); // 新建5个任务 for(int i=0; i<LATCH_SIZE; i++) new InnerThread().start(); System.out.println("main await begin."); // "主线程"等待线程池中5个任务的完成 doneSignal.await(); System.out.println("main await finished."); } catch (InterruptedException e) { e.printStackTrace(); } } static class InnerThread extends Thread{ public void run() { try { Thread.sleep(1000); System.out.println(Thread.currentThread().getName() + " sleep 1000ms."); // 将CountDownLatch的数值减1 doneSignal.countDown(); } catch (InterruptedException e) { e.printStackTrace(); } } } } 主线程通过doneSignal.await()等待其它线程将doneSignal递减至0。其它的5个InnerThread线程,每一个都通过doneSignal.countDown()将doneSignal的值减1;当doneSignal为0时,main被唤醒后继续执行。 ...

2015-06-26 · 1 min · 97 words · -

JAVA的可变类与不可变类

JAVA的可变类与不可变类 可变类和不变类(Mutable and immutable class)的初步定义: 可变类: 当你获得这个类的一个实例引用时,你可以改变这个实例的内容。 不变类: 当你获得这个类的一个实例引用时,你不可以改变这个实例的内容。不可变类的实例一但创建,其内在成员变量的值就不能被修改。 如何创建一个自己的不可变类: .所有成员都是private .不提供对成员的改变方法,例如: setXXXX .确保所有的方法不会被重载。手段有两种: 使用final Class(强不可变类),或者将所有类方法加上final(弱不可变类)。 .如果某一个类成员不是原始变量(primitive)或者不可变类,必须通过在成员初始化(in)或者get方法(out)时通过深度clone方法,来确保类的不可变。 一个示例 import java.util.Date; public final class BrokenPerson { private String firstName; private String lastName; private Date dob; public BrokenPerson( String firstName, public BetterPerson( String firstName, String lastName, Date dob) String lastName, Date dob) { { this.firstName = firstName; this.firstName = firstName; this.lastName = lastName; this.lastName = lastName; this.dob = dob; //error this.dob = new Date( dob.getTime() ); //correct ...

2015-06-26 · 2 min · 359 words · -

archlinux install

archlinux install download iso https://mirrors.tuna.tsinghua.edu.cn/archlinux/iso/ curl -O https://mirrors.tuna.tsinghua.edu.cn/archlinux/iso/2025.10.01/archlinux-2025.10.01-x86_64.iso Ventoy, usb-stick yay -S ventoy-bin copy to ventoy usb partition 用 ventoy U 盘引导系统 启动 sshd 设置 root 密码 进入 root@archiso 之后先设置 root 密码 passwd 连无线网 # 20250501, archlinux 的 iso 里默认已经安装 wpa_supplicant # start systemd-networkd and systemd-resolved service systemctl start systemd-networkd systemctl start systemd-resolved.service # wifi network 有默认配置 /etc/systemd/network/wifi.network # 设置 wifi 密码, 注意后面的 wlp3s0 替换成无线网卡的名字, 用 `ip a` 看一下 # psk 里写明文的密码 cat /etc/wpa_supplicant/wpa_supplicant-wlp3s0.conf network={ ssid="w1100n" psk="wifi_password_0" } sudo systemctl start wpa_supplicant@wlp3s0 systemctl start sshd 在 virtual box 里安装得设置一下端口映射 ...

2015-06-25 · 4 min · 655 words · -

windows netsh 端口转发

windows netsh 端口转发 http://aofengblog.blog.163.com/blog/static/631702120148573851740/ 在windows上用netsh动态配置端口转发 下载LOFTER客户端 使用多个虚拟机,将开发环境和工作沟通环境分开 (即时通,办公系统都只能在windows下使用…) ,将开发环境的服务提供给外部访问时,需要在主机上通过代理配置数据转发。 VirtualBox提供了端口转发的功能,可以将主机中的端口转发至指定IP的虚拟机中的端口,支持TCP协议和UDP协议。但有一个缺点: 需要重启虚拟主机才生效。 其实在Windows中,如果想做端口转发,可以使用Windows自身携带的服务:netsh,使用netsh interface portproxy指令,新增和修改配置信息后,即时生效,并且重启系统后配置信息仍然存在,非常方便。适用于WindowsXP、Windows7,其他的版本还没有试过,支持IPv4和IPv6,但是只支持TCP协议。 新增端口转发 命令 netsh interface portproxy add v4tov4 - 添加通过 IPv4 的 IPv4 和代理连接到的侦听项目。 netsh interface portproxy add v4tov6 - 添加通过 IPv6 的 IPv4 和代理连接到的侦听项目。 netsh interface portproxy add v6tov4 - 添加通过 IPv4 的 IPv6 和代理连接到的侦听项目。 netsh interface portproxy add v6tov6 - 添加通过 IPv6 的 IPv6 和代理连接到的侦听项目。 命令语法 以netsh interface portproxy add v4tov4为例,其语法格式如下: netsh interface portproxy add v4tov4 [listenport=]| ...

2015-06-13 · 2 min · 399 words · -

TypeScript

TypeScript TypeScript是一种由微软开发的自由和开源的编程语言。它是JavaScript的一个超集,兼容JavaScript,可以载入JS代码然后运行。 它与JavaScript相比进步的地方包括: 加入注释,让编译器理解所支持的对象和函数,编译器会移除注释,不会增加开销。 而JavaScript只是一个脚本语言,并非设计用于开发大型 Web 应用,JavaScript 没有提供类和模块的概念,而TypeScript扩展实现了这些特性。 它扩展了 JavaScript 的语法,因此现有的JavaScript代码可与其代码一起工作无需任何修改,它通过类型注解提供编译时的静态类型检查。TypeScript可处理已有的JavaScript代码,并只对其中的TypeScript代码进行编译。 TypeScript 最大的特点就是类型化,因此才叫做TypeScript。比起弱类型的JavaScript,类型化的TypeScript显得更加容易维护。 要在应用中使用 TypeScript 必须先编译,编译的结果是生成 js 文件,你可通过 TypeScript 编译器 tsc 命令来完成这个过程。如要编译test.ts(TypeScript文件的扩展名为.ts),可用如下命令: tsc test.ts 编译完成后就会在当前目录生成名为test.js的文件。 注: 不要将TypeScript看作是一门新的语言,它只是为了提升JavaScript代码质量的一个工具,最终TypeScript仍然要编译成JavaScript。 yarn global add typescript greeter.ts function greeter(person) { return “Hello, " + person; } let user = “Jane User”; document.body.textContent = greeter(user); ```bash tsc greeter.ts <!DOCTYPE html> <html> <head><title>title0</title></head> <body> <script src="greeter.js"></script> </body> </html> let num: number = 100.001; let str: string = num.toFixed(2); ...

2015-06-13 · 1 min · 91 words · -

临界区, 竞态条件

临界区, 竞态条件 临界区是程序中使用临界资源的一段程序 在同步的程序设计中,临界区 (Critical section) 指的是一个访问共享资源 (例如: 共享设备或是共享存储器) 的程序片段,而这些共享资源又无法同时被多个线程访问的特性。 当有线程进入临界区段时,其他线程或是行程必须等待 (例如: bounded waiting 等待法) ,有一些同步的机制必须在临界区段的进入点与离开点实现,以确保这些共享资源是被异或的使用,例如: semaphore。 只能被单一线程访问的设备,例如: 打印机。 临界区 Critical section 保证在某一时刻只有一个线程能访问数据的简便方法,在任意时刻只允许一个线程对资源进行访问。如果有多个线程试图同时访问临界区,那么在有一个线程进入后,其他所有试图访问临界区的线程将被挂起,并一直持续到进入临界区的线程离开。临界区在被释放后,其他线程可以继续抢占,并以此达到用原子方式操作共享资源的目的. 临界区指的是一个访问共用资源 (例如: 共用设备或是共用存储器) 的程序片段,而这些共用资源又无法同时被多个线程访问的特性。当有线程进入临界区段时, 其他线程或是进程必须等待 (例如: bounded waiting 等待法) ,有一些同步的机制必须在临界区段的进入点与离开点实现,以确保这些共用资源是被互斥获得使用, 竞态条件与临界区 在同一程序中运行多个线程本身不会导致问题,问题在于多个线程访问了相同的资源。如,同一内存区 (变量,数组,或对象) 、系统 (数据库,web services 等) 或文件。实际上,这些问题只有在一或多个线程向这些资源做了写操作时才有可能发生,只要资源没有发生变化,多个线程读取相同的资源就是安全的。 多线程同时执行下面的代码可能会出错: public class Counter { protected long count = 0; public void add(long value){ this.count = this.count + value; } } 想象下线程 A 和 B 同时执行同一个 Counter 对象的 add()方法,我们无法知道操作系统何时会在两个线程之间切换。JVM 并不是将这段代码视为单条指令来执行的,而是按照下面的顺序: 从内存获取 this.count 的值放到寄存器 ...

2015-06-11 · 1 min · 134 words · -

html input

html input <input type="value0"> hidden 定义隐藏的输入字段。 Hidden 对象代表一个 HTML 表单中的某个隐藏输入域。 这种类型的输入元素实际上是隐藏的。这个不可见的表单元素的 value 属性保存了一个要提交给 Web 服务器的任意字符串。如果想要提交并非用户直接输入的数据的话,就是用这种类型的元素。 在 HTML 表单中 标签每出现一次,一个 Hidden 对象就会被创建。 您可通过遍历表单的 elements[] 数组来访问某个隐藏输入域,或者通过使用document.getElementById()。 http://www.w3school.com.cn/jsref/dom_obj_hidden.asp http://www.wiloon.com/?p=6529

2015-06-10 · 1 min · 26 words · -

javascript 序列化与反序列化

javascript 序列化与反序列化 http://blog.csdn.net/zhangquanok/article/details/13002771 var objP = {}; objP.id = 1; objP.name = 2; objP.sex = 32; JSON.stringify(objP)//序列化 JSON.parse(e); //JSON.parse(e)反序列化

2015-06-10 · 1 min · 19 words · -

配置文件 HOCON

‘配置文件 HOCON’ HOCON (Human-Optimized Config Object Notation) 是一个易于使用的配置文件格式。 是由typesafe (开发scala和play framework的公司) 主导的项目 它被用于 Sponge 以及利用 Sponge API 的独立插件以储存重要的数据,比如配置或者玩家数据。HOCON 文件通常以 .conf 作为后缀名。 组成部分 一个 key 是一个键值对字符串中的前一个值 一个 value 可以是字符串、数字、对象、数组或者布尔值并紧随 key 的后面 一个 key-value separator 把键和值分离,可以是 : 或者 = 一个 comment 以 # 或者 // 开头,通常用于提供反馈或说明 示例: yellow-thing: “Sponge” 在这一示例中,key 是 yellow-thing,value 是 Sponge,而 key-value separator 是 :。 使用 HOCON HOCON 要比 JSON (JavaScript Object Notation) 更灵活,因为书写一个合法的 HOCON 的方式要更多。下面是两个合法的 HOCON 的例子。 示例一: player: { ...

2015-06-10 · 1 min · 113 words · -

系统架构图

系统架构图 系统架构图怎么画?系统架构图首先是人,人是构成系统架构图的核心,也就是系统架构师。IBM工程师的说明是: 架构师的主要责任是提供开发人员和项目经理之间的共用沟通媒体。他们负责让业务规则及需求与工程实践及限制相适应,以确保成功。 中文Wiki上的说明是: 系统架构师负责设计系统整体架构,从需求到设计的每个细节都要考虑到,把握整个项目,使设计的项目尽量效率高,开发容易,维护方便,升级简单。这两个部分加起来组成了系统架构师的定义。本文主要介绍系统架构图怎么画? 系统架构图怎么画?要画好系统架构图,首先明白系统架构图都有哪些,你要画的系统架构图属于?这是系统架构师工作内容与职责之基础。 http://chasefull.blog.51cto.com/6570525/1134536 http://blog.itpub.net/6517/viewspace-609654

2015-06-09 · 1 min · 8 words · -

移动平均线交叉交易策略

移动平均线交叉交易策略 移动平均线交叉外汇交易策略 — 是一种简单的交易系统,基于两个标准指标的交叉 —一条快的EMA (指数移动平均线) 和一条慢的EMA。您也可以免费使用我们的可调整移动平均线交易智能交易在MetaTrader平台上自动进行交易。特点非常简单的跟随策略。使用简单的指标。设置止损容易。移动平均线具有延迟性 —延迟可能达到10天。市场清淡时无效。策略设置可用于任何货币对和时间框架。往图表上添加一条指数移动平均线,时段设置为9,适用收盘价,设置为红色 (可选) — 这是一条快的移动平均线 (FMA) 。往图表上再添加一条指数移动平均线,时段设置为14,适用收盘价,设置为蓝色 (可选) — 这是一条慢的移动平均线 (SMA) 。进场条件 当FMA自下方与SMAj交叉时,进场做多。 当FMA自上方与SMA交叉时,进场做空。离场条件 多头止损应设置在发生交叉前上一个蜡烛台的低位处。空头止损设置在交叉前上一个蜡烛台的高位处。 止盈应根据止损进行设置,不应低于止损。建议设置为止损的1.5倍或2倍。 如果在触及止损或止盈之前,发生再次交叉,关闭当前头寸。 http://www.earnforex.com/cn/%E5%A4%96%E6%B1%87%E7%AD%96%E7%95%A5/%E7%A7%BB%E5%8A%A8%E5%B9%B3%E5%9D%87%E7%BA%BF%E4%BA%A4%E5%8F%89%E7%AD%96%E7%95%A5 http://www.voidcn.com/blog/zccz14/article/p-6305201.html https://www.zhihu.com/question/23245754

2015-06-08 · 1 min · 26 words · -

外汇EA

外汇EA http://foreign.ymq123.com/showtopic-38641.aspx 什么是外汇EA 中文全名叫智能交易系统,是通过电脑模拟人为操作来完成交易。交易员通过将交易思路进行编程,从而使电脑按照交易员的交易思路进 行无心态干扰的交易过程。 为什么要使用EA?EA使用的好处在哪里? EA最大的优势就是它的执行力,EA是机器,所以不会有情绪,不会因为亏损了懊恼或则盈利了骄傲而失去控制,不少都有这样的经历吧: 一次冲动或对市场的不服就失去几个月甚至几年的所有利润,但是EA不会。 EA还可以代替交易员进行操作,从而解放了交易员的交易时间,减少交易员的疲劳程度,杜绝了交易员某些人为的心态问题,从而能稳定的替代交易员完成交易。 EA是神话吗?有好的EA吗?有的,现在在市场上流通了大量的EA,但是有人说99%的都是垃圾EA;我认为是错误的,99%的EA都曾经工作过一段时间,至少在短期内它是可以盈利的,认为EA垃圾的原因很多;有可能是你根本就不懂得如何使用它,还有可能是你使用的过期版本,还有可能EA本来就是为短期市场特性而设计的。因为EA是人写的,你找那些**版EA没有技术人员的支持,又不懂得使用,以为一挂上去就自动赚钱,当然垃圾了,天下没有一劳永逸的事情,再完美的EA如果失去人的监控也会出错的。所以为什么绝大部分EA市面上测试一段时间就会消失?; i& ?6 A2 u; R0 h5 B3 G/ q ~ NEA不是圣杯,不是ATM机,不要梦想那一点点钱翻几倍几十倍,资本市场永远是钱多好赚钱,以小博大是不现实的,交易商提供高杠杆不是让你以小博大的,不过为了提供你的资金利用率而已。 EA的优势就在于一种盈利的交易策略它能执行下去,不会因为恐惧和贪婪而犯错。 在这里,我就把我多年的心血给大家晒晒单,我的这款EA叫: money_up。外汇智能交易软件Money_Up,于2009年开始研究,历经3年时间2011年4月份正式完成。如果有朋友感兴趣的话就加我球球吧: 壹⑥九叁六伍⑥伍壹六 。我在淘宝网上有售。Money_Up外汇智能交易软件用于欧元五分钟时间图表,浓缩三套做单策略 剥皮策略: 以某种长期均线作为趋势线,以震荡指标作为进出信号,盈利20点,止损300点,动态指标监控移动止损。不过测试发现十年只有1次止损,大部分都是由信号进出。 突破策略,简单点说就是构筑一个ATR通道,当价格突破通道的时候开仓,500点止盈,初始35点止损,此系统优秀之处在于有一个动态的跟踪系统可以适应趋势的变化。 l 反转策略,以一个布林带作为主要指标,上下边界附近做区间操作,160点止盈,70点止损,有跟踪止损。值得注意的是,这系统仅仅在GMT22-0点的时段开仓。 Money_Up是一款以安全性,稳定性为设计理念,以盈利最大化为设计目标的外汇智能EA软件。通过5年(2006 - 2010)复盘测试,从1000元做到1155万元,测试数据有些夸张,但证明稳定获利是真实成功的,而且绩效非常可观,本公司敢保证的是复盘测试和挂机测试出来的结果是一样的,至于未来能不能赢钱,这个谁也说不清楚,本公司敢保证的是复盘测试和挂机测试出来的结果是一样的,至于未来能不能赢钱,这个谁也说不清楚。本EA使用于欧美5分钟图表,MT4平台,对点差没有限制,资金量500美元即可运行。 那么为什么好的EA不能随便公开? [第一,毕竟是作者劳动成果,它结合了交易员太多的交易精,保护版权是对作者的尊重; 第二,公开了会产生交易者效应,因为这个市场是零和游戏,一旦公开了策略,大家都不会盈利。就像海龟法则,多么简单的策略: 超过20天最高点买,跌过10天最低点卖。您觉得它神秘吗?但是它确确实实在80年代给海龟们带来了巨大财富。然而,当它的策略公开后,便不那么有效了,虽然还是盈利的,不过效果是大打折扣,这就是交易者效应。 不过通常来说,你的EA再好,也好不会影响到整个市场,不太容易有海龟法则那样的威力了。而且现在交易系统越来越多,交易方法也花样百出,科技日新月异;和80年代已经不可同日而语。所以现在是交易系统和交易系统斗。如果您没有一套能盈利的交易系统 (无论您是自动还是非自动) ,那么您就是输在起跑线上了。

2015-06-04 · 1 min · 41 words · -

移动平均线 均线 Moving Average MA

‘移动平均线 均线 Moving Average MA’ SMA,简单移动平均线 EMA,指数平滑移动平均线 SMMA,平滑移动平均线,它的目的是为了让线条更加平滑些。 LWMA,线性加权移动平均线,因为MA是一种滞后指标,为了改善这种现象,为了提高一点滞后性就有了LWMA指标,给最近的价格更高的权重。 移动平均线的不足之一在于它们滞后于市场,因此并不一定能作为趋势转变的标志。为解决这一问题,使用5或10天的较短周期移动平均线将比40或200天的移动平均线更能反映出近期价格动向。 或者,移动平均线也可以通过组合两种不同时间跨度的平均线加以使用。无论使用5和20天的移动平均线,还是40和200天的移动平均线,买入信号通常在较短期平均线向上穿过较长期平均线时被查觉。与此相反,卖出信号会在较短期平均线向下穿过较长周期平均线时被提示。 有三种在数学上不同的移动平均线: 简单算术移动平均线;线型加权移动平均线;以及平方系数加权平均线。其中,最后一种是首选方法,因为它赋予最近的数据更多权重,并且在金融工具的整个周期中考虑数据。 移动平均线,Moving Average,简称MA,原本的意思是移动平均,由于我们将其制作成线形,所以一般称之为移动平均线,简称均线。它是将某一段时间的收盘价之和除以该周期。 比如日线MA5指5天内的收盘价除以5 。 移动平均线是由著名的美国投资专家Joseph E.Granville (葛兰碧,又译为格兰威尔) 于20世纪中期提出来的。均线理论是当今应用最普遍的技术指标之一,它帮助交易者确认现有趋势、判断将出现的趋势、发现过度延生即将反转的趋势。移动平均线,Moving Average,简称MA,原本的意思是移动平均,由于我们将其制作成线形,所以一般称之为移动平均线,简称均线。它是将某一段时间的收盘价之和除以该周期。 比如日线MA5指5天内的收盘价除以5 。 移动平均线是由著名的美国投资专家Joseph E.Granville (葛兰碧,又译为格兰威尔) 于20世纪中期提出来的。均线理论是当今应用最普遍的技术指标之一,它帮助交易者确认现有趋势、判断将出现的趋势、发现过度延生即将反转的趋势。 【转载】移动平均线SMA/EMA/SMMA/LWMA (2009-07-09 23:28:41) 转载▼ 标签: 杂谈 分类: 黄金投资技术分析学习 http://ta.mql4.com/cn/indicators/trends/moving_average 移动平均线指标显示某一个时间段平均工具性价格的数值。当我们计算移动平均线的时候,其实我们是在平均这段时间内工具性价格的数值。由于价格的变化,移动平均线指标要么增加要么减少。 有四种不同类型的移动平均线: 简单 (也被成为算术) 移动平均线, 指数移动平均线, 通畅移动平均线, 线形权数移动平均线。我们可以为任何一套顺序排列的数据来进行移动平均线的计算,包括开市和闭市价格,最高和最低价格,交易量和任何其他的指标。同时有两条移动平均线被使用的情况比较普遍。 只有在一种情况下,不同种类的移动平均线会产生相当大的分离,就是当权数系数不同的情况下 (该系数是被安排到最近的一个数据里的) ,我们在讨论简单移动平均线的时候,我们研究的时间段的所有价格都在数值上相等。移动平均线的数值更趋向于最近的价格。 解释价格平均移动最普遍的方法是就是将其动量与价格运动相比较。当工具性价格上升到其移动平均线之上时,购买信号出现了;当价格下落到移动平均线下面时,我们所得到的是一个卖出信号。 这种基于移动平均线的贸易体系,并不是设计用来提供给我们一个通道的: 市场处于低潮期的时候让我们进入,在进入高峰期的时候让我们出来。根据下列市场趋势的变化,它可以使得我们作出相应的行动:一旦价格探底,我们就开始买进;一旦价格攀升,我们就开始卖出。 移动平均线也可被运用于各种指标。那就是移动平均指标的解释和价格移动平均线解释相似的地方。如果指标上升到移动平均线上面的时候,那就意味着上升的指标运动还将继续。指标若是低于移动平均线,那就表明指标有可能继续下滑。 这是图表上移动平均线: 简单移动平均线 (SMA): Simple Moving Average 指数移动平均线 (EMA): Exponential MA 通畅移动平均线 (SMMA): Smoothed MA 线性权数移动平均线 (LWMA): Linear Weighted MA 加权移动平均线 (Weighted Moving Average,WMA) : 指计算平均值时将个别数据乘以不同数值。在技术分析中,n日WMA的最近期一个数值乘以n、次近的乘以n-1,如此类推,一直到0。 ...

2015-06-04 · 1 min · 156 words · -

HTML id、name、class

HTML id、name、class http://blog.csdn.net/ithomer/article/details/8080912 HTML中id、name、class 区别 分类: Script2012-10-17 13:53 27969人阅读 评论(7) 收藏 举报 classhtmlcssinput服务器applet HTML 中 id与name 区别 一个name可以同时对应多个控件,比如checkbox和radio 而id必须是全文档中唯一的 id的用途 id是HTML元素的Identity,主要是在客户端脚本里用。 label与form控件的关联,如 My Input for属性指定与label关联的元素的id,不可用name替代 脚本中获得对象: IE支持在脚本中直接以id (而不是name) 引用该id标识的对象。 例如上面的input,要在脚本中获得输入的内容,可以直接以 MyInput.value来获得。如果用DOM的话,则用document.getElementById(“MyInput”).value; 如果要用name的话,通常先得到包含控件的form,例如document.forms[0],然后从form再引用name,注意这样得到的是经过计算后将发送给服务器的值 name的用途 主要是用于获取提交表单的某表单域信息, 作为可与服务器交互数据的HTML元素的服务器端的标示,比如input、select、textarea、框架元素(iframe、frame、 window的名字,用于在其他frame或window指定target )和button等,这些元素都与表单(框架元素作用于form的target)提交有关,浏览器会根据name来设定发送到服务器的request, 在表单的接收页面只接收有name的元素, 所以赋ID的元素通过表单是接收不到值的。 我们可以在服务器端根据其Name通过Request.Params取得元素提交的值。在form里面,如果不指定name,就不会发送到服务器端。 HTML元素Input type=‘radio’分组,我们知道radio button控件在同一个分组类,check操作是mutex的,同一时间只能选中一个radio,这个分组就是根据相同的name属性来实现的。 建立页面中的锚点,我们知道link是获得一个页面超级链接,如果不用href属性,而改用name,如: ,我们就获得了一个页面锚点,如Experience (XP),详见 示例 作为对象的Identity,如Applet、Object、Embed等元素。比如在Applet对象实例中,我们将使用其name来引用该对象。 在IMG元素和MAP元素之间关联的时候,如果要定义IMG的热点区域,需要使用其属性usemap,使usemap="#name"(被关联的MAP元素的Name)。 某些特定元素的属性,如attribute,meta和param。例如为Object定义参数或Meta中。 ...

2015-06-02 · 1 min · 190 words · -

possibly; probably; perhaps; maybe

possibly; probably; perhaps; maybe http://web.etiantian.com/staticpages/study/question/question_701044.htm 这几个副词都有"可能"的意思,用法如下: (1) possible"或许;也许",所指的可能性较小,为加强语气,可与can或could连用;与may连用,表示的可能性更小。例如: It may possibly be true.也许是真的。 Please call me as soon as you possibly can.请尽快给我打电话。 Could you possibly tell me the answer﹖你能告诉我这个答案吗? (2)probably"很有可能;十之八九",其语义较强,可能性较大。在否定句中,probably不能紧跟在否定词之后。例如: It will probably be fine tomorrow.明天大概会是晴天。 译: 她大概不会来这里。 正: Probably she won’t come here. 正: She probably won’t come here. 正: She won’t come here probably. 误: She won’t probably come here. (3) perhaps"或许",含有"可能这样,也可能不这样"之意,其含义和用法与maybe一样,多用于口语。maybe多用于美国英语。在这几个单词中,语义最强的是probably,其次是perhaps和maybe,最弱的是possibly。例如: Perhaps we will be late for work.或许我们上班会迟到。 ...

2015-06-02 · 1 min · 77 words · -

Runtime

Runtime http://blog.csdn.net/csh624366188/article/details/6684327 http://lavasoft.blog.51cto.com/62575/15565 Runtime.getRuntime()可以取得当前JVM的运行时环境,这也是在Java中唯一一个得到运行时环境的方法。 Runtime上其他大部分的方法都是实例方法,也就是说每次进行运行时调用时都要用到getRuntime方法。 Runtime中的exit方法是退出当前JVM的方法,估计也是唯一的一个吧,因为我看到System类中的exit实际上也是通过调用Runtime.exit()来退出JVM的,这里说明一下Java对Runtime返回值的一般规则 (后边也提到了) ,0代表正常退出,非0代表异常中止,这只是Java的规则,在各个操作系统中总会发生一些小的混淆。 Runtime.addShutdownHook()方法可以注册一个hook在JVM执行shutdown的过程中,方法的参数只要是一个初始化过但是没有执行的Thread实例就可以。 (注意,Java中的Thread都是执行过了就不值钱的哦) 说到addShutdownHook这个方法就要说一下JVM运行环境是在什么情况下shutdown或者abort的。文档上是这样写的,当最后一个非精灵进程退出或者收到了一个用户中断信号、用户登出、系统shutdown、Runtime的exit方法被调用时JVM会启动shutdown的过程,在这个过程开始后,他会并行启动所有登记的shutdown hook (注意是并行启动,这就需要线程安全和防止死锁) 。当shutdown过程启动后,只有通过调用halt方法才能中止shutdown的过程并退出JVM。 那什么时候JVM会abort退出那?首先说明一下,abort退出时JVM就是停止运行但并不一定进行shutdown。这只有JVM在遇到SIGKILL信号或者windows中止进程的信号、本地方法发生类似于访问非法地址一类的内部错误时会出现。这种情况下并不能保证shutdown hook是否被执行。 常见的应用 内存管理: Java提供了无用单元自动收集机制。通过totalMemory()和freeMemory()方法可以知道对象的堆内存有多大,还剩多少。 Java会周期性的回收垃圾对象 (未使用的对象) ,以便释放内存空间。但是如果想先于收集器的下一次指定周期来收集废弃的对象,可以通过调用gc()方法来根据需要运行无用单元收集器。一个很好的试验方法是先调用gc()方法,然后调用freeMemory()方法来查看基本的内存使用情况,接着执行代码,然后再次调用freeMemory()方法看看分配了多少内存。下面的程序演示了这个构想。 //此实例来自《java核心技术》卷一 class MemoryDemo{ public static void main(String args[]){ Runtime r = Runtime.getRuntime(); long mem1,mem2; Integer someints[] = new Integer[1000]; System.out.println(“Total memory is : " + r.totalMemory()); mem1 = r.freeMemory(); System.out.println(“Initial free is : " + mem1); r.gc(); mem1 = r.freeMemory(); System.out.println(“Free memory after garbage collection : " + mem1); ...

2015-06-01 · 2 min · 255 words · -