start 12

现在晚上要照顾大喵,睡眠很不规律,所以早上必须定闹钟。而大喵就睡我旁边,m88体育 闹钟响的时候很容易也吵醒她。刚好看到小米手环的震动闹铃功能,正好能解决这个问题。于是果断天猫入手,趁帮一个朋友买东西,搭包裹寄过来。

老实说,看外观和做工,79块rmb的价钱还是很公道的:

前段时间诸多不顺,没太多精力打理博客。现在总算都尘埃落定了,还是要静下心来把很多事情坚持下去。

因为我好像查一万次都记不住英制和公制单位的换算,m88体育干脆自己写个工具,最起码不用每次查都绕道google。目前只有重量单位,慢慢添加其它。

实用计算器

还是用的AngularJS,这次相对前面写的两个小东西,稍有了点复杂度:多个输入/输出框要检测唯一输入。一开始用的$watch,貌似不太好用,主要是无法区分用户输入和计算结果变化,最后导致重复计算。查了好久才发现ng-change属性能避免这一点。

另外推荐一本Angular的书:AngularJS - Brad Green & Shyam Seshadri - O'Reilly

使用函数对象来定义运行策略

有些语言支持函数指针,代理(delegate),lambda表达式,或者其它类似的机制来存储和传递可执行的"函数"。这些特性允许程序在运行时动态改变行为,而这样的设计被称为"策略"模式(strategy pattern)。比如在c语言标准库中,qsort函数有一个参数是指向comparator函数的函数指针,这个comparator在排序过程中被用来对序列中的两个元素进行比较,通过传递不同的comparator函数,qsort可以动态采用不同的排序(比较)策略,而这个被传入的comparator就可以称为一个排序策略。

Java不支持函数指针,但通过对象引用可以实现类似的功能。通常说来,调用一个对象的方法,是要对这个对象本身进行操作。但如果一个方法接受的参数是指向其它对象的引用,那么这个方法也可以对这些传入的对象进行操作。如果一个类仅开放一个这样(对其他对象进行操作)的方法,那么它的对象就等同于一个指向该方法的函数指针,而这样的对象被称为函数对象。比如下面的类:

class StringLengthComparator {
	public int compare(String s1, String s2) {
		return s1.length() - s2.length();
	}
}

又在联系一个很不错的北欧职位,难得对方不在乎身份问题,说只要面试通过,他们就可以负责解决签证和工作许可。

于是开始和猎头各种眉来眼去:改简历,试探工资情况。。。看来一切都不错,马上就要正式递出简历,临了猎头这一方还要确认一下技术水平,发个链接过来做在线测试。这是完全正常的要求,而且以前也没少做类似的玩意儿,没啥可怕的,上吧。

结果就杯具了。这家猎头选了一个叫mi-candidate.com的网站,此站简直就是个半成品的破烂。登陆以后找不到测试入口,必须依靠一个莫名其妙的通过邮件发送的链接开始测试。没有任何热身或demo题目让人熟悉测试系统。这些问题也就是用户体验差一些,毕竟不是核心功能,也不用太多吐槽。最坑爹的是他家的题目,连html代码都弄不干净就把题目卖给别人,这就不能忍了。比如一道题目是这样显示的:

继承优于标签类型

开发者有时会遇到这样的类:其对象有多种不同"类别",每一"类别"的对象都用一个特定的标签来识别。比如下面的类,可以代表"圆圈"或"矩形":

// Tagged class - vastly inferior to a class hierarchy!
class Figure {
	enum Shape { RECTANGLE, CIRCLE };
	// Tag field - the shape of this figure
	final Shape shape;
	// These fields are used only if shape is RECTANGLE
	double length;
	double width;
	// This field is used only if shape is CIRCLE
	double radius;
	// Constructor for circle
	Figure(double radius) {
		shape = Shape.CIRCLE;
		this.radius = radius;
	}
	// Constructor for rectangle
	Figure(double length, double width) {
		shape = Shape.RECTANGLE;
		this.length = length;
		this.width = width;
	}
	double area() {
		switch(shape) {
			case RECTANGLE:
				return length * width;
			case CIRCLE:
				return Math.PI * (radius * radius);
			default:
				throw new AssertionError();
		}
	}
}

接口只用来定义类型

如果一个类实现了某个接口,那么这个接口类型可以成为指向该类对象的引用。因此类与接口之间的"实现"关系,应该能使用户通过接口了解对象的行为。除了这个场景以外,定义接口都是不合适的。违背上述原则的一个反例是常量接口,这样的接口不定义任何方法,仅含有静态final属性,每一个属性都被开放为常量。用户类通过实现这些接口来避免使用常量全名。比如下面的例子:

// Constant interface antipattern - do not use!
public interface PhysicalConstants {
	// Avogadro's number (1/mol)
	static final double AVOGADROS_NUMBER = 6.02214199e23;
	// Boltzmann constant (J/K)
	static final double BOLTZMANN_CONSTANT = 1.3806503e-23;
	// Mass of the electron (kg)
	static final double ELECTRON_MASS = 9.10938188e-31;
}

第3页 共19页