SVN递归忽略文件或目录

2015-03-20 • 技术文章

在SVN中忽略某个文件可以使用svn ps svn:ignore [filename|filelist] [dir]来实现,但是如果要实现一个文件列表的忽略最直观的方法是通过svn pe svn:ignore [dir]。在使用该命令时会遇到SVN编辑器未设置的提示,这时可以export SVN_EDITOR=vi指定vi或者其它编辑器来解决,为免今后再export也可以直接把export写进profile。

不过,我个人觉得不错的一个方案是创建一个.svnignore文件,在.svnignore文件里指定一个忽略列表,然后通过svn ps svn:ignore -F .svnignore [dir]来忽略比较好。如果有所有层忽略的需要,svn -R ps svn:ignore -F .svnignore .层层忽略,列表文件的目录不用加/直接递归忽略掉即可。

其实对于从仓库拉下来的工程,只要不手动添加不必要的文件来跟踪就没什么问题。如果使用IDEA等IDE,在设置中设定忽略项目也很方便。

国内外Windows平台免费个人安全软件评略

2015-02-27 • 业界评论

自从远离了瑞星产品的测试,已经很久没有大规模地把各种杀毒软件拿过来比一比了。但是最近在挑选Windows平台下适合家用的杀毒软件时却犯了难,于是只能配置好虚拟机和常用软件,装上各款杀毒软件来做个比较。这些年来,病毒的技术并没有什么大的进步,也没给予太多关注,但个人杀毒软件市场却已经是发生了翻天覆地的变化。

昔日的国内霸主,瑞星杀毒软件和防火墙虽然没有多少市场份额,但是无论是安全防御还是查杀率都还是很不错的,国内唯一的坚持独立自主开发杀毒引擎的厂商,防火墙在国内独树一帜,唯一缺点是总是试图让你装点瑞星其它没什么价值的产品,而且偶有广告弹窗,而且有一个烦人的瑞星软件部署系统,太多余,瑞星现在的境况不适合做平台何必还一直操着这么大的心呢,只能讨人厌了。要是瑞星现在决定做安静的小狮子还是不错的,总之,技术上推荐,恶性推广上差评。

金山毒霸,在市场上还是有一定的份额的。查杀和敢赔模式都不错,但防卫过当,我想在系统盘驱动器下稍微动点无关紧要的东西它都有意见,而且也有推广其它产品之嫌,因为我发现我家里的电脑上满屏金山的东西。启发杀毒误报略高,不适合高级用户使用,尤其是IT研发人员。

360杀毒,现今的霸主。查杀不错,有些独创的技术做得很不错,毕竟高中时候就知道的很多Windows安全界的高手都加盟了360,实力不可小觑,但启发误报太多,而且和金山一样防卫过当,不适合IT研发类人员使用。一般人用用还是很不错的。

百度杀毒,引入了卡巴斯基引擎,查杀没问题。防御级别恰到好处,界面也简洁明了,再加点防火墙功能就更好了。百度适合普通用户和专业人士使用,兼容性再好点就值得大力推荐了。

AVG,略简陋,只会杀毒,查杀率还行,免费版在其它方面没什么可圈可点的。界面上一半的区域用来推广收费版,讨人厌。总之,不推荐。

Avria,大名鼎鼎的小红伞,各方面都不错,缺点是防御拦截上没有放行功能,要想完成某些想要的“危险”操作,要关掉相应防御模块。界面太丑,不适合普通用户使用。

Comodo,防火墙世界排名第一,界面扁平化做得很漂亮。在病毒查杀上不够强,但沙盒、HIPS、防火墙做得很出色,就是不太适合普通用户,只适合专业人士使用,建议只装防火墙,但是Comodo对新版Windows的兼容性尚有待改进,测试过程中发生了装完软件再也开不了机的情况。

微软Defender(MSE),我只能委婉地表示,提升空间很大。安全习惯比较好的Windows用户可以使用,记得及时更新就行,似乎默认情况下不怎么更新病毒库等信息。

更多软件,不再一一评点。

总的来看,目前真没有哪款免费杀毒软件让我完全满意。如果以上安全软件的非功能性的痛点上能够得到改进,比如不再弹窗不再有各种推广,兼容性再好一点,那么将会出现以下几种非常不错的组合:对于普通用户,瑞星杀毒软件、百度杀毒中的一款来配合瑞星防火墙;更专业玩家可以选择用Comodo防火墙替换前面的瑞星防火墙;对于防火墙没什么要求的可以只用系统防火墙或者用系统高级防火墙。至于金山、360,鉴于我个人并不认同它们的过度防卫的安全策略,实在无法推荐给专业人士,不过普通用户用用还可以。对于其它国外软件,虽然病毒查杀率还不错,但是整体上做得很平庸,只能说不太推荐。

牙殇

2015-02-20 • 个人情感

未曾料,第一个倒下的却是你。

悲,泣。

名词解释:ETL、CAP和MESI

2015-01-25 • 技术文章

ETL

ETL即Extract-Transform-Load,用来描述将数据从来源端经过萃取(Extract)、转置(Transform)、加载(Load)至目的端的过程。ETL这个词常用在但不限于数据仓库。ETL是极为复杂的过程,而手写程序不易管理,有愈来愈多的企业采用工具协助ETL的开发,并运用其内置的元数据功能来存储来源与目的的映射以及转换规则。 工具并可以提供较强大的功能来连接来源及目的端,开发人员不用去熟悉各种相异的平台及数据的结构,亦能进行开发。例子:taskctl+kettle的免费解决方案。

