-
谨记一次被非标准属性background-position-y坑的过程
公司网站的背景是从早到晚渐变的,所以用了一张1px×13000px的图,每天根据时间不同,php那边算个bg-position中y的偏移值。 因为是php那边处理,当时php那边的人就顺手写了个inline style在某个module的layout的标签里: style=”background-position-y: {{ app.bg_position }}px” 后来我只是考虑到要把这个挪到全局layout里去,加个分号。 另加当时我脑残了一下css的平铺方向错写成了repeat-y,所以改好css,把style挪到正确的template里,我就没多想。 顺带确认了下repeat方向是x没错,bg-position位移方向是y没错,chrome下没错,IE下没错。 这便是一个悲剧的开始。 直到今天被人发现在firefox下白天显示着夜晚的深紫色渐变背景,只好开Inspector, 发现虽然body里有写样式,但inline element里却没有读到样式。 google之,才知道background-position-y/background-position-x是IE创造出的非标准属性,但是Chrome竟然支持了,但Firefox没有。 firefox没有…… =。=) 再高级的浏览器也是不可信的。
-
并发,缓存与guava
作为一个已经用了很长时间缓存的javaer,老实说到今天为止才真正知道缓存该怎么用。为什么这么说呢?考虑如下代码: public Object compute(Object key) { Object value = null; if ( (value = cache.get(key)) == null ) { value = compteValue(key); } cache.put(key, value); } 是不是很熟悉?典型的缓存客户端代码,但是这段代码是有问题的。问题不在cache,而在于这段代码本身。考虑如下的场景:
-
简易顺序执行框架attic开发笔记2
接上篇。 空格的处理 本来想自己写词法分析的,结果自己编译原理基础不牢固写出来老是死循环,所以使用opencsv。核心代码如下: CSVReader csvReader = new CSVReader(reader, ‘ ‘); String[] fields = null; while ((fields = csvReader.readNext()) != null) { // do stuff with fields } csvReader.close(); 这里使用空格代替CSV默认的分割符号冒号。
-
多态与延迟执行
上面的类图是针对最近改造的类图。 原先有多个command,执行各自的逻辑。现在由于command涉及的配置需要放缓存,抽象出config。config和command存在一定的映射关系,通过CommandFactory维持。考虑到config存入缓存时会以接口或者抽象类方式,取出时丢失了直接类型。使用VISITOR模式多态创建command。 现有command中有一个是条件型的,会根据执行时的上下文生成新的command并执行。在配置分离后,理论上变成生成新的config转换成command后执行。因为不想在CommandFactory中带入执行上下文(这样就破坏了简单的config-command关系),所以只能延迟到command执行时委托条件command的配置计算得到实际配置,再通过CommandFactory重新生成command,最后执行实际逻辑。 个人认为,这里理解的难点在于延迟执行。如果存在并不能立即决定的逻辑,则可以考虑返回一个实现某个接口的类,并包含执行的相关数据。比如这里返回ConditionalCommand,包含了ConditionalConfig和CommandFactory,在实际执行时计算。并通过CommandFactory的引用创建实际执行的Command后运行逻辑。
-
设计模式笔记1
设计模式的资料主要来自sourcemaking和《敏捷软件开发 原则、模式与实践》。 按照sourcemaking,设计模式主要分为 构造型模式 结构型模式 行为型模式 个人认为模式理解难度从低到高。 构造型模式 模式名 个人理解 FACTORY 由工厂决定创建哪个子类。多个子类,子类实例构造复杂时建议使用。Java中有基于static方法和新建工厂的方式。 ABSTRACT FACTORY 子类实例构造分组,比如多个“平台”,超类包含通用逻辑。“平台”与子类的实例矩阵。 BUILDER 多步创建。如果单步(方法)的参数比较复杂时推荐使用。 OBJECT POOL 对象池,典型如commons-pool,需要考虑并发问题。 PROTOTYPE 以某个实例为蓝本创建其他实例。Java中需要实现clone方法。
-
简易顺序执行框架attic开发笔记1
最近业余时间在写一个叫做attic的东西。attic的灵感来自《敏捷开发》中的验收测试,比如下面的验收测试脚本: AddEmp 1429 “Robert Martin” 3215.98 Payday Verfiy Paycheck EmpId 1429 Grosspay 3215.88 这是不懂编程的人,具体来说是业务人员也能看懂的验收测试脚本。《敏捷开发》没有对脚本的执行与实现做介绍,但是我觉得我get the point了: 按照行解析执行命令(Command) 类似CSV方式解析行,因为存在空格,不能直接按照空格split 有很多命令,需要命令库或者动态加载命令 转化为程序设计就是 val context = new CommandContext file.getLines.foreach{line => createCommand(line).execute(context) } context是命令之间交互的载体,个人认为命令之间肯定存在依赖关系 createCommand完成解析和创建命令,可能是这样: def createCommand(line: String): Command = { val cmdNameAndArgs = parse(line) val cmd = Class.forName(cmdNameAndArgs.name).newInstance.asInstanceOf[Command] cmd.setArguments(cmdNameAndArgs.arguments) return cmd } 这里cmd直接用load class的方式,便于扩展。parse部分相对难一些,我暂时用空格分割实现,之后肯定要换成类似CSV解析格式。 以上就是attic开发笔记第一部分。
-
scala模拟ketama算法
ketama是memcached客户端使用的一种一致性哈希算法。是为了解决余数实现分布不均匀的问题,在last.fm的一篇博客中首次提到。这里有一些介绍链接,其中第一篇是原博客。 http://www.last.fm/user/RJ/journal/2007/04/10/rz_libketama_-_a_consistent_hashing_algo_for_memcache_clients http://blog.csdnnet/kangojian/article/details/6708460 http://tech.idv2.com/2008/07/24/memcached-004/ 原博客里面提到算法步骤如下: Take your list of servers (eg: 1.2.3.4:11211, 5.6.7.8:11211, 9.8.7.6:11211) Hash each server string to several (100-200) unsigned ints Conceptually, these numbers are placed on a circle called the continuum. (imagine a clock face that goes from 0 to 2^32) Each number links to the server it was hashed from, so…
-
null-safe和scala的monad
长久以来,习惯了写如下的Java代码: User user = userService.get(1); if(user != null) { doStuff(); } 称之为null检查,亦有null != user的尤达式写法。 在学了Scala之后,知道了Option,改用如下写法:
-
落書き20130822 – 新发型
被某人说好久没更新博客了……于是水了一个晚上终于挤出了一张…… 上周被晾在家里了……我爸去桂林一周,某人去了千岛湖…… 于是终于有时间去烫头发了! 我敢保证,理发店的人肯定恨我,6月份我和他们说要去烫发,结果现在才去。 御用理发师不在,于是换了个人来烫,烫出来的风格也和以前差很大…… 个人觉得大概和泡面没什么太大的区别……orz 不过据说效果还好……那就还好吧…… 最近食完了《古书堂》,和文学少女比好像推理弱了点,但是很喜欢书中的氛围。 旧书店在国内见得比较少,也逛过几家,非常喜欢淘旧书的感觉~ 其实最初是有点想画翠星石的,但是没有灵感…… 我似乎是画不出同人图的人…… 最近因为物语系列有点喜欢上vofan的画,那种只用色块表达体积的方式很神奇~ 自己也瞎涂了一下,凑合凑合。