@NotNull 与 @NonNull 辨析

提到Java没有人不想到大名鼎鼎的NPE(Null Pointer Error),可见广大程序员受其毒害之深。所以做接口设计的时候,一个好的习惯就是注明Nullbility。 对于Nullable的参数或者返回值,从Java 8后Optional 是推荐的方式,因为它强迫接口使用者显示进行空值检测。

但如果接口设计中是想注明非空的情况呢,通常情况下你会发现有两个看起来很类似的annotation, @NotNull 以及 @Nonnull, 而且你可能会发现代码库里使用两者的都有。但是,正如Stackoverflow上的这个帖子分析道:

准确地说,你应该在接口设计时使用@Nonnull,而且为了达到预计效果,你必须要使用支持JSR-305标准的静态分析工具,比如Findbugs,IDEA或者Checker Framework,不然其效果就是个注释作用,并没有实际检查约束效果。如果你使用了Findbugs而且设置了所有Findbugs错误都会让你的build fail,这样你才充分利用了这个annotation。

那么NotNull该什么使用呢?这个annotation是用在运行时数值验证的,比如:

你注明了email不能为空,当你从数据库中加载数据到这个model后你就可以调用validator来检验创建的对象是否遵守规范,或者Person这个对象是Spring web resource的一个请求参数,比如:

如果你的web应用开启了bean validation的话person参数就会被自动校验,如果email为null的话resource就会自动返回400 BAD_REQUEST响应,因为客户端发送了一个不合格的数据。

所以看似相似确大不相同,需谨慎使用。

windows下由于文件路径中包含空格符导致的bug解决方案

举个例子:在windows系统中,有用户“Farmer John”(注意中间有空格分隔),在用户根目录下有用户的头像图片”C:UsersFarmer Johnphoto.jpg“。现在有一对图片操作的库函数foo,foo的输入参数即为图片路径,由于foo的实现不完善导致如果路径中包含空格符的话会有bug(比如遇到空格截断),但用户又不能修改该函数,更不可能为了这个bug而去修改用户名,此时的一个很好的hack方式就是用mklink来fix包含空格的那个目录或者文件。对于现在这个bug,可以这么解决:

注意对于一些权限较高的目录可能需要在admin模式下的cmd才能完成。此时会出现一个叫”Farmer-John“的symbolic link的目录,此时当你向foo传入”C:UsersFarmer-Johnphoto.jpg“时,现在为合法输入,该路径其实等价地指向”C:UsersFarmer Johnphoto.jpg“的实际地址,bug就hacked了。

这个bug告诉我们两点:

1. 论测试的重要性

2. 开发目录下的所有目录和文件命名尽可能简单,比如只包含英文字母和数字,以免造成不必要的麻烦。

又搬家了

收到SAE发来的云豆不足的通知,提醒我该去给他进贡铜臭了。话说我差不多已经做了半年的SAE的付费用户了,每个月交个10多元我那几个小网站差不多就能撑起来了,BAE从此就是路人了。不过由于上次github的Edcucation Package想到好像有送1~2的云主机优惠,于是就简单看了下。DigitOcean又有绑定信用卡太蛋疼也怕不安全,意外发现了亚马逊的AWS支持一年的free tier试用,花了点时间研究了下,最后决定把主机挪到AWS一年玩玩。

这是网站第二次大迁移。

AWS也需要一张信用卡,会先扣掉1$验证(之后返还),再电话验证过后就可以用了。成功后登陆控制台一看惊呆了,见下图: Continue reading

Something you should know about the abs function

It is a rule in math that the absolute value of a number must be no less than zero. Is it true in computer languages? Well, most of the case except one. Let me take C language for example.

For a 32-bits C interger, its value ranges from [-2147483648, 2147483647] .So for x = -2147483648, what is the result of abs(x)? 2147483648, -2147483648, 2147483647, 0 or something else?

The result depends on your compiler! Please be careful to handle this undefined result in your coding.

Let’s look into the implementation of the abs function in C:

So a potential bug may skip into your code like this situration:

But if you really test the above code in your computer, probobly you will find that the computer gives you the expected output. Here is a Demo on ideone.com; You are suggested trying on your machine!

What happens to the correct output occassion is that the compiler actually return a longer integer type like long long which is 8 bytes usually. For long long y = abs(INT_MIN);, y is equal to INT_MAX + 1 for sure.

This is as much as the modern compiler can help you reduce your bugs. If you code in this way:

This time bugs are more likely to happen on you. Nigel Jones gives some good solutions to the problem in his article: The absolute truth about abs().

In summary, there are several ways to avoid the abs bug: 1. Always use a longer type to store your abs result, like long long for int. But what type for long long? Therefore the better one is double, in the cost of casting time and more CPU cycles. 2. Write your own abs function like this one: safe abs function; 3. Carry out the comparision in the negative space because negetive space is larger than the postive space.

Both solution 2 & 3 require you to use your own abs function.

That’s my report on delving the absolute function in C language. Just as a saying goes: Think twice before you code 🙂

网站改版记

闲的蛋疼又来改首页了。二话不说,先上结果:戳我!

为什么要改版呢?一来老的版本看腻了。。二来之前那个内容太少,加上flickr老是被屏蔽,网页上就真没啥东西可以看的了。而且其实之前1.0的时候对移动设备支持不太好,基本在手机上就是废了。

