Menu Home

跟一个美国朋友聊天了解到的几点事情

昨天上午在星巴克coding,大约11点的时候旁边坐来一个很高大的美国人,叫Robert,来自于美国。。。出生在Texas,在Pennsylvania长大,在Arizona工作了7年,所以好像和很难说来自于哪个州。刚开始安安静静的坐了会,然后他看见我在coding,问”Are you making an app?”, 我说yes,然后就开始聊起来了,聊了大概2个小时,让我了解到一些比较惊讶,或者说之前不知道的事情。 ## 1. Android & Apple 在国内,除了我们苦逼的安卓开发者,对于绝大部分人来说,买Android机的最主要原因,应该是便宜吧?然而他告诉我,在美国并不是这样的,Android在美国是非常流行的,几乎75%是安卓,iPhone不到25%,为什么呢?因为Google,因为Google Maps,因为GMail,Youtube,Google Drive,Handout。。。Google在美国已经建立了非常庞大而完善的生态圈。而在这基础之下,是Google的 constant updates—-这才是Google最大的特点,或者说最大的优势—-这些updates保证了系统的流畅性,保证了APP极好的使用体验。此外,Google Play 的统一性保证了手机上的第三方app也能持续的得到更新。所以国外的安卓机远不像国内的系统那么卡,app体验那么差。然而这一切,在我大天朝的GFuckingW下面封锁的荡然无存,所以中国的Android机才这么慢,这么卡。这让我意识到,中国这么多人想买iPhone,甚至卖肾买iPhone,其实真不是我们多么虚荣,也不是iPhone真的有那么好,只是因为Android或者说Google的绝大块优势都已经被剥夺了,在这种情况下,我们并没有第二种选择。 恩,以后谁再跟我说他的安卓机很卡很慢,我知道该怎么回应了! ## 2. 该重视的是用户体验 这跟前一点有类似的地方。国内的一家店,你以为它在卖商品,其实它就是在买商品。国外的一家店,你以为它在卖商品,其实它买的是一种体验,一种感受。当时拿了星巴克作为例子,他问我为什么来这里,我说这里环境还不错,适合coding,于是分析了一下为什么会觉得这边环境还不错?因为这边的服务员服务态度很好,因为这里的桌子永远是干净的,这里永远都有洗手间(当然其实某一些店并没有洗手间),洗手间永远是干净的,甚至天花板都永远是干净的,这里的桌子和椅子高度刚好适合我用电脑,这里冬天有暖气夏天有冷气,这里边上有纸巾随时供我取用,而且纸巾质量还不错。。。所以说让你留恋,或者说下次还愿意来的,其实并不是咖啡本身,咖啡自然不能差,然而更重要的是这个环境,是你在这家店的这段时间,这家店给你的感受。。。想想,貌似至少我习惯去星巴克,的确是因为那里的环境。如果人多的话,我就会去一家偏一点的星巴克。 上面提到的几点,听起来简单,然而单单第一点国内能做到的,据我自己的经历,除了海底捞,没有第二家了。 你会说外婆家不这样,不照样爆满,然而有几个人会说“外婆家给我的用餐体验很好”呢?所以中国的餐饮酒店开到国外的少之又少,唯一听说的,也是海底捞。 ## 3. Social 这是也是非常让我脑洞大开的一点,我问他“Do you have many friends here” 他说yes,我问他们都是美国人吗?他说”No, most of them are Chinese, why meet American when you are in China, It makes […]

设计基础入门《写给大家看的设计书》

