最近开发人员招聘情况

作为整个技术团队的负责人,日常工作中十分重要的一项就是人才的引进,对于技术团队的发展来讲更是至关重要。

年后算是一个跳槽的高峰时段,投简历和来公司面试的也不少,但是合适的并不多。现在的程序员市场有这么几个特点:

  1. 培训热度持续走高,尤其是 iOS 培训。越来越多的人想通过培训进入软件行业,其教育背景也不再只是计算机相关专业。最近我看到的简历里,很多求职者之前的职业五花八门,如面点师、仓库管理员、销售人员、公关人员、建筑设计师。这足以说明程序员被越来越多的人认为是一个体面、高薪、有前途的职业。
  2. 培训质量有所下降,出现简历造假现象。我并不排斥培训,我也见过刚培训完成后,理论知识和实践能力都蛮不错的求职者。但相当多数的求职者,虽然刚培训完,一些基本的问题都还回答不清楚,更别提自己学习一些培训以外的知识了。通过看简历就能知道培训机构现在在教什么,比如 Java 现在的培训项目肯定是云笔记。另外,据说很多机构会引导求职者简历造假。有意思的是,我曾经看到一份简历,他简历中写的一个项目,是我从头到尾一直跟着的,所有参与过这个项目的人我都知道,可是我根本不认识这个人。
  3. 有些已经有两三年工作经验的人,一直在一家公司做一件事,也没有自己另外多学些东西做些东西,导致他的实际技术水平并不高,但被自己的工作年限蒙蔽了双眼,觉得自己很厉害了。他们肯定也能找到不错的工作,但我的团队是不需要的,未来的路也不会宽广吧。

我希望我的团队成员,是真正有技术感的人,而不是为了生存、为了薪水所以才做技术的人。如果你真正希望一起提高技术,做最好的产品,那就联系我吧!

苹果证书签发者过期

今天在向 App Store 提交程序包时,突然提示以下错误:

查看钥匙串访问,发现机器上所有的苹果开发者证书、发布证书,状态都变成了“此证书的签发者无效”:

搜索证书的签发者 Apple Worldwide Developer Relations Certification Authority,发现证书已于 2016 年 2 月 15 日过期。如果没有找到这个证书签发者,确保在左下方种类中选择了“所有项目”,并在菜单中找到“显示->显示已过期的证书”。

苹果开发者网站上也已经做了证书过期声明 ,在其中可以找到证书下载链接:https://developer.apple.com/certificationauthority/AppleWWDRCA.cer。下载并导入新的证书,并把旧证书删掉即可,这一次证书的有效期直到北京时间 2023 年 2 月 8 日。

Android 开发中禁止屏幕自动旋转

在 iOS 开发中,可以在工程属性里设置全局支持的屏幕朝向。对于只需要支持竖屏显示的应用,在 Device Orientation 中只保留 Portrait,取消选择 Landscape Left, Landscape Right, Upside Down 即可。也可以单独针对某个 View Controller 设置屏幕朝向,实现 UIViewController 的 supportedInterfaceOrientations 方法即可。

团队中的 Android Developer 没处理过这种问题,于是我顺便了解了一下。发现 Android 似乎没有方法全局进行设置,只能针对 Activity 进行设置。

一种方法是在需要限制屏幕旋转的 Activity 的 onCreate 方法里,加入一句:

1
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);

另外一种方法,是在 Androidmanifest.xml 中为需要限制屏幕旋转的 Activity 都添加属性:

1
android:screenOrientation="portrait"

如果需要全局进行限制,自然是采取前一种方法较好。可以让工程中的所有 Activity 都继承于一个基类 BaseActivity,那只须在 BaseActivity 里调用 setRequestedOrientation 即可。

小心时间格式里 yyyy 的大小写

团队里的测试工程师测试出一个 bug,表现是:在 Date Picker 选择了2015 年 12 月 27 日,但并显示到 Textfield 里时,变成了 2016-12-27。选择 12 月较早一些的日期,不会出现任何问题。

刚开始感觉一定是测试看花眼了,但尝试之后发现的确可以复现,而且,是必现!

检查了一下代码,发现此处的 NSDateFormatter 对象的 dateFormat 赋了 YYYY-MM-dd,总感觉哪里怪怪的。看了一下其他地方的代码,才意识到,年份一般都是写成小写的 yyyy 的。改成 yyyy-MM-dd 后,果然一切恢复正常了。

但是这个 yyyy 和 YYYY 到底有何区别呢?

查了一下资料,得知 YYYY 表示的是 Week Year,也就是当前日期所在周的年份。一周从周日开始,周六结束,只要本周跨年,就进入了下一年。所以 2015 年 12 月 27 日这一天,用 YYYY 得到的年份就是 2016。

苹果的开发文档中,对日期时间格式的描述是在 Introduction to Data Formatting Programming Guide For CocoaDate Formatters 章节里。从文档中可以看到,苹果遵循的规范是 UNICODE LOCALE DATA MARKUP LANGUAGE (LDML) PART 4: DATES。这个规范的最后有一张表 Date Field Symbol Table,里面记载了所有的时间描述符,挺有意思的,准备有时间的时候仔细看看。

UIControlEventTouchDown 延迟响应