那这次主要改了啥呢?

  1. 新的页面设计。好吧,不是我自己设计的,在html5up上找了个叫overflow的模板改的.布局基本沿用了overflow的设计。根据自己的需求做了些小修改。
  2. 首先支持i18n! 有没有很高霸上,多语言支持! 好吧现在还只支持英语。用的是前端的i18next库,如果我判断出用户的默认语言是非中文我就自动显示英文的站点。但是前端做i18n的不利之处就是ajax站点的通病,对搜索引擎支持不好。因为内容是js动态生成,无法被搜索引擎索引(虽然Google的机器人可以执行当前页面的js脚本,但是也很有限)。好在我对动态生成的内容无被索引需求,也就不管了。 Continue reading

Javascript String 字符串模板替换函数(轻量级)

很多情况下在写一些小页面时想用一些字符串模板,但Javascript又不原生支持字符串模板,只好用一些第三方库,但引用第三方库的缺点在于很多功能的冗余, 浪费前端加载时间和流量,甚至会造成命名冲突等问题。

其实有时候的需求很简单,不需要很高级的字符串模板功能,只需要像'My Name is {name}. Hello {herName}这样的线性替换就行。其实这个需求实现起来非常容易,四行代码就搞定了。如下:

JS 字符串模板替换函数

妈妈再也不用担心我用+来拼接字符串啦 🙂 Continue reading

Leo

April 13, 2014

花了一下午更新了下网站首页代码,主要进行了下面工作:

1. 重写了Flickr模块的代码,利用正则表达式提高了图片URL获取速度和加载速度

2. 新增了welcome.js,在控制台打印欢迎信息,很GEEK的方式,是个异步延迟加载模块

3. 把jQuery、nomalize等常见前端库换成了staticfile.org上的CDN,提高加载速度

4. 压缩了前端大部分代码,加载时间得到提升,消耗流量降至1.5M左右

5. 新增favicon,是个fudan的紫色logo

此版本为V2.0.

TODO:

1. 我的旅行轨迹

2. 我的摄影集(按主题分类)

3. 我的作品

Mac直接安裝Canon DPP系列升级版(适合无驱型Mac用户)

1. 首先到下面的网址下载canon最新的升级程序。没错是升级程序,当然的是mac的。
http://support-cn.canon-asia.com/

2. 解压。然后把解压后的文件(dpp3.XX_updater.app)复制到你的RMBP(例如桌面);

3. 右键dpp3.XX_updater.app,选择“显示包内容”,然后删除“contentsresourcesInfo.datx”。

4. 然后运行dpp3.XX_updater.app,神奇的情况发生了,可以安装DPP了,而不是提示升级。
总结:升级文件应该是一个完整的安装文件,只是canon基于特殊的想法给予了屏蔽,删除info.datx文件可解除。

参考文献:http://blog.sina.com.cn/s/blog_3ef766e00101ij0r.html

sae版的wordpress中的固定链接设置失败导致404解决大全

首先默认想仔细看本文的童鞋都是wordpress的初中级玩家、对php和服务器等也有一定的知识。

无论你通过哪种方式安装sae版的wordpress(代码仓库在线安装/下载wordpress改装版SVN提交),你如果碰到在设定wordpress固定链接时所有页面都出现404错误时,请看下文。

解决方案:URL重写(rewrite),也即自定义config.yaml。

一般情况:wordpress安装在根目录,这种问题的解决方案网上比较多,本质上都如下:

1. 修改根目录下的config.yaml文件(建议使用在线代码编辑方式,省去SVN不断提交的麻烦)。修改如下:

handle:
- rewrite: if (!is_file() && !is_dir() && path ~ "^/(.*)") goto "index.php/$1"

2. 点击保存,此时固定链接即可正常访问。

3. 简单解释下原理:is_file() 和 is_dir()判断当前URL是否是本地文件或者本地路径的名字,比如“www.louqibin.me/home.png” ,这个URL是我本地一张图片的路径,此时判断条件不成立,URL不重写,直接访问。但是比如“http://www.louqibin.me/2014/01/22/sae版的wordpress中的固定链接设置失败导致404解决大全/ ”,这个URL既不是一个文件路径也不是一个目录路径,同时path=”/2014/01/22/sae版的wordpress中的固定链接设置失败导致404解决大全/ ”,这个path满足正则表达式“^/(.*)””,该表达式要求判断path是否是以“/”开头之后跟任何字符,显然例子中的path满足,rewrite被激活,goto即为路径跳转,”index.php/$1″的意思是重定向到:

www.louqibin.me/index.php/2014/01/22/sae版的wordpress中的固定链接设置失败导致404解决大全/

即在原来URL中间插入/index.php/即可解决问题!

如果到这里你的问题还没有解决,正如我碰到的那样,我的情况是:我在一台sae服务器上装了多个wordpress,即在子目录下安装了wordpress。比如我在子目录blog和子目录dev下分别安装了两个博客。此时需要稍微改动下正则表达式如下:

handle:
- rewrite: if (!is_file() && !is_dir() && path ~ "^/(blog|dev)/(.*)") goto "$1/index.php/$2"

注意你应该根据你的情况修改正则表达式中的目录名字!

$1代表的是blog或者dev中任意一个字符串

$2代表的是(.*)中的所有字符。

原理都是一样的,在中间插入/index.php/。

刷新页面,怎么样,固定链接是不是生效了?恭喜!

 

除非注明,Leo’s Dev Blog文章均为原创,转载请以链接形式标明本文地址

本文地址:http://www.louqibin.me/dev/index.php/2013/08/08/为什么邮件地址中用等符号来代替.html