﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>BlogJava-心有多大舞台便有多大</title><link>http://www.blogjava.net/jjwwhmm/</link><description>Embrace changes, pursue excellence, share niceness.     MSN:fanci521@hotmail.com
</description><language>zh-cn</language><lastBuildDate>Fri, 05 Sep 2008 16:11:33 GMT</lastBuildDate><pubDate>Fri, 05 Sep 2008 16:11:33 GMT</pubDate><ttl>60</ttl><item><title>总结二:什么才是正确的工作态度?</title><link>http://www.blogjava.net/jjwwhmm/archive/2008/07/31/219107.html</link><dc:creator>pony</dc:creator><author>pony</author><pubDate>Thu, 31 Jul 2008 09:14:00 GMT</pubDate><guid>http://www.blogjava.net/jjwwhmm/archive/2008/07/31/219107.html</guid><wfw:comment>http://www.blogjava.net/jjwwhmm/comments/219107.html</wfw:comment><comments>http://www.blogjava.net/jjwwhmm/archive/2008/07/31/219107.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jjwwhmm/comments/commentRss/219107.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jjwwhmm/services/trackbacks/219107.html</trackback:ping><description><![CDATA[<p align="left">我们公司在外的名声一直不怎么好,看看it速查评论上的留言,很多从公司离开的老同事都一致评价很差.一个人说差并不重要,但10个人,20个人都这么说,那显然是这里存在很大的问题.<br />
我认为这其中很大一个问题就是公司没有让员工树立一个正确的工作态度.平常和一些员工聊天的时候,偶尔问问他们,"你认为在我们公司正确的工作态度是什么?",很多人都半开玩笑的说:"加班".可见大家是怎么理解公司的工作态度这个问题了.<br />
我认为,正确的工作态度包括两个方面的内容,一个是对公司的态度,另一个很重要的就是对个人的态度.公司里管理层太强调个人对于公司的态度,而忽略第二个方面的内容.两者只有有机结合在一起,才能让员工树立一个正确的工作态度,这样才能比较开心的工作.<br />
对公司的态度,就是要员工调整心态,正确定位自己在工作中的角色.工作并不只是在为老板工作,同时也是在为自己工作.盖房子的例子可能很多人都听说过.但在工作中,得过且过,混日子的还是不少.写的代码能正常工作就算完工,要知道,自己写的代码其实就是自己的门面.别人看了你的代码,就对你有了大致的印象.工作是自己建立人脉的最佳场所之一.建立人脉并非靠在公司拉关系,建立小团队来实现.所谓好事不出门,恶名传万里.对你的评价自在你周围同事的心中.<br />
对个人的态度,主要是指员工要明确个人目标和计划,选择适合发展的方向.对这一点,往往很多管理者都会强调.但在实际上是很难做到.喊口号容易,实际行动就难了.什么时候我们在周会上能听到管理者问你:这周你要学习的计划完成了没有?没有,至少我没碰到过.也许有人会说:个人的发展当然要个人自己把握.这是不对的.公司其实就是另外一个学校,在学校里,是老师在帮你发展,在公司,就是你的管理者是你的老师.管理者也要承担起这份责任.所谓一日为师,终生为父.试问,有几个管理者能对得起这句话.如果管理者能做到这一点,我想,员工自然愿意跟在你后面披荆斩棘.<br />
有了这两个方面的态度,还需要员工树立正确的价值观.价值观这个东西真的是十本书也说不完.在这里我就总结点自己的想法,树立以下几个观念:<br />
1.客户服务的意识.不只是购买公司产品的用户是我们的客户.任何会跟你相关的人,都应该成为你的客户.市场,运营,技术支持,财务,清算,等等,他们都是我们的客户,要调用你的代码的同事也是你的客户,要review你的代码的主管同样是你的客户.这个意识不只是体现在员工在与其他人接触沟通的时候,作为程序员,这个意识更重要的是体现在员工的代码中.一个需求的实现中体现出这样的意识后,它就是成为公司产品优于竞争对手的地方.<br />
2.成本意识.成本不应该成为一个神秘的东西,不应该是只有财务,CFO,老板才去考虑的东西.员工在做事情的时候,要善于考虑各种成本,要考虑开发的成本,要考虑测试的成本,要考虑运营你写的代码的成本,更要考虑用户使用你写的功能的成本.而一般员工仅仅能从开发成本上考虑就已经是算不错的了.带着这样的意识,要把它植入到写出的代码中.<br />
3.改进意识.在大学课本里我们就知道,一个系统,除了要有输入,处理,输出外,还有一个更加重要的模块,那就是反馈模块.一个系统如果没有反馈模块,那么随着时间的推移,系统熵的不断增加,就会处于崩溃.所以,员工在负责任何一个功能模块的时候,也要以这样的意识去负责自己的东西.这样才能正真把一个产品做到最好.<br />
4.协作与团队意识.这一点可是老生常谈了.但一般管理者往往只注意到要求员工合作完成团队目标,却不能共享团队成绩.员工之间也是同样,向大家汇报成绩的时候,往往是忘了曾经在这个过程中帮助过的人.只有懂得分享,别人才会愿意给予帮助.<br />
<br />
哎,一直都是热衷与技术,来写这些管理类的文章,有点写不来啊.</p>
<img src ="http://www.blogjava.net/jjwwhmm/aggbug/219107.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jjwwhmm/" target="_blank">pony</a> 2008-07-31 17:14 <a href="http://www.blogjava.net/jjwwhmm/archive/2008/07/31/219107.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>今天开始对这几年的工作做个总结,离开了,但过去的经验,教训不能忘记</title><link>http://www.blogjava.net/jjwwhmm/archive/2008/07/30/218705.html</link><dc:creator>pony</dc:creator><author>pony</author><pubDate>Wed, 30 Jul 2008 06:05:00 GMT</pubDate><guid>http://www.blogjava.net/jjwwhmm/archive/2008/07/30/218705.html</guid><wfw:comment>http://www.blogjava.net/jjwwhmm/comments/218705.html</wfw:comment><comments>http://www.blogjava.net/jjwwhmm/archive/2008/07/30/218705.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jjwwhmm/comments/commentRss/218705.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jjwwhmm/services/trackbacks/218705.html</trackback:ping><description><![CDATA[先说这次事故吧.总结的一句话:每上一个新的产品,都必须要有相应的运营监控模块.<br />
<br />
作为程序员,可以偶尔会埋怨:就算是天才写的代码,也会有漏洞,老板怎么能要求自己写的代码不犯错误.<br />
是的,无论是谁,都会犯错误.就算是建造核电站,核发电设施也会出现故障,发生泄露.<br />
对于这些关系国计民生的系统,与钱相关的支付系统,尤其是容忍不得半点错误.这就是一对矛盾,一方面<br />
错误不可避免,另一方面,错有不允许发生.作为管理者,在这个过程中应该怎么处置呢?<br />
<br />
可以从现实的系统中得到提示,看看核电站的建设,里三层,外三层的防护罩,值班人员24小时的监控,各种监控<br />
设备.从这里我们得到启发,在支付系统中,一样需要这样的防护错误:安全验证不能存在单点故障,也需要里三<br />
层,外三层的防护罩;其次,任何新开发上线的产品,还必须同时开发对应的监控程序,如果没有监控程序,哪怕产<br />
品已经全部测试通过也不能上线.<br />
<br />
网络支付系统所处的环境比起银行等金融机构只会更加恶劣,第一,人员没有银行的专业;第二:设备没有银行的<br />
好;第三:用户要比银行的用户"专业",第四:要比银行的系统更加开放.在这样的情况下,系统所面临的安全挑战,<br />
不仅来自恶意的用户,也会有来自没有经验的开发人员,不稳定的设备.以及各种用户千奇百怪的使用方法.如果<br />
想依靠只身的技术实力来一刀切的解决掉这些问题,那无疑是天方夜谭.大家都是在这个过程中不断的摸索,总结<br />
经验教训.<br />
<br />
但是,有一条是不变的:机制是永恒的,实现的策略是可以不断变化的.面对安全的问题,我们的机制就是:加强监控,<br />
把损失减到最小.而策略则会根据不同产品提出不同的监控方法.但如果一个新产品,没有按照这个机制去做,那么,<br />
总有一天,会为它付出代价.
<img src ="http://www.blogjava.net/jjwwhmm/aggbug/218705.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jjwwhmm/" target="_blank">pony</a> 2008-07-30 14:05 <a href="http://www.blogjava.net/jjwwhmm/archive/2008/07/30/218705.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>要走了,一切都仿佛还在昨天</title><link>http://www.blogjava.net/jjwwhmm/archive/2008/07/30/218611.html</link><dc:creator>pony</dc:creator><author>pony</author><pubDate>Wed, 30 Jul 2008 02:33:00 GMT</pubDate><guid>http://www.blogjava.net/jjwwhmm/archive/2008/07/30/218611.html</guid><wfw:comment>http://www.blogjava.net/jjwwhmm/comments/218611.html</wfw:comment><comments>http://www.blogjava.net/jjwwhmm/archive/2008/07/30/218611.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jjwwhmm/comments/commentRss/218611.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jjwwhmm/services/trackbacks/218611.html</trackback:ping><description><![CDATA[忍了快一年了,终于,以这次的事故为接口,选择离开.<br />
<br />
回想起在这里的三年时间,一切都还仿佛是在昨天一样.每次发生的事故,有时候夜里想起都会做噩梦,支付系统,对你是爱还是恨......<br />
<br />
不过,一切都不要埋怨,应该要向所有的人说声:谢谢.谢谢老板,是你让我有了在支付行业工作的机会;谢谢主管,是你让我有了从无到有的设计一个几千万用户访问的支付系统;谢谢同事,能和你们一道工作,感觉真好.有缘千里来相会,相信我们还有再聚的一天.<br />
<br />
永远不要放弃自己.有梦想谁都了不起.即使这次选择离开是件错误的事也不要紧,只要不做错人.做错事还有改正的机会,做错人,就永远没有重来的机会.<br />
<br />
<img src ="http://www.blogjava.net/jjwwhmm/aggbug/218611.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jjwwhmm/" target="_blank">pony</a> 2008-07-30 10:33 <a href="http://www.blogjava.net/jjwwhmm/archive/2008/07/30/218611.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>jQuery技巧</title><link>http://www.blogjava.net/jjwwhmm/articles/218478.html</link><dc:creator>pony</dc:creator><author>pony</author><pubDate>Tue, 29 Jul 2008 08:59:00 GMT</pubDate><guid>http://www.blogjava.net/jjwwhmm/articles/218478.html</guid><wfw:comment>http://www.blogjava.net/jjwwhmm/comments/218478.html</wfw:comment><comments>http://www.blogjava.net/jjwwhmm/articles/218478.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jjwwhmm/comments/commentRss/218478.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jjwwhmm/services/trackbacks/218478.html</trackback:ping><description><![CDATA[<p><strong>一、简介</strong><br />
<br />
<strong>1.1、概述</strong><br />
　　随着WEB2.0及 ajax思想在互联网上的快速发展传播，陆续出现了一些优秀的Js框架，其中比较著名的有Prototype、YUI、jQuery、mootools、 Bindows以及国内的JSVM框架等，通过将这些JS框架应用到我们的项目中能够使程序员从设计和书写繁杂的JS应用中解脱出来，将关注点转向功能需 求而非实现细节上，从而提高项目的开发速度。<a class="" title="entrymore" name="entrymore"></a><br />
　　jQuery是继prototype 之后的又一个优秀的Javascript框架。它是由 John Resig 于 2006 年初创建的，它有助于简化 JavaScript&#8482; 以及Ajax 编程。有人使用这样的一比喻来比较prototype和jQuery：prototype就像Java，而jQuery就像ruby. 它是一个简洁快速灵活的JavaScript框架，它能让你在你的网页上简单的操作文档、处理事件、实现特效并为Web页面添加Ajax交互。<br />
<br />
它具有如下一些特点：</p>
<ol>
    <li>代码简练、语义易懂、学习快速、文档丰富。
    <li>jQuery是一个轻量级的脚本，其代码非常小巧，最新版的JavaScript包只有20K左右。
    <li>jQuery支持CSS1-CSS3,以及基本的xPath。
    <li>jQuery是跨浏览器的，它支持的浏览器包括IE 6.0+, FF 1.5+, Safari 2.0+, Opera 9.0+。
    <li>可以很容易的为jQuery扩展其他功能。
    <li>能将JS代码和HTML代码完全分离，便于代码和维护和修改。
    <li>插件丰富，除了jQuery本身带有的一些特效外，可以通过插件实现更多功能，如表单验证、tab导航、拖放效果、表格排序、DataGrid，树形菜单、图像特效以及ajax上传等。</li>
