开放的API是个好东西:

从Google,Facebook,Twitter 到国内的各种SNS,微博站点,  它们中的绝大部分都有一套基于HTTP+XML/JSON的开放API。靠这些开放API, 一个简单的手机客户端也能做很多事情,如果配合自己的服务器程序,   开发者很快就可以推出一套低成本的客户端+网络服务。首先感谢这些开发API提供者, 不过我也想想说说我的看法:

先忆苦思甜,和早期的Webservice, SOAP XML 这些重型HTTP API比较,现在主流的解决方案:HTTP+JSON,已经是非常轻便好用了.  不知道还有没有人记得拿JBuilder自动生成Webservice代码的的时候,  我想只有靠代码行数拿工资的程序员才会怀念那些日子。

但是,现在的开放API还是有不少改进的空间, 我至少遇到了一些问题:

第一个问题:没有区分第三方客户端和服务器两个完全不同的环境。比如认证登录这块,采用Oauth是为了不让第三方站点获取到用户密码, 通过web界面登录再跳转.  对第三方web服务器是合适的。但是对客户端,我觉得这样是多此一举。使用WebView容易丢失焦点, 界面loading延迟, 而且也无法真正防止恶意客户端偷偷获取账号/密码。 这样的结果是什么呢?  最好的客户端都是不用Oauth的直接走特殊认证的。 如果一个API设计的结果是第三方要靠绕过它显示自己技术或者商务谈判或者用户体验牛逼。  那么可以认为这个API的适用范围需要调整了。