CAP

最近在做分布式数据库方面的工作,不可避免地讨论到CAP定理,CAP即一致性(Consistency)、可用性(Availability)和分区容忍性(Partition Tolerance)。

CAP定理指的是在分布式的环境下设计和部署系统时,有三个核心的系统需求,这三个要素最多只能同时实现两点,不可能三者兼顾。因此在进行分布式架构设计时,必须做出取舍。其中一致性和可用性很容易理解,那么什么是分区容忍性呢?其定义为除了整个网络的故障外,其他的故障(集)都不能导致整个系统无法正确响应。比如说,机器网线断了,那么partition就形成了。理解CAP定理的最简单方式是想象两个节点分处分区两侧。允许至少一个节点更新状态会导致数据不一致,即丧失了C性质。如果为了保证数据一致性,将分区一侧的节点设置为不可用,那么又丧失了A性质。除非两个节点可以互相通信,才能既保证C又保证A,这又会导致丧失P性质。

这个定理起源于加州大学伯克利分校(University of California, Berkeley)的计算机科学家埃里克·布鲁尔(Eric Brewer),故也称布鲁尔定理。

MESI

MESI是Modified、Exclusive、Shared、Invalid的首字母缩写,在大学的计算机组成原理教材里都有,讲的是缓存一致性的问题,这里再写出来就作为复习吧。

失效(Invalid)缓存段,要么已经不在缓存中,要么它的内容已经过时。为了达到缓存的目的,这种状态的段将会被忽略。一旦缓存段被标记为失效,那效果就等同于它从来没被加载到缓存中。

共享(Shared)缓存段,它是和主内存内容保持一致的一份拷贝,在这种状态下的缓存段只能被读取,不能被写入。多组缓存可以同时拥有针对同一内存地址的共享缓存段,这就是名称的由来。

独占(Exclusive)缓存段,和S状态一样,也是和主内存内容保持一致的一份拷贝。区别在于,如果一个处理器持有了某个E状态的缓存段,那其他处理器就不能同时持有它,所以叫“独占”。这意味着,如果其他处理器原本也持有同一缓存段,那么它会马上变成“失效”状态。

已修改(Modified)缓存段,属于脏段,它们已经被所属的处理器修改了。如果一个段处于已修改状态,那么它在其他处理器缓存中的拷贝马上会变成失效状态,这个规律和E状态一样。此外,已修改缓存段如果被丢弃或标记为失效,那么先要把它的内容回写到内存中——这和回写模式下常规的脏段处理方式一样。

参考资料

http://zh.wikipedia.org/wiki/ETL

http://zh.wikipedia.org/wiki/CAP%E5%AE%9A%E7%90%86

http://www.infoq.com/cn/articles/cache-coherency-primer

算法:环形公路加油站问题

2015-01-15 • 技术文章

现有一圆环形路,路上有n个加油站,第i个加油站储存有N[i]升容量的油,与下一个加油站之间有一定的距离g[i],一汽车初始无油,假设该车每公里消耗1升油,请问该车从哪个加油站出发可以绕该环形路行驶一圈。

方法一:从左往右遍历,在油量和最少的位置的下一个位置出发。

1
2
3
4
5
6
7
8
9
10
int res = 0, min = N[0] - g[0], sum = min, i = 1;
while(i < n) {
    sum += N[i] - g[i];
    if(sum < min) {
        min = sum;
        res = i;
    }
    ++i;
}
return sum >= 0 ? (res + 1) % n : -1;

方法二:开辟一个长度为N的数组v,记录N[i]-g[i]。从后往前遍历数组v,如果v[i]小于零,将其与v[i-1]合并,因为此时i不可能作为起点。如果v[i]不小于零,记入sum,并记录该位置pos(有可能作为起点)。最后,如果v[0]大于等于零,说明整个路段已经没有负的v[i]。返回0即可。如果v[0]+sum>=0,有满足条件的加油站,返回pos。否则,返回-1。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
int v[n];
for(int i = 0; i < n; ++i)
    v[i] = N[i] - g[i];
int sum = 0, pos = -1;
for(int i = n-1; i > 0; --i) {
    if(v[i] >= 0) {
        sum += v[i];
        pos = i;
    } else {
        v[i-1] += v[i];
    }
}
if(v[0] >= 0) 
    return 0;
else if(v[0] + sum >= 0)
    return pos;
else 
    return -1;

方法三:开辟一个长度为2*n-1的数组v,记录N[i]-g[i],这样就把一个环转化为一条线。使用两个指针start和end。如果[start,end]区间和小于0,令start=end+1并继续。直至找到长度为N的区间[start,end],并且区间和大于等于0。找到返回start,找不到返回-1。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
int v[2 * n];
for (int i = 0; i < n; ++i) {
    v[i] = N[i] - g[i];
    v[i+n] = N[i] - g[i];
}
int sum = 0;
for (int start = 0, end = 0; start <= n && end < 2 * n; end++) {
    if(sum + v[end] < 0) {
        start = end + 1;
        sum = 0;
    } else {
        if(end - start == n - 1) 
            return start;
        sum += v[end];
    }
}
return -1;

以上三种解法的时间复杂度均为O(n)。对于任意一个O(n)复杂度的DP题目,必有辅助数组仅与n有关,若刨除不需要计算的量还与两个以上的量有关,则不可能做到O(n)。