从名字可以看出,这本书是一本关于设计的书,一本很简单的基础入门书。说的具体一点,这里说的设计指的是界面设计,说得更具体一点,指的是如果安排、展现你现有的内容。 那“设计”这件事情,跟我们有什么关系呢?首先,爱美之心人皆有之,如果一件东西我们能做的更漂亮,那无疑会让我们心情也好一点。再次,日常生活中,我们多多少少也要涉及到一些关于设计的活动。最常见的比如说简历的设计,如果能把简历设计的漂亮、内容安排合理、重点突出,那多少会给我们找工作、面试加点分。 这本书主要讲了的是4个设计基本原则:亲密性、对齐、重复、对比。下面分别介绍一下。 亲密性 亲密性原则有两点内容:1. 相同或类似的东西放在一起;2. 不同的东西不要放在一起。 以下是一些使用亲密性原则前后的设计实例对比。  上图这是一个读书会传单的例子,左边的图没有任何组织性。右边的图把每一本书的内容放在一起,跟其他书用一定的空白隔开,最用的地址信息、联系人信息又跟书本信息隔开,实现了信息的组织性,同时具有更高的可读性。一下的例子也是类似,大家感受一下。 对齐原则 对其原则说的是,页面上的任何信息,都不能随便放在页面上,而是应该跟页面的某个元素(比如边界线)建立起关联。此外,这本书专门详细讲了居中对齐,因为居中对齐是我们非设计人员最常使用的对齐方式。这种对齐方式显得正式、工整、中规中矩,但是同时也很无聊乏味。所以作者的建议是谨慎使用这种对齐方式,在使用这种对齐方式之前,考虑一下其他的对齐方式能否适用,而不是默认使用居中对齐。 以下是一些使用对齐原则的例子。  上面的例子中,左边是居中对齐,显得单调乏味,右边使用了左对齐,显得有力,也有趣一点。同时使用亲密性原则把作者、日期信息跟标题隔开。这样读者一目了然,知道哪里是什么。  上面的例子说明了一个使用居中对齐的小tip,如果实在要使用居中对齐,那么可以试着设计得高瘦一点,这样显得苗条,精神。  上面的例子说明了另外一个小tip,可以利用界面上的某些元素,比如图片边界作为基准,进行对齐。 重复性原则 同种类型的元素,可以用相同的样式(字体大小、颜色、粗细等等)和标识进行重复。重复性原则相对来说我们会使用的比较多,参见下面的例子。  上图是一个酒吧的菜单,左边的菜单让人不知所以,类型、菜品及配料混在一起,右边经过整改以后,我们可以很清楚看到分类(Starters和Entrees),每种菜品及它的配料。 对比原则 对比原则讲的是,如果两个东西不一样,那么就让他们彻底不一样。在这里的重点就是要彻底。如果你有两种不同的文字信息,一种用12pt的字体来表示,一种用14pt的字体表示,这里的对比是不够明显的。相反,你可以一种用12pt,另外一种用20pt,这样对比相对会明显很多。 用来实现对比的元素有:字体种类、字体大小、粗细、斜体/正体、背景颜色、下划线、修饰符号等等。  在上面的例子中,右边的图相对于左边的图,大标题、小标题、正文对比相对左边的图要明显很多,内容结构相对也会看得清楚很多。  上面是一个简历的例子,可以看到,通过亲密性、对齐、加重对比,右边的效果相对左边要整齐有序、信息清晰很多,也会显得有趣很多。 最后,给出一个逐步使用各种原则的例子,看看能达到什么效果。 以下是原图:  以下在原图的基础上,使用亲密性原则,将大标题小标题、作者和日期分开,信息结构变得更清楚。  以下在上图的基础上,将居中对齐变成右对齐,显得更有活力、更有趣。   接下来再在上图的基础上,将主标题和作者使用背景色加剧对比,突出重点。   以上4个原则可能是这本书对于一般读者最有用的内容,此外,这本书后面还针对很多种特定的设计任务如名片、网站、传单等等,提出很多针对性的意见。接着还花了很大篇幅描述颜色的使用、各种字体的使用等等,可作为进阶的学习材料。

Shell命令行中的特殊字符及其转义(去除特殊含义)

## 特殊符号及其转义 我们知道,在一个shell命令是由命令名和它的参数组成的, 比如 cat testfile, 其中cat是命令名, testfile是参数. shell将参数testfile传递给cat命令. 但是, 如果参数中含有特殊字符, 比如说*, *我们知道,是表示任意多个(包括0个)任意字符. 那么shell的工作方式是,它会对这些特殊字符进行预先处理, 然后再将处理的结果传给那个命令. 比如说,如果你的当前目录有file, file1, file2 三个文件, 那么当你执行cat file*的时候, shell会对参数部分file*进行预先处理, 由于*表示任意多个(包括0个)任意字符,那么处理的结果便是file file1 file2,接下来,shell再将这个结果, 即file file1 file2传递给cat命令, 所以你看到的结果跟直接执行cat file file1 file2是一样的, 那就是三个文件的内容都显示在命令行终端. 实际上,我们有办法看到shell处理的结果是什么,或者说真正执行的命令是什么样子的, 那就是在你要执行的命令之前加上echo. 比如说,在上面的目录下,你执行echo cat file*, 那么你将看到 cat file file1, file2 上面那条命令,就是经过shell对参数的处理之后,真正执行的命令. 但是很多时候,我们希望传递给这些命令的,就是这些参数本身, 比如说,你当前目录下有一个文件的文件名就叫test*, 同时还有另外一个文件, test1. 而你只想看test*的内容, 这时候,如果你执行 […]

Ruby 文件操作 Cheatsheet