</ol>
<p>　　jQuery的设计会改变你写JavaScript代码的方式，降低你学习使用JS操作网页的复杂度，提高网页JS开发效率，无论对于js初学者还是资深专家，jQuery都将是您的首选。<br />
jQuery适合于设计师、开发者以及那些还好者，同样适合用于商业开发，可以说jQuery适合任何JavaScript应用的地方，可用于不同的Web应用程序中。<br />
官方站点：<a href="http://jquery.com/" target="_blank" mce_href="http://jquery.com/">http://jquery.com/</a>&nbsp;&nbsp; 中文站点：<a href="http://jquery.org.cn/" target="_blank" mce_href="http://jquery.org.cn/">http://jquery.org.cn/</a><br />
<br />
<strong>1.2、目的</strong><br />
　　通过学习本文档，能够对jQuery有一个简单的认识了解，清楚JQuery与其他JS框架的不同，掌握jQuery的常用语法、使用技巧及注意事项。<br />
<br />
<strong>二、使用方法</strong><br />
　　在需要使用JQuery的页面中引入JQuery的js文件即可。<br />
例如：&lt;script type="text/javascript" src="js/jquery.js" mce_src="js/jquery.js"&gt;&lt;/script&gt;<br />
　　引入之后便可在页面的任意地方使用jQuery提供的语法。<br />
<br />
<strong>三、学习教程及参考资料</strong><br />
　　请参照《jQuery中文API手册》和<a href="http://jquery.org.cn/visual/cn/index.xml" target="_blank" mce_href="http://jquery.org.cn/visual/cn/index.xml">http://jquery.org.cn/visual/cn/index.xml</a><br />
推荐两篇不错的jquery教程：《<a title="" href="http://www.k99k.com/jQuery_getting_started.html" target="_blank">jQuery的起点教程</a>》和《<a title="" href="http://www.ibm.com/developerworks/cn/xml/x-ajaxjquery.html" target="_blank">使用 jQuery 简化 Ajax 开发</a>》<br />
<br />
<br />
<strong>四、语法总结和注意事项</strong><br />
<br />
<span style="color: red"><strong>1、关于页面元素的引用</strong></span><br />
　　通过jquery的$()引用元素包括通过id、class、元素名以及元素的层级关系及dom或者xpath条件等方法，且返回的对象为jquery对象（集合对象），不能直接调用dom定义的方法。<br />
<br />
<span style="color: red"><strong>2、jQuery对象与dom对象的转换</strong></span><br />
　　只有jquery对象才能使用jquery定义的方法。注意dom对象和jquery对象是有区别的，调用方法时要注意操作的是dom对象还是jquery对象。<br />
普通的dom对象一般可以通过$()转换成jquery对象。<br />
如：$(document.getElementById("msg"))则为jquery对象，可以使用jquery的方法。<br />
　　由于jquery对象本身是一个集合。所以如果jquery对象要转换为dom对象则必须取出其中的某一项，一般可通过索引取出。<br />
　　如：$("#msg")[0]，$("div").eq(1)[0]，$("div").get()[1]，$("td")[5]这些都是dom对象，可以使用dom中的方法，但不能再使用Jquery的方法。<br />
以下几种写法都是正确的：<br />
$("#msg").html();<br />
$("#msg")[0].innerHTML;<br />
$("#msg").eq(0)[0].innerHTML;<br />
$("#msg").get(0).innerHTML;<br />
<br />
<span style="color: red"><strong>3、如何获取jQuery集合的某一项</strong></span><br />
　　对于获取的元素集合，获取其中的某一项（通过索引指定）可以使用<span style="color: blue">eq</span>或<span style="color: blue">get(n)</span>方法或者索引号获取，<span style="color: orange">要注意，eq返回的是jquery对象，而get(n)和索引返回的是dom元素对象</span>。对于jquery对象只能使用jquery的方法，而dom对象只能使用dom的方法，如要获取第三个&lt;div&gt;元素的内容。有如下两种方法：<br />
$("div").eq(2).html();&nbsp;&nbsp;&nbsp;&nbsp; //调用jquery对象的方法<br />
$("div").get(2).innerHTML;&nbsp;&nbsp; //调用dom的方法属性<br />
<br />
<strong><span style="color: red">4、同一函数实现set和get</span><br />
</strong>　　Jquery中的很多方法都是如此，主要包括如下几个：<br />
$("#msg").html();&nbsp;&nbsp;&nbsp;&nbsp; //返回id为msg的元素节点的html内容。<br />
$("#msg").html("&lt;b&gt;new content&lt;/b&gt;");&nbsp;&nbsp;<br />
//将&#8220;&lt;b&gt;new content&lt;/b&gt;&#8221; 作为html串写入id为msg的元素节点内容中,页面显示粗体的new content<br />
<br />
$("#msg").text();&nbsp;&nbsp;&nbsp;&nbsp; //返回id为msg的元素节点的文本内容。<br />
$("#msg").text("&lt;b&gt;new content&lt;/b&gt;");&nbsp;&nbsp;<br />
//将&#8220;&lt;b&gt;new content&lt;/b&gt;&#8221; 作为普通文本串写入id为msg的元素节点内容中,页面显示&lt;b&gt;new content&lt;/b&gt;<br />
<br />
$("#msg").height();&nbsp;&nbsp;&nbsp;&nbsp; //返回id为msg的元素的高度<br />
$("#msg").height("300");&nbsp;&nbsp; //将id为msg的元素的高度设为300<br />
$("#msg").width();&nbsp;&nbsp;&nbsp;&nbsp; //返回id为msg的元素的宽度<br />
$("#msg").width("300");&nbsp;&nbsp; //将id为msg的元素的宽度设为300<br />
<br />
$("input").val(");&nbsp;&nbsp; //返回表单输入框的value值<br />
$("input").val("test");&nbsp;&nbsp; //将表单输入框的value值设为test<br />
<br />
$("#msg").click();&nbsp;&nbsp; //触发id为msg的元素的单击事件<br />
$("#msg").click(fn);&nbsp;&nbsp; //为id为msg的元素单击事件添加函数<br />
同样blur,focus,select,submit事件都可以有着两种调用方法<br />
<br />
<span style="color: red"><strong>5、集合处理功能</strong></span><br />
　　对于jquery返回的集合内容无需我们自己循环遍历并对每个对象分别做处理，jquery已经为我们提供的很方便的方法进行集合的处理。<br />
包括两种形式：<br />
$("p").each(function(i){this.style.color=['#f00','#0f0','#00f'][i]})&nbsp;&nbsp;<br />
//为索引分别为0，1，2的p元素分别设定不同的字体颜色。<br />
<br />
$("tr").each(function(i){this.style.backgroundColor=['#ccc','#fff'][i%2]})&nbsp;&nbsp;<br />
//实现表格的隔行换色效果<br />
<br />
$("p").click(function(){alert($(this).html())})&nbsp;&nbsp;&nbsp;&nbsp;<br />
//为每个p元素增加了click事件，单击某个p元素则弹出其内容<br />
<br />
<span style="color: red"><strong>6、扩展我们需要的功能</strong></span><br />
$.extend({<br />
&nbsp;&nbsp; min: function(a, b){return a &lt; b?a:b; },<br />
&nbsp;&nbsp; max: function(a, b){return a &gt; b?a:b; } <br />
});&nbsp;&nbsp; //为jquery扩展了min,max两个方法<br />
使用扩展的方法（通过&#8220;$.方法名&#8221;调用）：<br />
alert("a=10,b=20,max="+$.max(10,20)+",min="+$.min(10,20));<br />
<br />
<span style="color: red"><strong>7、支持方法的连写</strong></span><br />
　　所谓连写，即可以对一个jquery对象连续调用各种不同的方法。<br />
　　例如：<br />
$("p").click(function(){alert($(this).html())})<br />
.mouseover(function(){alert('mouse over event')})<br />
.each(function(i){this.style.color=['#f00','#0f0','#00f'][i]});<br />
<br />
<span style="color: red"><strong>8、操作元素的样式</strong></span><br />
　　主要包括以下几种方式：<br />
$("#msg").css("background");&nbsp;&nbsp;&nbsp;&nbsp; //返回元素的背景颜色<br />
$("#msg").css("background","#ccc")&nbsp;&nbsp; //设定元素背景为灰色<br />
$("#msg").height(300); $("#msg").width("200");&nbsp;&nbsp; //设定宽高<br />
$("#msg").css({ color: "red", background: "blue" });//以名值对的形式设定样式<br />
$("#msg").addClass("select");&nbsp;&nbsp; //为元素增加名称为select的class<br />
$("#msg").removeClass("select");&nbsp;&nbsp; //删除元素名称为select的class<br />
$("#msg").toggleClass("select");&nbsp;&nbsp; //如果存在（不存在）就删除（添加）名称为select的class<br />
<br />
<span style="color: red"><strong>9、完善的事件处理功能</strong></span><br />
　　Jquery已经为我们提供了各种事件处理方法，我们无需在html元素上直接写事件，而可以直接为通过jquery获取的对象添加事件。<br />
如：<br />
$("#msg").click(function(){alert("good")})&nbsp;&nbsp; //为元素添加了单击事件<br />
$("p").click(function(i){this.style.color=['#f00','#0f0','#00f'][i]})<br />
//为三个不同的p元素单击事件分别设定不同的处理</p>
<p><font color="#e6421a">jQuery中几个自定义的事件</font>：<br />
（1）<span style="color: blue">hover(fn1,fn2)：</span>一个模仿悬停事件（鼠标移动到一个对象上面及移出这个对象）的方法。当鼠标移动到一个匹配的元素上面时，会触发指定的第一个函数。当鼠标移出这个元素时，会触发指定的第二个函数。<br />
//当鼠标放在表格的某行上时将class置为over，离开时置为out。<br />
$("tr").hover(function(){<br />
$(this).addClass("over");<br />
},<br />
&nbsp;&nbsp; function(){<br />
&nbsp;&nbsp; $(this).addClass("out"); <br />
});<br />
（2）<span style="color: blue">ready(fn):</span>当DOM载入就绪可以查询及操纵时绑定一个要执行的函数。<br />
$(document).ready(function(){alert("Load Success")})<br />
//页面加载完毕提示&#8220;Load Success&#8221;,相当于onload事件。与$(fn)等价<br />
（3）<span style="color: blue">toggle(evenFn,oddFn): </span>每次点击时切换要调用的函数。如果点击了一个匹配的元素，则触发指定的第一个函数，当再次点击同一元素时，则触发指定的第二个函数。随后的每次点击都重复对这两个函数的轮番调用。<br />
&nbsp;&nbsp; //每次点击时轮换添加和删除名为selected的class。<br />
&nbsp;&nbsp; $("p").toggle(function(){<br />
&nbsp;&nbsp;&nbsp;&nbsp; $(this).addClass("selected");&nbsp;&nbsp; <br />
&nbsp;&nbsp; },function(){<br />
&nbsp;&nbsp;&nbsp;&nbsp; $(this).removeClass("selected"); <br />
&nbsp;&nbsp; });<br />
（4）<span style="color: blue">trigger(eventtype):</span> 在每一个匹配的元素上触发某类事件。<br />
例如：<br />
&nbsp;&nbsp; $("p").trigger("click");&nbsp;&nbsp;&nbsp;&nbsp; //触发所有p元素的click事件<br />
（5）<span style="color: blue">bind(eventtype,fn)，unbind(eventtype): </span>事件的绑定与反绑定<br />
从每一个匹配的元素中（添加）删除绑定的事件。<br />
例如：<br />
$("p").bind("click", function(){alert($(this).text());});&nbsp;&nbsp; //为每个p元素添加单击事件<br />
$("p").unbind();&nbsp;&nbsp; //删除所有p元素上的所有事件<br />
$("p").unbind("click")&nbsp;&nbsp; //删除所有p元素上的单击事件<br />
<br />
<span style="color: red"><strong>10、几个实用特效功能</strong></span><br />
　　其中toggle()和slidetoggle()方法提供了状态切换功能。<br />
　　如toggle()方法包括了hide()和show()方法。<br />
　　slideToggle()方法包括了slideDown()和slideUp方法。<br />
<br />
<span style="color: red"><strong>11、几个有用的jQuery方法</strong></span><br />
<span style="color: blue">$.browser.浏览器类型：</span>检测浏览器类型。有效参数：safari, opera, msie, mozilla。如检测是否ie：$.browser.isie，是ie浏览器则返回true。<br />
<span style="color: blue">$.each(obj, fn)：</span>通用的迭代函数。可用于近似地迭代对象和数组（代替循环）。<br />
如<br />
$.each( [0,1,2], function(i, n){ alert( "Item #" + i + ": " + n ); }); <br />
等价于：<br />
var tempArr=[0,1,2];<br />
for(var i=0;i&lt;tempArr.length;i++){<br />
&nbsp;&nbsp; alert("Item #"+i+": "+tempArr[i]);<br />
}<br />
也可以处理json数据，如<br />
$.each( { name: "John", lang: "JS" }, function(i, n){ alert( "Name: " + i + ", Value: " + n ); });<br />
结果为：<br />
Name:name, Value:John<br />
Name:lang, Value:JS<br />
<span style="color: blue">$.extend(target,prop1,propN)：</span>用一个或多个其他对象来扩展一个对象，返回这个被扩展的对象。这是jquery实现的继承方式。<br />
如：<br />
$.extend(settings, options);&nbsp;&nbsp;<br />
//合并settings和options，并将合并结果返回settings中，相当于options继承setting并将继承结果保存在setting中。<br />
var settings = $.extend({}, defaults, options);<br />
//合并defaults和options，并将合并结果返回到setting中而不覆盖default内容。<br />
可以有多个参数（合并多项并返回）<br />
<span style="color: blue">$.map(array, fn)：</span>数组映射。把一个数组中的项目(处理转换后)保存到到另一个新数组中，并返回生成的新数组。<br />
如：<br />
var tempArr=$.map( [0,1,2], function(i){ return i + 4; });<br />
tempArr内容为：[4,5,6]<br />
var tempArr=$.map( [0,1,2], function(i){ return i &gt; 0 ? i + 1 : null; });<br />
tempArr内容为：[2,3]<br />
<span style="color: blue">$.merge(arr1,arr2):</span>合并两个数组并删除其中重复的项目。<br />
如：$.merge( [0,1,2], [2,3,4] )&nbsp;&nbsp; //返回[0,1,2,3,4]<br />
<span style="color: blue">$.trim(str)：</span>删除字符串两端的空白字符。 <br />
如：$.trim("&nbsp;&nbsp; hello, how are you?&nbsp;&nbsp; ");&nbsp;&nbsp; //返回"hello,how are you? "<br />
<br />
<span style="color: red"><strong>12、解决自定义方法或其他类库与jQuery的冲突</strong></span><br />
　　很多时候我们自己定义了$(id)方法来获取一个元素，或者其他的一些js类库如prototype也都定义了$方法，如果同时把这些内容放在一起就会引起变量方法定义冲突，Jquery对此专门提供了方法用于解决此问题。<br />
　　使用jquery中的<span style="color: blue">jQuery.noConflict();</span>方法即可把变量$的控制权让渡给第一个实现它的那个库或之前自定义的$方法。之后应用Jquery的时候只要将所有的$换成jQuery即可，如原来引用对象方法$("#msg")改为jQuery("#msg")。<br />
如：<br />
jQuery.noConflict(); <br />
// 开始使用jQuery<br />
jQuery("div&nbsp;&nbsp; p").hide();<br />
// 使用其他库的 $() <br />
$("content").style.display = 'none';</p>
<img src ="http://www.blogjava.net/jjwwhmm/aggbug/218478.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jjwwhmm/" target="_blank">pony</a> 2008-07-29 16:59 <a href="http://www.blogjava.net/jjwwhmm/articles/218478.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[转载]从一则笑话分析需求的陷阱 </title><link>http://www.blogjava.net/jjwwhmm/articles/218314.html</link><dc:creator>pony</dc:creator><author>pony</author><pubDate>Tue, 29 Jul 2008 03:39:00 GMT</pubDate><guid>http://www.blogjava.net/jjwwhmm/articles/218314.html</guid><wfw:comment>http://www.blogjava.net/jjwwhmm/comments/218314.html</wfw:comment><comments>http://www.blogjava.net/jjwwhmm/articles/218314.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jjwwhmm/comments/commentRss/218314.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jjwwhmm/services/trackbacks/218314.html</trackback:ping><description><![CDATA[<span style="font-size: 12px; font-family: ������">某日，老师在课堂上想考考学生们的智商，就问一个男孩:&#8220;树上有十只鸟，开枪打死一只，还剩几只？&#8221;&nbsp;<br />
男孩反问:&#8220;是无声枪么？&#8221;&nbsp;<br />
&#8220;不是。&#8221;&nbsp;<br />
&#8220;枪声有多大？&#8221;&nbsp;<br />
&#8220;80~100分贝。&#8221;&nbsp;<br />
&#8220;那就是说会震的耳朵疼？&#8221;&nbsp;<br />
&#8220;是。&#8221;&nbsp;<br />
&#8220;在这个城市里打鸟犯不犯法？&#8221;&nbsp;<br />
&#8216;不犯。&#8221;&nbsp;<br />
&#8220;您确定那只鸟真的被打死啦？&#8221;&nbsp;<br />
&#8220;确定。&#8221;老师已经不耐烦了，&#8221;拜托，你告诉我还剩几只就行了，OK？&#8221;&nbsp;<br />
&#8220;OK。鸟里有没有聋子？&#8221;&nbsp;<br />
&#8220;没有。&#8221;&nbsp;<br />
&#8220;有没有关在笼子里的？&#8221;&nbsp;<br />
&#8220;没有。&#8221;&nbsp;<br />
&#8220;边上还有没有其他的树，树上还有没有其他鸟？&#8221;&nbsp;<br />
&#8220;没有。&#8221;&nbsp;<br />
&#8220;方圆十里呢？&#8221;&nbsp;<br />
&#8220;就这么一棵树!&#8221;&nbsp;<br />
&#8220;有没有残疾或饿的飞不动的鸟？&#8221;&nbsp;<br />
&#8220;没有，都身体倍棒。&#8221;&nbsp;<br />
&#8220;算不算怀孕肚子里的小鸟？&#8221;&nbsp;<br />
&#8220;都是公的。&#8221;&nbsp;<br />
&#8220;都不可能怀孕？&#8221;&nbsp;<br />
&#8220;&#8230;&#8230;&#8230;，决不可能。&#8221;&nbsp;<br />
&#8220;打鸟的人眼里有没有花？保证是十只？&#8221;&nbsp;<br />
&#8220;没有花，就十只。&#8221;&nbsp;<br />
老师脑门上的汗已经流下来了，下课铃响起，但男孩仍继续问:&#8220;有没有傻的不怕死的？&#8221;&nbsp;<br />
&#8220;都怕死。&#8221;&nbsp;<br />
&#8220;有没有因为情侣被打中，自己留下来的？&#8221;&nbsp;<br />
&#8220;笨蛋，之前不是说都是公的嘛!&#8221;&nbsp;<br />
&#8220;同志可不可以啊!&#8221;&nbsp;<br />
&#8220;&#8230;&#8230;&#8230;&#8230;，性取向都很正常!&#8221;&nbsp;<br />
&#8220;会不会一枪打死两只？&#8221;&nbsp;<br />
&#8220;不会。&#8221;&nbsp;<br />
&#8220;一枪打死三只呢？&#8221;&nbsp;<br />
&#8220;不会。&#8221;&nbsp;<br />
&#8220;四只呢？&#8221;&nbsp;<br />
&#8220;更不会!&#8221;&nbsp;<br />
&#8220;五只呢？&#8221;&nbsp;<br />
&#8220;绝对不会!!!&#8221;&nbsp;<br />
&#8220;那六只总有可能吧？&#8221;&nbsp;<br />
&#8220;除非你他妈的是猪生的才有可能!&#8221;&nbsp;<br />
&#8220;&#8230;好吧，那么所有的鸟都可以自由活动么？&#8221;&nbsp;<br />
&#8220;完全可以。&#8221;&nbsp;<br />
&#8220;它们受到惊吓起飞时会不会惊慌失措而互相撞上？&#8221;&nbsp;<br />
&#8220;不会，每只鸟都装有卫星导航系统，而且可以自动飞行。&#8221;&nbsp;<br />
&#8220;恩，如果您的回答没有骗人，&#8221;学生满怀信心的回答，&#8220;打死的鸟要是挂在树上没掉下来，那么就剩一只，如果掉下来，就一只不剩。&#8221;&nbsp;<br />
老师当即倒!&nbsp;<br />
</span>
<img src ="http://www.blogjava.net/jjwwhmm/aggbug/218314.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jjwwhmm/" target="_blank">pony</a> 2008-07-29 11:39 <a href="http://www.blogjava.net/jjwwhmm/articles/218314.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[转载]说说大型高并发高负载网站的系统架构（更新）[Michael]</title><link>http://www.blogjava.net/jjwwhmm/articles/218311.html</link><dc:creator>pony</dc:creator><author>pony</author><pubDate>Tue, 29 Jul 2008 03:25:00 GMT</pubDate><guid>http://www.blogjava.net/jjwwhmm/articles/218311.html</guid><wfw:comment>http://www.blogjava.net/jjwwhmm/comments/218311.html</wfw:comment><comments>http://www.blogjava.net/jjwwhmm/articles/218311.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jjwwhmm/comments/commentRss/218311.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jjwwhmm/services/trackbacks/218311.html</trackback:ping><description><![CDATA[<h1 class="block_title"><a id="viewpost1_TitleUrl" href="http://www.blogjava.net/wangdei/archive/2008/07/28/218135.html">说说大型高并发高负载网站的系统架构（更新）[Michael]</a></h1>
<div class="post">
<div class="postcontent">另外看Michael更新了他的那篇经典的文章，为了让更多的人能够看到，决定转载过来。<br />
<br />
我在CERNET做过拨号接入平台的搭建，而后在Yahoo&amp;3721从事过搜索引擎前端开发，又在MOP处理过大型社区猫扑大杂烩的架构升级等工作，同时自己接触和开发过不少大中型网站的模块，因此在大型网站应对高负载和并发的解决方案上有一些积累和经验，可以和大家一起探讨一下。<br />
<br />
<br />
　　一个小型的网站，比如个人网站，可以使用最简单的html静态页面就实现了，配合一些图片达到美化效果，所有的页面均存放在一个目录下，这样的网站对系统架构、性能的要求都很简单，随着互联网业务的不断丰富，网站相关的技术经过这些年的发展，已经细分到很细的方方面面，尤其对于大型网站来说，所采用的技术更是涉及面非常广，从硬件到软件、编程语言、数据库、WebServer、防火墙等各个领域都有了很高的要求，已经不是原来简单的html静态网站所能比拟的。<br />
<br />
　　大型网站，比如门户网站。在面对大量用户访问、高并发请求方面，基本的解决方案集中在这样几个环节：使用高性能的服务器、高性能的数据库、高效率的编程语言、还有高性能的Web容器。但是除了这几个方面，还没法根本解决大型网站面临的高负载和高并发问题。<br />
<br />
　　上面提供的几个解决思路在一定程度上也意味着更大的投入，并且这样的解决思路具备瓶颈，没有很好的扩展性，下面我从低成本、高性能和高扩张性的角度来说说我的一些经验。<br />
<br />
<span style="color: #ff0000">1、HTML静态化</span><br />
　　其实大家都知道，效率最高、消耗最小的就是纯静态化的html页面，所以我们尽可能使我们的网站上的页面采用静态页面来实现，这个最简单的方法其实也是最有效的方法。但是对于大量内容并且频繁更新的网站，我们无法全部手动去挨个实现，于是出现了我们常见的信息发布系统CMS，像我们常访问的各个门户站点的新闻频道，甚至他们的其他频道，都是通过信息发布系统来管理和实现的，信息发布系统可以实现最简单的信息录入自动生成静态页面，还能具备频道管理、权限管理、自动抓取等功能，对于一个大型网站来说，拥有一套高效、可管理的CMS是必不可少的。<br />
<br />
　　除了门户和信息发布类型的网站，对于交互性要求很高的社区类型网站来说，尽可能的静态化也是提高性能的必要手段，将社区内的帖子、文章进行实时的静态化，有更新的时候再重新静态化也是大量使用的策略，像Mop的大杂烩就是使用了这样的策略，网易社区等也是如此。目前很多博客也都实现了静态化，我使用的这个Blog程序WordPress还没有静态化，所以如果面对高负载访问，<a href="http://www.bt285.cn/">www.bt285.cn</a>一定不能承受&nbsp;&nbsp;<br />
<br />
　　同时，html静态化也是某些缓存策略使用的手段，对于系统中频繁使用数据库查询但是内容更新很小的应用，可以考虑使用html静态化来实现，比如论坛中论坛的公用设置信息，这些信息目前的主流论坛都可以进行后台管理并且存储再数据库中，这些信息其实大量被前台程序调用，但是更新频率很小，可以考虑将这部分内容进行后台更新的时候进行静态化，这样避免了大量的数据库访问请求。<br />
<br />
　　在进行html静态化的时候可以使用一种折中的方法，就是前端使用动态实现，在一定的策略下进行定时静态化和定时判断调用，这个能实现很多灵活性的操作，我开发的小说网站故人居(<a href="http://www.5a520.cn/">www.5a520.cn</a>)就是使用了这样的方法，我通过设定一些html静态化的时间间隔来对动态网站内容进行缓存，达到分担大部分的压力到静态页面上，可以应用于中小型网站的架构上。小说网站的地址：http://<a href="http://www.5a520.cn/">www.5a520.cn</a>，顺便提一下，有喜欢小说的朋友多多支持我这个免费网站:)<br />
<br />
<span style="color: #ff0000">2、图片服务器分离</span><br />
　　大家知道，对于Web服务器来说，不管是Apache、IIS还是其他容器，图片是最消耗资源的，于是我们有必要将图片与页面进行分离，这是基本上大型网站都会采用的策略，他们都有独立的图片服务器，甚至很多台图片服务器。这样的架构可以降低提供页面访问请求的服务器系统压力，并且可以保证系统不会因为图片问题而崩溃。<br />
<br />
　　在应用服务器和图片服务器上，可以进行不同的配置优化，比如Apache在配置ContentType的时候可以尽量少支持，尽可能少的LoadModule，保证更高的系统消耗和执行效率。<br />
<br />
　　我的台球网站故人居8zone.cn也使用了图片服务器架构上的分离，目前是仅仅是架构上分离，物理上没有分离，由于没有钱买更多的服务器:)，大家可以看到故人居上的图片连接都是类似img.9tmd.com或者img1.9tmd.com的URL。<br />
<br />
　　<span style="color: #ff0000">另外，在处理静态页面或者图片、js等访问方面，可以考虑使用lighttpd代替Apache，它提供了更轻量级和更高效的处理能力。</span><br />
<br />
<span style="color: #ff0000">3、数据库集群和库表散列</span><br />
　　大型网站都有复杂的应用，这些应用必须使用数据库，那么在面对大量访问的时候，数据库的瓶颈很快就能显现出来，这时一台数据库将很快无法满足应用，于是我们需要使用数据库集群或者库表散列。<br />
<br />
　　在数据库集群方面，很多数据库都有自己的解决方案，Oracle、Sybase等都有很好的方案，常用的MySQL提供的Master/Slave也是类似的方案，您使用了什么样的DB，就参考相应的解决方案来实施即可。<br />
<br />
　　上面提到的数据库集群由于在架构、成本、扩张性方面都会受到所采用DB类型的限制，于是我们需要从应用程序的角度来考虑改善系统架构，库表散列是常用并且最有效的解决方案。我们在应用程序中安装业务和应用或者功能模块将数据库进行分离，不同的模块对应不同的数据库或者表，再按照一定的策略对某个页面或者功能进行更小的数据库散列，比如用户表，按照用户ID进行表散列，这样就能够低成本的提升系统的性能并且有很好的扩展性。sohu的论坛就是采用了这样的架构，将论坛的用户、设置、帖子等信息进行数据库分离，然后对帖子、用户按照板块和ID进行散列数据库和表，最终可以在配置文件中进行简单的配置便能让系统随时增加一台低成本的数据库进来补充系统性能。<br />
<br />
<span style="color: #ff0000">4、缓存</span><br />
　　缓存一词搞技术的都接触过，很多地方用到缓存。网站架构和网站开发中的缓存也是非常重要。这里先讲述最基本的两种缓存。高级和分布式的缓存在后面讲述。<br />
<br />
　　架构方面的缓存，对Apache比较熟悉的人都能知道Apache提供了自己的mod_proxy缓存模块，也可以使用外加的Squid进行缓存，这两种方式均可以有效的提高Apache的访问响应能力。<br />
<br />
　　网站程序开发方面的缓存，Linux上提供的Memcached是常用的缓存方案，不少web编程语言都提供memcache访问接口，php、perl、c和java都有，可以在web开发中使用，可以实时或者Cron的把数据、对象等内容进行缓存，策略非常灵活。一些大型社区使用了这样的架构。<br />
<br />
　　另外，在使用web语言开发的时候，各种语言基本都有自己的缓存模块和方法，PHP有Pear的Cache模块和eAccelerator加速和Cache模块，还要知名的Apc、XCache（国人开发的，支持！）php缓存模块，Java就更多了，.net不是很熟悉，相信也肯定有。<br />
<br />
<span style="color: #ff0000">5、镜像</span><br />
　　镜像是大型网站常采用的提高性能和数据安全性的方式，镜像的技术可以解决不同网络接入商和地域带来的用户访问速度差异，比如ChinaNet和EduNet之间的差异就促使了很多网站在教育网内搭建镜像站点，数据进行定时更新或者实时更新。在镜像的细节技术方面，这里不阐述太深，有很多专业的现成的解决架构和产品可选。也有廉价的通过软件实现的思路，比如Linux上的rsync等工具。<br />
<br />
<span style="color: #ff0000">6、负载均衡</span><br />
　　负载均衡将是大型网站解决高负荷访问和大量并发请求采用的终极解决办法。<br />
<br />
　　负载均衡技术发展了多年，有很多专业的服务提供商和产品可以选择，我个人接触过一些解决方法，其中有两个架构可以给大家做参考。另外有关初级的负载均衡DNS轮循和较专业的CDN架构就不多说了。<br />
<br />
<span style="color: #ff0000">6.1 硬件四层交换</span><br />
　　第四层交换使用第三层和第四层信息包的报头信息，根据应用区间识别业务流，将整个区间段的业务流分配到合适的应用服务器进行处理。　第四层交换功能就象是虚IP，指向物理服务器。它传输的业务服从的协议多种多样，有HTTP、FTP、NFS、Telnet或其他协议。这些业务在物理服务器基础上，需要复杂的载量平衡算法。在IP世界，业务类型由终端TCP或UDP端口地址来决定，在第四层交换中的应用区间则由源端和终端IP地址、TCP和UDP端口共同决定。<br />
<br />
　　在硬件四层交换产品领域，有一些知名的产品可以选择，比如Alteon、F5等，这些产品很昂贵，但是物有所值，能够提供非常优秀的性能和很灵活的管理能力。Yahoo中国当初接近2000台服务器使用了三四台Alteon就搞定了。<br />
<br />
<span style="color: #ff0000">6.2 软件四层交换</span><br />
　　大家知道了硬件四层交换机的原理后，基于OSI模型来实现的软件四层交换也就应运而生，这样的解决方案实现的原理一致，不过性能稍差。但是满足一定量的压力还是游刃有余的，有人说软件实现方式其实更灵活，处理能力完全看你配置的熟悉能力。<br />
<br />
　　软件四层交换我们可以使用Linux上常用的LVS来解决，LVS就是Linux Virtual Server，他提供了基于心跳线heartbeat的实时灾难应对解决方案，提高系统的鲁棒性，同时可供了灵活的虚拟VIP配置和管理功能，可以同时满足多种应用需求，这对于分布式的系统来说必不可少。<br />
<br />
　　一个典型的使用负载均衡的策略就是，在软件或者硬件四层交换的基础上搭建squid集群，这种思路在很多大型网站包括搜索引擎上被采用，这样的架构低成本、高性能还有很强的扩张性，随时往架构里面增减节点都非常容易。这样的架构我准备空了专门详细整理一下和大家探讨。<br />
<br />
<span style="color: #ff0000">6.3 七层交换</span><br />
　　大家都知道TCP/IP的七层协议，四层交换是基于传输层的，在这一层只能处理连接的管理，但是无法和业务关联起来，通常只能针对tcp、udp的连接来进行处理，而真正的业务逻辑需要后面的服务器群自己来处理，随着技术的发展，今天，我们在很多高级的应用中出现了七层交换。<br />
<br />
七层交换是基于TCP/IP的第七层应用层来实现的，在这一层上，首先我们可以区分出具体的应用，比如HTTP、TELNET、FTP、DNS等等，还能根据应用中传送的内容来进行策略的管理，比如我们有这么两个网站的路径 a.com/music/&#8230; 和a.com/photo/&#8230;&nbsp;<a href="http://www.yaonba.com.cn/">NBA</a>,<a href="http://www.5a520.cn/">小说520</a>&nbsp;,<a href="http://www.bt285.cn/">BT下载</a>,原来基于四层交换只能把这两个url的请求都分发到后面一组服务器上，但是七层交换可以判断访问的是music/还是photo/路径，然后分别分发到不通的服务器群上，从而实现更灵活的系统架构设计。<br />
<br />
当然，七层交换也分硬件和软件的实现方式，在这里我不细说了，硬件有著名的F5、Nortel等，软件有Haproxy等，当然，七层交换的软件目前还是在性能上要远远差别于硬件实现的，要知道，这些硬件都价格不菲&nbsp;&nbsp;<br />
<br />
总结：<br />
　　
<div>
<div>引用</div>
<div>对于大型网站来说，前面提到的每个方法可能都会被同时使用到，Michael这里介绍得比较浅显，具体实现过程中很多细节还需要大家慢慢熟悉和体会，有时一个很小的squid参数或者apache参数设置，对于系统性能的影响就会很大，希望大家一起讨论，达到抛砖引玉之效。</div>
</div>
</div>
</div>
<img src ="http://www.blogjava.net/jjwwhmm/aggbug/218311.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jjwwhmm/" target="_blank">pony</a> 2008-07-29 11:25 <a href="http://www.blogjava.net/jjwwhmm/articles/218311.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[转载]jquery radio取值，checkbox取值，select取值，radio选中，checkbox选中，select选中，及其相关 </title><link>http://www.blogjava.net/jjwwhmm/articles/218305.html</link><dc:creator>pony</dc:creator><author>pony</author><pubDate>Tue, 29 Jul 2008 03:20:00 GMT</pubDate><guid>http://www.blogjava.net/jjwwhmm/articles/218305.html</guid><wfw:comment>http://www.blogjava.net/jjwwhmm/comments/218305.html</wfw:comment><comments>http://www.blogjava.net/jjwwhmm/articles/218305.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jjwwhmm/comments/commentRss/218305.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jjwwhmm/services/trackbacks/218305.html</trackback:ping><description><![CDATA[<div class="postbody">
<p>获取一组radio被选中项的值<br />
var item = $('input[@name=items][@checked]').val();<br />
获取select被选中项的文本<br />
var item = $("select[@name=items] option[@selected]").text();<br />
select下拉框的第二个元素为当前选中值<br />
$('#select_id')[0].selectedIndex = 1;<br />
radio单选组的第二个元素为当前选中值<br />
$('input[@name=items]').get(1).checked = true;</p>
<p>获取值：</p>
<p>文本框，文本区域：$("#txt").attr("value")；<br />
多选框checkbox：$("#checkbox_id").attr("value")；<br />
单选组radio：&nbsp;&nbsp; $("input[@type=radio][@checked]").val();<br />
下拉框select： $('#sel').val();</p>
<p>控制表单元素：<br />
文本框，文本区域：$("#txt").attr("value",'');//清空内容<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $("#txt").attr("value",'11');//填充内容</p>
<p>多选框checkbox： $("#chk1").attr("checked",'');//不打勾<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $("#chk2").attr("checked",true);//打勾<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if($("#chk1").attr('checked')==undefined) //判断是否已经打勾</p>
<p>单选组radio：&nbsp;&nbsp;&nbsp; $("input[@type=radio]").attr("checked",'2');//设置value=2的项目为当前选中项<br />
下拉框select：&nbsp;&nbsp; $("#sel").attr("value",'-sel3');//设置value=-sel3的项目为当前选中项<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $("&lt;option value='1'&gt;1111&lt;/option&gt;&lt;option value='2'&gt;2222&lt;/option&gt;").appendTo("#sel")//添加下拉框的option<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $("#sel").empty()；//清空下拉框</p>
<br />
http://www.cnblogs.com/xlfj521/archive/2008/01/29/1057375.html</div>
<img src ="http://www.blogjava.net/jjwwhmm/aggbug/218305.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jjwwhmm/" target="_blank">pony</a> 2008-07-29 11:20 <a href="http://www.blogjava.net/jjwwhmm/articles/218305.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>java InetAddress 的dns cache问题</title><link>http://www.blogjava.net/jjwwhmm/archive/2008/07/09/213685.html</link><dc:creator>pony</dc:creator><author>pony</author><pubDate>Wed, 09 Jul 2008 07:57:00 GMT</pubDate><guid>http://www.blogjava.net/jjwwhmm/archive/2008/07/09/213685.html</guid><wfw:comment>http://www.blogjava.net/jjwwhmm/comments/213685.html</wfw:comment><comments>http://www.blogjava.net/jjwwhmm/archive/2008/07/09/213685.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jjwwhmm/comments/commentRss/213685.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jjwwhmm/services/trackbacks/213685.html</trackback:ping><description><![CDATA[jdk的InetAddress有一个特性,就是当系统访问过一个域名的时候,InetAddress就会通过其私有变量addressCache把域名对应的ip地址缓存起来.<br />
虽然缓存起来能极大的提高系统性能,但有时候会给系统带来很大的麻烦.例如,当对方改动了ip地址后,系统就不能再访问到新的ip地址了,这个时候最直接的方案就是:重启jvm!!!这对于需要7*24小时服务的系统来说,是不可忍受的.<br />
下面一段代码可以重现这个现象(但需要你在运行的时候是在调试模式):<br />
public void testDnsCachePolicy() throws Exception {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; InetAddress addr1 = InetAddress.getByName("<a href="http://www.baidu.com/">www.baidu.com</a>");<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println(addr1.getHostAddress());<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //在下一行设置断点.<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int i = 0;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; InetAddress addr2 = InetAddress.getByName("<a href="http://www.baidu.com/">www.baidu.com</a>");<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(addr2.getHostAddress());<br />
}<br />
具体测试方式是:<br />
1.修改c:/windows/system32/drivers/etc/hosts文件,在文件末尾加入:64.233.189.104&nbsp;&nbsp;&nbsp;&nbsp; <a href="http://www.baidu.com/">www.baidu.com</a><br />
这个ip地址是google的ip<br />
2.运行代码到断点处<br />
这时候打印出的ip地址是64.233.189.104<br />
3.修改hosts文件,把"64.233.189.104&nbsp;&nbsp;&nbsp;&nbsp; <a href="http://www.baidu.com/">www.baidu.com</a>"这行注释掉,"#64.233.189.104&nbsp;&nbsp;&nbsp;&nbsp; <a href="http://www.baidu.com/">www.baidu.com</a>"<br />
4.继续运行代码到结束<br />
这时候打印出的ip地址还是64.233.189.104,并没有更改为baidu的ip地址.<br />
<br />
那么应该怎么来解决这个问题呢?<br />
查了下网上的解决方案,一般是在启动jvm的时候,指定jvm参数:networkaddress.cache.ttl和networkaddress.cache.negative.ttl,具体的含义你可以查看InetAddress的源代码.<br />
这种方法的缺点是在JVM启动的时候就固定了dns的缓存策略.如果不缓存的话,对系统性能的影响是很大的,那么能不能动态的修改这个缓存的值呢?<br />
正好前段时间写了篇文章:怎么通过反射修改类的私有字段值.正好有了用武之地!<br />
下面是测试代码:<br />
//方法中的字符串常量policy,cache,addressCache请参考InetAddress源代码.<br />
public void testDnsCachePolicy() throws Exception {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; InetAddress addr1 = InetAddress.getByName("<a href="http://www.baidu.com/">www.baidu.com</a>");<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println(addr1.getHostAddress());<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //在下一行设置断点.<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int i = 0;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //修改缓存数据开始<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Class inetAddressClass = java.net.InetAddress.class;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; final Field cacheField = inetAddressClass.getDeclaredField("addressCache");&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cacheField.setAccessible(true);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; final Object obj = cacheField.get(inetAddressClass);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Class cacheClazz = obj.getClass();&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; final Field cachePolicyField = cacheClazz.getDeclaredField("policy");&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; final Field cacheMapField = cacheClazz.getDeclaredField("cache");&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cachePolicyField.setAccessible(true);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cacheMapField.setAccessible(true);&nbsp;&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; final Map cacheMap = (Map)cacheMapField.get(obj);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cacheMap.remove("<a href="http://www.baidu.com/">www.baidu.com</a>");<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //修改缓存数据结束<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; InetAddress addr2 = InetAddress.getByName("<a href="http://www.baidu.com/">www.baidu.com</a>");<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println(addr2.getHostAddress());<br />
}<br />
重新按照上面的测试方法测试一次,第2次已经能够拿到正确的ip地址了.<br />
<br />
如果在用apache的httpclient,那么,在把缓存中的数据清除后,需要重新创建GetMethod/PostMethod对象.<br />
例如:<br />
HttpClient client = new HttpClient();<br />
GetMethod m1 = new GetMethod("http://www.baidu.com");<br />
client.executeMethod(m1);<br />
String content = m1.getResponseBodyAsString();<br />
........//通过上面的反射方法清楚缓存<br />
//重新执行m1,仍然不会得到正确的结果<br />
client.executeMethod(m1);<br />
String content = m1.getResponseBodyAsString();<br />
//重新创建GetMethod,才能得到正确的结果<br />
GetMethod m2 = new GetMethod("http://www.baidu.com");<br />
client.executeMethod(m2);<br />
content = m2.getResponseBodyAsString();<br />
<img src ="http://www.blogjava.net/jjwwhmm/aggbug/213685.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jjwwhmm/" target="_blank">pony</a> 2008-07-09 15:57 <a href="http://www.blogjava.net/jjwwhmm/archive/2008/07/09/213685.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>我的JMS实践</title><link>http://www.blogjava.net/jjwwhmm/archive/2008/06/26/210840.html</link><dc:creator>pony</dc:creator><author>pony</author><pubDate>Thu, 26 Jun 2008 07:43:00 GMT</pubDate><guid>http://www.blogjava.net/jjwwhmm/archive/2008/06/26/210840.html</guid><wfw:comment>http://www.blogjava.net/jjwwhmm/comments/210840.html</wfw:comment><comments>http://www.blogjava.net/jjwwhmm/archive/2008/06/26/210840.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.blogjava.net/jjwwhmm/comments/commentRss/210840.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jjwwhmm/services/trackbacks/210840.html</trackback:ping><description><![CDATA[本文中只是把我的一些使用JMS的心得写出来,并非什么"最佳实践",有错误的请大家尽管拍砖!<br />
<br />
1.消息类型的选择<br />
Java的JMS消息类型有文本类型,对象类型,字节类型,流类型,XML类型,在实际项目中,用的最多的是文本类型,对象类型和xml类型的消息.建议最好不用对象类型,因为如果用对象类型的话,调试的时候是很麻烦的,首先你必须要写专门的测试代码用来发送消息,第二,必须要管理对象所属的类的不同版本,第三,不方便查看queue或者topic中的消息内容.而如果使用文本类型或者xml类型的消息,那么可以很容易的通过JMS中间件提供的一些管理工具来发送测试消息,查看消息内容,并且更加容易管理不同版本之间的兼容性.如果一定要用对象类型消息的话,建议使用xstream把对象转化为xml<br />
<br />
2.是使用queue还是topic?<br />
这两者的定义是很清楚的,也很容易区分.但是在实际项目中,如何来取舍呢?我的建议是尽量用queue.如果你的项目用到了JMS,那么你的系统也应该是到了需要部署在集群环境的规模了.用topic在集群环境下会带来很多麻烦.举个简单的例子,如果你是用MDB来处理topic的消息,你有一个MDB名为SampleMDB,它以集群的方式分别部署在A服务器和B服务器上.那么有可能同一条topic消息被同一个MDB处理两次.虽然一些JMS中间件提供商为解决这种问题提供了一些解决方案,例如把subsriber分组,但是它为开发和调试都带来了很大的麻烦.topic消息的处理也要比queue的复杂,很难跟踪topic消息的处理过程.<br />
那么,如果不用topic的话,怎么来实现topic这种性质的消息处理呢?可以写一个消息转发器,把一个queue上的消息转发给所有关注这个queue的其它queue中.例如,有一个queue,名为SampleQ1,一个消息发送者sender,一个消息转发器router,有三个handler A,B,C需要处理这个queue中的消息.那么,sender发送消息到SampleQ1,router接收SampleQ1的消息后分别发送到SampleQ1_A,SampleQ1_B,SampleQ1_C,handler A,B,C分别从队列SampleQ1_A,SampleQ1_B,SampleQ1_C中接收消息.<br />
<br />
3.用JMS来解决什么问题?<br />
一提起JMS可以做什么,第一想到的就是异步处理.面试的时候问JMS可以做什么?大多数的回答是:用JMS来异步发送邮件!(到底应该怎么样构建一个邮件发送系统不是本文的主题,以后有时间我会专门来谈谈在我的项目中,我是怎么来设计邮件发送系统的).其实,还可以用JMS来解决很多复杂的问题,例如分布,并发,系统解耦,负载均衡,热部署,触发器等等,这些复杂的问题因为引入了JMS而变的更加简单.下面简单介绍下解决分布,并发问题的场景.<br />
3.1 用JMS来解决并发问题<br />
queue的概念大家都很清楚了,那就是queue里的一条消息只会被一个消息接收者处理.基于这个概念,我们可以在系统中对并发要求很严格的模块中引入JMS的使用.例如,系统的送积分,一般这个模块是用一个定时器,例如quartz,每天定期查询数据库,如果发现有满足条件的记录,那么就把积分送给会员.如果同时有多个quartz在运行,那么必须严格控制防止并发的对同一条记录送多次积分.解决这个问题有很多方法,可以通过业务的设计,系统的部署,数据库的设计,事务的控制等方法来实现,在这里提一个用JMS来解决问题的方法:在插入记录的同时发送一个queue的消息.这样即使有多个送积分的MDB实例在运行,也只会被一个实例处理.<br />
<br />
3.2用JMS来解决分布的问题<br />
解决分布有两种类型,第一种是指消息是集中的,但消息的处理是分布的.例如,系统可能会被分为前台与后台,这两个系统是部署在不同的网段里的.那么怎么把前台发生的业务通知后台系统呢?当然,可以通过一个类似定时器的玩意定期去数据库查询.但这种方式要么就是浪费系统资源,可能在定期查询中80%的时间都是在做无用功,要么就是业务请求没有被及时处理.,因为定期的时间总是有一个时间间隔的.用JMS来处理这个问题会怎么样呢?前台系统在处理完业务请求后的同时发送一个消息到queue中,后台系统的消息接收者接收到消息后立即处理.这里消息的处理也可能有一定的延期,但这主要取决于消息服务器的硬件能力,网络带宽,消息接收者的处理速度等.<br />
<br />
第二中是指消息也是分布的.很多消息中间件都提供了消息路由的功能,即消息发送到一个消息服务器后,这个消息服务器根据定义的规则再把这条消息路由转发到其它的消息服务器.例如,可能在北京的一个数据中心部署了数据采集系统,采集到数据后以消息的方式发送到消息服务器,然后消息服务器再把这条消息路由到上海的数据中心,再由上海数据中心部署的数据处理系统来处理这条消息.<br />
<br />
4.JMS与事务,一定要用JTA事务吗<br />
很多人接触到JTA事务都是从用JMS开始的,毕竟同时要连多个数据库的的系统并不是那么的多!而要用JTA事务的话,就得要在笨重的应用服务器中部署.(当然,你也可以用类似atomikos的轻量级JTA事务管理器),更重要的是,并不是事务本身的技术有多复杂,而是事务的界定,这种事务的界定有时都不是程序员能决定的事情,需要在设计的时候就要考虑清楚,甚至可能还需要业务人员的参与.(题外话:经常问面试的,用spring的aop做什么?大多数答:用来管理事务!事务要真这么简单该多好啊!)<br />
我也不是要反对用JTA事务,而是要说明一下,用JMS,并非一定要用JTA事务.这可以分为三种场景:<br />
一,必须用JTA事务,这种情况下,一般消息的接收者只从消息本身获得数据并进行处理.所以必须要保证消息的发送与所依赖的业务保持一致.<br />
二.不需要用事务,这种情况下, 要么是业务无关紧要,例如用JMS来记录日志.要么是发送的消息仅仅是一个作为后续业务处理的一个触发器!消息接收者仅仅是从消息中获得一个id,然后根据这个id去查询所依赖的其它数据进行业务处理.即使消息丢失也没关系,可以通过其它的机制来补偿.<br />
三.消息丢失可以通过补偿事务来完成.这个依赖与具体实现,就不详细说了.<br />
<br />
5.处理消息永远比发送消息慢!<br />
要保证你的JMS应用稳定的运行,那么你必须在开发,部署的时候时刻重视这个问题.<br />
首先,需要把发送消息的连接池与接收消息的连接池分开.以避免接收消息的连接过过而导致发送消息的应用拿不到连接.<br />
在一个连接上并发的处理消息,而不是连接打开,处理一个消息,马上关闭连接.<br />
合理的设置消息的过期时间,否则消息日积月累,最终超出queue的size<br />
对于非关键业务的消息处理,可以采用异步处理的方法:接收到消息后并不是立刻处理,而是放到一个任务池或者线程池中处理.如果消息处理失败,则把消息重新发送回队列中.<br />
<br />
<img src ="http://www.blogjava.net/jjwwhmm/aggbug/210840.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jjwwhmm/" target="_blank">pony</a> 2008-06-26 15:43 <a href="http://www.blogjava.net/jjwwhmm/archive/2008/06/26/210840.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>不会偷懒的程序员不是好程序员!</title><link>http://www.blogjava.net/jjwwhmm/archive/2008/06/20/209400.html</link><dc:creator>pony</dc:creator><author>pony</author><pubDate>Fri, 20 Jun 2008 03:38:00 GMT</pubDate><guid>http://www.blogjava.net/jjwwhmm/archive/2008/06/20/209400.html</guid><wfw:comment>http://www.blogjava.net/jjwwhmm/comments/209400.html</wfw:comment><comments>http://www.blogjava.net/jjwwhmm/archive/2008/06/20/209400.html#Feedback</comments><slash:comments>4</slash:comments><wfw:commentRss>http://www.blogjava.net/jjwwhmm/comments/commentRss/209400.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jjwwhmm/services/trackbacks/209400.html</trackback:ping><description><![CDATA[<p>今天看了篇文章:<br />
http://blogoscoped.com/archive/2005-08-24-n14.html<br />
<br />
这篇文章是讲为什么好的程序员是既懒有笨的!哈哈!<br />
我记得在看UNIX编程艺术时,里面也有这么段话,说不会偷懒的程序员不是好程序员!<br />
为什么呢!我们可以举些简单的例子:<br />
1.只有懒惰的程序员才会去编写那些可以最终代替自己工作的自动化工具,好的程序员都会有一套自己的代码自动生成工具,有的是用模板语言,有的是用shell.在开发一个新的系统时,系统基础框架设计好后,很多业务层代码基本上都是一个模子出来的,要想让这些代码都是从一个模子里出来,那么就需要在底层下很大的功夫才能做到.所以,每个程序员够应该有,或者会写代码自动生成工具,当然,这个工具并不是一个成功工具!它的前提是你必须在底层有足够的抽象.<br />
<br />
2.只有懒惰的程序员才不会去去写大段的冗余重复的代码,他们会想出各种方法来避免这种冗余代码的情况,做的好的,就是在系统的基础架构层来解决大部分这样的问题,通过精致的设计模式,高度抽象的模块,易用的接口,高度可配置的基础平台等等来实现,做的一般的会利用各种开源工具来代替自己想要的代码,做的差些的就是不断利用refactor重构出那些重复代码.<br />
<br />
3.好程序员怎么可能"笨"呢!哈哈!俺们可都是天之骄子啊!小心我扔你鸡蛋啊!<br />
很聪明的程序员一般比较自信,难以听进别人的意见,在一个团队中,最怕的并不是怕没有技术好的人,而是怕那些很聪明的人不跟你团队保持一致,举个例子,可能团队里有一套通用的数据存取方法,但聪明的程序员会坚持己见,自己发明出一套新的方法来!聪明的程序员会认为自己更懂客户的需求,而不顾市场人员提出的需求.这也是为什么很多人会说"要对团队中听话的人委以重任",我当然不同意这种看法,但是,既聪明团队意识又好的人,就比较少见了.团队不行的话,一个人再聪明又有什么用?<br />
<br />
4.聪明的程序员喜欢自己重新发明轮子!笨的程序员喜欢利用聪明的程序员写出的代码!<br />
<br />
5.聪明的程序员一般有自己思维的定势,笨的程序员因为什么都不懂,所以他的眼里什么都是可能,什么都是不可能!查找代码问题的时候,聪明的程序员首先会说:这是系统的bug,笨的程序员会看看自己的代码是不是有拼写错误!笨的程序员跟容易换位思考,下面有个例子:<br />
一段关于web开发问题的程序员和客服人员的对话:<br />
</p>
<p>&#8220;从昨天开始我们的用户就看不到我们站点上的Logo了。&#8221;<br />
&#8220;他试过重启浏览器么？&#8221;<br />
&#8220;是的。&#8221;<br />
&#8220;他试过重启电脑么？&#8221;<br />
&#8220;是的。&#8221;<br />
&#8220;他清空过浏览器Cache么？&#8221;<br />
&#8220;是的。&#8221;<br />
&#8220;他的浏览器版本是IE6么？&#8221;<br />
&#8220;是的。&#8221;<br />
&#8220;他确信是真的看不到Logo了么？&#8221;<br />
&#8220;是的。&#8221;<br />
&#8220;他是在电脑显示器屏幕上看我们的站点么？&#8221;<br />
&#8220;什么？&#8221;<br />
&#8220;比如说，它可能是打印出来看不到？&#8221;<br />
&#8220;不。他是在显示器上看的。&#8221;<br />
&#8220;除了站点Logo之外，他是不是其他的图片都看不到？&#8221;<br />
&#8220;什么？哦。我再问问他。&#8221;<br />
</p>
<p>也许,聪明的程序员遇到这个问题的时候,甚至可能去找个图形算法分析下这个图片是否有问题!<br />
<br />
最后,以<a href="http://blogoscoped.com/archive/2005-08-24-n14.html">http://blogoscoped.com/archive/2005-08-24-n14.html</a>中的故事结尾,,以博列为看官一笑^_^<br />
It&#8217;s like the story of the centipede(蜈蚣). The centipede was very good at walking with its hundred legs. It never spent a thought on just how it could walk. Until one day, when a big black bug(臭虫) asked the centipede &#8220;How can you manage to <em>walk</em> with all those feet? Don&#8217;t you find it hard to coordinate their rhythm?&#8221; The black bug already left, when the centipede was still sitting down, pondering <em>how</em> it could walk, wondering, and (for the first time in his life) even worrying a little bit. From that day on, the centipede couldn&#8217;t walk anymore.<br />
So you better not think too much if you want to achieve something. And of course this is only half the truth, too... </p>
<img src ="http://www.blogjava.net/jjwwhmm/aggbug/209400.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jjwwhmm/" target="_blank">pony</a> 2008-06-20 11:38 <a href="http://www.blogjava.net/jjwwhmm/archive/2008/06/20/209400.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>通过反射修改类的私有字段值,调用私有方法</title><link>http://www.blogjava.net/jjwwhmm/archive/2008/06/19/209083.html</link><dc:creator>pony</dc:creator><author>pony</author><pubDate>Thu, 19 Jun 2008 02:14:00 GMT</pubDate><guid>http://www.blogjava.net/jjwwhmm/archive/2008/06/19/209083.html</guid><wfw:comment>http://www.blogjava.net/jjwwhmm/comments/209083.html</wfw:comment><comments>http://www.blogjava.net/jjwwhmm/archive/2008/06/19/209083.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.blogjava.net/jjwwhmm/comments/commentRss/209083.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jjwwhmm/services/trackbacks/209083.html</trackback:ping><description><![CDATA[<p>下面这个例子在实际项目中一般都不会这么用,只是用来说明怎么通过反射修改类的私有字段的值.<br />
<br />
有一个类TestData:<br />
<br />
public class TestData {<br />
&nbsp;private String name = "1";<br />
&nbsp;<br />
&nbsp;public String getName() {<br />
&nbsp;&nbsp;return name;<br />
&nbsp;}<br />
}<br />
在运行的时候怎么来修改name的值呢?<br />
<br />
public class TestReflection extends TestCase {<br />
&nbsp;public void testSetPrivateField() throws Exception {<br />
&nbsp;&nbsp;TestData data = new TestData();<br />
&nbsp;&nbsp;System.out.println(data.getName());<br />
&nbsp; Assert.assertEquals("1", data.getName());<br />
&nbsp;&nbsp;Field f = data.getClass().getDeclaredField("name");<br />
&nbsp;&nbsp;f.setAccessible(true);<br />
&nbsp;&nbsp;f.set(data, "2");<br />
&nbsp;&nbsp;System.out.println(data.getName());<br />
&nbsp; Assert.assertEquals("2", data.getName());<br />
&nbsp;}<br />
}<br />
运行结果:<br />
1<br />
2<br />
其中,最关键的代码是:<br />
f.setAccessible(true);<br />
这行代码把对象data上的name字段设置为public访问属性.<br />
<br />
既然私有字段可以这样访问,那么,类似的,私有方法也可以这样调用!<br />
改一下TestData:<br />
<br />
public class TestData {<br />
&nbsp;private String name = "1";<br />
&nbsp;<br />
&nbsp;public String getName() {<br />
&nbsp;&nbsp;return name;<br />
&nbsp;}<br />
&nbsp;<br />
&nbsp;private void setName(String name) {<br />
&nbsp;&nbsp;this.name = name;<br />
&nbsp;}<br />
}<br />
在TestData中增加了私有的setName方法,下面是测试代码:<br />
public class TestReflection extends TestCase {&nbsp;<br />
&nbsp;public void testInvokePrivateMethod() throws Exception {<br />
&nbsp;&nbsp;TestData data = new TestData();<br />
&nbsp;&nbsp;System.out.println(data.getName());<br />
&nbsp; Assert.assertEquals("1", data.getName());<br />
&nbsp;&nbsp;Method m = data.getClass().getDeclaredMethod("setName", String.class);<br />
&nbsp;&nbsp;m.setAccessible(true);<br />
&nbsp;&nbsp;m.invoke(data, "3");<br />
&nbsp;&nbsp;System.out.println(data.getName());<br />
&nbsp; Assert.assertEquals("3", data.getName());<br />
&nbsp;}<br />
}<br />
运行结果:<br />
1<br />
3<br />
其中最关键的代码行是:<br />
m.setAccessible(true);<br />
它把对象data的setName方法的访问属性设置为public.</p>
<p>那么这样调用私有方法,访问私有属性有什么用处呢?<br />
在实际项目中,我们会使用很多其它第三方的包,有的时候是通过修改源代码完成你想要的功能,有的时候,是因为第三方包中仅仅因为某几个方法的访问属性被设置为private,或者只要修改private的字段值即可.这个时候,用这种反射的方法就可以很容易实现了.<br />
<br />
另外一个场景就是从系统架构层来考虑数据封装.例如系统有一些元数据类,99%的情况下,我们只是提供get方法供其它应用层获得字段的值,如果把修改的set方法也提供出去,那么可能会影响到系统的可维护性.而在系统运行期间,又很难避免的要修改这些元数据的值.这种情况下,也可以通过这种反射的方式来实现.</p>
<img src ="http://www.blogjava.net/jjwwhmm/aggbug/209083.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jjwwhmm/" target="_blank">pony</a> 2008-06-19 10:14 <a href="http://www.blogjava.net/jjwwhmm/archive/2008/06/19/209083.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>hessian序列化协议+memcached的缓存存取</title><link>http://www.blogjava.net/jjwwhmm/archive/2008/06/18/208784.html</link><dc:creator>pony</dc:creator><author>pony</author><pubDate>Wed, 18 Jun 2008 02:04:00 GMT</pubDate><guid>http://www.blogjava.net/jjwwhmm/archive/2008/06/18/208784.html</guid><wfw:comment>http://www.blogjava.net/jjwwhmm/comments/208784.html</wfw:comment><comments>http://www.blogjava.net/jjwwhmm/archive/2008/06/18/208784.html#Feedback</comments><slash:comments>6</slash:comments><wfw:commentRss>http://www.blogjava.net/jjwwhmm/comments/commentRss/208784.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jjwwhmm/services/trackbacks/208784.html</trackback:ping><description><![CDATA[<p>大名鼎鼎的memcached恐怕没人不知道吧!hessian是一种远程调用的机制,类似与web service,不过它是使用自己的序列化协议.<br />
那么,为什么要把hessian的序列化协议和memcached结合起来实现缓存的读取呢?<br />
有过使用memcached的经验的人会了解到,php+memcached的性能是最好的,java+memcached的性能比较差,其主要原因就是在于java本身的序列化机制很慢.<br />
我做了个简单的测试,一个UserData类,有一个字符串属性,一个日期属性,一个double属性,分别用java,hessian来序列化一百万次,结果让人吃惊,不止是hessian序列化的速度要比java的快上一倍,而且hessian序列化后的字节数也要比java的少一倍.因为我在测试的时候只是做了序列化这部分的工作,并没有把序列化后的结果放到网络上传输,所以,实际中的性能hessian应该会更好!<br />
既然hessian的序列化协议要比java本身的好,而memcached客户端的性能又在很大程度上依赖与对象的序列化.所以,我就决定把我的cache实现中序列化这部分的工作改成用hessian来实现了.<br />
我用的memcached客户端是用的danga.MemCached包,主要是改动了MemCachedClient的get方法及set方法,在set方法中改为调用hessian的序列化:<br />
ByteArrayOutputStream bos = new ByteArrayOutputStream();<br />
//修改以前的序列化代码:<br />
&nbsp;//(new ObjectOutputStream( bos )).writeObject( value );<br />
//修改后的序列化代码:<br />
serializeByHessian(bos, value);<br />
&nbsp;val = bos.toByteArray();<br />
serializeByHessian方法如下:</p>
&nbsp;protected void serializeByHessian(OutputStream os, Object object) throws IOException {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;AbstractHessianOutput out = new Hessian2Output(os);;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SerializerFactory serializerFactory = getSerializerFactory();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;out.setSerializerFactory(serializerFactory);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;out.startReply();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;out.writeObject(object);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;out.completeReply();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;out.flush();<br />
&nbsp;}<br />
在get方法中主要是修改了这个方法调用的类ContextObjectInputStream的readObject方法:<br />
在ContextObjectInputStream中覆盖了readObjectOverride方法:<br />
&nbsp;protected Object readObjectOverride() throws IOException,&nbsp;&nbsp;ClassNotFoundException {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ByteArrayInputStream is = new ByteArrayInputStream(bytes);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ClHessian2Input in = new ClHessian2Input(is, this.mLoader);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;in.setSerializerFactory(getSerializerFactory());<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;int code = in.read();//"r"<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;int major = in.read();//&gt;=2<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;int minor = in.read();//0<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Object value = in.readObject();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;is.close();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return value;<br />
&nbsp;}<br />
因为我的框架是基于osgi的,所以我重载了Hessian2Input,把classloader作为参数传进去,否则hessian在反序列化的时候会找不到类.如果你没有用osgi框架的话,&nbsp;ClHessian2Input in = new ClHessian2Input(is, this.mLoader);这行代码就可以直接用:&nbsp;Hessian2Input in = new Hessian2Input(is);<br />
这样修改就基本完成了.<br />
我把memcached client的序列化协议改为hessian也有另外一个系统架构的原因,那就是因为我的服务层逻辑都是用java+spring+osgi的方式实现,而web层则是用php实现,两者之间通讯已经是采用hessian的远程调用.所以,部分缓存数据在服务层通过java设置到memcached服务器中,在php中一样可以用memcached php client读取出来.(php的memcached client我用的是memcached-client.php,而不是php扩展,所以一样可以修改memcached-client.php的序列化机制)<br />
<br />
<br />
<img src ="http://www.blogjava.net/jjwwhmm/aggbug/208784.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jjwwhmm/" target="_blank">pony</a> 2008-06-18 10:04 <a href="http://www.blogjava.net/jjwwhmm/archive/2008/06/18/208784.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>你的编程语言可以这样做吗？(map/reduce的js示范) (转)</title><link>http://www.blogjava.net/jjwwhmm/archive/2008/06/09/206800.html</link><dc:creator>pony</dc:creator><author>pony</author><pubDate>Mon, 09 Jun 2008 10:39:00 GMT</pubDate><guid>http://www.blogjava.net/jjwwhmm/archive/2008/06/09/206800.html</guid><wfw:comment>http://www.blogjava.net/jjwwhmm/comments/206800.html</wfw:comment><comments>http://www.blogjava.net/jjwwhmm/archive/2008/06/09/206800.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.blogjava.net/jjwwhmm/comments/commentRss/206800.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jjwwhmm/services/trackbacks/206800.html</trackback:ping><description><![CDATA[有一天，你在浏览自己的代码，发现有两大段代码几乎一样。实际上，它们确实是一样的——除了一个关于意大利面（Spaghetti）而另一个关于巧克力慕思（Chocolate Moose）。
<div class="code">&nbsp;// 一个小例子:<br />
&nbsp;<br />
&nbsp;alert("偶要吃意大利面!");<br />
&nbsp;alert("偶要吃巧克力慕思!");</div>
嗯，这个例子碰巧是用javascript写的，不过你就算不懂JavaScript，应该也能明白它在干什么。 <br />
<br />
拷贝代码不好。于是，你创建了个函数
<div class="code">&nbsp;function SwedishChef( food ){<br />
&nbsp;alert("偶要吃" + food + "!");<br />
&nbsp;}</div>
<div class="code">&nbsp;SwedishChef("意大利面");<br />
&nbsp;SwedishChef("巧克力慕思");</div>
Ok，这只是一个很小很小的例子而已，相信你能想像到个更实际一点的例子。这段代码有很多优点，你全都听过几万次了：可维护性、可读性、抽象性 = 好！ <br />
<br />
现在你留意到有另外两段代码几乎跟它们一模一样，除了一个反复调用一个叫BoomBoom的函数，另一个反复调用一个叫PutInPot的。除此之外，這两段代码简直没什么两样:
<div class="code">&nbsp;alert("拿龙虾");<br />
&nbsp;PutInPot("龙虾");<br />
&nbsp;PutInPot("水");</div>
<div class="code">&nbsp;alert("拿鸡肉");<br />
&nbsp;BoomBoom("鸡肉");<br />
&nbsp;BoomBoom("椰子酱");</div>
现在要想个办法，使得你可以將一个函数用作另一个函数的参数。这是个重要的能力，因为你更容易将框架代码写成一个函数（emu注：还记得template method模式吧？）。
<div class="code">&nbsp;function Cook( i1, i2, f ){<br />
&nbsp;alert("拿" + i1);<br />
&nbsp;f(i1);<br />
&nbsp;f(i2);<br />
&nbsp;}</div>
<div class="code">&nbsp;Cook( "龙虾", "水", PutInPot );<br />
&nbsp;Cook( "鸡肉", "椰子酱", BoomBoom );</div>
看看，我们居然把函数当成调用参数传递了！ <br />
<br />
你的编程语言能办到吗？ <br />
<br />
等等&#8230;&#8230;假如我们已经有了PutInPot和BoomBoom这些函数的具体实现代码（而且又不需要在别的地方重用它们），那么用内联语法把它们写进函数调用里面不是比显式的声明这两个函数更漂亮吗？
<div class="code">&nbsp;Cook( "龙虾", <br />
&nbsp;"水", <br />
&nbsp;function(x) { alert("pot " + x); }  );<br />
&nbsp;Cook( "鸡肉", <br />
&nbsp;"椰子酱", <br />
&nbsp;function(x) { alert("boom " + x); } );</div>
耶，真方便！请注意我只是随手创建了个函数，甚至不用考虑怎么为它起名，只要拎着它的耳朵把它往一个函数里头一丢就可以了。 <br />
<br />
当你一想到作为参数的匿名函数，你也许想到对那些对数组里的每个元素进行相同操作的代码。
<div class="code">&nbsp;var a = [1,2,3];</div>
<div class="code">&nbsp;for (i=0; i&lt;a.length; i++){<br />
&nbsp;a[i] = a[i] * 2;<br />
&nbsp;}</div>
<div class="code">&nbsp;for (i=0; i&lt;a.length; i++){<br />
&nbsp;alert(a[i]);<br />
&nbsp;}</div>
常常要对数组里的所有元素做同一件事，因此你可以写个这样的函数来帮忙：
<div class="code">&nbsp;function map(fn, a){<br />
&nbsp;for (i = 0; i &lt; a.length; i++){<br />
&nbsp;a[i] = fn(a[i]);<br />
&nbsp;}<br />
&nbsp;}</div>
现在你可以把上面的东西改成：
<div class="code">&nbsp;map( function(x){return x*2;}, a );<br />
&nbsp;map( alert, a );</div>
另一个常见的任务是将数组内的所有元素按照某总方式汇总起来：
<div class="code">&nbsp;function sum(a){<br />
&nbsp;var s = 0;<br />
&nbsp;for (i = 0; i &lt; a.length; i++)<br />
&nbsp;s += a[i];<br />
&nbsp;return s;<br />
&nbsp;}<br />
&nbsp;<br />
&nbsp;function join(a){<br />
&nbsp;var s = "";<br />
&nbsp;for (i = 0; i &lt; a.length; i++)<br />
&nbsp;s += a[i];<br />
&nbsp;return s;<br />
&nbsp;}<br />
&nbsp;<br />
&nbsp;alert(sum([1,2,3]));<br />
&nbsp;alert(join(["a","b","c"]));</div>
sum和join长得很像，你也许想把它们抽象为一个将数组内的所有元素按某种算法汇总起來的泛型函数：
<div class="code">&nbsp;function reduce(fn, a, init){<br />
&nbsp;var s = init;<br />
&nbsp;for (i = 0; i &lt; a.length; i++)<br />
&nbsp;s = fn( s, a[i] );<br />
&nbsp;return s;<br />
&nbsp;}<br />
&nbsp;<br />
&nbsp;function sum(a){<br />
&nbsp;return reduce( function(a, b){ return a + b; }, a, 0 );<br />
&nbsp;}<br />
&nbsp;<br />
&nbsp;function join(a){<br />
&nbsp;return reduce( function(a, b){ return a + b; }, a, "" );<br />
&nbsp;}</div>
许多早期的编程语言没法子做这种事。有些语言容许你做，却又困难重重（例如C有函数指针，但你要在別处声明和定义函数）。面向对象语言也不确保你用函数可以干些啥（把函数当对象处理？）。 <br />
<br />
如
果你想将函数视为一类对象，Java要求你建立一个有单方法的对象，称为算子对象。许多面向对象语言要你为每个类都建立一个完整文件，像这样开发可真叫
快。如果你的编程語言要你使用算子对象来包装方法（而不是把方法本身当成对象），你就不能徹底得到现代（动态）编程语言的好处。不妨试试看你可否退货拿回
些钱？ <br />
<br />
不用再写那些除了经过一个数组对每个元素做一些事情之外一无是处的函数，有什么好处？ <br />
<br />
让我们看回map函数。当你要对数组内的每个元素做一些事，你很可能不在乎哪个元素先做。无论由第一个元素开始执行，还是是由最后一个元素执行，你的结果都是一样的，对不？如果你手头上有2個CPU，你可以写段代码，使得它们各对一半的元素工作，于是乎map快了两倍。 <br />
<br />
或
者，发挥一下想像力，设想你在全球有千千万万台服务器分布在全世界的若干个数据中心，你有一个真的很大很大的数组，嗯，再发挥一下想像力，设想这个数组记
录有整个互联网的内容。还了，现在你可以在几千台服务器上同时执行map，让每台服务器都来解决同一个问题的一小部分。 <br />
<br />
那么在这个例子里面，编写一段非常快的代码来搜索整个互联网这个问题，其实就和用一个简单的字符串搜索器（算子）作为参数来调用map函数一样简单了。 <br />
<br />
希
望你注意到一个真正有意思的要点，如果你想要把map/reduce模式变成一个对所有人都有用，对所有人都能立刻派上用场的技术，你只需要一个超级天才
来写最重要的一部分代码，来让map/reduce可以在一个巨大的并行计算机阵列上运行，然后其他旧的但是一向在单一个循环中运行良好的代码，仍可以保
持正确的运行，惟一的差别只是比原来单机运行快了n倍。这意味着它们都一不留神突然变成可以被用来解决一个巨大的问题的代码。 <br />
<br />
让我再啰嗦一下，通过把&#8220;循环&#8221;这个概念加以抽象，你可以把用任何你喜欢的方式来实现&#8220;循环&#8221;过程，包括可以实现让循环迭代速度随着硬件计算能力保持令人满意的同步增长。 <br />
<br />
你现在应该可以明白不久为何对那些对<a href="http://www.joelonsoftware.com/articles/ThePerilsofJavaSchools.html" title="http://www.joelonsoftware.com/articles/ThePerilsofJavaSchools.html" target="_blank">除了Java之外什么都沒被学过的计算机系学生表示不满</a>了：<br />
( <a href="http://www.joelonsoftware.com/articles/ThePerilsofJavaSchools.html" title="http://www.joelonsoftware.com/articles/ThePerilsofJavaSchools.html" target="_blank">http://www.joelonsoftware.com/articles/ThePerilsofJavaSchools.html</a> ) ：<br />
<br />
Without
understanding functional programming, you can't invent MapReduce, the
algorithm that makes Google so massively scalable. The terms Map and
Reduce come from Lisp and functional programming. MapReduce is, in
retrospect, obvious to anyone who remembers from their 6.001-equivalent
programming class that purely functional programs have no side effects
and are thus trivially parallelizable. The very fact that Google
invented MapReduce, and Microsoft didn't, says something about why
Microsoft is still playing catch up trying to get basic search features
to work, while Google has moved on to the next problem: building
Skynet^H^H^H^H^H^H the world's largest massively parallel
supercomputer. I don't think Microsoft completely understands just how
far behind they are on that wave. <br />
<br />
不理解函数式编程，你就发明不了MapReduce这个让Google的计算能力如此具有可扩展性的算法。Map和Reduce这两个术语源自Lisp语言和函数式编程&#8230;&#8230;（这是另一篇文章的内容，emu也不是很理解其中的各种说法的来龙去脉，就不翻译了） <br />
<br />
我希望你现在明白，把函数当成基本类型的（动态）编程语言能让你在编程过程中更好的进行抽象化，也就是使代码精悍、功能更内聚、更具可重用性及更具有扩展性。很多的Google应用使用Map/Reduce模式，因此一有人对其优化或修正缺陷，它们就都可以从中得益。 <br />
<br />
我
准备要再罗嗦一下，我认为最有生产力的编程语言莫过于能让你在不同层次上都可以进行抽象化的。老掉牙的FORTRAN 语言以前是不让你写函数的注。C
有函数指针，可是它们都非常丑丑丑丑丑丑丑丑陋，不允许匿名声明，又不能在用它们时实现它们而偏偏要放在別处去实现。Java让你使用算子对象，一种更丑
陋的东西。正如Steve Yegge所述，Java是個<a href="http://steveyegge.blogspot.com/2006/03/execution-in-kingdom-of-nouns.html" title="http://steveyegge.blogspot.com/2006/03/execution-in-kingdom-of-nouns.html" target="_blank">名词王国</a> <br />
( <a href="http://steveyegge.blogspot.com/2006/03/execution-in-kingdom-of-nouns.html" title="http://steveyegge.blogspot.com/2006/03/execution-in-kingdom-of-nouns.html" target="_blank">http://steveyegge.blogspot.com/2006/03/execution-in-kingdom-of-nouns.html</a> )。 <br />
<br />
<strong>作者注：</strong>这
里提起了FORTRAN，不过我上次使用FORTRAN是27年前的事了。FORTRAN是有函数的，我码字那会儿脑子里面想的大概是GW-BASIC语
言。（emu注，basic确实只有所谓的子程序和go-sub语句，作用只是重新组织代码结构而已，没有参数和调用堆栈，因此没有真正的函数调用）<br />
<br />
<strong>译者注：</strong>原作者起了《你的编程语言可以这样做吗》这个标题其实并不是这篇文章的真正价值所在，我转这篇文章也不是因为原作者可以把语言的初级技巧玩得转，而是因为这是一篇map/reduce模型的示范。
<img src ="http://www.blogjava.net/jjwwhmm/aggbug/206800.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jjwwhmm/" target="_blank">pony</a> 2008-06-09 18:39 <a href="http://www.blogjava.net/jjwwhmm/archive/2008/06/09/206800.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>今天,俺们的市场总监离开了.郁闷啊</title><link>http://www.blogjava.net/jjwwhmm/archive/2008/06/06/206262.html</link><dc:creator>pony</dc:creator><author>pony</author><pubDate>Fri, 06 Jun 2008 03:00:00 GMT</pubDate><guid>http://www.blogjava.net/jjwwhmm/archive/2008/06/06/206262.html</guid><wfw:comment>http://www.blogjava.net/jjwwhmm/comments/206262.html</wfw:comment><comments>http://www.blogjava.net/jjwwhmm/archive/2008/06/06/206262.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jjwwhmm/comments/commentRss/206262.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jjwwhmm/services/trackbacks/206262.html</trackback:ping><description><![CDATA[又一重量级人物出走,过两天,还有一个同事也要离开.到底还要相信是铁打的营盘流水的兵呢,还是俺们的营盘不是铁打的?<br />
发发牢骚,唉!
<img src ="http://www.blogjava.net/jjwwhmm/aggbug/206262.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jjwwhmm/" target="_blank">pony</a> 2008-06-06 11:00 <a href="http://www.blogjava.net/jjwwhmm/archive/2008/06/06/206262.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>UNIX编程艺术的一段话</title><link>http://www.blogjava.net/jjwwhmm/archive/2008/06/04/205925.html</link><dc:creator>pony</dc:creator><author>pony</author><pubDate>Wed, 04 Jun 2008 13:32:00 GMT</pubDate><guid>http://www.blogjava.net/jjwwhmm/archive/2008/06/04/205925.html</guid><wfw:comment>http://www.blogjava.net/jjwwhmm/comments/205925.html</wfw:comment><comments>http://www.blogjava.net/jjwwhmm/archive/2008/06/04/205925.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jjwwhmm/comments/commentRss/205925.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jjwwhmm/services/trackbacks/205925.html</trackback:ping><description><![CDATA[看这本书我最经常回顾的一段话是：<br />
&nbsp;&nbsp;&nbsp;&nbsp; &#8220;软件设计和实现应该是一门充满快乐的艺术，一种高水平的游戏。如果这种态度对你来说听起来有些荒谬，或者令你隐约感到有些困窘，那么情停下来，想一想，问问自己是不是已经把什么给遗忘了。如果只是为了赚钱或是打发时间，你为什么要搞软件设计而不是别的什么呢？你肯定曾经也认为软件设计值得你付出激情......"<br />
<br />
<img src ="http://www.blogjava.net/jjwwhmm/aggbug/205925.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jjwwhmm/" target="_blank">pony</a> 2008-06-04 21:32 <a href="http://www.blogjava.net/jjwwhmm/archive/2008/06/04/205925.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>盖茨向开发人员告别演讲的一句话有感</title><link>http://www.blogjava.net/jjwwhmm/archive/2008/06/04/205900.html</link><dc:creator>pony</dc:creator><author>pony</author><pubDate>Wed, 04 Jun 2008 10:18:00 GMT</pubDate><guid>http://www.blogjava.net/jjwwhmm/archive/2008/06/04/205900.html</guid><wfw:comment>http://www.blogjava.net/jjwwhmm/comments/205900.html</wfw:comment><comments>http://www.blogjava.net/jjwwhmm/archive/2008/06/04/205900.html#Feedback</comments><slash:comments>3</slash:comments><wfw:commentRss>http://www.blogjava.net/jjwwhmm/comments/commentRss/205900.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jjwwhmm/services/trackbacks/205900.html</trackback:ping><description><![CDATA[周二在&#8220;TechEd Developers&#8221;大会上，微软董事会主席比尔&#183;盖茨(Bill Gates)面对满屋的开发人员，发表了退隐前的最后一次公开演讲。在开幕演讲上，盖茨说了这么一句话，&#8220;微软的成功在于我们和开发人员的关系。&#8221; <br />
看到这句话的时候,我想到了现在的公司,现在公司老板的意思就是不要企业文化,而是通过明确的管理规范来约束企业员工,如果所有的员工都一视同仁,开发人员与市场人员,运营人员都在相同的管理制度下工作的话,那么怎么来提现"微软的成功在于我们和开发人员的关系"?<br />
我一直坚定自己从事互联网行业的工作,就是因为在这个舞台上,每个人都可能有机会,每一个人都更加能够发挥自己的主观能动性,而且更加容易.作为互联网企业中最前线的员工---开发人员,如果企业不能提供一个有效的机制来激发他们创作的激情,而只是把他们当作工具来使用的话,那么很难想像企业的前途.又联想到现在google大量高级开发人员,甚至管理人员都纷纷出走,究其原因,是因为这里限制了他们的创造性.我相信,没有一个其它的行业能比处在互联网行业这个时代的浪潮之尖的行业中更能体会到创造的乐趣!<br />
所以,我认为,互联网企业中,公司与开发人员的关系这个问题,应该要被提到公司的战略管理的高度来重视这个问题.
<img src ="http://www.blogjava.net/jjwwhmm/aggbug/205900.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jjwwhmm/" target="_blank">pony</a> 2008-06-04 18:18 <a href="http://www.blogjava.net/jjwwhmm/archive/2008/06/04/205900.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>顺势而为,逆反心理,止跌止涨,禁止全仓,久盘必跌.</title><link>http://www.blogjava.net/jjwwhmm/archive/2008/06/04/205749.html</link><dc:creator>pony</dc:creator><author>pony</author><pubDate>Wed, 04 Jun 2008 03:28:00 GMT</pubDate><guid>http://www.blogjava.net/jjwwhmm/archive/2008/06/04/205749.html</guid><wfw:comment>http://www.blogjava.net/jjwwhmm/comments/205749.html</wfw:comment><comments>http://www.blogjava.net/jjwwhmm/archive/2008/06/04/205749.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jjwwhmm/comments/commentRss/205749.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jjwwhmm/services/trackbacks/205749.html</trackback:ping><description><![CDATA[置顶以提醒自己.
<img src ="http://www.blogjava.net/jjwwhmm/aggbug/205749.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jjwwhmm/" target="_blank">pony</a> 2008-06-04 11:28 <a href="http://www.blogjava.net/jjwwhmm/archive/2008/06/04/205749.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>OSGI启动参数-Dosgi.compatibility.bootdelegation=true的作用</title><link>http://www.blogjava.net/jjwwhmm/archive/2008/06/02/205315.html</link><dc:creator>pony</dc:creator><author>pony</author><pubDate>Mon, 02 Jun 2008 05:59:00 GMT</pubDate><guid>http://www.blogjava.net/jjwwhmm/archive/2008/06/02/205315.html</guid><wfw:comment>http://www.blogjava.net/jjwwhmm/comments/205315.html</wfw:comment><comments>http://www.blogjava.net/jjwwhmm/archive/2008/06/02/205315.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jjwwhmm/comments/commentRss/205315.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jjwwhmm/services/trackbacks/205315.html</trackback:ping><description><![CDATA[今天写le一个bundle,名字叫JmsSendBundle,用spring的jms template来实现发送jms消息.,写完之后,在eclipse环境中运行都正常,但导出到我的osgi环境中,始终报一个错误:java.lang.NoClassDefFoundError: javax/naming/Referenceable
<div>搞了一上午,最后比较eclipse和我自己的osgi的启动环境变量,发现eclipse中<span  style="font-family: 'lucida grande'; font-size: 11px; white-space: pre; ">osgi.compatibility.bootdelegation的值是true,而我的是false,结果把这个参数改成true之后就可以了.</span></div>
<div><font  face="'lucida grande'" size="3"><span  style="font-size: 11px; white-space: pre;">然后去google了下osgi.compatibility.bootdelegation这个参数的作用,<span  style="font-family: Tahoma; font-size: 12px; line-height: 18px; white-space: normal; ">如果该参数值为"true"，当一个类或资源查找不到时，类加载器会启动父类加载器进行最后的查找。该参数的默认值为"true",不知道我的为什么缺省成false了.</span></span></font></div>
<img src ="http://www.blogjava.net/jjwwhmm/aggbug/205315.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jjwwhmm/" target="_blank">pony</a> 2008-06-02 13:59 <a href="http://www.blogjava.net/jjwwhmm/archive/2008/06/02/205315.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>equinox开发osgi时的一个小技巧:定义公用的jar文件.</title><link>http://www.blogjava.net/jjwwhmm/archive/2008/05/29/203922.html</link><dc:creator>pony</dc:creator><author>pony</author><pubDate>Thu, 29 May 2008 11:33:00 GMT</pubDate><guid>http://www.blogjava.net/jjwwhmm/archive/2008/05/29/203922.html</guid><wfw:comment>http://www.blogjava.net/jjwwhmm/comments/203922.html</wfw:comment><comments>http://www.blogjava.net/jjwwhmm/archive/2008/05/29/203922.html#Feedback</comments><slash:comments>3</slash:comments><wfw:commentRss>http://www.blogjava.net/jjwwhmm/comments/commentRss/203922.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jjwwhmm/services/trackbacks/203922.html</trackback:ping><description><![CDATA[一般在开发java项目的时候,我们会有一些公用的jar文件,在开发bundle的时候,如果把这些jar文件重复的在各bundle中复制的话,即烦琐,又容易出错.<br />
今天我琢磨出一个方法,虽然不敢说这么做是否是正确方法,但至少解决了正确的问题(用错误的方法解决正确的事总比用正确的方法解决错误的事好!哈哈).下面是解决的方法:<br />
&nbsp;1.修改org.eclipse.osgi.xxxxxx.jar文件<br />
&nbsp;&nbsp; a.把文件中META-INF目录中的ECLIPSE.SF,ECLIPSE.RSA文件删除掉(因为jar文件是通过SF文件来保证jar中的内容不被篡改!如果不了解这个的,可以去查下jar的详细说明)<br />
&nbsp;&nbsp; b.修改jar根目录下的J2SE-1.5.profile文件(如果你开发osgi使用的是其它J2SE环境,请编辑相应的文件)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 这个文件中定义了osgi启动时的org.osgi.framework.system.packages属性,因为osgi中每个bundle都有自己独立的classpath,那么在各个bundle之间共享的class就是通过这个属性中定义的包来指定的.(如果不了解osgi的class载入机制,请参阅osgi的入门教材!),你可以在文件中的这个属性值上加入自己的包,例如:<br />
&nbsp;........<br />
&nbsp;org.ietf.jgss,\<br />
&nbsp;org.omg.*,\<br />
&nbsp;org.w3c.*,\<br />
&nbsp;org.xml.*,\<br />
&nbsp;sun.*,\<br />
&nbsp;demo.*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //这一行是新增加的包<br />
2.把demo.*所在的jar文件加入到启动osgi的classpath中,一般你可以系统环境变量的classpath中加入这个jar文件路径.<br />
3.把第1步中修改后的osgi jar文件拷贝到eclipse的plugins目录下,重新启动eclipse<br />
4.打开一个bundle的MANIFEST.MF文件,在dependencies项中,你就可以在imported packages中导入刚才定义的demo包了.<br />
<br />
虽然这样做可以做到在各个bundle间共享一些jar文件,但这些公用的jar一定要确认清楚,否则会给以后的开发带来麻烦!因为之所以用osgi来开发,就是为了使用它的class loader的管理机制. 
<img src ="http://www.blogjava.net/jjwwhmm/aggbug/203922.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jjwwhmm/" target="_blank">pony</a> 2008-05-29 19:33 <a href="http://www.blogjava.net/jjwwhmm/archive/2008/05/29/203922.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>OOD比OOP更重要</title><link>http://www.blogjava.net/jjwwhmm/archive/2008/05/29/203892.html</link><dc:creator>pony</dc:creator><author>pony</author><pubDate>Thu, 29 May 2008 09:35:00 GMT</pubDate><guid>http://www.blogjava.net/jjwwhmm/archive/2008/05/29/203892.html</guid><wfw:comment>http://www.blogjava.net/jjwwhmm/comments/203892.html</wfw:comment><comments>http://www.blogjava.net/jjwwhmm/archive/2008/05/29/203892.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.blogjava.net/jjwwhmm/comments/commentRss/203892.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jjwwhmm/services/trackbacks/203892.html</trackback:ping><description><![CDATA[OOP相对比较容易学习,毕竟与编程语言的语法有很大关系.但是OOD就很复杂了,一个大的系统,到了后期越来越混乱,大多数原因是随着新员工的不断加入,他们不能和以前的老员工或者已离职的员工的设计概念保持一致.或者由于系统上线后,新来的业务需求大部分是以一个个小的特性加入到系统中,所以开发人员,管理人员都以一种很容易实现的方式去做这些事情,结果到后面就乱成一团.所以,系统在后期有个重要的工作,就是不断进行架构的重构,以便使新的模块,代码能与以前的在构架概念上保持一致.一个大的系统如果不以OOD的方式设计,那么构架师基本上很难把这个系统向新的涉众解释清楚,无论你是用用例图,类图,序列图,还是交互图,部署图,都难.必须要以一个个的子系统去描述它.<br />
总之,概念完整性是系统成功的关键.设计上的技术可能对某一个模块的影响会比较大.<br />
<img src ="http://www.blogjava.net/jjwwhmm/aggbug/203892.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jjwwhmm/" target="_blank">pony</a> 2008-05-29 17:35 <a href="http://www.blogjava.net/jjwwhmm/archive/2008/05/29/203892.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>公司要封外网了,极度郁闷中</title><link>http://www.blogjava.net/jjwwhmm/archive/2008/05/29/203811.html</link><dc:creator>pony</dc:creator><author>pony</author><pubDate>Thu, 29 May 2008 05:51:00 GMT</pubDate><guid>http://www.blogjava.net/jjwwhmm/archive/2008/05/29/203811.html</guid><wfw:comment>http://www.blogjava.net/jjwwhmm/comments/203811.html</wfw:comment><comments>http://www.blogjava.net/jjwwhmm/archive/2008/05/29/203811.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.blogjava.net/jjwwhmm/comments/commentRss/203811.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jjwwhmm/services/trackbacks/203811.html</trackback:ping><description><![CDATA[这两天书也没心情看了,想到不久上班连google都不能用了,作为一个程序员,还有什么意思?今天前台已经郁闷一天了,因为没得上网!还有好几个财务的,今天msn上都看不到他们的身影了.
<div>是不是到时候改改变下自己了?郁闷啊!</div>
<img src ="http://www.blogjava.net/jjwwhmm/aggbug/203811.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jjwwhmm/" target="_blank">pony</a> 2008-05-29 13:51 <a href="http://www.blogjava.net/jjwwhmm/archive/2008/05/29/203811.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Oracle AS的远程调试</title><link>http://www.blogjava.net/jjwwhmm/archive/2008/05/28/203446.html</link><dc:creator>pony</dc:creator><author>pony</author><pubDate>Wed, 28 May 2008 03:57:00 GMT</pubDate><guid>http://www.blogjava.net/jjwwhmm/archive/2008/05/28/203446.html</guid><wfw:comment>http://www.blogjava.net/jjwwhmm/comments/203446.html</wfw:comment><comments>http://www.blogjava.net/jjwwhmm/archive/2008/05/28/203446.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jjwwhmm/comments/commentRss/203446.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jjwwhmm/services/trackbacks/203446.html</trackback:ping><description><![CDATA[如果要使OracleAS支持远程调试功能,需要在目录: \OracleAS_1\opmn\conf,修改配置文件opmn.xml:
<div><span  style="font-family: white-space: pre; ">&lt;module-data></span>
<pre>&lt;category id="start-parameters">
&lt;data id="java-options" value="-server &lt;del>Xdebug &lt;/del>Xnoagent -Djava.compiler=NONE
-Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=4000
-Djava.security.policy=$ORACLE_HOME/j2ee/home/config/java2.policy
-Djava.awt.headless=true"/>
&lt;/category>
&lt;/module-data>
</pre>
</div>
<img src ="http://www.blogjava.net/jjwwhmm/aggbug/203446.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jjwwhmm/" target="_blank">pony</a> 2008-05-28 11:57 <a href="http://www.blogjava.net/jjwwhmm/archive/2008/05/28/203446.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>linux下so文件的创建及调用方法</title><link>http://www.blogjava.net/jjwwhmm/archive/2008/05/21/201850.html</link><dc:creator>pony</dc:creator><author>pony</author><pubDate>Wed, 21 May 2008 02:56:00 GMT</pubDate><guid>http://www.blogjava.net/jjwwhmm/archive/2008/05/21/201850.html</guid><wfw:comment>http://www.blogjava.net/jjwwhmm/comments/201850.html</wfw:comment><comments>http://www.blogjava.net/jjwwhmm/archive/2008/05/21/201850.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.blogjava.net/jjwwhmm/comments/commentRss/201850.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jjwwhmm/services/trackbacks/201850.html</trackback:ping><description><![CDATA[<br />
<div>1.创建so文件</div>
<div>这一步很简单,只需要在用cc编译的时候,加上-shared选项即可,这样成成的执行程序即为动态链接库,例如:</div>
<div>&#160;&#160; &#160; cc -shared -o hello.so hello.c</div>
<div>2.调用so文件中的函数的步骤</div>
<div>&#160;&#160; a. 包含so中函数的头文件,包含<span  style="font-size: 14px; line-height: 20px; ">dlfcn.h头文件,这个头文件中定义了打开so文件,调用so的函数,关闭so的函数</span></div>
<div>&#160;&#160; b.申明so中函数的类型变量</div>
<div>&#160;&#160; c.用dlopen函数打开so文件,返回句柄</div>
<div>&#160;&#160; d.用dlsym函数以上c步骤中得到的句柄,得到so文件中要调用的函数的动态地址,并把这个地址赋值给在b步骤中申明的函数类型变量</div>
<div>&#160;&#160; e.通过b中申明的函数类型变量调用so中的函数</div>
<div>&#160;&#160; f.用dlclose函数关闭c中得到的句柄所指向的so动态连接库</div>
<div>挺简单吧!</div>
<img src ="http://www.blogjava.net/jjwwhmm/aggbug/201850.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jjwwhmm/" target="_blank">pony</a> 2008-05-21 10:56 <a href="http://www.blogjava.net/jjwwhmm/archive/2008/05/21/201850.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Felix设计中的一个疑问</title><link>http://www.blogjava.net/jjwwhmm/archive/2008/05/19/201412.html</link><dc:creator>pony</dc:creator><author>pony</author><pubDate>Mon, 19 May 2008 08:11:00 GMT</pubDate><guid>http://www.blogjava.net/jjwwhmm/archive/2008/05/19/201412.html</guid><wfw:comment>http://www.blogjava.net/jjwwhmm/comments/201412.html</wfw:comment><comments>http://www.blogjava.net/jjwwhmm/archive/2008/05/19/201412.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.blogjava.net/jjwwhmm/comments/commentRss/201412.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jjwwhmm/services/trackbacks/201412.html</trackback:ping><description><![CDATA[这两天在看apache的osgi框架felix的源代码,对里面很多类的构造函数都有个logger感到很疑惑,一个logger对象会成为一个类的构造函数所必须要的参数吗?
<div>例如:</div>
<div>public Felix(Logger logger, Map configMutableMap, List activatorList) {...}</div>
<div>private EventDispatcher(Logger logger) {...}</div>
<div>protected BundleContextImpl(Logger logger, Felix felix, FelixBundle bundle) {...}</div>
<div>这样的例子太多了.我还看不出这样使用logger有什么好处,应该是跟osgi框架的每个bundle使用单独的classpath有关,不知道哪位可以解释下.谢谢!</div>
<img src ="http://www.blogjava.net/jjwwhmm/aggbug/201412.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jjwwhmm/" target="_blank">pony</a> 2008-05-19 16:11 <a href="http://www.blogjava.net/jjwwhmm/archive/2008/05/19/201412.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Collective Intelligence读书笔记之Inroduction to Collective Intelligence</title><link>http://www.blogjava.net/jjwwhmm/archive/2008/05/19/201369.html</link><dc:creator>pony</dc:creator><author>pony</author><pubDate>Mon, 19 May 2008 05:38:00 GMT</pubDate><guid>http://www.blogjava.net/jjwwhmm/archive/2008/05/19/201369.html</guid><wfw:comment>http://www.blogjava.net/jjwwhmm/comments/201369.html</wfw:comment><comments>http://www.blogjava.net/jjwwhmm/archive/2008/05/19/201369.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jjwwhmm/comments/commentRss/201369.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jjwwhmm/services/trackbacks/201369.html</trackback:ping><description><![CDATA[在第一章的Collective Intelligence的介绍中,作者通过Netflix和google两个公司的例子来说明了Collective Intelligence的应用.但具体Collective Intelligence的定义到底是什么呢?作者并没有明确给出,所以我在读书笔记中也就直接用这两个单词了.
<div>这本书将会告诉读者,通过一些API,应用机器学习算法和统计方法来收集数据的一些方法.那么什么是机器学习呢?这个概念我倒是还有映像,幸好以前研究过语音识别,所以对人工智能方面的知识还有一点基础^_^作者给出的定义是:</div>
<div>An algorithm is given a set of data and infers information about the properties of the data---and that information allows it to make predictions about other data that it might see in the future.简单的说,就是给定一组数据,然后通过一个算法推断出一个数据模型,然后,利用这个模型可以对未来的其它数据做出预测.作者通过一个垃圾邮件过滤的简单例子形象的说明了机器学习的过程!</div>
<div>机器学习常用到的一些算法包括决策树,神经网络等,我还记得语音识别中用到了隐马尔科夫模型,DTW,线性预测LPC,聚类等模型,但主要的都是基于数学方法和统计方法,真是后悔数学没学好啊:(</div>
<div>作者罗列了一些机器学习算法的应用场景,例如Google的page rank,Amozon的推荐系统,在金融系统中的防欺骗检测,产品市场预测,供应链管理等方面.</div>
<img src ="http://www.blogjava.net/jjwwhmm/aggbug/201369.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jjwwhmm/" target="_blank">pony</a> 2008-05-19 13:38 <a href="http://www.blogjava.net/jjwwhmm/archive/2008/05/19/201369.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Collective Intelligence读书笔记之Foreword</title><link>http://www.blogjava.net/jjwwhmm/archive/2008/05/16/200924.html</link><dc:creator>pony</dc:creator><author>pony</author><pubDate>Fri, 16 May 2008 07:22:00 GMT</pubDate><guid>http://www.blogjava.net/jjwwhmm/archive/2008/05/16/200924.html</guid><wfw:comment>http://www.blogjava.net/jjwwhmm/comments/200924.html</wfw:comment><comments>http://www.blogjava.net/jjwwhmm/archive/2008/05/16/200924.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jjwwhmm/comments/commentRss/200924.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jjwwhmm/services/trackbacks/200924.html</trackback:ping><description><![CDATA[<p>今天终于拿到了这本期盼已久的书,可惜是英文的,鉴于对这本书的敬仰!也只好咬着头皮读下去了!<br />
刚看了序言,把里面精彩的两段摘录下来:<br />
Web2.0...Getting users to participage is the first step.Learning from those users and shapping your site based on what they do and pay attention to is the second step.<br />
在web2.0中,让用户参与到你的系统中来只是其中的第一步,更多的是要从这些用户的行为中不断学习,并在这些经验的基础上优化你的web站点<br />
<br />
It's not longer enough to know how to build a database-backed web site.If you want to succeed,you need to know how to mine the data that users are ading,both explicitly and as a side effect of their activity on your site.<br />
如果你想成功的话,仅仅局限于知道怎么构建一个基于数据路的web站点还是很不够的,你需要知道怎么从用户增加的web内容中提炼出有用的数据.</p>
 <img src ="http://www.blogjava.net/jjwwhmm/aggbug/200924.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jjwwhmm/" target="_blank">pony</a> 2008-05-16 15:22 <a href="http://www.blogjava.net/jjwwhmm/archive/2008/05/16/200924.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>equinox的osgi命令</title><link>http://www.blogjava.net/jjwwhmm/archive/2008/05/14/200343.html</link><dc:creator>pony</dc:creator><author>pony</author><pubDate>Wed, 14 May 2008 01:49:00 GMT</pubDate><guid>http://www.blogjava.net/jjwwhmm/archive/2008/05/14/200343.html</guid><wfw:comment>http://www.blogjava.net/jjwwhmm/comments/200343.html</wfw:comment><comments>http://www.blogjava.net/jjwwhmm/archive/2008/05/14/200343.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jjwwhmm/comments/commentRss/200343.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jjwwhmm/services/trackbacks/200343.html</trackback:ping><description><![CDATA[<span style="font-size: 10.5pt; color: rgb(0,0,0); font-family: ''Courier New''; mso-spacerun: ''yes''">控制osgi framework的命令:<br />
&nbsp;launch&nbsp;-&nbsp;start&nbsp;the&nbsp;OSGi&nbsp;Framework</span><span style="font-size: 10.5pt; font-family: ''Courier New''; mso-spacerun: ''yes''"><O:P></O:P></span>
<p class="0" style="layout-grid-mode: char; text-align: justify"><font size="3"><span style="font-size: 10.5pt; color: rgb(0,0,0); font-family: ''Courier New''; mso-spacerun: ''yes''">&nbsp;</span><span style="font-size: 10.5pt; color: rgb(0,0,0); font-family: ''Courier New''; mso-spacerun: ''yes''">shutdown&nbsp;-&nbsp;shutdown&nbsp;the&nbsp;OSGi&nbsp;Framework</span><span style="font-size: 10.5pt; font-family: ''Courier New''; mso-spacerun: ''yes''"><O:P></O:P></span></font></p>
<p class="0" style="layout-grid-mode: char; text-align: justify"><font size="3"><span style="font-size: 10.5pt; color: rgb(0,0,0); font-family: ''Courier New''; mso-spacerun: ''yes''">&nbsp;</span><span style="font-size: 10.5pt; color: rgb(0,0,0); font-family: ''Courier New''; mso-spacerun: ''yes''">close&nbsp;-&nbsp;shutdown&nbsp;and&nbsp;exit</span><span style="font-size: 10.5pt; font-family: ''Courier New''; mso-spacerun: ''yes''"><O:P></O:P></span></font></p>
<p class="0" style="layout-grid-mode: char; text-align: justify"><font size="3"><span style="font-size: 10.5pt; color: rgb(0,0,0); font-family: ''Courier New''; mso-spacerun: ''yes''">&nbsp;</span><span style="font-size: 10.5pt; color: rgb(0,0,0); font-family: ''Courier New''; mso-spacerun: ''yes''">exit&nbsp;-&nbsp;exit&nbsp;immediately&nbsp;(System.exit)</span><span style="font-size: 10.5pt; font-family: ''Courier New''; mso-spacerun: ''yes''"><O:P></O:P></span></font></p>
<p class="0" style="layout-grid-mode: char; text-align: justify"><font size="3"><span style="font-size: 10.5pt; color: rgb(0,0,0); font-family: ''Courier New''; mso-spacerun: ''yes''">&nbsp;</span><span style="font-size: 10.5pt; color: rgb(0,0,0); font-family: ''Courier New''; mso-spacerun: ''yes''">init&nbsp;-&nbsp;uninstall&nbsp;all&nbsp;bundles</span><span style="font-size: 10.5pt; font-family: ''Courier New''; mso-spacerun: ''yes''"><O:P></O:P></span></font></p>
<p class="0" style="layout-grid-mode: char; text-align: justify"><font size="3"><span style="font-size: 10.5pt; color: rgb(0,0,0); font-family: ''Courier New''; mso-spacerun: ''yes''">&nbsp;</span><span style="font-size: 10.5pt; color: rgb(0,0,0); font-family: ''Courier New''; mso-spacerun: ''yes''">setprop&nbsp;&lt;key&gt;=&lt;value&gt;&nbsp;-&nbsp;set&nbsp;the&nbsp;OSGi&nbsp;property<br />
</span><span style="font-size: 10.5pt; font-family: ''Courier New''; mso-spacerun: ''yes''"><O:P><br />
控制bundle的命令:</O:P></span></font></p>
<p class="0" style="layout-grid-mode: char; text-align: justify"><font size="3"><span style="font-size: 10.5pt; color: rgb(0,0,0); font-family: ''Courier New''; mso-spacerun: ''yes''">&nbsp;</span><span style="font-size: 10.5pt; color: rgb(0,0,0); font-family: ''Courier New''; mso-spacerun: ''yes''">install&nbsp;-&nbsp;install&nbsp;and&nbsp;optionally&nbsp;start&nbsp;bundle&nbsp;from&nbsp;the&nbsp;given&nbsp;URL</span><span style="font-size: 10.5pt; font-family: ''Courier New''; mso-spacerun: ''yes''"><O:P></O:P></span></font></p>
<p class="0" style="layout-grid-mode: char; text-align: justify"><font size="3"><span style="font-size: 10.5pt; color: rgb(0,0,0); font-family: ''Courier New''; mso-spacerun: ''yes''">&nbsp;</span><span style="font-size: 10.5pt; color: rgb(0,0,0); font-family: ''Courier New''; mso-spacerun: ''yes''">uninstall&nbsp;-&nbsp;uninstall&nbsp;the&nbsp;specified&nbsp;bundle(s)</span><span style="font-size: 10.5pt; font-family: ''Courier New''; mso-spacerun: ''yes''"><O:P></O:P></span></font></p>
<p class="0" style="layout-grid-mode: char; text-align: justify"><font size="3"><span style="font-size: 10.5pt; color: rgb(0,0,0); font-family: ''Courier New''; mso-spacerun: ''yes''">&nbsp;</span><span style="font-size: 10.5pt; color: rgb(0,0,0); font-family: ''Courier New''; mso-spacerun: ''yes''">start&nbsp;-&nbsp;start&nbsp;the&nbsp;specified&nbsp;bundle(s)</span><span style="font-size: 10.5pt; font-family: ''Courier New''; mso-spacerun: ''yes''"><O:P></O:P></span></font></p>
<p class="0" style="layout-grid-mode: char; text-align: justify"><font size="3"><span style="font-size: 10.5pt; color: rgb(0,0,0); font-family: ''Courier New''; mso-spacerun: ''yes''">&nbsp;</span><span style="font-size: 10.5pt; color: rgb(0,0,0); font-family: ''Courier New''; mso-spacerun: ''yes''">stop&nbsp;-&nbsp;stop&nbsp;the&nbsp;specified&nbsp;bundle(s)</span><span style="font-size: 10.5pt; font-family: ''Courier New''; mso-spacerun: ''yes''"><O:P></O:P></span></font></p>
<p class="0" style="layout-grid-mode: char; text-align: justify"><font size="3"><span style="font-size: 10.5pt; color: rgb(0,0,0); font-family: ''Courier New''; mso-spacerun: ''yes''">&nbsp;</span><span style="font-size: 10.5pt; color: rgb(0,0,0); font-family: ''Courier New''; mso-spacerun: ''yes''">refresh&nbsp;-&nbsp;refresh&nbsp;the&nbsp;packages&nbsp;of&nbsp;the&nbsp;specified&nbsp;bundles</span><span style="font-size: 10.5pt; font-family: ''Courier New''; mso-spacerun: ''yes''"><O:P></O:P></span></font></p>
<p class="0" style="layout-grid-mode: char; text-align: justify"><font size="3"><span style="font-size: 10.5pt; color: rgb(0,0,0); font-family: ''Courier New''; mso-spacerun: ''yes''">&nbsp;</span><span style="font-size: 10.5pt; color: rgb(0,0,0); font-family: ''Courier New''; mso-spacerun: ''yes''">update&nbsp;-&nbsp;update&nbsp;the&nbsp;specified&nbsp;bundle(s)</span><span style="font-size: 10.5pt; font-family: ''Courier New''; mso-spacerun: ''yes''"><O:P></O:P></span></font></p>
显示bundle状态的命令:<br />
<p class="0" style="layout-grid-mode: char; text-align: justify"><font size="3"><span style="font-size: 10.5pt; color: rgb(0,0,0); font-family: ''Courier New''; mso-spacerun: ''yes''">&nbsp;</span><span style="font-size: 10.5pt; color: rgb(0,0,0); font-family: ''Courier New''; mso-spacerun: ''yes''">status&nbsp;[-s&nbsp;[&lt;comma&nbsp;separated&nbsp;list&nbsp;of&nbsp;bundle&nbsp;states&gt;]&nbsp;&nbsp;[&lt;segment&nbsp;of&nbsp;bsn&gt;]]&nbsp;-&nbsp;display&nbsp;installed&nbsp;bundles&nbsp;and&nbsp;registered&nbsp;services</span><span style="font-size: 10.5pt; font-family: ''Courier New''; mso-spacerun: ''yes''"><O:P></O:P></span></font></p>
<p class="0" style="layout-grid-mode: char; text-align: justify"><font size="3"><span style="font-size: 10.5pt; color: rgb(0,0,0); font-family: ''Courier New''; mso-spacerun: ''yes''">&nbsp;</span><span style="font-size: 10.5pt; color: rgb(0,0,0); font-family: ''Courier New''; mso-spacerun: ''yes''">ss&nbsp;[-s&nbsp;[&lt;comma&nbsp;separated&nbsp;list&nbsp;of&nbsp;bundle&nbsp;states&gt;]&nbsp;&nbsp;[&lt;segment&nbsp;of&nbsp;bsn&gt;]]&nbsp;-&nbsp;display&nbsp;installed&nbsp;bundles&nbsp;(short&nbsp;status)</span><span style="font-size: 10.5pt; font-family: ''Courier New''; mso-spacerun: ''yes''"><O:P></O:P></span></font></p>
<p class="0" style="layout-grid-mode: char; text-align: justify"><font size="3"><span style="font-size: 10.5pt; color: rgb(0,0,0); font-family: ''Courier New''; mso-spacerun: ''yes''">&nbsp;</span><span style="font-size: 10.5pt; color: rgb(0,0,0); font-family: ''Courier New''; mso-spacerun: ''yes''">services&nbsp;{filter}&nbsp;-&nbsp;display&nbsp;registered&nbsp;service&nbsp;details</span><span style="font-size: 10.5pt; font-family: ''Courier New''; mso-spacerun: ''yes''"><O:P></O:P></span></font></p>
<p class="0" style="layout-grid-mode: char; text-align: justify"><font size="3"><span style="font-size: 10.5pt; color: rgb(0,0,0); font-family: ''Courier New''; mso-spacerun: ''yes''">&nbsp;</span><span style="font-size: 10.5pt; color: rgb(0,0,0); font-family: ''Courier New''; mso-spacerun: ''yes''">packages&nbsp;{&lt;pkgname&gt;|&lt;id&gt;|&lt;location&gt;}&nbsp;-&nbsp;display&nbsp;imported/exported&nbsp;package&nbsp;details</span><span style="font-size: 10.5pt; font-family: ''Courier New''; mso-spacerun: ''yes''"><O:P></O:P></span></font></p>
<p class="0" style="layout-grid-mode: char; text-align: justify"><font size="3"><span style="font-size: 10.5pt; color: rgb(0,0,0); font-family: ''Courier New''; mso-spacerun: ''yes''">&nbsp;</span><span style="font-size: 10.5pt; color: rgb(0,0,0); font-family: ''Courier New''; mso-spacerun: ''yes''">bundles&nbsp;[-s&nbsp;[&lt;comma&nbsp;separated&nbsp;list&nbsp;of&nbsp;bundle&nbsp;states&gt;]&nbsp;&nbsp;[&lt;segment&nbsp;of&nbsp;bsn&gt;]]&nbsp;-&nbsp;display&nbsp;details&nbsp;for&nbsp;all&nbsp;installed&nbsp;bundles</span><span style="font-size: 10.5pt; font-family: ''Courier New''; mso-spacerun: ''yes''"><O:P></O:P></span></font></p>
<p class="0" style="layout-grid-mode: char; text-align: justify"><font size="3"><span style="font-size: 10.5pt; color: rgb(0,0,0); font-family: ''Courier New''; mso-spacerun: ''yes''">&nbsp;</span><span style="font-size: 10.5pt; color: rgb(0,0,0); font-family: ''Courier New''; mso-spacerun: ''yes''">bundle&nbsp;(&lt;id&gt;|&lt;location&gt;)&nbsp;-&nbsp;display&nbsp;details&nbsp;for&nbsp;the&