<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    2006年10月30日

    論劍歸來(一)

    應(yīng)朋友邀請(qǐng),周六早從上海出發(fā)往杭州參加阿里巴巴網(wǎng)俠大會(huì)。同行四人,有銳道的macro chen、楊光(還是我?guī)煹埽⒁苿?dòng)的王偉旭(特長(zhǎng)是linux和網(wǎng)絡(luò)安全,也是中國linux推廣的先驅(qū))。一路上,言談甚歡。老莊給我們訂的票,他一早腸胃有恙,仍然堅(jiān)持把票送到火車站,之后去吊鹽水,下午又出現(xiàn)在會(huì)場(chǎng)。確實(shí)精神可嘉,建議阿里巴巴頒發(fā)“最佳精神獎(jiǎng)”。

    到杭州已是中午,錯(cuò)過了上午大會(huì)。下午Robbin進(jìn)行Java技術(shù)展望和RoR實(shí)現(xiàn)REST的演講,既然是朋友,肯定是要捧場(chǎng)的。Robbin旁征博引,以其深厚的技術(shù)功底和對(duì)新技術(shù)的敏銳洞察贏得了聽眾。

    晚上一堆人去聚會(huì),各路豪杰紛至:有阿里巴巴的,有自己創(chuàng)業(yè)的,有技術(shù)大牛,還有媒體(Infoq),出版社(博文的周總領(lǐng)3員大將赴會(huì))。大家互換名片,認(rèn)識(shí)的不免寒暄幾句,不認(rèn)識(shí)的也很快就熟捻了,還不時(shí)有“原來你就是×××”的驚呼,原來網(wǎng)上就“互通心曲”,只是一直沒機(jī)會(huì)認(rèn)識(shí)罷了。

    席間觥籌交錯(cuò),具體內(nèi)容暫且不表,只說一件令我感受頗深之事。一個(gè)阿里巴巴的員工表現(xiàn)出對(duì)公司的無比忠誠,講起公司的獎(jiǎng)懲制度,說是一個(gè)員工的績(jī)效不僅跟所在項(xiàng)目相關(guān),還與部門、其它部門甚至整個(gè)公司的業(yè)績(jī)相關(guān)。所以只要是對(duì)公司有利的事情,即使與自己現(xiàn)在的工作無關(guān),他們也會(huì)去做。按常理來說,這有點(diǎn)不公平,我只能努力做好自己的事情,而如果別人不努力,我就是白做。但如果大家都努力,又變成了共贏。

    這里讓我講一個(gè)簡(jiǎn)單的博弈問題,就是“囚徒困境”。AB兩個(gè)同犯被抓,因?yàn)闆]有其它任何證據(jù)和證人,只能讓2人分別交供。如果AB都矢口否認(rèn),那么兩人無罪釋放。如果A承認(rèn),B不承認(rèn);A是坦白從寬,判1年;B抗拒從嚴(yán),判5年,反之亦然。如果2人都承認(rèn),ok證據(jù)確鑿,各判2年。如果2人都是理性人,且沒有互通消息,按照博弈,每個(gè)人的最優(yōu)解就是承認(rèn),也就是各判2年。其實(shí)對(duì)2人真正有利的就是打死不承認(rèn)然后都無罪釋放,而這種狀態(tài)在理性人的假設(shè)下是很難實(shí)現(xiàn)的--除非有一個(gè)教父,一直灌輸他們不要出賣同伙。

    馬云就是這個(gè)“教父”!

    卡內(nèi)基有篇文章,我總結(jié)成一句話就是:用崇高的理想打動(dòng)別人。據(jù)說馬云一直是以個(gè)人魅力及“創(chuàng)造中國電子商務(wù)的明天”類似的理想,激勵(lì)員工的。有了統(tǒng)一的企業(yè)文化,員工都不計(jì)較個(gè)人得失,努力奮進(jìn),最終企業(yè)和所有員工取得共贏,這絕對(duì)是擺脫“囚徒困境”的典型案例。

    話說回來,阿里巴巴能讓你感受到團(tuán)隊(duì)的力量,一群精英在一塊做很有價(jià)值的事情,對(duì)每個(gè)人也是很好的鍛煉。個(gè)人認(rèn)為,如果有吃苦耐勞的打算,眼光放長(zhǎng)遠(yuǎn)點(diǎn),又沒有其它方面的束縛,阿里巴巴的確是不錯(cuò)的選擇。(得向阿里巴巴收代言費(fèi),呵呵!)

    第二天聽了多場(chǎng)論道,主要是SAAS,搜索,分詞方面。結(jié)合阿里巴巴的戰(zhàn)略,我把幾點(diǎn)融合起來講一下。這個(gè)下篇再細(xì)細(xì)道來。

     

     

    posted @ 2007-05-21 20:35 pesome 閱讀(1133) | 評(píng)論 (1)編輯 收藏

    sitemesh的問題及解決

    再說 sitemesh 的問題,同樣是做 openfans 網(wǎng)摘功能出現(xiàn)的。做好了 IE 插件,有 fans 反饋說彈出頁面太大,這也難怪,用了 sitemesh head footer 都在頁面上,想縮小頁面,肯定得把 head footer 都去掉,做個(gè)干凈點(diǎn)的。既然用了 sitemesh 肯定是希望最方便的搞定這個(gè),而不用動(dòng)任何邏輯(包括頁面邏輯)。這個(gè)好辦,文檔里有說,通過在 sitemesh.xml 中增加

    < mapper

    ???????????
    class = " com.opensymphony.module.sitemesh.mapper.ParameterDecoratorMapper " >

    ???????????
    < param?name = " decorator.parameter " ?value = " decorator " ? />

    ???????????
    < param?name = " parameter.name " ?value = " confirm " ? />

    ???????????
    < param?name = " parameter.value " ?value = " true " ? />

    ???????
    </ mapper >

    就能搞定,這樣只需要使用參數(shù)如 saveSnippet.html?decorator=simple&confirm=true ,就能讓它使用指定的 decorator 。然后做一個(gè)去掉 head footer 只保留必要的 js css 引用的 simple.jsp 頁面,同時(shí)在 decorator.xml 中配

    < decorator?name = " simple " ?page = " simple.jsp " ></ decorator >

    就應(yīng)該可以搞定。

    但怎么測(cè),就是不使用這個(gè) simple decorator 。沒辦法,只好跟進(jìn) sitemesh 源碼中去調(diào)試,進(jìn)入 ParameterDecoratorMapper 類,它繼承了 AbstractDecoratorMapper 類,然后有一個(gè) init 方法一個(gè) getDecorator 方法。各打一個(gè)斷點(diǎn), init 方法在 tomcat 啟動(dòng)就會(huì)執(zhí)行,也正常初始化了, getDecorator 方法卻始終不調(diào)用,一時(shí)想不出辦法。看到篇文章說不自己寫 sitemesh.xml 而使用自帶的 com/opensymphony/module/sitemesh/factory/sitemesh-default.xml 也可以,于是備份并刪除我寫的 sitemesh.xml ,居然成功了。為什么我寫的就不行呢?差別一是我的簡(jiǎn)化了很多,只有

    < mapper

    ????
    class ="com.opensymphony.module.sitemesh.mapper.ConfigDecoratorMapper" >

    ???????????
    < param? name ="config" ?value ="${decorators-file}" ? />

    ???????
    </ mapper >

    和剛加的

    ParameterDecoratorMapper ,二就是順序,我的 ParameterDecoratorMapper 放在了 ConfigDecoratorMapper 后面,會(huì)不會(huì)是順序原因呢,調(diào)換一下,果然成功了。問題是解決了,原理呢?再花點(diǎn)時(shí)間跟一下代碼了解下原理,原來使用了 Factory ,它會(huì)調(diào)用各個(gè)配置的 Mapper init 方法,并放入 map 中,然后到時(shí)選擇一個(gè) Mapper ,如果符合條件就使用,否則繼續(xù)往下找。這里就有了順序的問題,因?yàn)槲以?/span> decorator.xml 中使用了
    <decorator?name="default"?page="default.jsp">

    ????????
    <pattern>/*.html</pattern>

    ????
    </decorator>

    ,這樣如果 ConfigDecoratorMapper 放在前面,他就先找這個(gè) Mapper ,一看 saveSnippet.html?decorator=simple&confirm=true ,符合 pattern 啊,就使用它了,另一個(gè) ParameterDecoratorMapper 根本得不到機(jī)會(huì),所以也進(jìn)不了它的 getDecorator 方法。換了順序就是它先進(jìn)去,所以執(zhí)行,其它的 url 也是先找它,但不匹配,就又交給 ConfigDecoratorMapper 了。呵呵,問題也解決了,對(duì) sitemesh 的認(rèn)識(shí)又進(jìn)了一步。

    posted @ 2007-03-11 22:54 pesome 閱讀(2993) | 評(píng)論 (0)編輯 收藏

    中文問題的解決

    這次給 openfans 做網(wǎng)摘功能,主體程序倒是很快就寫完了,另外要做個(gè) IE 插件,卻碰到了不少問題。 IE 插件其實(shí)很簡(jiǎn)單,就是用 js 獲得頁面的標(biāo)題、 url 和選擇的內(nèi)容,然后通過彈出窗口,將其送到服務(wù)器。這里就有中文的問題了,開始使用 escape ,如 escape(title) 形式, request.getParameter 碰到中文就為 null ,網(wǎng)上搜了一通,說是可以通過 java 編碼搞定,但拿到就為 null 了,還怎么換編碼?忙活了好幾個(gè)小時(shí),又是 alert ,又是 document.write ,看上去也沒什么問題。不 escape ,直接在瀏覽器中輸入帶中文的 url ,拿到的不為 null 了,拿到后,通過 new String(str.getBytes("ISO-8859-1"), "UTF-8"); 還真顯示正常了。但用 window.open 又出亂碼了。看到文章說還有 encodeURIComponent 方法可用,就試了下,把 escape 換成 encodeURIComponent 居然搞定了,服務(wù)端還是得用 new String(str.getBytes("ISO-8859-1"), "UTF-8") 進(jìn)行處理。注意這里用的 tomcat ,它的默認(rèn)編碼就是 "ISO-8859-1" ,如果改了編碼程序也得做相應(yīng)的改動(dòng)了。

    posted @ 2007-03-11 22:51 pesome 閱讀(1042) | 評(píng)論 (0)編輯 收藏

    hibernate native sql的小技巧

    為了性能考慮,使用了 native sql 。因?yàn)樾枰猪摚枰?/span> 2 個(gè) sql ,一個(gè)獲取 list 一個(gè)取得總數(shù)。獲取 list 很好寫:

    ?

    ?1 private ?List?getListByNativeSQL( final ?Class?cls,? final ?String?sql)? {
    ?2
    ?3 ??????? return ?(List)?getHibernateTemplate().execute( new ?HibernateCallback()? {
    ?4
    ?5 ??????????? public ?Object?doInHibernate(Session?session)
    ?6
    ?7 ?????????????????? throws ?HibernateException? {
    ?8
    ?9 ?????????????? return ?session.createSQLQuery(sql).addEntity(cls).list();
    10
    11 ???????????}

    12
    13 ???????}
    );
    14
    15 ????}

    16

    ?

    獲取總數(shù)查了下 hibernate reference, 試了幾次才明白用法 :

    ?1 private ?BigInteger?getCountByNativeSQL( final ?String?sql)? {
    ?2
    ?3 ??????? return ?(BigInteger)?getHibernateTemplate().execute(
    ?4
    ?5 ?????????????? new ?HibernateCallback()? {
    ?6
    ?7 ?????????????????? public ?Object?doInHibernate(Session?session)
    ?8
    ?9 ????????????????????????? throws ?HibernateException? {
    10
    11 ????????????????????? return ?(BigInteger)?(session.createSQLQuery(sql).uniqueResult());
    12
    13 ??????????????????}

    14
    15 ??????????????}
    );
    16
    17 ????}

    18

    這里的

    sql 是“ select count(*) 開頭的”。這里大家可能要問,為什么要使用 BigInteger ,因?yàn)槿绻?/span> uniqueResult() 默認(rèn)就返回 BigInteger ,而 BigInteger cast Integer 會(huì)出錯(cuò)。那么如果我就是要返回 Integer 呢,可以通過下面的辦法實(shí)現(xiàn):

    ?1 private ?Integer?getCountByNativeSQL( final ?String?sql)? {
    ?2
    ?3 ??????? return ?(Integer)?getHibernateTemplate().execute(
    ?4
    ?5 ?????????????? new ?HibernateCallback()? {
    ?6
    ?7 ?????????????????? public ?Object?doInHibernate(Session?session)
    ?8
    ?9 ????????????????????????? throws ?HibernateException? {
    10
    11 ????????????????????? return ?(Integer)?(session.createSQLQuery(sql).addScalar( " count " ,?Hibernate.INTEGER).uniqueResult());
    12
    13 ??????????????????}

    14
    15 ??????????????}
    );
    16
    17 ????}

    18

    大家注意粗體的部分,這里是給一個(gè)

    alias 賦予類型,那么 sql 就需要變成以 ”select count(*) as count ” 開頭了。

    posted @ 2007-03-02 10:52 pesome 閱讀(5255) | 評(píng)論 (2)編輯 收藏

    php5+mysql5+apache2需要注意的幾點(diǎn)

    今天為了在本機(jī)裝個(gè)wordpress玩玩,搞了搞php5+mysql5+apache2。網(wǎng)上搜了一篇文檔,很快就讓php與apache跑起來了,但連mysql始終不行。報(bào)錯(cuò):Call to undefined function mysql_connect()。查了一下半天,就是php關(guān)于mysql的ext沒配好,但我改了php.ini啊,也把"extension=php_mysql.dll"放出來了。查了好久,看到一篇說php5需要加上"extension=php_mysqli.dll",試了下果然好了。
    ???? 然后需要以index.php作為默認(rèn)的welcomefile(不知道怎么叫,web.xml里是這個(gè)),需要在"DirectoryIndex index.html index.html.var"后加上 index.php就行。
    然后飛快的裝了phpmyadmin、dvbbs的php版。發(fā)現(xiàn)php應(yīng)用的安裝的確很是方便,解壓,拷貝到htdocs下,馬上就能運(yùn)行了,比java應(yīng)用簡(jiǎn)單的多,更別提復(fù)雜的要死的企業(yè)應(yīng)用了。這點(diǎn)上java要好好向php學(xué)習(xí)啊。

    posted @ 2007-01-14 17:34 pesome 閱讀(1292) | 評(píng)論 (0)編輯 收藏

    開始研究電子支付

    項(xiàng)目需要,開始研究電子支付。國外的電子支付提供商,得好好研究它的文檔和api。全是e文,只能慢慢看了。

    posted @ 2007-01-12 15:41 pesome 閱讀(1292) | 評(píng)論 (1)編輯 收藏

    準(zhǔn)備給openfans添加spring2.0支持

    ? 學(xué)習(xí)了下spring2.0。對(duì)openfans而言,有2個(gè)比較重要的改進(jìn)。首先是aspectj的支持,可以方便的使用aspectj語法定義aspect和pointcut了,openfans準(zhǔn)備在domain object的自動(dòng)注入上和權(quán)限等方面使用aop。另外就是spring form標(biāo)簽庫的引入,現(xiàn)在springmvc也有自己的標(biāo)簽庫,以前自己給checkbox和radio寫的request.getParameter可以改寫了。

    posted @ 2006-12-28 15:15 pesome 閱讀(1136) | 評(píng)論 (1)編輯 收藏

    一個(gè)定時(shí)更新cache框架

         摘要: 應(yīng)項(xiàng)目需要做了一個(gè)定時(shí)更新的 cache 框架,采用 spring+quartz 很方便的實(shí)現(xiàn),可以適用任何需要定時(shí)才更新的地方,比如靜態(tài)網(wǎng)頁 cache 等。代碼很簡(jiǎn)單: ---------------------------------QuartzCacheHandler-------------------...  閱讀全文

    posted @ 2006-12-13 14:46 pesome 閱讀(4132) | 評(píng)論 (7)編輯 收藏

    這次做portal的一些總結(jié)(二)

    接著前面的寫。上文主要寫了 ajax portal 中的使用,這篇寫集群方面的體會(huì)。現(xiàn)在比較流行的架構(gòu)就是前端 F5 做負(fù)載均衡,后面 2 臺(tái) websphere server 做成集群,各自都有 HttpServer ,每個(gè) HttpServer 都向 2 臺(tái) was 做轉(zhuǎn)發(fā)。這樣每臺(tái)都能獨(dú)立完成從 HttpServer was 的流程。一臺(tái)出現(xiàn)故障, F5 首先進(jìn)行切換,只向正常 server HttpServer 發(fā)起請(qǐng)求,這臺(tái) HttpServer 再進(jìn)行切換只向同一臺(tái) server 上的 was 做轉(zhuǎn)發(fā)。這次 portal 就是采用的這種架構(gòu),不妨稱為架構(gòu) A

    另一種簡(jiǎn)單點(diǎn)的架構(gòu)就是只做 F5 負(fù)載均衡,不做 was 集群,每臺(tái) websphere server 上的 HttpServer 接受 F5 轉(zhuǎn)發(fā)的請(qǐng)求,只向本 server was 轉(zhuǎn)發(fā)。這樣每臺(tái) websphere server 保持獨(dú)立,相互間沒有數(shù)據(jù)交換和轉(zhuǎn)發(fā)。不妨稱為架構(gòu) B

    架構(gòu) A B 各有優(yōu)劣,適合不同的需要,下面進(jìn)行些比較:

    ????????? 從應(yīng)用部署上看:

    A 使用了 websphere 集群,由一個(gè) DeployManager 進(jìn)行分發(fā),部署應(yīng)用,只需部署一次,由 DM 分發(fā)到幾個(gè)節(jié)點(diǎn)上。而 B 每個(gè) server 都是獨(dú)立的,部署應(yīng)用只能一臺(tái)臺(tái)部署,如果 server 較少差別還不明顯,如果達(dá)到 10 臺(tái)以上,一臺(tái)臺(tái)部署將是一個(gè)比較痛苦的事情。

    ????????? session 上看:

    A 使用了 websphere 集群,可以使用集群提供的 session 復(fù)制,對(duì)于一些關(guān)鍵應(yīng)用(某臺(tái)服務(wù)器宕機(jī), session 也必須保持的應(yīng)用)很有必要。而對(duì)于一些能夠允許 session 丟失的應(yīng)用,才可以使用 B 。當(dāng)然 A 也可以關(guān)閉 session 復(fù)制,因?yàn)?/span> session 復(fù)制不管是使用數(shù)據(jù)庫方式還是內(nèi)存方式,總會(huì)消耗一定的性能。具體消耗多少性能,就要看不同的 application server session 復(fù)制方案了,想深入了解,可以看集群方面的文檔,我也只記得一個(gè)比較簡(jiǎn)單的 round robbin 了。

    ????????? 從架構(gòu)復(fù)雜性看:

    B 更為簡(jiǎn)單,因?yàn)闆]有 DM 的概念,每臺(tái) server 都保持獨(dú)立。而使用了 DM 有時(shí)也會(huì)出現(xiàn)莫名奇妙的問題,這當(dāng)然是由于不了解 DM 的機(jī)制所致,但總歸也增加了復(fù)雜度,這點(diǎn)在后面的教訓(xùn)中進(jìn)行說明。

    ????????? 從水平擴(kuò)展性上看:

    B 肯定更勝一籌。只要 F5 能支持,多少臺(tái) server 都沒關(guān)系。而 A 多臺(tái) server 做集群,要看 websphere 支持的節(jié)點(diǎn)數(shù)量,應(yīng)該不會(huì)太大。這個(gè)如果哪位同學(xué)知道,敬請(qǐng)告知。

    當(dāng)然 A B 在服務(wù)器較多的情況下是可以共存的,可以考慮幾臺(tái)機(jī)器做集群,然后集群間做負(fù)載均衡,這樣既可以減少部署的復(fù)雜度,又可以帶來較好的水平擴(kuò)展。由于沒做過更大型的項(xiàng)目,這個(gè)也只是我的假象,請(qǐng)做過的同學(xué)斧正。

    ?

    說一說集群中碰到的問題。

    ????????? 首先是對(duì)各節(jié)點(diǎn)的同步:

    有時(shí)為了方便測(cè)試,我們只對(duì)其中一個(gè)節(jié)點(diǎn)進(jìn)行更改,測(cè)試通過再放到其它節(jié)點(diǎn)。而如果測(cè)試周期較長(zhǎng),有時(shí)就會(huì)造成節(jié)點(diǎn)的不同步,出現(xiàn)各種各樣莫名其妙的問題。一個(gè)經(jīng)驗(yàn)就是:無論如何,在每天下班前要保證各節(jié)點(diǎn)的同步,不同步的現(xiàn)象不要過夜。

    ????????? 然后是對(duì) DM 的理解:

    我現(xiàn)在還只是實(shí)踐階段,沒有看過相關(guān)文檔。從意義上看,它控制了相關(guān)的配置文件,如果進(jìn)行節(jié)點(diǎn)同步,就會(huì)由它把配置文件同步到它管理的節(jié)點(diǎn)上。這對(duì)配置文件的修改提出了要求。我們開始只修改節(jié)點(diǎn)的配置文件而沒有修改 DM 的,結(jié)果進(jìn)行節(jié)點(diǎn)同步就會(huì)覆蓋修改的配置文件,帶來很多不必要的工作。經(jīng)驗(yàn)就是:或者修改 DM 的配置文件,然后進(jìn)行節(jié)點(diǎn)同步,或者直接同時(shí)修改所有節(jié)點(diǎn)和 DM 的。

    ????????? 還有關(guān)于 cache 的:

    Cache 是性能優(yōu)化的一個(gè)有效手段。在單機(jī)環(huán)境下,最簡(jiǎn)單的就是內(nèi)存 cache ,使用 static Map 就行。而在集群環(huán)境中, cache 就變的比較復(fù)雜了。首先還是從應(yīng)用需求入手,是否要保持每臺(tái)機(jī)器的 cache 同步。如果只是信息展示等要求不高的 cache ,不需保證 cache 的同步,問題也比較簡(jiǎn)單,自己寫內(nèi)存 cache ,或者使用開源的 cache 組件如 ehcache,oscache 等就可以很好的解決問題。而如果需要 cache 在幾個(gè)節(jié)點(diǎn)保持同步,就需要特殊的機(jī)制了, ehcache 等號(hào)稱支持分布式 cache ,但好像需要 jgroup ,配置比較麻煩,我沒有用過,有用過的同學(xué)請(qǐng)指教。我本來想使用 session 保存,然后進(jìn)行 session 同步,后來 IBM 建議使用數(shù)據(jù)庫 cache ,即自己寫代碼, cache 在數(shù)據(jù)庫中。這樣不需要 session 同步,對(duì)象不大,性能也能得到保證,現(xiàn)在用下來效果還可以。

    ?

    posted @ 2006-12-13 13:39 pesome 閱讀(3803) | 評(píng)論 (9)編輯 收藏

    這次做portal的一些總結(jié)(一)

    這次做 ibm portal ,算是臨危受命。做了幾個(gè)月的 SA 離職,留下一個(gè)功能和性能都有很多問題的項(xiàng)目,臨時(shí)讓我頂上。經(jīng)過一個(gè)多月的緊張工作(經(jīng)常加班,上班上不了網(wǎng),也沒時(shí)間上網(wǎng)),總算功能和性能上都能達(dá)到客戶要求了。而我也由一個(gè)不懂 portal 的人,經(jīng)過項(xiàng)目中實(shí)戰(zhàn),不說成為高手,一般的概念、開發(fā)、配置、優(yōu)化等也都有了很多體會(huì)。

    這次技術(shù)上值得推薦的就是合理的使用 ajax ,既加快了首頁的 load 速度,又帶來了很好的用戶體驗(yàn)。開始首頁上所有 portlet 都是串行加載,有的 portlet 比如新郵件,依賴于 mail 系統(tǒng)提供的接口。開始這個(gè)接口在較大壓力下就出現(xiàn)性能瓶頸,后在我們的要求下替換了協(xié)議,性能也在 1s-2s 之間。如果采用常規(guī)的辦法,加上 wps 驗(yàn)證、運(yùn)算,顯示主題、皮膚,加載所有 portlet ,響應(yīng)時(shí)間肯定在 10s 以上。

    我在 openfans 中使用了 ajax ,有些經(jīng)驗(yàn),所以決定采用異步加載:首頁 load 時(shí)一些 portlet 直接顯示正在 loading 的字樣,在 body onload 時(shí)再使用 ajax 填充內(nèi)容;使用 iframe portlet ,也是 src 先指向一個(gè)靜態(tài)的正在 loading 頁面, body onload 時(shí)再替換 src 到實(shí)際地址(這是 ajax 模式的一種)。這樣首頁登錄實(shí)際上只經(jīng)過 wps 內(nèi)部的驗(yàn)證和顯示,所有業(yè)務(wù)邏輯都是加載成功后再并行進(jìn)行。實(shí)際表現(xiàn)效果就是:頭上的主題很快出來,一塊塊區(qū)域顯示正在 loading 字樣,性能快的 portlet 很快出來,需要幾秒的 portlet 隨后出來,而不是讓用戶傻等 10 s 再一下全部顯示。

    使用 ajax 同時(shí)也能解決頁面刷新問題和獲取返回值的問題。比如前面顯示新郵件的 portlet ,用戶點(diǎn)擊了一封郵件,新郵件數(shù)應(yīng)該減 1 ,剛點(diǎn)擊的郵件也應(yīng)該上頁面上消失。原始的做法就是刷新整個(gè)頁面,既加大服務(wù)器壓力,又帶來很差的用戶體驗(yàn)。使用 ajax ,在點(diǎn)擊后 1s (或者更長(zhǎng),這取決于郵件系統(tǒng)對(duì)點(diǎn)擊操作的響應(yīng)快慢)刷新 div 的內(nèi)容,用戶甚至感覺不到內(nèi)容已經(jīng)更新。其它 portlet 也不需要重新載入,大大減輕服務(wù)器的壓力。有的操作需要提交給其它系統(tǒng),而且可能成功可能失敗,這就需要獲得返回值。如果使用普通的 form 提交,需要更新整個(gè)頁面。而使用 ajax 提交,可以方便的獲得其返回值,進(jìn)而顯示不同的提示。

    另一個(gè)架構(gòu)上的特點(diǎn)就是 portal 服務(wù)器職責(zé)單一 。開始所有的業(yè)務(wù)邏輯都是寫在 portlet 里,加重了 portlet 服務(wù)器的壓力。我進(jìn)來后做的一個(gè)大的規(guī)劃就是,把業(yè)務(wù)邏輯抽離到其它 server 上,然后通過 ajax 加載到 portlet 中。這樣既可以充分利用服務(wù)器資源(新的 server 使用單獨(dú)的內(nèi)存空間和線程池),又使得 portal 服務(wù)器職責(zé)更單一:僅進(jìn)行驗(yàn)證、權(quán)限控制、主題、皮膚和 portlet 的展示。

    先寫這么多。因?yàn)槭褂昧?/span> 2 臺(tái) server 做集群,在分布式環(huán)境下,開發(fā)也有了更多的要求(比如 cache ),后一篇文章再細(xì)細(xì)道來。

    posted @ 2006-11-28 14:49 pesome 閱讀(3659) | 評(píng)論 (9)編輯 收藏

    程序之外

    難得有空,寫篇程序之外的文章,關(guān)于壓力的,也是自己近來的親身體會(huì)。

    眾所周知軟件這行壓力是很大的。各種各樣的問題層出不窮,每天上班工作內(nèi)容都是排的滿滿的,遇到突發(fā)問題就得加班。如果不及時(shí)進(jìn)行疏解,積累到一定的程度,就可能產(chǎn)生一定的負(fù)面問題,比如上班精神狀態(tài)差、注意力不能集中、遇事喜歡逃避等等。我就親身經(jīng)歷了這樣的狀況,明知自己工作積極性差、效率很低,但也很難一下子找回自我。

    一次偶然的出游讓我從中很快走了出來。一個(gè)親戚考上廈大的博士,我請(qǐng)了 2 天的假,利用周末時(shí)間順便去廈門旅游。廈門依山傍海,的確是旅游的好去處。晚上到海邊,涼風(fēng)習(xí)習(xí),光腳沿著沙灘走過,任起落的潮水在腿上腳上留下層層薄沙。內(nèi)心也變得平靜,能夠感受到海的呼吸。天地間仿佛只剩下我和大海,在進(jìn)行心靈的交流,俗世煩擾皆拋諸腦后,只剩下對(duì)海的依戀。白天去爬南普陀山,并不太高,慢慢爬到山頂,整個(gè)思明區(qū)盡收眼底,遠(yuǎn)處一艘快艇在海面掠過,留下一條美麗的浪花。然后順山而下到植物園,途徑無數(shù)奇花異草、層天老樹,走得累了,找個(gè)湖邊石凳休息一下,人也覺得輕松愉快。

    經(jīng)過大自然的洗禮,回到單位,人的精神面貌煥然一新,抱著積極的心態(tài)處理事情,很多問題迎刃而解。壓力測(cè)試做的很累,經(jīng)常要熬夜,但通過一輪輪的測(cè)試,逐步定位到性能問題所在,自己也學(xué)了不少相關(guān)知識(shí),想想也就沒那么煩了。

    做事的方式,也有了長(zhǎng)進(jìn)。我現(xiàn)在信奉人一時(shí)只做一件事效率最高的原則。事情再多,也是一件件做,每天安排好近日的工作,并排個(gè)優(yōu)先級(jí),什么是要親自處理的,什么是讓別人處理的,什么是需要預(yù)先通知他人的,需要什么資源,每件事情的預(yù)計(jì)時(shí)間如何,需要如何 check 等等。做好一件事就打個(gè)勾,做到心中有數(shù)。如果事情有延誤,分析是什么原因,該如何補(bǔ)救,而不要有太大的心理負(fù)擔(dān),自己盡力了就好,是自己的責(zé)任就要勇敢扛下,死不了人的。這其實(shí)是很簡(jiǎn)單的原則,誰都能夠?qū)W會(huì),但的確很管用。

    總結(jié):壓力是無處不在的,關(guān)鍵在于如何應(yīng)對(duì)和排解。用積極的心態(tài)和恰當(dāng)?shù)姆椒鎸?duì),壓力也就沒那么大了。感覺壓力積累到一定程度,在還未影響正常工作之前就先想辦法排解,出去旅游、運(yùn)動(dòng)等都是緩解壓力的好辦法。

    posted @ 2006-11-06 22:27 pesome 閱讀(1169) | 評(píng)論 (2)編輯 收藏

    關(guān)于代碼的一些比喻

    最近對(duì)項(xiàng)目組的一些較差的代碼進(jìn)行了些重構(gòu),同時(shí)靈光一閃,對(duì)代碼有些比較形象的比喻。

    壞的代碼就象揉面團(tuán),管什么接口什么實(shí)現(xiàn)全揉成一團(tuán),一個(gè)方法幾百行,注釋寫再多也是面團(tuán)(夾了些小紙條而已)。然后需要重用了,就是從中抓起一把面團(tuán),然后放到其它的面團(tuán)里繼續(xù)揉。這樣重復(fù)代碼一堆,什么易讀性、擴(kuò)展性、可維護(hù)性都是無從談起。

    好的代碼就象堆積木,接口實(shí)現(xiàn)定義清清楚楚,每個(gè)接口只做一件事情,重復(fù)代碼都是通過更細(xì)的接口來消除。重用就是把積木塊往該放的地方堆,這樣的代碼,幾個(gè)大塊幾個(gè)小塊一目了然,只要方法命名規(guī)范,連注釋都可以省去。這樣耦合性低,易讀性、擴(kuò)展性、可維護(hù)性都可以得到保證。

    把面團(tuán)變成積木并不復(fù)雜,定義好模具,面團(tuán)一團(tuán)團(tuán)往里面填充,待穩(wěn)定下來,就成了一塊塊積木。這里關(guān)鍵就是模具的制作,推薦制作寶典: martin fowler 的那本重構(gòu)。還得有模具的丈量工具,就非 junit 莫屬了。

    posted @ 2006-10-30 17:42 pesome 閱讀(1473) | 評(píng)論 (0)編輯 收藏

    數(shù)據(jù)庫同步trigger的記錄

    ??? 項(xiàng)目需要寫了幾個(gè)數(shù)據(jù)庫同步用的 trigger ,就是記錄用戶的操作到一個(gè) temp 表,然后每天通過 webservice 同步到其它系統(tǒng),同步成功清空該 temp 表。自認(rèn)為寫的還行,做個(gè)記錄。是 db2 的。

    ?

    -- 用戶組新增觸發(fā)器

    --DROP TRIGGER TG_USERG;

    CREATE TRIGGER LIBING.TG_USERG AFTER INSERT ON LIBING.TM_USERG

    ? REFERENCING NEW AS NROW

    ? FOR EACH ROW

    ? MODE DB2SQL??

    ? BEGIN ATOMIC

    ?

    ? declare @groupId integer;

    ? declare @name varchar(30);

    ? declare @descn varchar(100);

    ? declare @syntype varchar(4);

    ? declare @ddlsql varchar(1024);

    ? declare @isprimary char(1);

    ? declare @updateTime timestamp;

    ? declare @createTime timestamp;

    ? declare @createBy integer;

    ? declare @updateBy integer;

    ? declare @groupType integer;

    ? declare @adminType integer;

    ? declare @appId integer;

    ?

    ? declare @oldGroupId integer;

    ?

    ? set @groupId=NROW.GROUP_ID;

    ? set @name=NROW.name;

    ? set @descn=NROW.descn;

    ? set @syntype=NROW.syn_type;

    ? set @ddlsql=NROW.ddlsql;

    ? set @isprimary=NROW.isprimary;

    ? set @updateTime=NROW.update_time;

    ? set @createTime=NROW.create_time;

    ? set @createBy=NROW.create_by;

    ? set @updateBy=NROW.update_by;

    ? set @groupType=NROW.group_type;

    ? set @adminType=NROW.admin_type;

    ? set @appId=NROW.app_id;

    ?

    ? INSERT INTO TM_USERG_TEMP(GROUP_ID,NAME,DESCN,DDLSQL,ISPRIMARY,UPDATE_TIME,CREATE_TIME,

    ? ?????????? ?CREATE_BY,UPDATE_BY,GROUP_TYPE,ADMIN_TYPE,APP_ID,ACTION) VALUES (@groupId,@name,@descn,

    ????????????? ?@ddlsql,@isprimary,@updateTime,@createTime,@createBy,@updateBy,@groupType,@adminType,@appId,'INSERT');

    ? END;

    ?

    ? -- 更新用戶組數(shù)據(jù)的觸發(fā)器

    ?-- DROP TRIGGER TG_USERG_UPDATE;

    ? CREATE TRIGGER TG_USERG_UPDATE AFTER UPDATE ON TM_USERG

    ? ?????????? ?REFERENCING NEW AS NROW

    ????????????? ?FOR EACH ROW

    ????????????? ?MODE DB2SQL

    ????????????? ?BEGIN ATOMIC

    ????????????? ?

    ????????????? ?declare @groupId integer;

    ? ?????????? ?declare @name varchar(30);

    ? ?????????? ?declare @descn varchar(100);

    ? ?????????? ?declare @syntype varchar(4);

    ? ?????????? ?declare @ddlsql varchar(1024);

    ? ?????????? ?declare @isprimary char(1);

    ? ?????????? ?declare @updateTime timestamp;

    ? ?????????? ?declare @createTime timestamp;

    ? ?????????? ?declare @createBy integer;

    ? ?????????? ?declare @updateBy integer;

    ? ?????????? ?declare @groupType integer;

    ? ?????????? ?declare @adminType integer;

    ? ?????????? ?declare @appId integer;

    ????????????? ?

    ????????????? ?set @groupId=NROW.GROUP_ID;

    ? ?????????? ?set @name=NROW.name;

    ? ?????????? ?set @descn=NROW.descn;

    ? ?????????? ?set @syntype=NROW.syn_type;

    ? ?????????? ?set @ddlsql=NROW.ddlsql;

    ? ?????????? ?set @isprimary=NROW.isprimary;

    ? ?????????? ?set @updateTime=NROW.update_time;

    ? ?????????? ?set @createTime=NROW.create_time;

    ? ?????????? ?set @createBy=NROW.create_by;

    ? ?????????? ?set @updateBy=NROW.update_by;

    ? ?????????? ?set @groupType=NROW.group_type;

    ? ?????????? ?set @adminType=NROW.admin_type;

    ? ?????????? ?set @appId=NROW.app_id;

    ????????????? ?

    ????????????? ?-- 如果已經(jīng)有 update 則只記錄最后一條 update

    ????????????? ?IF EXISTS(SELECT GROUP_ID FROM TM_USERG_TEMP WHERE GROUP_ID=@groupId AND ACTION='UPDATE') THEN

    ????????????? ? ???? UPDATE TM_USERG_TEMP SET GROUP_ID=@groupId,

    ????????????? ? ???? ? ??????????? NAME=@name,DESCN=@descn,DDLSQL=@ddlsql,

    ?????????????????????????????????? ISPRIMARY=@isprimary,UPDATE_TIME=@updateTime,

    ?????????????????????????????????? CREATE_TIME=@createTime,CREATE_BY=@createBy,

    ?????????????????????????????????? UPDATE_BY=@updateBy,GROUP_TYPE=@groupType,

    ?????????????????????????????????? ADMIN_TYPE=@adminType,APP_ID=@appId,ACTION='UPDATE'

    ?????????????????????????????????? where GROUP_ID=@groupId AND ACTION='UPDATE';

    ????????????? ?-- 如果有 insert 則把后面的 update 當(dāng)作 insert

    ????????????? ELSEIF? EXISTS(SELECT GROUP_ID FROM TM_USERG_TEMP WHERE GROUP_ID=@groupId AND ACTION='INSERT') THEN

    ???????????????????? UPDATE TM_USERG_TEMP SET GROUP_ID=@groupId,

    ????????????? ? ???? ? ??????????? NAME=@name,DESCN=@descn,DDLSQL=@ddlsql,

    ?????????????????????????????????? ISPRIMARY=@isprimary,UPDATE_TIME=@updateTime,

    ?????????????????????????????????? CREATE_TIME=@createTime,CREATE_BY=@createBy,

    ?????????????????????????????????? UPDATE_BY=@updateBy,GROUP_TYPE=@groupType,

    ?????????????????????????????????? ADMIN_TYPE=@adminType,APP_ID=@appId,ACTION='INSERT'

    ?????????????????????????????????? where GROUP_ID=@groupId AND ACTION='INSERT';

    ????????????? ELSE????? INSERT INTO TM_USERG_TEMP(GROUP_ID,NAME,DESCN,DDLSQL,ISPRIMARY,UPDATE_TIME,CREATE_TIME,

    ? ?????????? ? ??????????? ???CREATE_BY,UPDATE_BY,GROUP_TYPE,ADMIN_TYPE,APP_ID,ACTION) VALUES (@groupId,@name,@descn,

    ????????????? ? ??????????? ?? @ddlsql,@isprimary,@updateTime,@createTime,@createBy,@updateBy,@groupType,@adminType,@appId,'UPDATE');

    ????????????? end if;

    ????????????? ?END;??????????

    ?

    ?

    -- 刪除用戶組觸發(fā)器

    --DROP TRIGGER TG_USERG_DELETE;

    CREATE TRIGGER TG_USERG_DELETE AFTER DELETE ON TM_USERG

    ?????? ? REFERENCING OLD AS OROW

    ?????? ? FOR EACH ROW

    ?????? ? MODE DB2SQL

    ?????? ? BEGIN ATOMIC

    ?????? ?

    ?????? ? declare @groupId integer;

    ? ??? ??declare @name varchar(30);

    ? ??? ??declare @descn varchar(100);

    ? ??? ??declare @syntype varchar(4);

    ? ??? ??declare @ddlsql varchar(1024);

    ? ??? ??declare @isprimary char(1);

    ? ??? ??declare @updateTime timestamp;

    ? ??? ??declare @createTime timestamp;

    ? ??? ??declare @createBy integer;

    ? ??? ??declare @updateBy integer;

    ? ??? ??declare @groupType integer;

    ? ??? ??declare @adminType integer;

    ? ??? ??declare @appId integer;

    ????????????? ?

    ?????? ? set @groupId=OROW.GROUP_ID;

    ? ??? ??set @name=OROW.name;

    ? ??? ??set @descn=OROW.descn;

    ? ??? ??set @syntype=OROW.syn_type;

    ? ??? ??set @ddlsql=OROW.ddlsql;

    ? ??? ??set @isprimary=OROW.isprimary;

    ? ??? ??set @updateTime=OROW.update_time;

    ? ??? ??set @createTime=OROW.create_time;

    ? ??? ??set @createBy=OROW.create_by;

    ? ??? ??set @updateBy=OROW.update_by;

    ? ??? ??set @groupType=OROW.group_type;

    ? ??? ??set @adminType=OROW.admin_type;

    ? ??? ??set @appId=OROW.app_id;

    ?????? ?

    ?????? ?? -- 如果沒有操作記錄,則插入 delete 記錄

    ?????? ?? IF NOT EXISTS(SELECT GROUP_ID FROM TM_USERG_TEMP WHERE GROUP_ID=@groupId) THEN

    ?????? ?? ? ??INSERT INTO TM_USERG_TEMP(GROUP_ID,NAME,DESCN,DDLSQL,ISPRIMARY,UPDATE_TIME,CREATE_TIME,

    ? ?????????? ?CREATE_BY,UPDATE_BY,GROUP_TYPE,ADMIN_TYPE,APP_ID,ACTION) VALUES (@groupId,@name,@descn,

    ????????????? ?@ddlsql,@isprimary,@updateTime,@createTime,@createBy,@updateBy,@groupType,@adminType,@appId,'DELETE');

    ????????????? ?

    ????????????? ?-- 如果有 insert 記錄,則整體結(jié)果相當(dāng)于沒有進(jìn)行任何操作

    ????????????? ?ELSEIF EXISTS(SELECT GROUP_ID FROM TM_USERG_TEMP WHERE GROUP_ID=@groupId and ACTION='INSERT') THEN

    ????????????? ? ??????????? DELETE FROM TM_USERG_TEMP WHERE GROUP_ID=@groupId and ACTION='INSERT';

    ????????????? ?-- 如果沒有 insert 記錄,則只需記錄最后的 delete 操作

    ????????????? ?ELSE

    ????????????? ? ???? ? UPDATE TM_USERG_TEMP set ACTION='DELETE' where GROUP_ID=@groupId;

    ?????? ?? END IF;

    ?????? ??

    ?????? ?? END;

    posted @ 2006-10-30 17:06 pesome 閱讀(1412) | 評(píng)論 (0)編輯 收藏

    <2006年10月>
    24252627282930
    1234567
    891011121314
    15161718192021
    22232425262728
    2930311234

    導(dǎo)航

    統(tǒng)計(jì)

    公告

    主要記錄作者在學(xué)習(xí)java中的每一步足跡。除非特別說明,所有文章均為本blog作者原創(chuàng),如需轉(zhuǎn)載請(qǐng)注明出處和原作者,如用于商業(yè)目的,需跟作者本人聯(lián)系。
    歡迎大家訪問:

    常用鏈接

    留言簿(16)

    隨筆分類

    隨筆檔案

    文章分類

    文章檔案

    相冊(cè)

    收藏夾

    java技術(shù)

    人間百態(tài)

    朋友們的blog

    搜索

    最新評(píng)論

    閱讀排行榜

    評(píng)論排行榜

    主站蜘蛛池模板: 国产免费内射又粗又爽密桃视频 | 久久免费精品一区二区| 免费观看亚洲人成网站| 国产精品亚洲色婷婷99久久精品| 成人人免费夜夜视频观看| jlzzjlzz亚洲jzjzjz| 久久不见久久见中文字幕免费 | 亚洲国产午夜中文字幕精品黄网站| 亚洲av片在线观看| 免费又黄又爽又猛的毛片| 有色视频在线观看免费高清在线直播| 亚洲国产成人精品91久久久| 一区二区三区免费高清视频| 亚洲日韩v无码中文字幕| 久久久久久免费一区二区三区| 亚洲综合婷婷久久| 成视频年人黄网站免费视频| 亚洲精品9999久久久久无码| 国产亚洲精品国看不卡| 99ee6热久久免费精品6| 亚洲中文字幕无码中文| 免费在线精品视频| 秋霞人成在线观看免费视频| www.亚洲成在线| 亚洲国产91精品无码专区| 日本免费在线观看| 亚洲首页国产精品丝袜| 免费少妇a级毛片| 久久久高清日本道免费观看| 亚洲精品色播一区二区| 亚洲综合AV在线在线播放| 亚洲免费在线视频观看| 深夜福利在线免费观看| 亚洲美女色在线欧洲美女| 国产在线观看免费完整版中文版 | 国产精品九九久久免费视频 | 亚洲A∨精品一区二区三区| 久久免费观看国产精品88av| 亚洲av永久无码天堂网| 国产AV无码专区亚洲AV毛网站| 女人被男人桶得好爽免费视频|