每次都要查,真是蛋疼,不如一次性总结一下,以后再不记得就来这里找好了。 以下代码中需要用到的文件名:filename = ‘testfile.txt’ 读取其中的全部内容:File.read(filename) 将一个字符串一次性写入这个文件: File.write(filename, str) 读取文件内容,依次处理其中的每一行: File.foreach(filename) do |line| #process each line end 判断文件是否存在:File.exists?(filename) 删除文件:File.delete(filename) 文件重命名:File.rename(filename, new_name) 文件的名字:file.path # file是一个File对象 文件的绝对路径:File.absolute_path(filename) 当前所在目录:Dir.pwd 当前登录用户的home目录:Dir.home 创建文件夹:Dir.mkdir(dir_name) #注意,如果父目录不存在的话,这里无法创建子目录 删除文件夹:Dir.rmdir(dir_name) 创建多级目录(mkdir -p):FileUtils.mkdir_p(path) #这里需要require fileutils 找出当前目录下的所有文件或目录:Dir.glob("*") 找出当前目录下的所有Ruby文件:Dir.glob("*.rb") 判断目录是否存在:Dir.exists?(dir_name) 用文件夹和文件组成一个路径:File.join(dir_name, filename) 当前文件(正在执行的文件)相对于当前所在目录(pwd目录)的相对路径:__FILE__ 当前文件(正在执行的文件)的目录相对于当前所在目录(pwd目录)的相对路径:File.dirname(__FILE__) 当前文件(正在执行的文件)的绝对路径:File.expand_path(__FILE__) 当前文件(正在执行的文件)所在目录的绝对路径:File.expand_path(File.dirname(__FILE__)) 最后附上File.open(filename, mode) 中的mode各种取值以及含义: Mode | Meaning —–+——————————————————– "r" […]

用Robolectric来做Android unit testing

作为一只本科非计算机专业的程序猿,手动写单元测试是我从来没接触过的东西,甚至在几个月前,我都不知道单元测试是什么东西。倒不是说没听过这个词,也不是不知道它的大概是什么东西——“用来测试一个方法,或者是一小块代码的测试代码”。然而真正是怎么做的?我并没有一个概念,或者说并没有一个感觉。 记得第一份工作在创新工场的时候,听当时的boss @王明礼 说,公司有个神级的程序员(。。。名字忘了。。。),他会写大量的单元测试,甚至50%以上的代码都是单元测试。当时崇拜之极,却仍然觉得写单元测试是很麻烦的一件事情。 扯远了,话说回来,当你接触多了国外的技术博客,视频之后,你会发现,单元测试甚至TDD,在国外是非常流行的事情。很多人甚至说离开了单元测试,他们便没有办法写代码。这些都让我对单元测试的好感度逐渐的上升。然而,真正让我下定决心,一定要研究一下这个东西的,是前段时间看大名鼎鼎的《重构:改善现有代码的艺术》里面的一段话: I've found that writing good tests greatly speeds my programming, even if I'm not refactoring. This was a surprise for me, and it is counterintuitive for many programmers… –Martin Fowler 《Refactoring: Improving the Design of Existing Code》 是的,你没看错,他说单元测试可以节约时间,提高开发速度!!!身为一个无可救药的懒癌患者,看了这句话简直就像看到了一道神光似的!既然都可以节省时间,那肯定是要看看的啊! 有趣的是,Martin Fowler在《重构》里面说他最初是因为 Dave Thomas说的一句话,让他走上了单元测试的不归路。而我这几天刚好又在看Dave Thomas写的《Programming Ruby 1.9 […]

Otto: No More Callbacks

