日记 - Android 实习测试题
Preface
有个小伙伴给我介绍了一家互联网公司,说让我投份简历看看能不能争取到一份校招实习资格。后来和这个公司的 HR 联系了一下,说让我先做做题。题目一共两道:
- 第1题可能涉及到公司的业务,这里不做透露。
- 第2题是写一个 Android 自定义控件,是个尺子控件,要求使用系统提供的绘图API(
android.graphics.Canvas
)来做。
下面我就说下这次做自定义尺子控件都学到了什么。
开发流程记录
Day 1:
-
上午: 看 Android 自定义组件 的官方文档,Google 找了两三篇中文教程,又到 GitHub 上看了一些 Demo 的源码,大致知道了
View
类的几个主要方法。 -
下午: 搭建项目开发环境(Android Studio, AVD, etc.),覆盖了
android.view.View
类的3个方法onTouchEvent(MotionEvent event)
: 负责接受任何触摸事件onMeasure(int widthMeasureSpec, int heightMeasureSpec)
: 负责算出控件在被载入后应该占用多大地方onDraw(Canvas canvas)
: 负责绘制控件
然后又实现了3个度量单位(
Centimeters
,Inches
,Feet
)的枚举类以及换算它们类。
Day 2:
- 看了下
DPI(Dots(或者说 Pixels) per Inches)
、dp(Device-Independent Pixels)
、sp(Size-Independent Pixels)
的定义以及换算方法,并编写到度量单位换算类里. 比较令我意外的是,把 Centimeter 转成dp
需要乘以一个数,这个数字居然是个常量。我还反复的在纸上推了几遍(在此感谢 KhanAcademy 教我了一种新的对待单位的方式),后来在尺子实现出来之后没有任何毛病。后来我又想了想 其实很正常,因为dp
是以 DPI=160 为基准来计算的,最后的算式里它被消除掉了,于是整个算式就和 DPI 没什么关系了。 本来还想支持sp
的换算来着,虽然本质上和dp
一样,但因为有些视力障碍的用户会在系统设置里调整文字缩放,因此想实现这个单位还需要读取系统设置,为了主要进度 暂时放弃了这个功能。 - 进一步完善了
Ruler
类,因为构造函数里可选的初始化成员变量太多(>=4个,参考 《Effective Java》 这本书),于是使用了Builder
设计模式。 - 初步的在
onDraw(Canvas canvas)
里做了一些运算,以及画出了错误的尺子刻度。
Day 3:
- 更换了4种绘制时候的刻度运算方法(事实上只有最后2种是对的),折腾了一天到了 17 点还是有刻度跳跃的 bug。后来发现居然是 float 精度的问题,
-4 - -4.6
能给我算出0.59999999
出来,然后Math.floor
一下就变成了 5。后来分析了一下,发现所有这种运算结果都是很接近正确运算结果的,于是就改用了Math.round
。 - 用了一些时间把尺子大刻度下面的数字绘制上去了。
- 清理代码,整理注释。
最后将源码发送到了 HR 指定的邮箱。
后续
今天早上 HR 向我打了个招呼 然后附了一张和Android部门Leader对话的截图,没有通过的原因有2:
- 简历内容与职位要求不符
- 目前 Android 开发部门不缺人
嘛,还是感谢 HR 给我展示自己能力的机会。
心得
以前学 Java 的时候 经常听说 float
和 double
的精度问题,因此不能用于有精确要求的场景(比如银行计算转帐金额的时候)。然而这次我才真正见识到它的威力,因为这个不能算作 bug 的 bug,我耗费了近一天的时间,这个教训来得够深刻。
更新历史
14 Jun 2017: 首次发布 15 Jun 2018:
- 添加: Android 实习测试题的后续结果.