一个 UIButton,其上绑定了 UIControlEventTouchDown 事件。在模拟器上一切正常,反应速度很快,但在真机上出现了很怪异的反应迟钝。通过观察发现,如果按下按钮的右半边,也就是屏幕右边一侧的部分,则不会有反应迟钝现象。如果按下按钮的左半边,也就是屏幕左边一侧的部分,只要按下之后手指不移动,则会一直无响应,直到手指在按钮上产生了位移,才会响应事件。

经调查,这个问题自 iOS 7 开始出现,出现原因是由 iOS 7 开始引入的右滑返回。只需设置以下属性即可避免该问题的出现。

1
[self.navigationController.interactivePopGestureRecognizer setDelaysTouchesBegan:NO];

而且,这样并不会影响正常的右滑返回。

在 Auto layout 下应用 UIView 动画

在之前不使用 Autolayout 时,如果需要做简单的 UIView 动画,只需要:

1
2
3
[UIView animateWithDuration:0.25 animations:^{
[_topView setFrame:CGRectMake(0,0,100,35)];
}];

但是使用 Autolayout,不能再手动去更改 frame。而且我们会发现,如果按照之前的做法直接改写成:

1
2
3
[UIView animateWithDuration:0.25 animations:^{
[_constraintTopViewHeight setConstant:35];
}];

是没有动画效果的,依然会瞬间改变它的约束。

正确的方法是:

1
2
3
4
[_constraintTopViewHeight setConstant:35];
[UIView animateWithDuration:0.25 animations:^{
[self.view layoutIfNeeded];
}];

EI Capitan brings the missing Hex color picker

OS X 里的颜色选取器一直没有集成十六进制的功能,这给程序员和设计师带来了诸多不便,于是有开发者制作了对系统 Color Picker 的增强插件,如我一直在用的 Hex Color Picker,在系统的 Color Picker 中增加了一栏,专门用来输入十六进制的颜色值,系统全局都能用,很是方便。

但是它在 EI Capitan 上不再好用了,因为系统加入了一项新的安全技术,称作系统完整性保护,即使 root 账户也不允许修改系统主要程序的内容。相应的,像 XtraFinder、HexColorPicker 之类的系统增强类软件,在 EI Capitan 上都只能歇菜了。

不过,好在 Apple 已经发觉到了我们的诉求,在系统的 Color Picker 里增加了十六进制的功能,虽然有些隐蔽:

在第二个选项卡 (Color Slider) 中的 RGB Sliders 里面,下方有个 Hex Color 文本框。

限制最大输入字符数(更新)

这篇博客 中提到的限制 UITextView 最大输入字符数的方法,依然是有问题的。问题出现于用拼音输入法输入中文的时候,比如键入“你好世界”,对应的拼音为“nihaoshijie”。限制最大长度为 5,则虽然“你好世界”为四个字,但在输入拼音字符的时候,会超过 5 个字符,导致无法输入进去。

iOS:UITextField中文输入法输入时对字符长度的限制 这篇文章中提出了一个方法,经尝试是可以正确处理这种情形的。基本方法如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
- (void)textViewDidChange:(UITextView *)textView {
NSString *lang = [[textView textInputMode] primaryLanguage];
// 对简体中文输入进行特殊处理
if ([lang isEqualToString:@"zh-Hans"]) {
UITextRange *selectedRange = [textView markedTextRange];
// 获取高亮部分
UITextPosition *position = [textView positionFromPosition:selectedRange.start offset:0];
if (!position) {
// 没有高亮选择的字,则进行字数限制
if (textView.text.length > LENGTH_LIMIT) {
textView.text = [textView.text substringToIndex:LENGTH_LIMIT];
}
} else{
// 有高亮选择的字,认为现在正在拼音输入状态,暂不进行限制
}
} else {
// 简体中文以外的直接限制,暂不考虑其他语言
if (textView.text.length > LENGTH_LIMIT) {
textView.text = [textView.text substringToIndex:LENGTH_LIMIT];
}
}
}

同时,在上面这篇文章中还受到一点启示,UITextField 是没有类似 textViewDidChange 这样的代理方法的,所以对于 UITextField 我们该怎么办?可以通过监听 UITextFieldTextDidChangeNotification 通知来达到一样的目的。

在初始化时添加监听:

1
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(textFieldDidChanged:) name:@"UITextFieldTextDidChangeNotification" object:_textField];

实现监听方法:

1
2
3
4
-(void)textFieldDidChanged:(NSNotification *)notification {
UITextField *textField = (UITextField*)notification.object;
...
}

别忘了在 dealloc 时移除监听:

1
[[NSNotificationCenter defaultCenter] removeObserver:self name:@"UITextFieldTextDidChangeNotification" object:_textField];

向 Eclipse 中导入项目提示 JRE unbound

在 Eclipse 中导入 Java 项目后,常会出现编译报错,一个很常见的原因是工程属性中所定义的某些 Library 在本地找不到。又经常是本地安装的版本与工程属性中指定的版本不一致,比如本地安装了 JRE 8,但工程属性中定义的是使用 JRE 7。

在左侧的对应工程上点右键 -> Build Path -> Configure Build Path,在弹出的对话框中,右侧顶部点选 Libraries,下方的列表中会发现有几项后面有 “(unbound)” 后缀。此时就代表,项目属性中定义的版本,在本地找不到,所以无法编译。

解决方法也很简单,如果本地没有安装所需要的 Library,安装上就好。如果本地安装了,只是版本不一致,而且可以用本地版本替代的情况,可以选择 unbound 的条目,再点击右侧 Edit 按钮,在列表中选择本地有的版本,或者直接选择 Workspace default JRE,即可解决。