Otto: No more callbacks 你要做一个todo app,有一个Activity里面有一个ListView显示你所有的task,你的数据存储在服务器。假设你没采用任何的软件架构(MVC、MVP、MVVM等等),每次app打开的时候,你从服务器把数据load下来,load完了以后,通过callback把数据传给Activity,然后显示到listview里面。代码结构大概是这个样子 public class TasksActivity extends Activity { private ListView mListView; //… private void loadTasks() { TaskModel model = new TaskModel(); model.setTaskCallback(new TaskCallback() { public void onError(String msg, int code) { // handle error } public void onSucceed(List<Task> tasks) { updateTaskList(tasks); } }); model.loadTasks(); } private […]

Regular expression: All you need to know

Regular expressions are nuts. You have spent lots of time studying them and later when you actually need to write one, you come up with nothing. That’s why you need a cheatsheet, like this one. ## Abbreviations used in this post RE for regular expression. /regular_expression_content/ regular_expression_content is the text […]

博客换回Jekyll,顺带简介一下Jekyll

个人网站开起来有一段时间了,当时目标是每周写一篇文章,不过到现在也没写多少篇哈哈。。 刚开始的时候是用Jekyll来做的,后来觉得不够自由,版式太固定不好扩展。于是又推倒,用Rails自己写了一个,用Jekyll的默认主题作为样式风格,用Redcarpet来做markdown的rendering。这些都很简单,唯一的问题在于,Jekyll的默认主题虽然简洁,但是太简陋了,于是自己试着去改一些布局啊,样式啊,都是CSS的东西。折腾了几次以后,我终于要承认,我并不是一个CSS guy,我并不是非常enjoy这个过程,而且还觉得挺烦人的。所以想想,还是算了,我想写东西,那就专注于写东西吧,样式的东西交给别人去做。 于是乎,又想到了Jekyll,心想像Jekyll这样一个popular的博客引擎,应该有很多很漂亮的主题吧,于是搜了一下,找到了这个,也就是你现在看到的这个,个人感觉这是个非常适合blog的主题,既漂亮,同时也是content focused,于是决定就用这个了。从Rails app搬回Jekyll,最大的遗憾,就是之前的一些评论不能一起搬走,好可惜的感觉! ### 关于Jekyll <!–more–> 稍微介绍一下Jekyll,Jekyll是一个static page generator,应该是如今用的最广泛的吧,因为github pages用的是这个。 Jekyll的工作原理,类似于一个文本转化器,它的原材料是markdown文本,经过它的转换以后,变成了由HTML/CSS/JS组成的静态页面,这些静态页面产生以后,你把他们放到nginx或apache的root directory,就可以通过互联网访问了。是的,没有“后台”!没有数据库!没有动态代码(除非你把前端的JS代码看作“动态代码”)!!!Everything is static, thus everything is simple! 要使用Jekyll也很简单,首先你要有Ruby,要有Gem,然后 gem install jekyll jekyll new my-blog cd my-blog jekyll serve 用浏览器打开localhost:4000,你就可以看到你创建的第一个jekyll博客网站了。以后你要写自己的文章,只需要用markdown编辑器写好,保存为.md文件,然后放到my-blog/_post里面。系统会自动将你在_post下面的文章一个个遍历出来,放在首页。 更多的信息你可以在Jekyll官网看到。 ### 免费托管到github pages 用Jekyll的一个好处是,你可以用github pages来免费托管你的博客,将你的blog目录(如前面的my-blog)关联一个github pages专用的github repo。然后只管git push到repo就好了,简直不要太方便。 具体操作请看这里。 ### 用Disqus来给你的blog加上评论功能 评论是很重要的,每一个写文章的人,除了希望自己写的东西能让别人看到,帮助到别人,还希望能得到读者的支持和鼓励,评论是最重要的一个途径。此外,评论还能让别人指出你文章中的错误,或者与别的读者的交流等等。 现在问题来了,前面提到,Jekyll产生的是静态页面,没有数据库,那么评论怎么保存呢?答案是我们不保存,或者说的更清楚一点,我们不自己保存评论。我们可以用第三方的专业的评论管理工具,来帮助保存,显示评论等等一系列相关功能。我这里选的是国外的Disqus,这是用的最广泛的评论管理服务。使用了以后,发现这里还有一个非常大的好处,那就是你注册一个账号,就可以直接用来评论别人的文章了。我的意思是,比如说,另外一个人也开了一个自己的博客网站,也使用了Disqus,那么你可以直接用你的Disqus账号评论他的文章,再也不用输入所谓的用户名,email等等一系列烦人的东西。 使用Disqus加上评论功能真的是非常非常简单,不信请看这里。 Disqus的简单让我产生了一个很严重的疑问,它是怎么来防伪的呢?我看了它的代码,并没有任何secret key这样的东西。它是怎么防止别人用我的账号来给他的文章加评论呢?或者说,它能不能防止? […]

从AndroidStudio的启动参数开始,了解一下JVM的一些东西(内存使用,JIT等)

如果你使用AndroidStudio经常觉得很卡,那有可能是因为系统给AS分配的内存不够的原因。打开/Applications/Android Studio.app/Contents/bin/studio.vmoptions (Mac),可以看到有以下配置: -Xms128m -Xmx750m -XX:MaxPermSize=350m -XX:ReservedCodeCacheSize=96m -XX:+UseCompressedOops 这些参数分别是什么意思呢? ####-Xms128m The -Xms option sets the initial and minimum Java heap size. The Java heap (the “heap”) is the part of the memory where blocks of memory are allocated to objects and freed during garbage collection. 就是JVM启动的起始堆内存,堆内存是分配给对象的内存。这里我把它改成了512m ####-Xmx750m This option sets […]