第二个问题是, API的往往是按照服务自身逻辑完整性设计的, 而不是按照使用案例设计的, 一个糟糕的例子如下,显示最近朋友的更新,需要先获取朋友列表ID, 然后获取每个朋友个人信息, 然后获取每个朋友产生的文字内容。  这不是调用3次API的问题, 这是调用1+2/*N次API的问题。

第三个问题:  客户端代码跑后台线程是受限的, 很多API给出的资源都是单独的URL。 如果很多零零碎碎的小图片需要同屏幕显示,而手机又存在手机和WIFI两种速度差别很大的网络,客户端需要大量的代码来处理异步读取和错误处理(请考虑可能还有几个网站API要同时支持). 而且这段代码维护起来也很痛苦. (这个时候在server写一个页面, 然后在客户端直接用Webview显示是个不错的办法)

最后一个问题:  更新! 在服务器上更新, 废弃一个API是非常快的事情。 但是客户端上就慢多了,客户端不同的版本共存则是常事。 如果开放API做了不兼容的修改, 老的客户端就完全不可用了. 如果你使用了些第三方API的封装库而它没有更新,你会更痛苦。我们的做法是在服务器有一整套proxy api server, 客户端尽可能和自己的API打交道, 把对开放API的支持放到Server上做,这样倒是能解决问题。但是我觉得从专业分工的角度上看, 不是每个客户端团队都有应该做这样的事情。

那么我们该怎么做呢?

如果是你客户端开发者, 隔离,封装是必要的, 如果可能, 尽量把开放API放到Server上支持,保持客户端的简单. (另外离那些非官方的API封装包远远的!)如果你是服务器程序员,  真心希望你可以尝试一下客户端网络编程,比如iPhone和Android. 这样能帮助你设计出更好的API. 毕竟: 你总需要用用自己设计的东西嘛.

posted @ 2011-12-05 13:44 tech.cap 阅读(126) 评论(0) 编辑

【更新】很多朋友不同意我的意见,其实我想表达的是一个先后顺序的问题, 并非是重要程度。好的产品能让技术重要起来.

做项目,特别是创业项目,  实现好的点子总是一件令人抓狂的事情。明明非常有经验,为什么还是总延期呢?看上去没有技术难度,却很容易陷入到实现细节中出不来呢。这几天想了很多,基本上笔者总是遇到下面一个循环:

  • 关于某个功能,有了一个好点子
  • 开始实现, 但是很快发现在细节上要做的东西貌似比较多
  • 于是开始设计复杂的对象关系和结构, 希望通过代码把它们管理起来. "以后好扩展"(很多人的口头禅)
  • 但是...发现点子需要调整, 设计上有变化。
  • 发现明明只是小调整, 却要改很多地方, 大量的"以后好扩展"的设计完全用不上了?
  • 直接重新开始写代码, 但是不知不觉又慢慢滑入步骤3的流程中.

这个循环,很明显会浪费掉宝贵的时间。如果是创业的小团队,更是耗不起,但是为什么会这样呢?直观的看:这是过度设计。但是这个错误背后,我觉得有一个更大的错误:在好产品还不存在的情况下就开始追求好代码

这是一个错误吗? 我想很多人可能不会同意。 但是仔细想一下, 它很有可能是! 特别是在时间紧迫的情况下。 我的理解是这样:好代码的用处不是为了自娱自乐, 而是为了方便修改, 应对变化.  但这一切都有赖于产品细节的支撑, 可惜的是, 初创的产品细节可以认为是最不稳定的.  没有它们做支撑. 强求好代码,  结果多半是一些设计模式/经验模式的堆砌.  写起来很爽,  过期得更快. 毕竟我们人类的智力是总结经验, 而不是预测未来。

结论: 对于创业的团队来说, 最重要的东西不一定是最优先的,就算技术是核心竞争力,代码虽然重要,但是必须得先有好产品,等产品相对靠谱了,再仔细设计你的技术架构吧 

posted @ 2011-12-01 12:11 tech.cap 阅读(2397) 评论(34) 编辑

AndroidiOS那个好?应该先往哪个上面投入资源?多次被人问到此类问题,笔者刚好自己的项目也需要考虑iOS版本。就索性进行了一番调研,于是有了本文(本次不讨论越狱的iOS)

首先从情感上,你喜欢哪个就好,就像百事可乐和可口可乐,当然这个比喻不是很恰当,因为可乐喝起来几乎一样,但是Android和iOS还是有很大差别的。

iOS来源于Apple的OSX,是UNIX系统,OSX已经有差不多10年的历史,从内核底层到软件架构都是逐步发展过来的。iOS使用ObjectivC这个古老的语言来做开发。而Android是Google基于Linux搞来的,严格意义上讲Android并不是一个Linux系统,它没有Linux的xwin,没有glibc,缺乏一整套标准的Linux程序。Android应用绝大部分都是使用JAVA开发,跑在Dalvik虚拟机上(一小部分使用NDK)。 Google在底层也修改了很多东西。Android算是一个全新的操作系统. 所以:

  • Android使用JAVA,上手容易很多,如果有很好的JAVA Lib加持,开发效率会高些
  • iOS没有虚拟机, 也没有GC,性能要好一些,当然这个差别会随着Google的改进越来越小
  • iOS的开发框架很成熟而且和MAC上通用,同样的知识体系,也可以开发MAC应用,Android相比是全新的框架, 还会继续进化.

 iOS和设备紧密集成。软硬件一家公司通吃。但是Android无法做到, 通常的情况是:Google放出源代码。 芯片厂商需要1-3个月来做自己的芯片方案, 手机厂商从芯片厂商处买到方案和代码, 进行自己的集成,定制工作,有时候还需要针对运营商进行定制。 所以: 

  • iOS的设备集成度和驱动优化都是最好的。电源管理一块就可见一斑,而Android厂商就鱼龙混杂。可能排头的厂商的旗舰机器会好些,但是由于Android工期一般都比iOS设备短(请看HTC和三星出机器的速度),所以整体上和iOS比是有差距的。
  • Android天然存在升级周期延迟的问题, 而且厂商做升级是也是有成本的。卖手机的厂商无法顾及整个生态链,目前这个无解,除非Google做点什么。
  • 由于有多家厂商自己做定制,Android还存在设备的分裂问题(fragmentation), 作为过来人,我告诉你这个是很头痛的事情, 且不论调试时间和人力, 光买一大堆设备的成本就不小。最关键的是它会伤美工/UE的心。

iOS是被Apple严格控制的系统。 在大部分情况下, 第三方应用是无法拿到所有API的。 这意味系统级别的很多功能只有Apple能做(比如打电话,拦截短信)。此外一些涉及用户隐私的API还会导致系统弹出对话框询问用户。 同样第三方runtime做应用开发也是基本不可行的(Flash当初也是被这个条款拒过)。 反过来Android完全不一样,首先Android是开源的,在设计上Android就允许自由替换系统组件, Android也没有强制限制API的情况,(hidden API也可以call,没有人会找你麻烦)。 系统级别的权限是下放到厂商手中,如果厂商愿意给,那第三方开发者就可以做任何事情。 普通应用的权限认证也是在安装的时候就一次性授权完成。 之后不会骚扰用户。所以: 

  • Android平台可以做的事情远远比iOS多, 你可以做电话管理,地址簿,短信管理,可以自己跑后台service。 替换掉系统的组件非常容易
  • Android平台也可以跑其他系统的Runtime, 比如Flash, 有了NDK, 你要自己接入一个虚拟机也是可能的。Google不会管你
  • 任何人可以拿Android自己改个独立的系统出来,也许这样做的意义和前景有问题,但是同样,没有人限制你

 iOS上唯一的下载应用途径就是Appstore,开发者做应用上线还要通过Apple审核,就算通过了,如果挂羊头卖狗肉乱来或者调用了不该用的API, Apple一样随时可以下架。管理非常严格。反过来Android上非常松懈:

  1. 厂商可以内置应用。经常会扔一些莫名其妙的软件预装在手机上, 笔者在厂商的时候深刻体会到乱选软件是很好玩的事情。而且我们不会让你删除掉的。
  2. Google的官方菜市场不做应用审核,开发者上传软件很随意,这是个自由市场。
  3. 国内还存在大量第三方软件菜市场。以及豌豆夹类似的PC端管理软件。
  4. 如果用户选择允许“未知来源”,那么通过web下载或者安装卡上的软件也是可以的。似乎国内用户都是允许的。所以:
  • iOS上的精品软件多,竞争激烈但管理有序,开发者也容易挣钱。
  • Android上虽然也有精品软件,但是垃圾软件更多, 甚至有恶意软件。 因为无门槛,基本上软件都是免费,卖不起钱, 大部分都靠广告。
  • Android还有一堆杀毒软件,这是典型的“没有困难,制造困难也要上”的精神。
  • Android上还有一堆安慰剂软件,比如能帮你省电的或者是帮你杀后台进程的来提升性能的, 笔者作为做过底层开发的人,笑而不语。

写了这么多分析, 结论呢? 事实上你是什么样的角色,决定了用谁更好。 

  • 如果你是普通用户,请关贴, 本文不是用来给普通用户选机的。
  • 如果你是一个个人软件开发者,  iOS适合你, 市场规范, 做应用省心。 
  • 如果你是一个软件和服务的创业公司, iOS也是适合你做demo的和第一个产品的, 产品靠谱了,用户在用了,有人给钱了,再往Android走也是可行的。 除非你做的应用要涉及硬件或者需要非常高的系统权限, 如果是那样你也只有选择Android。因为国内的厂商肯定要比苹果要容易谈下来。
  • 如果你是一个要做硬件和系统定制的公司, 那么基本上你只有Android可以选。Android的解决方案的成本也在不断下降。
  • 如果你是一个有中国特色的公司,想搞点移动业务玩玩, 还要瞒着用户做很多事情。  那么Android也是更好的, 就算你不作恶, 控制权在自己手中也会方便运作一点。

 

 

 

posted @ 2011-12-01 01:26 tech.cap 阅读(7636) 评论(34) 编辑

由于当前的ruby并不支持unicode, 所以中文相关的处理在ruby中一直比较模糊,基本上是各自尝试的路子, 我也列出一些帮助自己整理思路

utf8和unicode的关系

utf其实是(Unicode Translation Format), 也就是unicode在传输时候的编码, 有utf8和utf16等多种编码, 其实uf8是一个对中文字很不友好的编码, 为什么呢,因为在utf8中, 一个中文是占用3个字节,而一个英文ascii字符却只占用1个字节, 这样一方面使得中文体积膨胀较厉害, 另外一方面也不能简单的通过计算字节数来推算字符数. utf16就比较正常, 每个字符占用两个字节.但是目前utf16已经后面的utf32应用较少, utf8 是比较公认的编码

utf8 还是 gb2312/gbk

我个人选择utf8,因为我觉得gb2312/gbk不是通用编码,如果使用可能还会有其他问题(比如多语言支持)

转换编码

我们需要require 'iconv' 库, 然后执行

Iconv.conv("utf8","GBK","....") #把字符由GBK转换为UTF8

当源字符集中含有非法编码的时候,我们需要告诉iconv忽略, 否则iconv会报错停止

Iconv.conv("utf8//IGNORE","GBK//IGNORE","....")

utf8 的中文操作:

计算字符数:

在默认的ruby环境下面, 需要执行


require 'jcode'

$KCODE='u' # 或者$KCODE='UTF8' 两者是等价的

计算字符数:

使用jsize或者jlength

"你好".size # 6

"你好".jsize # 2

截取字符操作

"你好"[0,1] #乱码

"你好".scan(/./)[0,1].join # "你"


当然还有另外一个办法:

利用utf16编码每个字都是2个字节(头还有两个字节)的特点,我们可以先把字符转换为utf16,然后按照[0,n*2+2]的方法截取前n个字符 (试验成功.求证中)

Iconv.conv("UTF8","UTF16",Iconv.conv("UTF16","UTF8","你好a中b文")[0,8]) #你好a


posted @ 2006-12-14 23:12 tech.cap 阅读(29) 评论(0) 编辑

ruby下面中文分词的搜索如何进行?

目前开始考虑这个问题, 目标是使用ferret, ferret是lucene搜索引擎的ruby版本, 凭借一点lucene的经验, 我个人是非常喜欢ferret的, 靠lucene强大的分词,index,search功能, 可以做出很多有趣的功能, 但是ferret有两个难点

  1. 不支持中文分词,而且集成第三方分词对我来说较困难(没有开发c的经验,而且我知道的中文分词算法都是java版本)
  2. 有时候做索引会出错,好象是段地址错误, 因为ferret是在前台index, 所以错误也是在前台fastcig进程中, 感觉很不爽

原来的想法

利用ferret 和lucene兼容的特点, 单独写一个java 类库, 定时对资源做索引,不过后来为了效率(index比lucene快), 新版本的ferret放弃了和lucene兼容, 这个想法是不可行了

更新后的想法

利用mysql中文分词插件,这个东西倒是很好,但是偏偏只支持mysql4.0,和mysql 5.1 beta, 刚好不支持我目前用的mysql5.0.x 由于没有现成版本可以用, 也只好放弃(这个插件只能用来全文搜索, 不像ferret还有其他好玩的功能)

目前的想法:

  1. 在ferret中通过rjb调用 lucene的中文分词然后再index
  2. 需要index的model都增加一个属性indexed,新建或者更新的时候都把indexed设置为false
  3. 把java写好的中外分词通过rjb包装为一个drb service,或者干脆挂在resin上做http页面调用
  4. 在后台,单独的程序定时启动把所有未index的记录select出来(indexed=false), 然后逐一调用第二步开发的进行分词,即是过程中出错, 也不影响前台页面, 这里只改动ferret的ruby代码.
  5. 如果可能, 搜索程序通过远程协议来对keyword分词,然后再搜索

缺点

  1. 这个方案看上去比较恶心.很像一件到处是补丁的衣服, 目前没有时间慢慢去研究ferret中的c代码. 只好通过java来绕圈子

  2. 在后台运行index的话, 就无法实时搜索当前文章, 而是有一个延时, 不过我觉得这个好解决. 另外后台index 就算出错了也不影响前台页面, 大不了有些记录搜索不到而已

  3. 对keyword分词会有速度影响, 不过影响应该很小


posted @ 2006-12-10 18:15 tech.cap 阅读(30) 评论(0) 编辑

最近新建立了一个rails project 想尝试一下test driven 开发, 于是就呼啦呼啦写了几个测试, 这个时候怪异的事情发生了 使用rake 调用测试或者直接执行ruby测试程序, 都会报如下错误

undefined method `use_transactional_fixtures='

真是非常莫名奇妙, 尝试检查mysql, 检查表类型都没有问题(innodb), 又进一步检查, 发现我的testcase实际上没有被注入rails的扩展, 全部变成了最普通的testcase, 真是郁闷! 当晚上google查了半天, 也没有解决

第二天上线咨询了cookoo 以后, 再度测试了一番, 发现新建立的rails project没有这个问题, 于是怀疑到安装的plugin有问题, 又把plugin全部删除, 问题依旧...(中间省略若干) ... 终于发现,原来是ZenTest 这个gem包导致, 尝试把ZenTest/test/test_help.rb 这个文件移走, 问题解决

接下来分析原因 , 发现我的project用到了cached_model , cached_model 会引入ZenTest, ZenTest中的test_help.rb和rails中的test_help.rb 重名, 由于cached_model 会先载入, 所以ZenTest把后者的test_help覆盖掉, 直接导致rails的环境无法加载

ZenTest(test_help.rb) Rails(test_help.rb) 两者无法共存,所以移走前者就好了


posted @ 2006-12-08 13:47 tech.cap 阅读(18) 评论(0) 编辑
posted @ 2006-12-04 15:30 tech.cap 阅读(22) 评论(0) 编辑
posted @ 2006-04-05 01:21 tech.cap 阅读(23) 评论(0) 编辑
posted @ 2006-03-31 02:58 tech.cap 阅读(25) 评论(0) 编辑
posted @ 2006-03-29 11:39 tech.cap 阅读(11) 评论(0) 编辑