@o6z 老师上次#openparty推荐学习lisp,昨天看到 http://tryhaskell.org/ 这个网站很不错,晚上 @alex_hal9000 同学又推荐了 http://learnyouahaskell.com。
我的.profile里面的alias,之前使用kill $(ps auwx | …
我的.profile里面的alias,之前使用kill $(ps auwx | grep qTfnNC | grep -v grep | awk ‘{ print $2 }’)的方法放在.profile里面就不好用了,所以最近就一直没有使用它。既然还是反复在用它(连接断开vpn以后经常需要重启ssh代理),所以还是修正它好了。
alias px="ssh -qTfnNC -D 7777 yourdomain.com"
alias kpx="(ps auwx | grep qTfnNC | grep -v grep | awk '{ print $2 }')|xargs kill;px"
看到这段话,来自这里: Recently I discovered that l…
看到这段话,来自这里:
Recently I discovered that learning a foreign language teaches you two things: how to communicate in that language and how to communicate in your own language to non-native speakers. You learn that simple grammatical structures and shorter sentences are easier to understand. You get a feeling for when someone’s following you and which words in the sentence are most important to pronounce clearly.
感觉说的很好。你需要知道如何和没有熟练掌握这门语言(或者领域)的人交流,你需要知道如用简单的表述,清晰的表达你的意思。
Refactory in Python: 使用受控类型而不是Hash和tuple
在《Clean Code》中提到了函数传递的参数不应该超过3个,如果超过三个推荐将它们变为符合数据结构。
在Python的应用中,对于这个场景,我看到一般的做法就是使用Hash。其实Hash就是一种Key-Value store,是一种弱类型的结构,好比一个没有shema的object。这样做起初看来是很舒服的,因为它自然的让你可以访问到一个复合数据结构。可是据我观察这一般都是Bad smell。缺点在于:
- 你不知道这个Hash中有哪些key,经常会造成需要翻看很多代码才能知道key有哪些,从哪里来的。
- 由于Hash是弱数据类型,你很有可能把Key写错,如有的地方用了”User”有的地方是”user”,就有可能发生由于误解造成的bug。
- 因为Hash是一个开放数据结构,所以你无法控制它被get和set,这容易造成你的hash在多次传递过程中被意外的覆盖,这是非常危险的一种bug。
- 如果使用了Hash,随着时间的推移它很有可能成为垃圾桶。就是一个全局的Hash被传递很多层,大家都依赖它并向里面插入自己的数据。由于这样的Hash根本不可能知道自己的数据属于哪些领域模型,所以它可能会承载多个领域模型的部分数据结构。这对复杂度来说是一个灾难,由于数据和行为分离,它会鼓励系统模块间函数的拷贝和粘贴,最后造成一团存在大量重复的乱麻。如果你的代码发展到这个地步,那它基本上是维护和重构的地域。
- python中hash的访问方式不好看,你需要hash[“user”]这样去访问。:D
对于以数据为中心的系统,你看到一个Hash被传递于超过一次函数调用,那么你最好对它马上进行重购。将它处理为一个可控的数据类型(如Class和Namedtuple)。
非受控类型还有另外一种表现形式,那就是tuple。tuple让python变得强大,尤其是它被用在平行赋值的情况下,如:
def fucntion_a(): a, b = 10, 20 return a, b def function_b(): price, amount = function_a()
这种情况下它有很不错的表现力。但是在非平行赋值的情况下使用tuple传递数据结构就是一种Bad smell了。如:
def function_a(): my_tuple = ('tin', 'male', 28) return my_tuple def function_b(): a_tuple = function_a() name = a_tuple[0] age = a_tuple[2] .....
这种情况的邪恶是使用了顺序来约定数据结构,它比起hash来说明显的问题就是僵化、不容易阅读。僵化是说当你发现需要传递更多数据的时候你需要在顺序中添加新的元素,此时如果你像插入在前面几个元素之间,你会面临大量的index修改操作,非常容易造成bug。不容易阅读是,如果不在同一个文件中,你怎么知道0, 1, 2分别是哪个属性的index,为此你肯定花大量力气写注释,而且这个注释需要随你的修改而修改,非常恼人,遗漏了就是bug。所以它们那是明显的bad smell。
上面两种情况属于同样一种情况,那就是使用非受控数据结构表示结构化数据。那么如何“使用受控类型而不是Hash和tuple”呢?一般来说很简单。一种是写一个数据结构的Class,这种情况是你发现这里的数据结构是潜在的领域模型的时候非常有用:
class BusinessLogData: date = datetime.now() username = 'Unknow user' business_type = '' .....
好处是当你发现系统中围绕这个数据结构的算法或者说行为的时候你马上就有一个地方存放这些逻辑了,会让你很舒服。而且逐渐的你的领域模型就会清晰了,这对没有使用领域模型驱动的系统进行重构的时候很有用。另外一种情况,你可能知道没有什么逻辑在数据结构上,它就是给算法访问的纯数据type。那么可以使用namedtuple。它实际上是一种元编程。官方的例子是这样的。
Point = namedtuple('Point', 'x y', verbose=True) p1 = Point(11, y=22) p2 = Point._make((11, 22))
我个人认为namedtuple非常方便,很象ruby中的struct。它对于已经使用tuple传递数据的系统的重构非常有效,因为_make这样使用tuple创建namedtuple实例的方法非常适合重构,可以马上消除0, 1, 2这样的index magic number。而且在使用sql的时候它也是非常有用的工具,官方例子:
EmployeeRecord = namedtuple('EmployeeRecord', 'name, age, title, department, paygrade') import csv for emp in map(EmployeeRecord._make, csv.reader(open("employees.csv", "rb"))): print emp.name, emp.title import sqlite3 conn = sqlite3.connect('/companydata') cursor = conn.cursor() cursor.execute('SELECT name, age, title, department, paygrade FROM employees') for emp in map(EmployeeRecord._make, cursor.fetchall()): print emp.name, emp.title
OK,到这里这个重构实践就阐述完毕了。下面我会继续讨论Refactory in Python这个话题。
看到那些背着书包穿着校服的中学生,感觉现在比那个时候自由和快乐了,而且也比那个时…
看到那些背着书包穿着校服的中学生,感觉现在比那个时候自由和快乐了,而且也比那个时候富裕了很多。可代价是,我变老了。
Talk with Douglas Corkford
我问他最近在研究什么,他说他最近在研究安全。我问他安全是指哪方面的安全,他说主要是跨站攻击的相关标准。他说网站的安全主要是HTML标准的落后造成的,所以这里非常混乱,总有各种棘手的跨站攻击问题。要想解决跨站攻击的问题,一定要有标准来规范跨domain的通讯,来保证其安全。
关于Lucas Film,他说那段时间非常棒!他负责技术的研究,他举例说CD啦、DVD啦还有各种他们特效相关的一些技术。
我问了他为什么的新版本为什么没有人推广,反观HTML就有很多人在推广。
关于Html,Corkford说这里根本就没有一个标准,已经很久都没有一个标准发布了。他说HTML 5只是一个proposal,它不是一个标准。我问他真正在推广HTML 5的大公司有哪些呢,他说只有Google在真正的推广它。
我问他对服务器端使用Javascript怎么样?他说这是Great的,而且能看出他对此非常高兴。我问他是否在使用Node.js,他说Yahoo已经在尝试使用Node.js,其中包括用它来帮助测试YUI3。我问他现在Node.js的api变化似乎还比较大,他说是这样的,因为它正在被活跃的开发中,他说非常期待他尽快成熟并被更加广泛的使用。
我问他对CSS3现状的看法。他说现在CSS也是很久没有一个标准了,而且先前的CSS标准设计的非常不好,没有解决Web开发者遇到的问题,给他们带来了很多的痛苦。我问他对CSS3的看法,他说现在的路线走的不对,它没有很好的去解决关键问题。他认为CSS现在需要解决关键的问题是对于不同的显示设备的排版的支持。他说现在大的显示器,还有更细密的显示器,还有小的显示设备,他们对复杂排版的支持的特性的考虑都太差了。所以我们就无法用css实现让你的排版/布局在各种设备上看起来都是”Great”。
我问他对于这些不同设计的显示设备的布局是不是有两个瓶颈,一个是设计师本身的瓶颈,另外一个是css特性的瓶颈。他说不是的,他说设计师是没有瓶颈的,问题都处在css标准对这些多列的布局的描述太欠缺了。我问他从Ux的角度看人类的阅读不能很宽,但是似乎CSS3已经开始想要解决这个问题了。他说现在的解决方案还很不够,因为它们都没有从阅读和设计者的角度去考虑排版,所以它就无法让你的Web页面在手机上看起来是单列布局,而到了巨大的显示器上的时候可以像报纸一样使用阅读舒适的多列布局。他认为是这个问题限制了设计师的创造力,他认为在合理的css特性下,设计师可以完成很完美的自适应布局设计。
我问他对于Jim Webber所说的Web as platform的看法,他说Web是一个非常棒的东西,但是Web标准是非常烂的。因为现在大家越来越认识到Web的强大好用的时候,标准已经成了万恶之渊(这个词是我杜撰的),所以现在大家要花更大的力量在Web标准上。他说现在Web标准的一个很大问题是模块化不够好,或者说切分的不够细。造成超级多的特性被堆积在一个标准里面,这样这个标准就一直无法发布,并且也会越来越难用。他认为应该按照我们的使用场合和特性将Web标准切分开,帮助每一个部分可以关注一个点,这样的Web标准发布的就会频繁很多。解决我们现在面临的大量问题。
我问了他如何做Javascript的测试,他说的确很烦人,说Javascript的一个麻烦的问题就是无法在服务器端测试。我问他Yahoo是否也就是使用Selenium这样的客户端测试工具,他说实际上他们也是使用这样的工具。他说这里的问题还是在于标准,因为你做客户端测试实际上不是在测试你的代码,而是在测试浏览器。他说因为浏览器对标准实现各异,而且他们还有自己的bug,造成你实际上是在这些浏览器写测试。他说如果标准能够更好,这里就会减少痛苦。
我问他你认为在View这一层是否应该分开给人看的View和给计算机读的View,这里是否有一种中间的View能够结合它们呢?他说这不就是Json么?我问他Json对于人类来说易读么?他反问我他不是已经比XML容易读了很多么?他说Json已经是一种非常接近于人类自然的描述数据的方式了。(而Html还是倾向于为人类的阅读而设计的数据结构,当然他是面向浏览器的。)
他说今晚他要讲的话题就是关于我们谈的这些问题的,关于标准,关于Web。
Qcon Beijing 2010笔记:失败来临的征兆
Aiming for the wrong target
Assumption $1
Users care about the things the do-features-not the software or hardware you run
Assumption #2: Faults and errors will occur.
Your can choose to engineer safe failure modes into your system or to accept whatever random failure modes naturally occur
Engineering Failure Modes
Tolerance : Absorb shocks . but do not transmit them
Severability: Limit functionality instead of crashing completely
Recoverablility: Allow component-level restarts instead of rebooting the world
Resilience: Recover from transient effects automatically
These produce consistent availability of reatures
工程化失败模式
容忍:将震荡吸收,而不是传递它
服务能力:功能缩水而不是整个损坏
恢复能力:允许组件重启,而不是让整个世界“重新启动”
弹性:能够从瞬时性(Transient)的影响中恢复
这样可以保持功能的可用性
Stability Antipatterns
1. Intergration Poinnts
Intergrations are the #1 risk to stability
Your first job is to protect against integration points
Every socket process. Pip or remote procedure call can and will eventlually kill your system
Even database calls can hang. in obvious and not-so-obvious ways
“In Spec” vs. “Out of Spec”
“In Spec” failures
TCP connection refused
HTTP response code 500
Error message in XML response
Out of spec failures
TCP connection
Remember this
Large systems fail faster than small ones
2. Chain Reaction:
Cascading Failure: Failure in one system causes calling systems to be jeopardized
Remember this
Prevent Cascading Failure to stop cracks from jumping to the gap
3. Users: Can’t live with them…
First type of “bad” user
Front-page viewer: creates useless sessions, ties up memory for no reason
Application servers are all fragile to sessions: Users can ….
Handle traffic surges gracefully: Turn off expensive features when the system is busy. Divert of throttle users. Preserve a good experience for some when you can’t server all. Reduce the burden of serving each user. Be especially …
Second type of “bad” user
Buyers: (most expensive type of user to service, secure pages requires more cpu, more pages, external integration), High conversion rate is bad for the systems!. Your sponsors may not agree
Blocked Threads: Request handling threads are precious. Protect them.
Most common for of “crash”: all request threads blocked. Very difficult to test for:. Best bet: keep threads isolated. Use well-tested. High-lvel contracts for cross-thread communication
Attacks of Self-Denail: Good marketing can kill your system at any time
Defending the ramparts: avoid deep links, setup static landing pages, only allow the user’s second click to reach application servers. Allow throtting of …
Remember this
Keep lines of communication open , protect shared resources, expect ..
Scaling Effects
*QA and Dev balance?
Unbalanced Capacities
Traffic floods sometimes start inside the data center walls.
SLA Inversion: Surviving by luck alone.
Unbounded Result Sets: Limited resources, unlimited data volumns
记住:要使用显示的数据容量测试
给这个倒霉的G1装了一个Sunny_SenseV4.1 – “I’m Back…
给这个倒霉的G1装了一个Sunny_SenseV4.1 – “I’m Back”,这个Rom感觉还不错,作为2.1的Rom(Eclair on Hero),它的性能很好,它甚至比我刚才用的cm-4.2.15.1还要快一些。
今天在freebsd里面build一个“hadoop-gpl-compressi…
今天在freebsd里面build一个“hadoop-gpl-compression”,里面依赖的lzo总是有问题。提示:
configure: error: lzo headers were not found...
问题是我已经用ports装了lzo和lzo2(实际上装lzo2就可以了)。后来经过反复尝试,这样可以编译了:
env JAVA_HOME=/usr/local/diablo-jdk1.6.0 C_INCLUDE_PATH=/usr/local/include LIBRARY_PATH=/usr/local/lib ant clean compile-native tar
这样Hbase就可以开启LZO压缩了。
在Mac (snow leopard)里面让你的ssh支持跳跃,需要ssh的fo…
在Mac (snow leopard)里面让你的ssh支持跳跃,需要ssh的forward agent。你可以实验一下在自己登录的服务器上面再ssh localhost一下,如果问你密码也就是说你的key没有生效,那么说明你的forward agent没有生效。那么首先:
ssh-add -K ~/.ssh/id_rsa ssh-add -K ~/.ssh/id_dsa
然后修改你的/etc/ssh_config,将ForwardAgent no修改为:
ForwardAgent yes
@lixiaohong同学还推荐在你登录的服务器上面也打开这个选项,这样你就可以顺利的跳来跳去了。