一個程序員多年的收藏

文章分類:Java編程
程序員珍藏的東西會是什麼?呵呵,除了平時寫的代碼,就是那些百看不厭的電子書了。 

昨天很鬱悶,我用了5年的移動硬盤,莫名奇妙的壞掉了。裏面40G的資料所有報銷了。 
爲了避免再重蹈覆轍,我決定把重要的電子書都放到網絡硬盤上去備份。索性將這些資料的下載方式公佈出來,與你們分享,必定會有你想要的! 

下載的兄弟注意了,點擊下載後,能夠在url中看到後綴名:),若是把後綴名改錯了就看不了了,全部的資料都有人下載過了,應該都能看。


Python相關的資料還能夠看:http://jythoner.javaeye.com/blog/569987



新書區 

Python源碼剖析: 下載文件 Python源碼剖析.chm (670.21 KB)

Python黑客: 下載文件 Gray Hat Python Python Programming for Hackers and Reverse Engineers.pdf (3.30 MB)

上一本書的源碼: 下載文件 ghpython_src.zip (606.56 KB)

php5手冊: 下載文件 php5手冊.chm (5.70 MB)

Google Adsense的祕密: 下載文件 《Google Adsense的祕密》中文版.pdf (905.51 KB)

《Google_Cash》快速致富手冊,主要講如何利用Google Adwords網賺: 下載文件 《Google_Cash》快速致富手冊.pdf (2.23 MB)

Google cash補充,Day job killer中文版: 下載文件 跟打工生涯說再見.pdf (749.96 KB)

Java 

Java API 1.6中文版: 下載文件 JDK API 1.6.0 zh_CN.CHM (35.12 MB)

下載文件 《java編程思想》第三版 第四版包括習題答案(8.92 MB) 

下載文件 Java Collections.pdf (1.33 MB)

下載文件 Java_Collections-src.zip (150.21 KB)

下載文件 Java IO.chm (2.76 MB)

下載文件 Java NIO.pdf (1.40 MB)

下載文件 IO.gif (36.00 KB)

下載文件 JDBC Recipes A Problem Solution Approach.pdf (5.23 MB)

下載文件 Java Network Programming.chm (1.97 MB)

下載文件 Servlets and JavaServer Pages The J2EE Tier.pdf (4.73 MB)

英文版: 下載文件 Java.Threads.3rd.Edition.chm (685.45 KB)

中文版: 下載文件 java線程.pdf (20.26 MB)

Java與模式絕對高清版: 下載文件 Java與模式.pdf (39.64 MB)

爲何要看上面的那些書?請看我之前 的 帖子:Java 推薦讀物與源代碼閱讀: http://jythoner.javaeye.com/blog/311434

Java程序員必備的書籍,比API更有用: 下載文件 The Java Developers Almanac 1.4.chm (679.90 KB)

找工做必備: 下載文件 125條常見的java面試筆試題大彙總.pdf (95.17 KB)

一本Java實現的數據結構書籍: 下載文件 Java數據結構與算法.pdf (25.35 MB)

學Struts,Hibernate,Spring,若是不懂反射的原理,就不用談了: 下載文件 Java Reflection In Action.pdf (1.70 MB)

JMX,Jboss的基礎,jdk5後被歸入進來: 下載文件 JMX In Action.pdf (4.76 MB)

Junit絕對經典書籍: 下載文件 Junit in action.pdf (15.64 MB)

一本專門講jdk1.5新特性的書,英文版: 下載文件 Java 1.5 Tiger A Developer's Notebook.chm(411.57 KB)

中文版: 下載文件 Java 1.5 Tiger A Developer's Notebook.pdf (7.23 MB)

源代碼: 下載文件 Java 1.5 Tiger A Developer's Notebook.zip (38.18 KB)

下載文件 Java極限編程.pdf (23.96 MB)

下載文件 uml distilled.chm (1.52 MB)

下載文件 Expert One-on-One J2EE Design and Development.chm (10.66 MB)

下載文件 測試驅動開發.pdf (6.89 MB)

若是不知道上面4本書的做者,那麼基本上你的Java算白學了 

Ant手冊: 下載文件 Apache Ant Manual 1.7.chm (949.48 KB)

英文版: 下載文件 UML for Java Programmers.pdf (1.77 MB)

中文版: 下載文件 UML for Java Programmers中文版.pdf (2.51 MB)

源代碼: 下載文件 UML for Java Programmers.rar (465.36 KB)

下載文件 Java實用系統開發指南.pdf (57.82 MB)

下載文件 JAVA優化編程.pdf (13.58 MB)

下載文件 Java and XML(英文第三版).chm (3.79 MB)

下載文件 Apress.Pro.XML.Development.with.Java.Technology.pdf (12.83 MB)



Eclipse插件開發 

一個高手推薦的4本必讀書: 

中文版: 下載文件 Contributing to Eclipse Principles, Patterns and PlugIns.pdf (23.29 MB)

英文版: 下載文件 Contributing to Eclipse Principles, Patt ... (4.93 MB)

下載文件 Eclipse Building Commercial-Quality Plug-ins.chm (20.11 MB)

下載文件 Eclipse Modeling Framework.chm (3.20 MB)

下載文件 Eclipse Rich Client Platform Designing Coding and Packaging Java Applications.chm(4.90 MB)

下載文件 SWT-A Developer's Note Book.chm (1.53 MB)

API: 下載文件 swt jface API.pdf (7.59 MB)


Linux 

中國Linuxer應該沒人不知道鳥哥,這本書是基礎版與網絡版的合集: 下載文件 鳥哥的Linux私房菜.pdf (36.43 MB)

命令大全,支持查找: 下載文件 Linux命令大全(修改版).chm (345.84 KB)

無心間發現的,裏面記載了不少實用的命令: 下載文件 Unix Toolbox.pdf (350.31 KB)

學習shell編程必讀,裏面包括一份詳細的學習筆記: 下載文件 LINUX與UNIX SHELL編程指南.zip (19.22 MB)

Sed和Awk惟一的書: 下載文件 Sed and Awk.pdf 中文版(6.89 MB)

下載文件 AWK單行腳本快速參考.doc (52.50 KB)

下載文件 SED單行腳本快速參考.doc (91.00 KB)

一張RE圖表: 下載文件 regular-expressions-cheat-sheet-v2.pdf (647.55 KB)

Linux+認證書籍: 下載文件 McGraw.Hill.Linux.plus.Certification.Study Guide.pdf (28.60 MB)

下載文件 O'Reilly.Bash.Cookbook.pdf (3.16 MB)

下載文件 A Practical Guide to Linux Commands, Edi ... (3.61 MB)



Oracle 


Oracle9i OCP官方培訓教程: 
下載文件 sql.zip (3.34 MB)

下載文件 dba1.zip (1.78 MB)

下載文件 dba2.zip (2.95 MB)

下載文件 Perf.zip (6.90 MB)

Oracle 10教程: 
下載文件 Oracle.Database.10g.Administration.Workshop.II.Student.Guide.pdf (4.74 MB)

下載文件 Oracle.Database.10g.Administration.Workshop.I.Student.Guide.pdf (5.66 MB)

下載文件 Sybex.OCA.Oracle.10g.Administration.I.Study.Guide.pdf (18.20 MB)

下載文件 Sybex.OCP.Oracle.10g.Administration.II.Study.Guide.pdf (15.39 MB)

Oracle 11g官方培訓教程: 
下載文件 d49996gc10_ppt Oracle Database 11g SQL Fundamentals I.rar (2.26 MB)

下載文件 d49994gc10_ppt Oracle Database 11g SQL Fundamentals II.rar (1.78 MB)

下載文件 d50102gc10_ppt Oracle Database 11g Administration Workshop I.rar (11.00 MB)

下載文件 d50079gc10_ppt Oracle Database 11g Administration Workshop II.rar (6.31 MB)

下載文件 d50317gc10_ppt Oracle Database 11g Performance Tuning.rar (3.63 MB)

英文版: 下載文件 d50081gc10_ppt Oracle Database 11g New Features for Administrators.rar(6.64 MB)

中文版: 下載文件 d50081cn11_ppt Oracle Database 11g - New Features for Administrators.rar (6.58 MB)



下載文件 d46592gc11_ppt Oracle Database 10g Managing Oracle on Linux for System Administrators.rar (1.25 MB) 

下載文件 d50311gc10_ppt Oracle Database 11g RAC Administration.rar (7.80 MB)



下載文件 Oracle Database 10g.chm (2.43 MB)

下載文件 ORACLE.10G入門與實踐.pdf (39.58 MB)

下載文件 Oracle.Database.10g實用培訓教程.pdf (47.49 MB)

下載文件 精通ORACLE.10G備份與恢復.pdf (23.90 MB)



Python 
BASIC: 

A Byte of Python(Python 3.0)  下載文件 A Byte of Python.pdf (564.61 KB) 

A Byte of Python中文版  下載文件 Python簡明教程.pdf (784.85 KB) 

下載文件 Dive into Python.zip (763.71 KB)

下載文件 Dive into Python 中文版.zip (3.51 MB)

下載文件 Python Essential Reference 4th Edition.pdf (4.80 MB)

下載文件 Python精要參考.pdf (678.65 KB)

下載文件 Learning Python.pdf (4.80 MB)

下載文件 Core Python Programming 2nd Edition.chm (3.45 MB)

高清完整版  下載文件 Python核心編程第二版.pdf (5.16 MB) 

下載文件 Python Standard Library.chm (355.63 KB)

下載文件 Python Standard Library中文版.pdf (1.00 MB)

下載文件 Python Cookbook.chm (1.00 MB)

下載文件 Python Cookbook Collection.chm (2.53 MB)

Guido 2007年Python大會ppt,關於python3.0新特性  下載文件 Py3k2007PyCon.ppt (134.00 KB) 



GUI: 

下載文件 wxPython In Action.rar (9.24 MB)

wxPython in Action中文版  下載文件 wxPython實戰(中文版).pdf (3.54 MB) 

下載文件 wxPythonInAction_src.zip (333.41 KB)



WEB: 

Django Book 收費版 下載文件 The Definitive Guide to Django 2nd Edition.pdf (5.92 MB)

下載文件 Practical Django Projects 2nd Edition.pdf (4.89 MB)



GAE: 

下載文件 Google App Engine 入門.pdf (227.23 KB)

下載文件 Google App Engine 開發人員指南.pdf (855.70 KB)

下載文件 Using Google App Engine.pdf (3.20 MB)

下載文件 Developing With Google App Engine.pdf (3.35 MB)



Other: 

下載文件 Twisted Network Programming Essentials Python.chm (1.24 MB)

下載文件 Python for Unix and Linux System Administration.pdf (3.41 MB)

下載文件 Text Processing in Python.chm (871.68 KB)

下載文件 Python Programming on Win32.chm (2.10 MB)

下載文件 Jython for Java Programmers.chm (713.20 KB)



English 


下載文件 古典 1677超核心詞表.pdf (1.34 MB)

下載文件 古典 1677超核心詞表.rm (3.41 MB)

下載文件 新東方李玉技老師的734條高頻詞組.pdf (77.00 KB)

下載文件 英語經常使用短語詞典.chm (2.31 MB)



Perl 

下載文件 Perl Cook Book.pdf (9.22 MB)

英文版: 下載文件 Learning.Perl.4ed.En.chm (699.96 KB)

中文版: 下載文件 Learning.Perl.4ed.Cn.pdf (1.19 MB)

一本講用perl進行automation測試的好書: 下載文件 Perl Testing.chm (640.57 KB)



Other 


下載文件 Agile Web Development with Rails 3rdEdition.pdf (10.87 MB)

譚浩強那本: 下載文件 C語言程序設計.pdf (9.95 MB)

下載文件 C語言趣味編程百例.pdf (4.72 MB)

下載文件 數據庫系統概論(第三版).pdf (10.16 MB)

下載文件 php5手冊.chm (5.70 MB)

精通正則表達式: 下載文件 Mastering Regular Expressions.chm (1.45 MB)
程序員珍藏的東西會是什麼?呵呵,除了平時寫的代碼,就是那些百看不厭的電子書了。 

昨天很鬱悶,我用了5年的移動硬盤,莫名奇妙的壞掉了。裏面40G的資料所有報銷了。 
爲了避免再重蹈覆轍,我決定把重要的電子書都放到網絡硬盤上去備份。索性將這些資料的下載方式公佈出來,與你們分享,必定會有你想要的! 

Java Linux Oracle Perl相關的資料請看:http://jythoner.javaeye.com/blog/570792

BASIC: 

A Byte of Python(Python 3.0)  下載文件 A Byte of Python.pdf (564.61 KB) 

A Byte of Python中文版  下載文件 Python簡明教程.pdf (784.85 KB) 

下載文件 Dive into Python.zip (763.71 KB)

下載文件 Dive into Python 中文版.zip (3.51 MB)

下載文件 Python Essential Reference 4th Edition.pdf (4.80 MB)

下載文件 Python精要參考.pdf (678.65 KB)

下載文件 Learning Python.pdf (4.80 MB)

下載文件 Core Python Programming 2nd Edition.chm (3.45 MB)

高清完整版  下載文件 Python核心編程第二版.pdf (5.16 MB) 

下載文件 Python Standard Library.chm (355.63 KB)

下載文件 Python Standard Library中文版.pdf (1.00 MB)

下載文件 Python Cookbook.chm (1.00 MB)

下載文件 Python Cookbook Collection.chm (2.53 MB)

Guido 2007年Python大會ppt,關於python3.0新特性  下載文件 Py3k2007PyCon.ppt (134.00 KB) 



GUI: 

下載文件 wxPython In Action.rar (9.24 MB)

wxPython in Action中文版  下載文件 wxPython實戰(中文版).pdf (3.54 MB) 

下載文件 wxPythonInAction_src.zip (333.41 KB)



WEB: 

Django Book 收費版 下載文件 The Definitive Guide to Django 2nd Edition.pdf (5.92 MB)

下載文件 Practical Django Projects 2nd Edition.pdf (4.89 MB)



GAE: 

下載文件 Google App Engine 入門.pdf (227.23 KB)

下載文件 Google App Engine 開發人員指南.pdf (855.70 KB)

下載文件 Using Google App Engine.pdf (3.20 MB)

下載文件 Developing With Google App Engine.pdf (3.35 MB)



Other: 

下載文件 Twisted Network Programming Essentials Python.chm (1.24 MB)

下載文件 Python for Unix and Linux System Administration.pdf (3.41 MB)

下載文件 Text Processing in Python.chm (871.68 KB)

下載文件 Python Programming on Win32.chm (2.10 MB)

下載文件 Jython for Java Programmers.chm (713.20 KB)
一、HTML靜態化其實你們都知道,效率最高、消耗最小的就是純靜態化的html頁面,因此咱們儘量使咱們的網站上的頁面採用靜態頁面來實現,這個最簡單的方法其實也是最有效的方法。可是對於大量內容而且頻繁更新的網站,咱們沒法所有手動去挨個實現,因而出現了咱們常見的信息發佈系統CMS,像咱們常訪問的各個門戶站點的新聞頻道,甚至他們的其餘頻道,都是經過信息發佈系統來管理和實現的,信息發佈系統能夠實現最簡單的信息錄入自動生成靜態頁面,還能具有頻道管理、權限管理、自動抓取等功能,對於一個大型網站來講,擁有一套高效、可管理的CMS是必不可少的。除了門戶和信息發佈類型的網站,對於交互性要求很高的社區類型網站來講,儘量的靜態化也是提升性能的必要手段,將社區內的帖子、文章進行實時的靜態化,有更新的時候再從新靜態化也是大量使用的策略,像Mop的大雜燴就是使用了這樣的策略,網易社區等也是如此。同時,html靜態化也是某些緩存策略使用的手段,對於系統中頻繁使用數據庫查詢可是內容更新很小的應用,能夠考慮使用html靜態化來實現,好比論壇中論壇的公用設置信息,這些信息目前的主流論壇均可以進行後臺管理而且存儲再數據庫中,這些信息其實大量被前臺程序調用,可是更新頻率很小,能夠考慮將這部份內容進行後臺更新的時候進行靜態化,這樣避免了大量的數據庫訪問請求。
二、圖片服務器分離你們知道,對於Web服務器來講,無論是Apache、IIS仍是其餘容器,圖片是最消耗資源的,因而咱們有必要將圖片與頁面進行分離,這是基本上大型網站都會採用的策略,他們都有獨立的圖片服務器,甚至不少臺圖片服務器。這樣的架構能夠下降提供頁面訪問請求的服務器系統壓力,而且能夠保證系統不會由於圖片問題而崩潰,在應用服務器和圖片服務器上,能夠進行不一樣的配置優化,好比apache在配置ContentType的時候能夠儘可能少支持,儘量少的LoadModule,保證更高的系統消耗和執行效率。

三、數據庫集羣和庫表散列大型網站都有複雜的應用,這些應用必須使用數據庫,那麼在面對大量訪問的時候,數據庫的瓶頸很快就能顯現出來,這時一臺數據庫將很快沒法知足應用,因而咱們須要使用數據庫集羣或者庫表散列。在數據庫集羣方面,不少數據庫都有本身的解決方案,Oracle、Sybase等都有很好的方案,經常使用的MySQL提供的Master/Slave也是相似的方案,您使用了什麼樣的DB,就參考相應的解決方案來實施便可。上面提到的數據庫集羣因爲在架構、成本、擴張性方面都會受到所採用DB類型的限制,因而咱們須要從應用程序的角度來考慮改善系統架構,庫表散列是經常使用而且最有效的解決方案。咱們在應用程序中安裝業務和應用或者功能模塊將數據庫進行分離,不一樣的模塊對應不一樣的數據庫或者表,再按照必定的策略對某個頁面或者功能進行更小的數據庫散列,好比用戶表,按照用戶ID進行表散列,這樣就可以低成本的提高系統的性能而且有很好的擴展性。sohu的論壇就是採用了這樣的架構,將論壇的用戶、設置、帖子等信息進行數據庫分離,而後對帖子、用戶按照板塊和ID進行散列數據庫和表,最終能夠在配置文件中進行簡單的配置便能讓系統隨時增長一臺低成本的數據庫進來補充系統性能。

四、緩存緩存一詞搞技術的都接觸過,不少地方用到緩存。網站架構和網站開發中的緩存也是很是重要。這裏先講述最基本的兩種緩存。高級和分佈式的緩存在後面講述。架構方面的緩存,對Apache比較熟悉的人都能知道Apache提供了本身的緩存模塊,也能夠使用外加的Squid模塊進行緩存,這兩種方式都可以有效的提升Apache的訪問響應能力。網站程序開發方面的緩存,Linux上提供的Memory Cache是經常使用的緩存接口,能夠在web開發中使用,好比用Java開發的時候就能夠調用MemoryCache對一些數據進行緩存和通信共享,一些大型社區使用了這樣的架構。另外,在使用web語言開發的時候,各類語言基本都有本身的緩存模塊和方法,PHP有Pear的Cache模塊,Java就更多了,.net不是很熟悉,相信也確定有。

五、鏡像鏡像是大型網站常採用的提升性能和數據安全性的方式,鏡像的技術能夠解決不一樣網絡接入商和地域帶來的用戶訪問速度差別,好比 ChinaNet和EduNet之間的差別就促使了不少網站在教育網內搭建鏡像站點,數據進行定時更新或者實時更新。在鏡像的細節技術方面,這裏不闡述太深,有不少專業的現成的解決架構和產品可選。也有廉價的經過軟件實現的思路,好比Linux上的rsync等工具。
六、負載均衡負載均衡將是大型網站解決高負荷訪問和大量併發請求採用的終極解決辦法。負載均衡技術發展了多年,有不少專業的服務提供商和產品能夠選擇,我我的接觸過一些解決方法,其中有兩個架構能夠給你們作參考。

七、硬件四層交換第四層交換使用第三層和第四層信息包的報頭信息,根據應用區間識別業務流,將整個區間段的業務流分配到合適的應用服務器進行處理。 第四層交換功能就象是虛 IP,指向物理服務器。它傳輸的業務服從的協議多種多樣,有HTTP、FTP、NFS、Telnet或其餘協議。這些業務在物理服務器基礎上,須要複雜的載量平衡算法。在IP世界,業務類型由終端TCP或UDP端口地址來決定,在第四層交換中的應用區間則由源端和終端IP地址、TCP和UDP端口共同決定。在硬件四層交換產品領域,有一些知名的產品能夠選擇,好比Alteon、F5等,這些產品很昂貴,可是物有所值,可以提供很是優秀的性能和很靈活的管理能力。Yahoo中國當初接近2000臺服務器使用了三四臺Alteon就搞定了

。八、軟件四層交換你們知道了硬件四層交換機的原理後,基於OSI模型來實現的軟件四層交換也就應運而生,這樣的解決方案實現的原理一致,不過性能稍差。可是知足必定量的壓力仍是遊刃有餘的,有人說軟件實現方式其實更靈活,處理能力徹底看你配置的熟悉能力。軟件四層交換咱們能夠使用Linux上經常使用的LVS來解決,LVS就是Linux Virtual Server,他提供了基於心跳線heartbeat的實時災難應對解決方案,提升系統的魯棒性,同時可供了靈活的虛擬VIP配置和管理功能,能夠同時知足多種應用需求,這對於分佈式的系統來講必不可少。一個典型的使用負載均衡的策略就是,在軟件或者硬件四層交換的基礎上搭建squid集羣,這種思路在不少大型網站包括搜索引擎上被採用,這樣的架構低成本、高性能還有很強的擴張性,隨時往架構裏面增減節點都很是容易。這樣的架構我準備空了專門詳細整理一下和你們探討。對於大型網站來講,前面提到的每一個方法可能都會被同時使用到,我這裏介紹得比較淺顯,具體實現過程當中不少細節還須要你們慢慢熟悉和體會,有時一個很小的squid參數或者apache參數設置,對於系統性能的影響就會很大,但願你們一塊兒討論,達到拋磚引玉之效。


用squid作web cache server,而apache在squid的後面提供真正的web服務。固然使用這樣的架構必需要保證主頁上大部分都是靜態頁面。這就須要程序員的配合將頁面在反饋給客戶端以前將頁面所有轉換成靜態頁面。
基本看出sina和sohu對於頻道等欄目都用了相同的技術,即squid來監聽這些IP的80端口,而真正的web server來監聽另一個端口。從用戶的感受上來講不會有任何的區別,而相對於將web server直接和客戶端連在一塊兒的方式,這樣的方式明顯的節省的帶寬和服務器。用戶訪問的速度感受也會更快。
http://www.dbanotes.net/arch/yupoo_arch.html 

帶寬:4000M/S (參考) 
服務器數量:60 臺左右 
Web服務器:Lighttpd, Apache, nginx 
應用服務器:Tomcat 
其餘:Python, Java, MogileFS 、ImageMagick 等 

關於 Squid 與 Tomcat 

Squid 與 Tomcat 彷佛在 Web 2.0 站點的架構中較少看到。我首先是對 Squid 有點疑問,對此阿華的解釋是"目前暫時還沒找到效率比 Squid 高的緩存系統,原來命中率的確不好,後來在 Squid 前又裝了層 Lighttpd, 基於 url 作 hash, 同一個圖片始終會到同一臺 squid 去,因此命中率完全提升了"

對於應用服務器層的 Tomcat,如今 Yupoo! 技術人員也在逐漸用其餘輕量級的東西替代,而 YPWS/YPFS 如今已經用 Python 進行開發了。 

名次解釋: 

· YPWS--Yupoo Web Server YPWS 是用 Python開發的一個小型 Web 服務器,提供基本的 Web 服務外,能夠增長針對用戶、圖片、外鏈網站顯示的邏輯判斷,能夠安裝於任何有空閒資源的服務器中,遇到性能瓶頸時方便橫向擴展。

· YPFS--Yupoo File System 與 YPWS 相似,YPFS 也是基於這個 Web 服務器上開發的圖片上傳服務器。 


【Updated: 有網友留言質疑 Python 的效率,Yupoo 老大劉平陽在 del.icio.us 上寫到 "YPWS用Python本身寫的,每臺機器每秒能夠處理294個請求, 如今壓力幾乎都在10%如下"】

圖片處理層 

接下來的 Image Process Server 負責處理用戶上傳的圖片。使用的軟件包也是 ImageMagick,在上次存儲升級的同時,對於銳化的比率也調整過了(我我的感受,效果的確好了不少)。」Magickd「 是圖像處理的一個遠程接口服務,能夠安裝在任何有空閒 CPU資源的機器上,相似 Memcached的服務方式。

咱們知道 Flickr 的縮略圖功能原來是用 ImageMagick 軟件包的,後來被雅虎收購後出於版權緣由而不用了(?);EXIF 與 IPTC Flicke 是用 Perl 抽取的,我是很是建議 Yupoo! 針對 EXIF 作些文章,這也是潛在產生受益的一個重點。

圖片存儲層 

原來 Yupoo! 的存儲採用了磁盤陣列櫃,基於 NFS 方式的,隨着數據量的增大,」Yupoo! 開發部從07年6月份就開始着手研究一套大容量的、能知足 Yupoo! 從此發展須要的、安全可靠的存儲系統「,看來 Yupoo! 系統比較有信心,也是滿懷期待的,畢竟這要支撐以 TB 計算的海量圖片的存儲和管理。咱們知道,一張圖片除了原圖外,還有不一樣尺寸的,這些圖片統一存儲在 MogileFS 中。

對於其餘部分,常見的 Web 2.0 網站必須軟件都能看到,如 MySQL、Memcached 、Lighttpd 等。Yupoo! 一方面採用很多相對比較成熟的開源軟件,一方面也在自行開發定製適合本身的架構組件。這也是一個 Web 2.0 公司所必須要走的一個途徑。

很是感謝一下 Yupoo! 阿華對於技術信息的分享,技術是共通的。下一個能爆料是哪家? 

--EOF-- 

lighttpd+squid這套緩存是放在另一個機房做爲cdn的一個節點使用的,圖中沒描繪清楚,給你們帶來不便了。 
squid前端用lighttpd沒用nginx,主要是用了這麼久,沒出啥大問題,因此就沒想其餘的了。 
URL Hash的擴展性的確很差,能作的就是不輕易去增減服務器,咱們目前是5臺服務器作一組hash. 

咱們如今用Python寫的Web Server,在效率方面,我能夠給個測試數據,根據目前的訪問日誌模擬訪問測試的結果是1臺ypws,平均每秒處理294個請求(加載全部的邏輯判斷)。
在可靠性上,還不沒具體的數據,目前運行1個多月尚未任何異常。 

lvs每一個節點上都裝nginx,主要是爲了反向代理及處理靜態內容,不過apache已顯得不是那麼必需,準備逐漸去掉。 

咱們處理圖片都是即時的,咱們目前半數以上的服務器都裝了magickd服務,用來分擔圖片處理請求。 



http://www.dbanotes.net/review/tailrank_arch.html 

天天數以千萬計的 Blog 內容中,實時的熱點是什麼? Tailrank 這個 Web 2.0 Startup 致力於回答這個問題。 

專門爆料網站架構的 Todd Hoff 對 Kevin Burton 進行了採訪。因而咱們能瞭解一下 Tailrank 架構的一些信息。每小時索引 2400 萬的 Blog 與 Feed,內容處理能力爲 160-200Mbps,IO 寫入大約在10-15MBps。每月要處理 52T 之多的原始數據。Tailrank 所用的爬蟲如今已經成爲一個獨立產品:spinn3r。

服務器硬件 

目前大約 15 臺服務器,CPU 是 64 位的 Opteron。每臺主機上掛兩個 SATA 盤,作 RAID 0。據我所知,國內不少 Web 2.0 公司也用的是相似的方式,SATA 盤容量達,低廉價格,堪稱不二之選。操做系統用的是 Debian Linux 。Web 服務器用 Apache 2.0,Squid 作反向代理服務器。

數據庫 

Tailrank 用 MySQL 數據庫,聯邦數據庫形式。存儲引擎用 InnoDB, 數據量 500GB。Kevin Burton 也指出了 MySQL 5 在修了一些 多核模式下互斥鎖的問題(This Bug?)。到數據庫的JDBC 驅動鏈接池用 lbpool 作負載均衡。MySQL Slave 或者 Master的複製用 MySQLSlaveSync 來輕鬆完成。不過即便這樣,還要花費 20%的時間來折騰 DB。

其餘開放的軟件 

任何一套系統都離不開合適的 Profiling 工具,Tailrank 也不利外,針對 Java 程序的 Benchmark 用 Benchmark4j。Log 工具用 Log5j(不是 Log4j)。Tailrank 所用的大部分工具都是開放的。

Tailrank 的一個比較大的競爭對手是 Techmeme,雖然兩者暫時看面向內容的側重點有所不一樣。其實,最大的對手仍是本身,當須要挖掘的信息量愈來愈大,若是精準並及時的呈現給用戶內容的成本會愈來愈高。從如今來看,Tailrank 離預期目標還差的很遠。期待羅馬早日建成


YouTube架構學習 

關鍵字: YouTube 

原文: YouTube Architecture 

YouTube發展迅速,天天超過1億的視頻點擊量,但只有不多人在維護站點和確保伸縮性。 

平臺 
Apache 
Python 
Linux(SuSe) 
MySQL 
psyco,一個動態的Python到C的編譯器 
lighttpd代替Apache作視頻查看 

狀態 
支持天天超過1億的視頻點擊量 
成立於2005年2月 
於2006年3月達到天天3千萬的視頻點擊量 
於2006年7月達到天天1億的視頻點擊量 
2個系統管理員,2個伸縮性軟件架構師 
2個軟件開發工程師,2個網絡工程師,1個DBA 

處理飛速增加的流量 

Java代碼 

1. while (true) 

2. { 

3. identify_and_fix_bottlenecks(); 

4. drink(); 

5. sleep(); 

6. notice_new_bottleneck(); 

7. } 

while (true) 



identify_and_fix_bottlenecks(); 

drink(); 

sleep(); 

notice_new_bottleneck(); 




天天運行該循環屢次 

Web服務器 
1,NetScaler用於負載均衡和靜態內容緩存 
2,使用mod_fast_cgi運行Apache 
3,使用一個Python應用服務器來處理請求的路由 
4,應用服務器與多個數據庫和其餘信息源交互來獲取數據和格式化html頁面 
5,通常能夠經過添加更多的機器來在Web層提升伸縮性 
6,Python的Web層代碼一般不是性能瓶頸,大部分時間阻塞在RPC 
7,Python容許快速而靈活的開發和部署 
8,一般每一個頁面服務少於100毫秒的時間 
9,使用psyco(一個相似於JIT編譯器的動態的Python到C的編譯器)來優化內部循環 
10,對於像加密等密集型CPU活動,使用C擴展 
11,對於一些開銷昂貴的塊使用預先生成並緩存的html 
12,數據庫裏使用行級緩存 
13,緩存完整的Python對象 
14,有些數據被計算出來併發送給各個程序,因此這些值緩存在本地內存中。這是個使用不當的策略。應用服務器裏最快的緩存將預先計算的值發送給全部服務器也花不了多少時間。只需弄一個代理來監聽更改,預計算,而後發送。

視頻服務 
1,花費包括帶寬,硬件和能源消耗 
2,每一個視頻由一個迷你集羣來host,每一個視頻被超過一臺機器持有 
3,使用一個集羣意味着: 
-更多的硬盤來持有內容意味着更快的速度 
-failover。若是一臺機器出故障了,另外的機器能夠繼續服務 
-在線備份 
4,使用lighttpd做爲Web服務器來提供視頻服務: 
-Apache開銷太大 
-使用epoll來等待多個fds 
-從單進程配置轉變爲多進程配置來處理更多的鏈接 
5,大部分流行的內容移到CDN: 
-CDN在多個地方備分內容,這樣內容離用戶更近的機會就會更高 
-CDN機器常常內存不足,由於內容太流行以至不多有內容進出內存的顛簸 
6,不太流行的內容(天天1-20瀏覽次數)在許多colo站點使用YouTube服務器 
-長尾效應。一個視頻能夠有多個播放,可是許多視頻正在播放。隨機硬盤塊被訪問 
-在這種狀況下緩存不會很好,因此花錢在更多的緩存上可能沒太大意義。 
-調節RAID控制並注意其餘低級問題 
-調節每臺機器上的內存,不要太多也不要太少 

視頻服務關鍵點 
1,保持簡單和廉價 
2,保持簡單網絡路徑,在內容和用戶間不要有太多設備 
3,使用經常使用硬件,昂貴的硬件很難找到幫助文檔 
4,使用簡單而常見的工具,使用構建在Linux裏或之上的大部分工具 
5,很好的處理隨機查找(SATA,tweaks) 

縮略圖服務 
1,作到高效使人驚奇的難 
2,每一個視頻大概4張縮略圖,因此縮略圖比視頻多不少 
3,縮略圖僅僅host在幾個機器上 
4,持有一些小東西所遇到的問題: 
-OS級別的大量的硬盤查找和inode和頁面緩存問題 
-單目錄文件限制,特別是Ext3,後來移到多分層的結構。內核2.6的最近改進可能讓Ext3容許大目錄,但在一個文件系統裏存儲大量文件不是個好主意 
-每秒大量的請求,由於Web頁面可能在頁面上顯示60個縮略圖 
-在這種高負載下Apache表現的很是糟糕 
-在Apache前端使用squid,這種方式工做了一段時間,可是因爲負載繼續增長而以失敗了結。它讓每秒300個請求變爲20個 
-嘗試使用lighttpd可是因爲使用單線程它陷於困境。遇到多進程的問題,由於它們各自保持本身單獨的緩存 
-如此多的圖片以至一臺新機器只能接管24小時 
-重啓機器須要6-10小時來緩存 
5,爲了解決全部這些問題YouTube開始使用Google的BigTable,一個分佈式數據存儲: 
-避免小文件問題,由於它將文件收集到一塊兒 
-快,錯誤容忍 
-更低的延遲,由於它使用分佈式多級緩存,該緩存與多個不一樣collocation站點工做 
-更多信息參考Google Architecture,GoogleTalk Architecture和BigTable 

數據庫 
1,早期 
-使用MySQL來存儲元數據,如用戶,tags和描述 
-使用一整個10硬盤的RAID 10來存儲數據 
-依賴於信用卡因此YouTube租用硬件 
-YouTube通過一個常見的革命:單服務器,而後單master和多read slaves,而後數據庫分區,而後sharding方式 
-痛苦與備份延遲。master數據庫是多線程的而且運行在一個大機器上因此它能夠處理許多工做,slaves是單線程的而且一般運行在小一些的服務器上而且備份是異步的,因此slaves會遠遠落後於master
-更新引發緩存失效,硬盤的慢I/O致使慢備份 
-使用備份架構須要花費大量的money來得到增長的寫性能 
-YouTube的一個解決方案是經過把數據分紅兩個集羣來將傳輸分出優先次序:一個視頻查看池和一個通常的集羣
2,後期 
-數據庫分區 
-分紅shards,不一樣的用戶指定到不一樣的shards 
-擴散讀寫 
-更好的緩存位置意味着更少的IO 
-致使硬件減小30% 
-備份延遲下降到0 
-如今能夠任意提高數據庫的伸縮性 

數據中心策略 
1,依賴於信用卡,因此最初只能使用受管主機提供商 
2,受管主機提供商不能提供伸縮性,不能控制硬件或使用良好的網絡協議 
3,YouTube改成使用colocation arrangement。如今YouTube能夠自定義全部東西而且協定本身的契約 
4,使用5到6個數據中心加CDN 
5,視頻來自任意的數據中心,不是最近的匹配或其餘什麼。若是一個視頻足夠流行則移到CDN 
6,依賴於視頻帶寬而不是真正的延遲。能夠來自任何colo 
7,圖片延遲很嚴重,特別是當一個頁面有60張圖片時 
8,使用BigTable將圖片備份到不一樣的數據中心,代碼查看誰是最近的 

學到的東西 
1,Stall for time。創造性和風險性的技巧讓你在短時間內解決問題而同時你會發現長期的解決方案 
2,Proioritize。找出你的服務中核心的東西並對你的資源分出優先級別 
3,Pick your battles。別怕將你的核心服務分出去。YouTube使用CDN來分佈它們最流行的內容。建立本身的網絡將花費太多時間和太多money 
4,Keep it simple!簡單容許你更快的從新架構來回應問題 
5,Shard。Sharding幫助隔離存儲,CPU,內存和IO,不只僅是得到更多的寫性能 
6,Constant iteration on bottlenecks: 
-軟件:DB,緩存 
-OS:硬盤I/O 
-硬件:內存,RAID 
7,You succeed as a team。擁有一個跨越條律的瞭解整個系統並知道系統內部是什麼樣的團隊,如安裝打印機,安裝機器,安裝網絡等等的人。With a good team all things are possible。

http://hideto.javaeye.com/blog/130815 

Google架構學習 

關鍵字: Google 

原文:Google Architecture 

Google是伸縮性的王者。Google一直的目標就是構建高性能高伸縮性的基礎組織來支持它們的產品。 

平臺 
Linux 
大量語言:Python,Java,C++ 

狀態 
在2006年大約有450,000臺廉價服務器 
在2005年Google索引了80億Web頁面,如今沒有人知道數目 
目前在Google有超過200個GFS集羣。一個集羣能夠有1000或者甚至5000臺機器。成千上萬的機器從運行着5000000000000000字節存儲的GFS集羣獲取數據,集羣總的讀寫吞吐量能夠達到每秒40兆字節
目前在Google有6000個MapReduce程序,並且每月都寫成百個新程序 
BigTable伸縮存儲幾十億的URL,幾百千千兆的衛星圖片和幾億用戶的參數選擇 

堆棧 
Google形象化它們的基礎組織爲三層架構: 
1,產品:搜索,廣告,email,地圖,視頻,聊天,博客 
2,分佈式系統基礎組織:GFS,MapReduce和BigTable 
3,計算平臺:一羣不一樣的數據中內心的機器 
4,確保公司裏的人們部署起來開銷很小 
5,花費更多的錢在避免丟失日誌數據的硬件上,其餘類型的數據則花費較少 

可信賴的存儲機制GFS(Google File System) 
1,可信賴的伸縮性存儲是任何程序的核心需求。GFS就是Google的核心存儲平臺 
2,Google File System - 大型分佈式結構化日誌文件系統,Google在裏面扔了大量的數據 
3,爲何構建GFS而不是利用已有的東西?由於能夠本身控制一切而且這個平臺與別的不同,Google須要: 
-跨數據中心的高可靠性 
-成千上萬的網絡節點的伸縮性 
-大讀寫帶寬的需求 
-支持大塊的數據,可能爲上千兆字節 
-高效的跨節點操做分發來減小瓶頸 
4,系統有Master和Chunk服務器 
-Master服務器在不一樣的數據文件裏保持元數據。數據以64MB爲單位存儲在文件系統中。客戶端與Master服務器交流來在文件上作元數據操做而且找到包含用戶須要數據的那些Chunk服務器
-Chunk服務器在硬盤上存儲實際數據。每一個Chunk服務器跨越3個不一樣的Chunk服務器備份以建立冗餘來避免服務器崩潰。一旦被Master服務器指明,客戶端程序就會直接從Chunk服務器讀取文件
6,一個上線的新程序能夠使用已有的GFS集羣或者能夠製做本身的GFS集羣 
7,關鍵點在於有足夠的基礎組織來讓人們對本身的程序有所選擇,GFS能夠調整來適應個別程序的需求 

使用MapReduce來處理數據 
1,如今你已經有了一個很好的存儲系統,你該怎樣處理如此多的數據呢?好比你有許多TB的數據存儲在1000臺機器上。數據庫不能伸縮或者伸縮到這種級別花費極大,這就是 MapReduce出現的緣由
2, MapReduce是一個處理和生成大量數據集的編程模型和相關實現。用戶指定一個 map方法來處理一個鍵/值對來生成一箇中間的鍵/值對,還有一個reduce方法來合併全部關聯到一樣的中間鍵的中間值。許多真實世界的任務均可以使用這種模型來表現。以這種風格來寫的程序會自動並行的在一個大量機器的集羣裏運行。運行時系統照顧輸入數據劃分、程序在機器集之間執行的調度、機器失敗處理和必需的內部機器交流等細節。這容許程序員沒有多少並行和分佈式系統的經驗就能夠很容易使用一個大型分佈式系統資源
3,爲何使用 MapReduce? 
-跨越大量機器分割任務的好方式 
-處理機器失敗 
-能夠與不一樣類型的程序工做,例如搜索和廣告。幾乎任何程序都有 map和reduce類型的操做。你能夠預先計算有用的數據、查詢字數統計、對TB的數據排序等等
4, MapReduce系統有三種不一樣類型的服務器 
-Master服務器分配用戶任務到 Map和Reduce服務器。它也跟蹤任務的狀態
- Map服務器接收用戶輸入並在其基礎上處理 map操做。結果寫入中間文件
-Reduce服務器接收 Map服務器產生的中間文件並在其基礎上處理reduce操做
5,例如,你想在全部Web頁面裏的字數。你將存儲在GFS裏的全部頁面拋入 MapReduce。這將在成千上萬臺機器上同時進行而且全部的調整、工做調度、失敗處理和數據傳輸將自動完成
-步驟相似於:GFS ->  Map -> Shuffle -> Reduction -> Store Results back into GFS
-在 MapReduce裏一個 map操做將一些數據映射到另外一箇中,產生一個鍵值對,在咱們的例子裏就是字和字數
-Shuffling操做彙集鍵類型 
-Reduction操做計算全部鍵值對的綜合併產生最終的結果 
6,Google索引操做管道有大約20個不一樣的 map和reduction。
7,程序能夠很是小,如20到50行代碼 
8,一個問題是掉隊者。掉隊者是一個比其餘程序慢的計算,它阻塞了其餘程序。掉隊者可能由於緩慢的IO或者臨時的CPU不能使用而發生。解決方案是運行多個一樣的計算而且當一個完成後殺死全部其餘的
9,數據在 Map和Reduce服務器之間傳輸時被壓縮了。這能夠節省帶寬和I/O。

在BigTable裏存儲結構化數據 
1,BigTable是一個大伸縮性、錯誤容忍、自管理的系統,它包含千千兆的內存和1000000000000000的存儲。它能夠每秒鐘處理百萬的讀寫 
2,BigTable是一個構建於GFS之上的分佈式哈希機制。它不是關係型數據庫。它不支持join或者SQL類型查詢 
3,它提供查詢機制來經過鍵訪問結構化數據。GFS存儲存儲不透明的數據而許多程序需求有結構化數據 
4,商業數據庫不能達到這種級別的伸縮性而且不能在成千上萬臺機器上工做 
5,經過控制它們本身的低級存儲系統Google獲得更多的控制權來改進它們的系統。例如,若是它們想讓跨數據中心的操做更簡單這個特性,它們能夠內建它 
6,系統運行時機器能夠自由的增刪而整個系統保持工做 
7,每一個數據條目存儲在一個格子裏,它能夠經過一個行key和列key或者時間戳來訪問 
8,每一行存儲在一個或多個tablet中。一個tablet是一個64KB塊的數據序列而且格式爲SSTable 
9,BigTable有三種類型的服務器: 
-Master服務器分配tablet服務器,它跟蹤tablet在哪裏而且若是須要則從新分配任務 
-Tablet服務器爲tablet處理讀寫請求。當tablet超過大小限制(一般是100MB-200MB)時它們拆開tablet。當一個Tablet服務器失敗時,則100個Tablet服務器各自挑選一個新的tablet而後系統恢復。
-Lock服務器造成一個分佈式鎖服務。像打開一個tablet來寫、Master調整和訪問控制檢查等都須要互斥 
10,一個locality組能夠用來在物理上將相關的數據存儲在一塊兒來獲得更好的locality選擇 
11,tablet儘量的緩存在RAM裏 

硬件 
1,當你有不少機器時你怎樣組織它們來使得使用和花費有效? 
2,使用很是廉價的硬件 
3,A 1,000-fold computer power increase can be had for a 33 times lower cost if you you use a failure-prone infrastructure rather than an infrastructure built on highly reliable components. You must build reliability on top of unreliability for this strategy to work. 
4,Linux,in-house rack design,PC主板,低端存儲 
5,Price per wattage on performance basis isn't getting better. Have huge power and cooling issues
6,使用一些collocation和Google本身的數據中心 

其餘 
1,迅速更改而不是等待QA 
2,庫是構建程序的卓越方式 
3,一些程序做爲服務提供 
4,一個基礎組織處理程序的版本,這樣它們能夠發佈而不用懼怕會破壞什麼東西 

Google未來的方向 
1,支持地理位置分佈的集羣 
2,爲全部數據建立一個單獨的全局名字空間。當前的數據由集羣分離 
3,更多和更好的自動化數據遷移和計算 
4,解決當使用網絡劃分來作廣闊區域的備份時的一致性問題(例如保持服務即便一個集羣離線維護或因爲一些損耗問題) 

學到的東西 
1,基礎組織是有競爭性的優點。特別是對Google而言。Google能夠很快很廉價的推出新服務,而且伸縮性其餘人很難達到。許多公司採起徹底不一樣的方式。許多公司認爲基礎組織開銷太大。Google認爲本身是一個系統工程公司,這是一個新的看待軟件構建的方式
2,跨越多個數據中心仍然是一個未解決的問題。大部分網站都是一個或者最多兩個數據中心。咱們不得不認可怎樣在一些數據中心之間完整的分佈網站是很須要技巧的 
3,若是你本身沒有時間從零開始從新構建全部這些基礎組織你能夠看看Hadoop。Hadoop是這裏不少一樣的主意的一個開源實現 
4,平臺的一個優勢是初級開發人員能夠在平臺的基礎上快速而且放心的建立健全的程序。若是每一個項目都須要發明一樣的分佈式基礎組織的輪子,那麼你將陷入困境由於知道怎樣完成這項工做的人相對較少
5,協同工做不一直是擲骰子。經過讓系統中的全部部分一塊兒工做則一個部分的改進將幫助全部的部分。改進文件系統則每一個人從中受益並且是透明的。若是每一個項目使用不一樣的文件系統則在整個堆棧中享受不到持續增長的改進
6,構建自管理系統讓你不必讓系統關機。這容許你更容易在服務器之間平衡資源、動態添加更大的容量、讓機器離線和優雅的處理升級 
7,建立可進化的基礎組織,並行的執行消耗時間的操做並採起較好的方案 
8,不要忽略學院。學院有許多沒有轉變爲產品的好主意。Most of what Google has done has prior art, just not prior large scale deployment.
9,考慮壓縮。當你有許多CPU而IO有限時壓縮是一個好的選擇。 



http://blog.daviesliu.net/2006/09/09/010620/ 

Lighttpd+Squid+Apache搭建高效率Web服務器 

架構原理 

Apache一般是開源界的首選Web服務器,由於它的強大和可靠,已經具備了品牌效應,能夠適用於絕大部分的應用場合。可是它的強大有時候卻顯得笨重,配置文件得讓人望而生畏,高併發狀況下效率不過高。而輕量級的Web服務器Lighttpd倒是後起之秀,其靜態文件的響應能力遠高於 Apache,聽說是Apache的2-3倍。Lighttpd的高性能和易用性,足以打動咱們,在它可以勝任的領域,儘可能用它。Lighttpd對 PHP的支持也很好,還能夠經過Fastcgi方式支持其餘的語言,好比Python。

畢竟Lighttpd是輕量級的服務器,功能上不能跟Apache比,某些應用沒法勝任。好比Lighttpd還不支持緩存,而如今的絕大部分站點都是用程序生成動態內容,沒有緩存的話即便程序的效率再高也很難知足大訪問量的需求,並且讓程序不停的去作同一件事情也實在沒有意義。首先,Web程序是須要作緩存處理的,即把反覆使用的數據作緩存。即便這樣也還不夠,單單是啓動Web處理程序的代價就很多,緩存最後生成的靜態頁面是必不可少的。而作這個是 Squid的強項,它本是作代理的,支持高效的緩存,能夠用來給站點作反向代理加速。把Squid放在Apache或者Lighttpd的前端來緩存 Web服務器生成的動態內容,而Web應用程序只須要適當地設置頁面實效時間便可。 

即便是大部份內容動態生成的網站,仍免不了會有一些靜態元素,好比圖片、JS腳本、CSS等等,將Squid放在Apache或者Lighttp 前端後,反而會使性能降低,畢竟處理HTTP請求是Web服務器的強項。並且已經存在於文件系統中的靜態內容再在Squid中緩存一下,浪費內存和硬盤空間。所以能夠考慮將Lighttpd再放在Squid的前面,構成 Lighttpd+Squid+Apache的一條處理鏈,Lighttpd在最前面,專門用來處理靜態內容的請求,把動態內容請求經過proxy模塊轉發給Squid,若是Squid中有該請求的內容且沒有過時,則直接返回給Lighttpd。新請求或者過時的頁面請求交由Apache中Web程序來處理。通過Lighttpd和Squid的兩級過濾,Apache須要處理的請求將大大減小,減小了Web應用程序的壓力。同時這樣的構架,便於把不一樣的處理分散到多臺計算機上進行,由Lighttpd在前面統一把關。

在這種架構下,每一級都是能夠進行單獨優化的,好比Lighttpd能夠採用異步IO方式,Squid能夠啓用內存來緩存,Apache能夠啓用MPM 等,而且每一級均可以使用多臺機器來均衡負載,伸縮性很好。
2009  -  10  -  31

Java基礎學習筆記

文章分類:Java編程
1.Java語言的特色:面向對象,跨平臺,多線程 

2.Java運行環境:JVM+Java API 

3.數據類型: 
boolean 1 
char 16 
byte 8 
short 16 
int 32 
long 64 
float 32 
double 64 

4.面向對象: 
封裝:類  
繼承:單一繼承  
多態:重寫(Overridding)與重載(Overloading) 
在子類中,方法的參數個數和返回值都與父類相同,稱爲重寫 
在同一個類中,方法的參數不一樣,稱爲重載 

5.做用域: 
private 子類不能繼承 
default 若是不在同一包中,子類不能繼承 
protected 
public 
        
6.垃圾回收原理:有向圖原則(另外一種爲計數器類型),可能會有內存泄漏,計數器類型與有向圖類型相比:效率更高,可是精度偏低,由於它很難發現變量循環引用的問題 
會有內存泄漏的代碼: 
Vector v=new Vector(10) 
for (int i=0;i<10;i++){ 
Object o=new Object(); 
v.add(o); 
o=null; 

解決方法: 
v=null; 

7.棧與堆:原始數據類型存放在棧裏,對象數據類型存放在堆中,棧中存放堆中的地址。 

8.變量比較:==比較的是棧,原始數據類型相同,可是引用類型值不等,equals比較的是堆,特例是string,java.lang.String類是final類型的,所以不能夠繼承這個類、不能修改這個類。

9.變量複製:原始數據類型複製的是值,引用數據類型複製的是棧中的引用,因此當一個修改的時候,會影響另外一個。對象複製:Object.clone()方法 

10.引用傳遞和值傳遞:原始數據類型傳遞的是值,引用數據類型傳遞的是棧中的引用 

11.異常:(Java.lang.Exception)檢查時異常,(Java.lang.RuntimeException)運行時異常,((java.lang.Error)錯誤,檢查時異常必須處理

12.集合:collection: set:HashSet TreeSet 
list:ArrayList LinkedList Vector Stack 
map:Hash Map Tree Map HashTable Properties

13.Set裏的元素是不能重複的,什麼方法來區分重複與否呢? 是用==仍是 
equals()? 它們有何區別? 
Set裏的元素是不能重複的,那麼用iterator()方法來區分重複與否。equals()是判讀兩 
個Set是否相等。 
equals()和==方法決定引用值是否指向同一對象equals()在類中被覆蓋,爲的是當兩個 
分離的對象的內容和類型相配的話,返回真值 

14.ArrayList, Vector, LinkedList的存儲性能和特性 
ArrayList和Vector都是使用數組方式存儲數據,此數組元素數大於實際存儲的數據 
以便增長和插入元素,它們都容許直接按序號索引元素,可是插入元素要涉及數組元 
素移動等內存操做,因此索引數據快而插入數據慢,Vector因爲使用了synchronized方 
法(線程安全),一般性能上較ArrayList差,而LinkedList使用雙向鏈表實現存儲,按序 
號索引數據須要進行前向或後向遍歷,可是插入數據時只須要記錄本項的先後項即 
可,因此插入速度較快。 

1五、Hash Map和Hashtable的區別。 
Hash Map是Hashtable的輕量級實現(非線程安全的實現),他們都完成了 Map接口,
主要區別在於Hash Map容許空(null)鍵值(key),因爲非線程安全,效率上可能高於
Hashtable。 
Hash Map容許將null做爲一個entry的key或者value,而Hashtable不容許。
Hash Map把Hashtable的contains方法去掉了,改爲containsvalue和containsKey。由於
contains方法容易讓人引發誤解。 
Hashtable繼承自Dictionary類,而Hash Map是Java1.2引進的 Map interface的一個實現。
最大的不一樣是,Hashtable的方法是Synchronize的,而Hash Map不是,在多個線程訪問
Hashtable時,不須要本身爲它的方法實現同步,而Hash Map 就必須爲之提供外同步。
Hashtable和Hash Map採用的hash/rehash算法都大概同樣,因此性能不會有很大的差別。
定時執行任務的三種方法: 

1)java.util.Timer. 

2)ServletContextListener. 

3)org.springframework.scheduling.timer.ScheduledTimerTask 

1)java.util.Timer 
這個方法應該是最經常使用的,不過這個方法須要手工啓動你的任務: 
Timer timer=new Timer(); 
timer.schedule(new ListByDayTimerTask(),10000,86400000); 
這裏的ListByDayTimerTask類必須extends TimerTask裏面的run()方法。 

2)ServletContextListener 
這個方法在web容器環境比較方便,這樣,在web server啓動後就能夠自動運行該任務,不須要手工操做。 
將ListByDayListener implements ServletContextListener接口,在contextInitialized方法中加入啓動Timer的代碼,在 contextDestroyed方法中加入cancel該Timer的代碼;而後在web.xml中,加入listener:
<-listener> 
<-listener-class>com.qq.customer.ListByDayListener</listener-class> 
<-/listener> 

3)org.springframework.scheduling.timer.ScheduledTimerTask若是你用spring,那麼你不須要寫Timer類了,在schedulingContext-timer.xml中加入下面的內容就能夠了:
<?xml version="1.0" encoding="UTF-8"?> 
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">

<beans> 
<bean id="timer" class="org.springframework.scheduling.timer.TimerFactoryBean"> 
<property name="scheduledTimerTasks"> 
<list> 
<ref local="MyTimeTask1"/> 
</list> 
</property> 
</bean> 

<bean id="MyTimeTask" class="com.qq.timer.ListByDayTimerTask"/> 

<bean id="MyTimeTask1" class="org.springframework.scheduling.timer.ScheduledTimerTask">
<property name="timerTask"> 
<ref bean="MyTimeTask"/> 
</property> 
<property name="delay"> 
<value>10000</value> 
</property> 
<property name="period"> 
<value>86400000</value> 
</property> 
</bean> 
</beans> 

以上內容轉載自:http://dev.csdn.net/author/xtpdcsse/ec8e8080a5b04fa79e7d4828bc807d3f.html

下面是個人實現。 

1)利用java.util.Timer. 代碼以下 

<1>StartThread.java 

[java]  view plain copy
  1. package com.jview.main;<BR>
  2. import java.util.Date;<BR>
  3. import java.util.Timer;<BR>
  4. import java.util.TimerTask;<BR>
  5. import org.apache.log4j.Logger;<BR>
  6. public class StartThreadextends Thread {<BR>
  7. private static Logger logger = Logger.getLogger("StartThread");<BR>
  8. public static final int EXECUTE_CYC = 86400000//24*60*60*1000毫秒<BR>
  9. int startH = 9;<BR>
  10. int startM = 52;<BR>
  11. private Timer _timer ;<BR>
  12. private Date _statDate;<BR>
  13. private Date _nowDate;<BR>
  14. public StartThread(){<BR>
  15. _nowDate = new Date();<BR>
  16. _timer = new Timer();<BR>
  17. _statDate = newDate(_nowDate.getYear(),_nowDate.getMonth(),_nowDate.getDate(),startH,startM);<BR>
  18. }<BR>
  19. public void StartUp(){<BR>
  20. _timer.schedule(<BR>
  21. new TimerTask() {<BR>
  22. public void run()<BR>
  23. {<BR>
  24. logger.info("開始統計...");<BR>
  25. try {<BR>
  26. Class.forName("com.jview.stat.StatPlan").newInstance();<BR>
  27. catch (InstantiationException e) {<BR>
  28. // TODO Auto-generated catch block<BR>
  29. e.printStackTrace();<BR>
  30. catch (IllegalAccessException e) {<BR>
  31. // TODO Auto-generated catch block<BR>
  32. e.printStackTrace();<BR>
  33. catch (ClassNotFoundException e) {<BR>
  34. // TODO Auto-generated catch block<BR>
  35. e.printStackTrace();<BR>
  36. }<BR>
  37. }<BR>
  38. },_statDate,EXECUTE_CYC);<BR>
  39. }<BR>
  40. public static void main(String[] args) {<BR>
  41. StartThread _statUp = new StartThread();<BR>
  42. _statUp.StartUp();<BR>
  43. } <BR>
  44. }
[java]  view plain copy
  1. package com.jview.main;  
  2.   
  3. import java.util.Date;  
  4.   
  5. import java.util.Timer;  
  6.   
  7. import java.util.TimerTask;  
  8.   
  9. import org.apache.log4j.Logger;  
  10.   
  11. public class StartThread extends Thread {  
  12.   
  13.     private static Logger logger = Logger.getLogger("StartThread");  
  14.   
  15.     public static final int EXECUTE_CYC = 86400000//24*60*60*1000毫秒  
  16.   
  17.     int startH = 9;  
  18.   
  19.     int startM = 52;  
  20.   
  21.     private Timer _timer ;  
  22.   
  23.     private Date _statDate;  
  24.   
  25.     private Date _nowDate;  
  26.   
  27.     public StartThread(){  
  28.   
  29.         _nowDate = new Date();  
  30.   
  31.         _timer = new Timer();  
  32.   
  33.         _statDate = new Date(_nowDate.getYear(),_nowDate.getMonth(),_nowDate.getDate(),startH,startM);  
  34.   
  35.     }  
  36.   
  37.     public void StartUp(){  
  38.   
  39.         _timer.schedule(  
  40.   
  41.                 new TimerTask() {  
  42.   
  43.                     public void run()  
  44.   
  45.                     {  
  46.   
  47.                         logger.info("開始統計...");  
  48.   
  49.                         try {  
  50.   
  51.                             Class.forName("com.jview.stat.StatPlan").newInstance();  
  52.   
  53.                         } catch (InstantiationException e) {  
  54.   
  55.                             // TODO Auto-generated catch block  
  56.   
  57.                             e.printStackTrace();  
  58.   
  59.                         } catch (IllegalAccessException e) {  
  60.   
  61.                             // TODO Auto-generated catch block  
  62.   
  63.                             e.printStackTrace();  
  64.   
  65.                         } catch (ClassNotFoundException e) {  
  66.   
  67.                             // TODO Auto-generated catch block  
  68.   
  69.                             e.printStackTrace();  
  70.   
  71.                         }  
  72.   
  73.                     }  
  74.   
  75.                 },_statDate,EXECUTE_CYC);  
  76.   
  77.     }  
  78.   
  79.     public static void main(String[] args) {  
  80.   
  81.         StartThread _statUp = new StartThread();  
  82.   
  83.         _statUp.StartUp();  
  84.   
  85.     }     
  86.   
  87. }  

<2>StatPlan.java 
[java]  view plain copy
  1. package com.jview.stat;<BR>
  2. import java.util.Calendar;<BR>
  3. import org.apache.log4j.Logger;<BR>
  4. public class StatPlan {<BR>
  5. <BR>
  6. <BR>
  7. private static Logger logger = Logger.getLogger("StatPlan");<BR>
  8. private int i = 0;<BR>
  9. private StatPlanService _sps ;<BR>
  10. public StatPlan(){<BR>
  11. _sps = new StatWeekPlan();<BR>
  12. statPlan();<BR>
  13. }<BR>
  14. <BR>
  15. public void statPlan(){<BR>
  16. Calendar _c = Calendar.getInstance();<BR>
  17. logger.info("stat plan ... 執行"+ i +"次,時間:"+_c.getTime());<BR>
  18. _sps.StatPlan();<BR>
  19. i++;<BR>
  20. for(int i = 0; i<9999;i++){<BR>
  21. if(i==0 || i==9998){<BR>
  22. logger.info(""+i);<BR>
  23. }<BR>
  24. }<BR>
  25. }<BR>
  26. }
[java]  view plain copy
  1. package com.jview.stat;  
  2.   
  3. import java.util.Calendar;  
  4.   
  5. import org.apache.log4j.Logger;  
  6.   
  7. public class StatPlan {  
  8.   
  9.    
  10.   
  11.   
  12.   
  13.     private static Logger logger = Logger.getLogger("StatPlan");  
  14.   
  15.     private int i = 0;  
  16.   
  17.     private StatPlanService _sps ;  
  18.   
  19.     public StatPlan(){  
  20.   
  21.         _sps = new StatWeekPlan();  
  22.   
  23.         statPlan();  
  24.   
  25.     }  
  26.   
  27.       
  28.   
  29.     public void statPlan(){  
  30.   
  31.         Calendar _c = Calendar.getInstance();  
  32.   
  33.         logger.info("stat plan ... 執行"+ i +"次,時間:"+_c.getTime());  
  34.   
  35.         _sps.StatPlan();  
  36.   
  37.         i++;  
  38.   
  39.         for(int i = 0; i<9999;i++){  
  40.   
  41.             if(i==0 || i== 9998){  
  42.   
  43.                 logger.info(""+i);  
  44.   
  45.             }  
  46.   
  47.         }  
  48.   
  49.     }  
  50.   
  51. }  

<3>StatWeekPlan .java 
[java]  view plain copy
  1. import org.apache.log4j.Logger;<BR>
  2. <BR>
  3. public class StatWeekPlanextends StatPlanService {<BR>
  4. private static Logger logger = Logger.getLogger("StatWeekPlan");<BR>
  5. public void StatPlan(){<BR>
  6. logger.info("this is statWeekPlan");<BR>
  7. }<BR>
  8. }<BR>
  9. <4>StatPlanService .java<BR>
  10. public class StatPlanService {<BR>
  11. public void StatPlan(){ <BR>
  12. }<BR>
  13. }
[java]  view plain copy
  1. import org.apache.log4j.Logger;  
  2.   
  3.   
  4.   
  5. public class StatWeekPlan extends StatPlanService {  
  6.   
  7.     private static Logger logger = Logger.getLogger("StatWeekPlan");  
  8.   
  9.     public void StatPlan(){  
  10.   
  11.         logger.info("this is statWeekPlan");  
  12.   
  13.     }  
  14.   
  15. }  
  16.   
  17. <4>StatPlanService .java  
  18.   
  19. public class StatPlanService {  
  20.   
  21.     public void StatPlan(){      
  22.   
  23.     }  
  24.   
  25. }  

2)ServletContextListener.實現 
<1> SysStatListener .java 
[java]  view plain copy
  1. import java.util.Date;<BR>
  2. import java.util.Timer;<BR>
  3. import java.util.TimerTask;<BR>
  4. import javax.servlet.ServletContextEvent;<BR>
  5. import javax.servlet.ServletContextListener;<BR>
  6. import org.apache.log4j.Logger;<BR>
  7. public class SysStatListenerimplements ServletContextListener{<BR>
  8. private static Logger logger = Logger.getLogger("ListByDayListener");<BR>
  9. private StatTask _sTask;<BR>
  10. public void contextDestroyed(ServletContextEvent scevent) {<BR>
  11. String status = "中止系通通計線程";<BR>
  12. scevent.getServletContext().log(status);<BR>
  13. logger.info(status);<BR>
  14. _sTask.shutDown();<BR>
  15. }<BR>
  16. public void contextInitialized(ServletContextEvent scevent) {<BR>
  17. String status = "啓動系通通計線程";<BR>
  18. scevent.getServletContext().log(status);<BR>
  19. logger.info(status);<BR>
  20. _sTask = new StatTask();<BR>
  21. _sTask.startUp();<BR>
  22. }<BR>
  23. }
[java]  view plain copy
  1. import java.util.Date;  
  2.   
  3. import java.util.Timer;  
  4.   
  5. import java.util.TimerTask;  
  6.   
  7. import javax.servlet.ServletContextEvent;  
  8.   
  9. import javax.servlet.ServletContextListener;  
  10.   
  11. import org.apache.log4j.Logger;  
  12.   
  13. public class SysStatListener implements ServletContextListener{  
  14.   
  15.     private static Logger logger = Logger.getLogger("ListByDayListener");  
  16.   
  17.     private StatTask _sTask;  
  18.   
  19.     public void contextDestroyed(ServletContextEvent scevent) {  
  20.   
  21.         String status = "中止系通通計線程";  
  22.   
  23.         scevent.getServletContext().log(status);  
  24.   
  25.         logger.info(status);  
  26.   
  27.         _sTask.shutDown();  
  28.   
  29.     }  
  30.   
  31.     public void contextInitialized(ServletContextEvent scevent) {  
  32.   
  33.         String status = "啓動系通通計線程";  
  34.   
  35.         scevent.getServletContext().log(status);  
  36.   
  37.         logger.info(status);  
  38.   
  39.         _sTask = new StatTask();  
  40.   
  41.         _sTask.startUp();  
  42.   
  43.     }  
  44.   
  45. }  

<2> StatTask .java 
[java]  view plain copy
  1. import java.util.Date;<BR>
  2. import java.util.Timer;<BR>
  3. import java.util.TimerTask;<BR>
  4. import org.apache.log4j.Logger;<BR>
  5. public class StatTaskextends Thread {<BR>
  6. private static Logger logger = Logger.getLogger("StartThread");<BR>
  7. public staticfinal int EXECUTE_CYC =86400000;<BR>
  8. int startH = 9;<BR>
  9. int startM = 52;<BR>
  10. private Timer _timer ;<BR>
  11. private Date _statDate;<BR>
  12. private Date _nowDate;<BR>
  13. public StatTask(){<BR>
  14. _nowDate = new Date();<BR>
  15. _timer = new Timer();<BR>
  16. _statDate = newDate(_nowDate.getYear(),_nowDate.getMonth(),_nowDate.getDate(),startH,startM);<BR>
  17. }<BR>
  18. public void startUp(){<BR>
  19. _timer.schedule(<BR>
  20. new TimerTask() {<BR>
  21. public void run()<BR>
  22. {<BR>
  23. logger.info("開始統計...");<BR>
  24. try {<BR>
  25. Class.forName("com.jview.stat.StatPlan").newInstance();<BR>
  26. catch (InstantiationException e) {<BR>
  27. // TODO Auto-generated catch block<BR>
  28. e.printStackTrace();<BR>
  29. catch (IllegalAccessException e) {<BR>
  30. // TODO Auto-generated catch block<BR>
  31. e.printStackTrace();<BR>
  32. catch (ClassNotFoundException e) {<BR>
  33. // TODO Auto-generated catch block<BR>
  34. e.printStackTrace();<BR>
  35. }<BR>
  36. }<BR>
  37. },_statDate,EXECUTE_CYC);<BR>
  38. }<BR>
  39. public void shutDown(){<BR>
  40. _timer.cancel();<BR>
  41. }
[java]  view plain copy
  1. import java.util.Date;  
  2.   
  3. import java.util.Timer;  
  4.   
  5. import java.util.TimerTask;  
  6.   
  7. import org.apache.log4j.Logger;  
  8.   
  9. public class StatTask extends Thread {  
  10.   
  11.     private static Logger logger = Logger.getLogger("StartThread");  
  12.   
  13.     public static final int EXECUTE_CYC = 86400000;  
  14.   
  15.     int startH = 9;  
  16.   
  17.     int startM = 52;  
  18.   
  19.     private Timer _timer ;  
  20.   
  21.     private Date _statDate;  
  22.   
  23.     private Date _nowDate;  
  24.   
  25.     public StatTask(){  
  26.   
  27.         _nowDate = new Date();  
  28.   
  29.         _timer = new Timer();  
  30.   
  31.         _statDate = new Date(_nowDate.getYear(),_nowDate.getMonth(),_nowDate.getDate(),startH,startM);  
  32.   
  33.     }  
  34.   
  35.     public void startUp(){  
  36.   
  37.         _timer.schedule(  
  38.   
  39.                 new TimerTask() {  
  40.   
  41.                     public void run()  
  42.   
  43.                     {  
  44.   
  45.                         logger.info("開始統計...");  
  46.   
  47.                           try {  
  48.   
  49.                               Class.forName("com.jview.stat.StatPlan").newInstance();  
  50.   
  51.                           } catch (InstantiationException e) {  
  52.   
  53.                               // TODO Auto-generated catch block  
  54.   
  55.                               e.printStackTrace();  
  56.   
  57.                           } catch (IllegalAccessException e) {  
  58.   
  59.                              // TODO Auto-generated catch block  
  60.   
  61.                               e.printStackTrace();  
  62.   
  63.                          } catch (ClassNotFoundException e) {  
  64.   
  65.                             // TODO Auto-generated catch block  
  66.   
  67.                              e.printStackTrace();  
  68.   
  69.                          }  
  70.   
  71.                     }  
  72.   
  73.                 },_statDate,EXECUTE_CYC);  
  74.   
  75.     }  
  76.   
  77.     public void shutDown(){  
  78.   
  79.         _timer.cancel();  
  80.   
  81.     }  

<3>在web.xml中添加下面的內容(注:下面的內容放到<filter- mapping>的後面)
<listener> 
<listener-class>com.jview.auto.stat.SysStatListener </listener-class> 
</listener> 

這篇文章是由José M. Aguilar在他卓越的博客中以西班牙語的形式首發,其後Timm Martin在得到Aguilar先生的受權下,對該文章進行翻譯、修改,而且在DevTopics上發佈。

如下13個小技巧能夠使得你的代碼在長時間內依然可以保持容易理解和維護。 

1. 對不一樣級別的代碼進行註釋 

對於不一樣級別的代碼塊,要使用統一的方法來進行註釋。例如: 

對於每個類,須要包含一段簡明扼要的描述,做者和上一次修改的時間 
對於每個方法,須要包含這個方法的用途,功能,參數以及返回結果 
當你在一個團隊裏面的時候,採用一套註釋的標準是很是重要的。固然,使用一種你們都承認的註釋約定和工具(例如C#的XML註釋和Java的Javadoc)在必定程度上能推進這項任務。

2. 使用段落註釋 

首先把代碼塊分解成多個「段落」,每個段落都執行單一的任務;而後在每個「段落」開始以前添加註釋,告訴閱讀代碼的人接下來的這段代碼是幹什麼用的 

// 檢查全部記錄都是正確的 
foreach (Record record in records) 

if (rec.checkStatus()==Status.OK) 

. . . 


// 如今開始進行處理 
Context ctx = new ApplicationContext(); 
ctx.BeginTransaction(); 
. . . 
3. 對齊註釋行 

對於那些在行末寫有註釋的代碼,應該對齊註釋行來使得方便閱讀 

const MAX_ITEMS = 10; // maximum number of packets 
const MASK = 0x1F; // mask bit TCP 

有些開發人員使用tab來對齊註釋,而另一些人會用空格來對齊。因爲tab在不一樣的編輯器和集成開發環境中會有所不一樣,因此最佳的方法是使用空格來對齊註釋行。 

4. 不要侮辱閱讀者的智慧 

要避免沒用的註釋,例如 

if (a == 5) //若是a等於5 
counter = 0 //把counte設爲0 

這不單把時間浪費在寫沒用的註釋上面,同時也在分散讀者的注意力。 

5. 要有禮貌 

應當避免沒有禮貌的註釋,例如「要注意一些愚蠢的用戶會輸入一個負數」,或者「修正由菜鳥工程師寫的愚蠢得可憐的代碼而致使的反作用」。這樣的註釋對於代碼的寫註釋的人來講並無任何好處,同時你永遠都不會知道未來這些註釋會被誰來閱讀,你的老闆,一個客戶或者是剛纔被你數落的愚蠢得可憐的工程師。

6. 直截了當 

不要在註釋裏面寫過多的廢話。避免在註釋裏面賣弄ASCII藝術,寫笑話,做詩和過於冗長。簡而言之就是保持註釋的簡單和直接。 

7. 使用統一的風格 

有些人以爲註釋應該讓非程序員也能看懂。另一些人以爲註釋須要面對的讀者只是程序員。不管如何,正如Successful Strategies for Commenting Code中所說的,最重要的是註釋的風格須要統一,而且老是面向相同的讀者。就本身而論,我懷疑非程序員是否會去讀代碼,因此我以爲註釋應該面向程序員來寫。

8. 在內部使用特殊的標籤 

當你在一個團隊裏工做的時候,採用一組一致的標籤能幫助不一樣的程序員溝通。例如,不少團隊會採用「TODO」標籤來表示一段還沒有完成的代碼 

int Estimate(int x, int y) 

// TODO: implement the calculations 
return 0; 


標籤註釋並不會解釋代碼,它們尋求注意或者是傳遞信息。可是若是適當地使用這種技術,要記住跟進這段代碼而且完成該標籤傳遞的任務。 

9. 在寫代碼的同時添加註釋 

當你在寫代碼並且記憶猶新的同時就添加註釋。若是等到項目後期才添加註釋,會讓你事倍功半。「我沒有時間寫註釋」,「個人時間很緊迫」和「項目已經延遲了」,這些都是不寫註釋的常見藉口。有些工程師覺最佳的解決方法是「註釋先行」。例如:

public void ProcessOrder() 

// Make sure the products are available 
// Check that the customer is valid 
// Send the order to the store 
// Generate bill 


10. 把本身想象爲註釋的讀者(事實上就是如此) 

當你正在給代碼寫註釋的時候,不只僅爲往後維護你的代碼的開發者考慮,同時也設想一下若是本身就是註釋的讀者。Phil Haack曾經說過: 

「一旦一行代碼被敲到文件中, 你就已經要開始維護那一行代碼了。」 

因此,咱們本身就是好(或者壞)註釋的第一個受益者(或者受害者)。 

11. 更新代碼的時候要更新註釋 

若是註釋沒有隨着代碼的修改而更新,那麼這些註釋將是毫無心義的。代碼和註釋須要同步,不然註釋只會讓維護代碼的開發者更加痛苦。須要特別注意的是,一些重構的工具會自動更新代碼,可是卻沒有自動更新註釋,那麼註釋就天然而然地過時做廢了。

12. 良好可讀性代碼是註釋的金科玉律 

對於不少開發者來講,一個基本的原則就是:讓代碼本身描述本身。雖然有人懷疑這是由不喜歡寫註釋的程序員所倡導的一場運動,可是無需解釋的代碼有很大的好處,這些代碼更加容易理解甚至讓註釋變得沒有必要。例如,在個人文章Fluid Interfaces中就給你們展現了什麼是清晰的無需解釋的代碼。

Calculator calc = new Calculator(); 
calc.Set(0); 
calc.Add(10); 
calc.Multiply(2); 
calc.Subtract(4); 
Console.WriteLine( 「Result: {0}」, calc.Get() ); 

在這個例子裏面,註釋就像是違反了第4條技巧那樣,變得毫無必要。要寫出可讀性好的代碼,你須要使用適當的命名方式(在經典的 Ottinger’s Rules中有闡述),保證恰當的縮進,而且採用編碼風格指導。若是代碼不遵照這條技巧,那麼註釋看起來就好像是爲本身很差的代碼的寫道歉信同樣。

13. 跟你的同事分享這些技巧 

雖然從第10條技巧中咱們已經知道了本身就是好註釋的得益者,可是這些技巧對於全部的開發者來講都是頗有幫助的,尤爲是整個團隊都有相同共識的狀況下。所以,大方地跟你的同事去分享這些技巧,讓咱們寫出更加容易理解和維護的代碼。
2009  -  03  -  10

log4j配置文件的含義

今天試着用了一下log4j來處理java中的日誌,感受良好,順便記錄一下log4j的配置文件log4j.properties各語句的含義。

這是一個數據庫配置文件 

#這是一個配置文件實例,PropertyConfigurator將使用這個文件 : 
#聲明一個appender變量名爲JDBC 
log4j.rootLogger=DEBUG, JDBC 

#JDBC是一個JDBCAppender類,這個類能夠寫消息到數據庫 
log4j.appender.JDBC=com.benqguru.palau.log.jdbc.test.JDBCAppender 

#1.鏈接數據庫的數據庫選項 
log4j.appender.JDBC.url=jdbc:mysql://localhost:3306/logtest 
log4j.appender.JDBC.username=root 
log4j.appender.JDBC.password= 

#2.指定你本身的JDBCConnectionHandler的鏈接器選項 
log4j.appender.JDBC.connection_class=com.benqguru.palau.log.jdbc.test.MyConnectionHandler

#3.指定一個靜態的SQL語句的SQL選項,這個語句將在每次消息事件發生時被執行 
log4j.appender.JDBC.sql=INSERT INTO LOGTEST (id, msg, created_on, created_by) VALUES (1, @MSG@, sysdate, 'me')

#4. 指定數據庫中一個表的表選項。 
log4j.appender.JDBC.table=logtest 

#5.描述表的重要列的列選項(非空列是必須被描述的) 
log4j.appender.JDBC.columns=id_seq~EMPTY id~ID~MyIDHandler msg~MSG created_on~TIMESTAMP created_by~STATIC~Thomas Fenner

#6.定義消息佈局器的佈局器選項(可選) 
log4j.appender.JDBC.layout=org.apache.log4j.PatternLayout 
log4j.appender.JDBC.layout.ConversionPattern=%m 

#7.定義消息事件緩衝器的大小的緩衝器選項(可選) 
log4j.appender.JDBC.buffer_size=1 

#8.定義自動提交的提交選項(可選) 
log4j.appender.JDBC.docommit=N 

##########下面是英文說明############# 
#Date - %d{DATE}[slf5s.DATE] 
#Priority - %p[slf5s.PRIORITY] 
#NDC - %x[slf5s.NDC] 
#Thread - %t[slf5s.THREAD] 
#Category - %c[slf5s.CATEGORY] 
#Location - %l[slf5s.LOCATION] 
#Message - %m[slf5s.MESSAGE] 

#log4j.appender.R.layout.ConversionPattern=[slf5s.start]%d{DATE}[slf5s.DATE]%n/ 
# %p[slf5s.PRIORITY]%n%x[slf5s.NDC]%n%t[slf5s.THREAD]%n/ 
# %c[slf5s.CATEGORY]%n%l[slf5s.LOCATION]%n%m[slf5s.MESSAGE]%n%n 
##########下面是中文說明############# 
#%m 輸出代碼中指定的消息 
#%p 輸出優先級,即DEBUG,INFO,WARN,ERROR,FATAL 
#%r 輸出自應用啓動到輸出該log信息耗費的毫秒數 
#%c 輸出所屬的類目,一般就是所在類的全名 
#%t 輸出產生該日誌事件的線程名 
#%n 輸出一個回車換行符,Windows平臺爲「/r/n」,Unix平臺爲「/n」 
#%d 輸出日誌時間點的日期或時間,默認格式爲ISO8601,也能夠在其後指定格式, 
#好比:%d{yyy MMM dd HH:mm:ss,SSS},輸出相似:2002年10月18日 22:10:28,921 
#%l 輸出日誌事件的發生位置,包括類目名、發生的線程,以及在代碼中的行數。舉例:Testlog4.main(TestLog4.java:10) 


這是一個普通的配置文件 

#log4j會解析這個文件 
log4j.debug=false 
#暫時還不清楚這兩個屬性的做用 
log4j.disableOverride=true 
log4j.disable=INFO 
#設置記錄全部類的日誌的優先級別 
log4j.rootLogger=DEBUG,dest1,dest2 
#設置這個包記錄日誌爲假的話 
#dist1,dist2就不會記錄com.benqguru.commons.logging.test.LoggingSample的日誌,只有dist3會記錄. 
#反之,會記錄,這樣就會重複記錄 
log4j.additivity.com.benqguru.commons.logging.test.LoggingSample=false 
#特別指定某個特殊包的日誌級別和目標設備 
log4j.category.com.benqguru.commons.logging.test.LoggingSample=WARN, dest3 
#這個目標設備用來debug 
log4j.appender.dest1=org.apache.log4j.ConsoleAppender 
#log4j.appender.dest1.layout=org.apache.log4j.SimpleLayout 
log4j.appender.dest1.layout=org.apache.log4j.PatternLayout 
#%-4r %-5p [%t] %37c %3x - %m%n 
log4j.appender.dest1.layout.ConversionPattern=%d %p %c - <%m> (%F.%M:%L) %t%n 

#這個目標設備用來trace 
log4j.appender.dest2=org.apache.log4j.RollingFileAppender 
#該文件記錄日誌的級別(INFO如下的級別不記錄) 
log4j.appender.dest2.Threshold=INFO 
#文件保存路徑 
log4j.appender.dest2.File=c:/log4jlog.htm 
#是否往文件追加信息 
log4j.appender.dest2.Append=true 
#設置文件最大值 
log4j.appender.dest2.MaxFileSize=5KB 
#設置備份文件的最大數量 
log4j.appender.dest2.MaxBackupIndex=10 
#使用一個html格式來記錄日誌 
log4j.appender.dest2.layout=org.apache.log4j.HTMLLayout 
#是否打印該消息的代碼行 
log4j.appender.dest2.layout.LocationInfo=true 
#設置該日誌的html的標題 
log4j.appender.dest2.layout.Title=My app title 

#這個目標設備用來trace指定類或包 
log4j.appender.dest3=org.apache.log4j.DailyRollingFileAppender 
#log4j.appender.dest3.Threshold=DEBUG 
log4j.appender.dest3.File=c:/SpecPackageLog.htm 
log4j.appender.dest3.Append=false 
log4j.appender.dest3.layout=org.apache.log4j.HTMLLayout 
log4j.appender.dest3.layout.LocationInfo=true 
log4j.appender.dest3.layout.Title=My app title 

在Sun的API中對在對 「最大匹配Greedy」「最小匹配Reluctant」「徹底匹配Possessive」的描述,不能讓我明白他們有什麼區別,如今將我對這三種匹配模式的理解寫出來,供你們參考。


一、Greediness(貪心)匹配: 

X?、X*、X+、X{n,}都是最大匹配。例如你要用「<.+>」去匹配「a<tr>aava </tr>abb」,也許你所期待的結果是想匹配「<tr>」,可是實際結果卻會匹配到「<tr>aava </tr>」。這是爲何呢?下面咱們跟蹤下最大匹配的匹配過程。

①「<」匹配字符串的「<」。②「.+」匹配字符串的「tr>aava </tr>ab」,在進行最大匹配時,它把兩個「>」都匹配了,它匹配了全部字符,直到文本的最後字符「b」 ③這時,發現不能成功匹配「>」,開始按原路回退,用「a」與「>」匹配,直到「ab」前面的「>」匹配成功。


二、Reluctant(Laziness)最小匹配 

X?、X*、X+、X{n,}都是最大匹配。好,加個?就成了Laziness匹配。例如X??、X*?、X+?、X{n,}?都是最小匹配,其實X{n,m}?和X{n }?有些多餘。

最小匹配意味者,.+? 匹配一個字符後,立刻試一試>的匹配可能,失敗了,則.+? 再匹配一個字符,再立刻試一試>的匹配可能。JDK文檔中Greedy 和 Reluctant,它是以eat一口來隱喻的,因此翻譯成貪吃和(勉強的)厭食最貼切了。不過我喜歡最大匹配、最小匹配的說法。


三、Possessive徹底匹配 

與最大匹配不一樣,還有一種匹配形式:X?+、X*+、X++、X{n,}+等,成爲徹底匹配。它和最大匹配同樣,一直匹配全部的字符,直到文本的最後,但它不禁原路返回。也就是說,一口匹配,搞不定就算了,到也乾脆,偶喜歡。

Use a possessive quantifier for situations where you want to seize all of something without ever backing off; it will outperform the equivalent greedy quantifier in cases where the match is not immediately found.

[java]  view plain copy
  1. import java.util.regex.Matcher;<BR>
  2. import java.util.regex.Pattern;<BR>
  3. <BR>
  4. public class RegularExpression {<BR>
  5. <BR>
  6. public static void main(String[] args) {<BR>
  7. // 簡單認識正則表達式的概念<BR>
  8. <BR>
  9. // p("abc".matches("..."));<BR>
  10. // p("a8729a".replaceAll("//d", "-"));<BR>
  11. // Pattern p = Pattern.compile("[a-z]{3}");<BR>
  12. // Matcher m = p.matcher("fgh");<BR>
  13. // p(m.matches());<BR>
  14. // p("aaas".matches("[a-z]{3,}"));<BR>
  15. <BR>
  16. // 初步認識. * + ?<BR>
  17. <BR>
  18. // p("a".matches("."));<BR>
  19. // p("aa".matches("aa"));<BR>
  20. // p("aaaa".matches("a*"));<BR>
  21. // p("aaaa".matches("a+"));<BR>
  22. // p("".matches("a*"));<BR>
  23. // p("aaaa".matches("a?"));<BR>
  24. // p("".matches("a?"));<BR>
  25. // p("a".matches("a?"));<BR>
  26. // p("214523145234532".matches("//d{3,100}"));<BR>
  27. // p("192.168.0.231".matches("//d{1,3}//.//d{1,3}//.//d{1,3}//.//d{1,3}"));<BR>
  28. // p("192".matches("[0-2][0-9][0-9]"));<BR>
  29. <BR>
  30. // 範圍<BR>
  31. <BR>
  32. // p("a".matches("[abc]"));<BR>
  33. // p("a".matches("[^abc]"));<BR>
  34. // p("A".matches("[a-zA-Z]"));<BR>
  35. // p("a".matches("[a-z]|[A-Z]"));<BR>
  36. // p("A".matches("[a-z[A-Z]]"));<BR>
  37. // p("R".matches("[A-Z&&[RFG]]"));<BR>
  38. <BR>
  39. // 認識/s /w /d /<BR>
  40. <BR>
  41. // p(" /n/r/t".matches("//s{4}"));<BR>
  42. // p(" ".matches("//S"));<BR>
  43. // p("a_8".matches("//w{3}"));<BR>
  44. // p("abc888&^%".matches("[a-z]{1,3}//d+[&^#%]+"));<BR>
  45. // p("//".matches("////"));<BR>
  46. <BR>
  47. // POSIX Style<BR>
  48. <BR>
  49. // p("a".matches("//p{Lower}"));<BR>
  50. <BR>
  51. // boundary<BR>
  52. <BR>
  53. // p("hello sir".matches("^h.*"));<BR>
  54. // p("hello sir".matches(".*ir$"));<BR>
  55. // p("hello sir".matches("^h[a-z]{1,3}o//b.*"));<BR>
  56. // p("hellosir".matches("^h[a-z]{1,3}o//b.*")); // whilte lines<BR>
  57. // p("/n".matches("^[//s&&[^//n<BR>
  58. // p("aaa 8888c".matches(".*//d{4}."));<BR>
  59. // p("aaa8888c".matches(".*//b//d{4}."));<BR>
  60. // p("aaa8888c".matches(".*//d{4}."));<BR>
  61. // p("aaa 8888c".matches(".*//b//d{4}."));<BR>
  62. <BR>
  63. // email<BR>
  64. <BR>
  65. // p("asdfasdfsafsf@dsdfsdf.com".matches("[//w[.-]]+@[//w[.-]]+//.[//w]+"));<BR>
  66. <BR>
  67. // matches find lookingAt<BR>
  68. <BR>
  69. // Pattern p = Pattern.compile("//d{3,5}");<BR>
  70. // String s = "123-34345-234-00";<BR>
  71. // Matcher m = p.matcher(s);<BR>
  72. // p(m.matches());<BR>
  73. // m.reset();<BR>
  74. // p(m.find());<BR>
  75. // p(m.start() + "-" + m.end());<BR>
  76. // p(m.find());<BR>
  77. // p(m.start() + "-" + m.end());<BR>
  78. // p(m.find());<BR>
  79. // p(m.start() + "-" + m.end());<BR>
  80. // p(m.find());<BR>
  81. // //p(m.start() + "-" + m.end());<BR>
  82. // p(m.lookingAt());<BR>
  83. // p(m.lookingAt());<BR>
  84. // p(m.lookingAt());<BR>
  85. // p(m.lookingAt());<BR>
  86. <BR>
  87. // replacement<BR>
  88. <BR>
  89. // Pattern p = Pattern.compile("java", Pattern.CASE_INSENSITIVE);<BR>
  90. // Matcher m = p<BR>
  91. // .matcher("java Java JAVa JaVa IloveJAVA you hateJava afasdfasdf");<BR>
  92. // StringBuffer buf = new StringBuffer();<BR>
  93. // int i = 0;<BR>
  94. // while (m.find()) {<BR>
  95. // i++;<BR>
  96. // if (i % 2 == 0) {<BR>
  97. // m.appendReplacement(buf, "java");<BR>
  98. // } else {<BR>
  99. // m.appendReplacement(buf, "JAVA");<BR>
  100. // }<BR>
  101. // }<BR>
  102. // m.appendTail(buf);<BR>
  103. // p(buf);<BR>
  104. <BR>
  105. // group<BR>
  106. <BR>
  107. // Pattern p = Pattern.compile("(//d{3,5})([a-z]{2})");<BR>
  108. // String s = "123aa-34345bb-234cc-00";<BR>
  109. // Matcher m = p.matcher(s);<BR>
  110. // while (m.find()) {<BR>
  111. // p(m.group());<BR>
  112. // }<BR>
  113. <BR>
  114. // qulifiers<BR>
  115. <BR>
  116. // Pattern p = Pattern.compile(".{3,10}+[0-9]");<BR>
  117. // String s = "aaaa5bbbb68";<BR>
  118. // Matcher m = p.matcher(s);<BR>
  119. // if (m.find())<BR>
  120. // p(m.start() + "-" + m.end());<BR>
  121. // else<BR>
  122. // p("not match!");<BR>
  123. <BR>
  124. // non-capturing groups<BR>
  125. <BR>
  126. // Pattern p = Pattern.compile(".{3}(?=a)");<BR>
  127. // String s = "444a66b";<BR>
  128. // Matcher m = p.matcher(s);<BR>
  129. // while (m.find()) {<BR>
  130. // p(m.group());<BR>
  131. // }<BR>
  132. <BR>
  133. // back refenrences<BR>
  134. <BR>
  135. // Pattern p = Pattern.compile("(//d(//d))//2");<BR>
  136. // String s = "122";<BR>
  137. // Matcher m = p.matcher(s);<BR>
  138. // p(m.matches());<BR>
  139. <BR>
  140. // flags的簡寫<BR>
  141. Pattern p = Pattern.compile("java", Pattern.CASE_INSENSITIVE);<BR>
  142. p("Java".matches("(?i)(java)"));<BR>
  143. }<BR>
  144. <BR>
  145. public staticvoid p(Object o) {<BR>
  146. System.out.println(o);<BR>
  147. }<BR>
  148. <BR>
  149. }<BR>
[java]  view plain copy
  1. import java.util.regex.Matcher;  
  2.   
  3. import java.util.regex.Pattern;  
  4.   
  5.   
  6.   
  7. public class RegularExpression {  
  8.   
  9.   
  10.   
  11.     public static void main(String[] args) {  
  12.   
  13.         // 簡單認識正則表達式的概念  
  14.   
  15.   
  16.   
  17.         // p("abc".matches("..."));  
  18.   
  19.         // p("a8729a".replaceAll("//d", "-"));  
  20.   
  21.         // Pattern p = Pattern.compile("[a-z]{3}");  
  22.   
  23.         // Matcher m = p.matcher("fgh");  
  24.   
  25.         // p(m.matches());  
  26.   
  27.         // p("aaas".matches("[a-z]{3,}"));  
  28.   
  29.   
  30.   
  31.         // 初步認識. * + ?  
  32.   
  33.   
  34.   
  35.         // p("a".matches("."));  
  36.   
  37.         // p("aa".matches("aa"));  
  38.   
  39.         // p("aaaa".matches("a*"));  
  40.   
  41.         // p("aaaa".matches("a+"));  
  42.   
  43.         // p("".matches("a*"));  
  44.   
  45.         // p("aaaa".matches("a?"));  
  46.   
  47.         // p("".matches("a?"));  
  48.   
  49.         // p("a".matches("a?"));  
  50.   
  51.         // p("214523145234532".matches("//d{3,100}"));  
  52.   
  53.         // p("192.168.0.231".matches("//d{1,3}//.//d{1,3}//.//d{1,3}//.//d{1,3}"));  
  54.   
  55.         // p("192".matches("[0-2][0-9][0-9]"));  
  56.   
  57.   
  58.   
  59.         // 範圍  
  60.   
  61.   
  62.   
  63.         // p("a".matches("[abc]"));  
  64.   
  65.         // p("a".matches("[^abc]"));  
  66.   
  67.         // p("A".matches("[a-zA-Z]"));  
  68.   
  69.         // p("a".matches("[a-z]|[A-Z]"));  
  70.   
  71.         // p("A".matches("[a-z[A-Z]]"));  
  72.   
  73.         // p("R".matches("[A-Z&&[RFG]]"));  
  74.   
  75.   
  76.   
  77.         // 認識/s /w /d /  
  78.   
  79.   
  80.   
  81.         // p(" /n/r/t".matches("//s{4}"));  
  82.   
  83.         // p(" ".matches("//S"));  
  84.   
  85.         // p("a_8".matches("//w{3}"));  
  86.   
  87.         // p("abc888&^%".matches("[a-z]{1,3}//d+[&^#%]+"));  
  88.   
  89.         // p("//".matches("////"));  
  90.   
  91.   
  92.   
  93.         // POSIX Style  
  94.   
  95.   
  96.   
  97.         // p("a".matches("//p{Lower}"));  
  98.   
  99.   
  100.   
  101.         // boundary  
  102.   
  103.   
  104.   
  105.         // p("hello sir".matches("^h.*"));  
  106.   
  107.         // p("hello sir".matches(".*ir$"));  
  108.   
  109.         // p("hello sir".matches("^h[a-z]{1,3}o//b.*"));  
  110.   
  111.         // p("hellosir".matches("^h[a-z]{1,3}o//b.*")); // whilte lines  
  112.   
  113.         // p("/n".matches("^[//s&&[^//n  
  114.   
  115.         // p("aaa 8888c".matches(".*//d{4}."));  
  116.   
  117.         // p("aaa8888c".matches(".*//b//d{4}."));  
  118.   
  119.         // p("aaa8888c".matches(".*//d{4}."));  
  120.   
  121.         // p("aaa 8888c".matches(".*//b//d{4}."));  
  122.   
  123.   
  124.   
  125.         // email  
  126.   
  127.   
  128.   
  129.         // p("asdfasdfsafsf@dsdfsdf.com".matches("[//w[.-]]+@[//w[.-]]+//.[//w]+"));  
  130.   
  131.   
  132.   
  133.         // matches find lookingAt  
  134.   
  135.   
  136.   
  137.         // Pattern p = Pattern.compile("//d{3,5}");  
  138.   
  139.         // String s = "123-34345-234-00";  
  140.   
  141.         // Matcher m = p.matcher(s);  
  142.   
  143.         // p(m.matches());  
  144.   
  145.         // m.reset();  
  146.   
  147.         // p(m.find());  
  148.   
  149.         // p(m.start() + "-" + m.end());  
  150.   
  151.         // p(m.find());  
  152.   
  153.         // p(m.start() + "-" + m.end());  
  154.   
  155.         // p(m.find());  
  156.   
  157.         // p(m.start() + "-" + m.end());  
  158.   
  159.         // p(m.find());  
  160.   
  161.         // //p(m.start() + "-" + m.end());  
  162.   
  163.         // p(m.lookingAt());  
  164.   
  165.         // p(m.lookingAt());  
  166.   
  167.         // p(m.lookingAt());  
  168.   
  169.         // p(m.lookingAt());  
  170.   
  171.   
  172.   
  173.         // replacement  
  174.   
  175.   
  176.   
  177.         // Pattern p = Pattern.compile("java", Pattern.CASE_INSENSITIVE);  
  178.   
  179.         // Matcher m = p  
  180.   
  181.         // .matcher("java Java JAVa JaVa IloveJAVA you hateJava afasdfasdf");  
  182.   
  183.         // StringBuffer buf = new StringBuffer();  
  184.   
  185.         // int i = 0;  
  186.   
  187.         // while (m.find()) {  
  188.   
  189.         // i++;  
  190.   
  191.         // if (i % 2 == 0) {  
  192.   
  193.         // m.appendReplacement(buf, "java");  
  194.   
  195.         // } else {  
  196.   
  197.         // m.appendReplacement(buf, "JAVA");  
  198.   
  199.         // }  
  200.   
  201.         // }  
  202.   
  203.         // m.appendTail(buf);  
  204.   
  205.         // p(buf);  
  206.   
  207.   
  208.   
  209.         // group  
  210.   
  211.   
  212.   
  213.         // Pattern p = Pattern.compile("(//d{3,5})([a-z]{2})");  
  214.   
  215.         // String s = "123aa-34345bb-234cc-00";  
  216.   
  217.         // Matcher m = p.matcher(s);  
  218.   
  219.         // while (m.find()) {  
  220.   
  221.         // p(m.group());  
  222.   
  223.         // }  
  224.   
  225.   
  226.   
  227.         // qulifiers  
  228.   
  229.   
  230.   
  231.         // Pattern p = Pattern.compile(".{3,10}+[0-9]");  
  232.   
  233.         // String s = "aaaa5bbbb68";  
  234.   
  235.         // Matcher m = p.matcher(s);  
  236.   
  237.         // if (m.find())  
  238.   
  239.         // p(m.start() + "-" + m.end());  
  240.   
  241.         // else  
  242.   
  243.         // p("not match!");  
  244.   
  245.   
  246.   
  247.         // non-capturing groups  
  248.   
  249.   
  250.   
  251.         // Pattern p = Pattern.compile(".{3}(?=a)");  
  252.   
  253.         // String s = "444a66b";  
  254.   
  255.         // Matcher m = p.matcher(s);  
  256.   
  257.         // while (m.find()) {  
  258.   
  259.         // p(m.group());  
  260.   
  261.         // }  
  262.   
  263.   
  264.   
  265.         // back refenrences  
  266.   
  267.   
  268.   
  269.         // Pattern p = Pattern.compile("(//d(//d))//2");  
  270.   
  271.         // String s = "122";  
  272.   
  273.         // Matcher m = p.matcher(s);  
  274.   
  275.         // p(m.matches());  
  276.   
  277.   
  278.   
  279.         // flags的簡寫  
  280.   
  281.         Pattern p = Pattern.compile("java", Pattern.CASE_INSENSITIVE);  
  282.   
  283.         p("Java".matches("(?i)(java)"));  
  284.   
  285.     }  
  286.   
  287.   
  288.   
  289.     public static void p(Object o) {  
  290.   
  291.         System.out.println(o);  
  292.   
  293.     }  
  294.   
  295.   
  296.   
  297. }  
2009  -  02  -  06

Java snippets02

[java]  view plain copy
  1. if (Character.isLowerCase(ch[i])) {<BR>
  2. char temp = Character.toUpperCase(ch[i]);<BR>
  3. ch[i] = temp;<BR>
  4. else if (Character.isUpperCase(ch[i])) {<BR>
  5. char temp = Character.toLowerCase(ch[i]);<BR>
  6. ch[i] = temp;<BR>
  7. }
[java]  view plain copy
  1. if (Character.isLowerCase(ch[i])) {  
  2.   
  3.     char temp = Character.toUpperCase(ch[i]);  
  4.   
  5.     ch[i] = temp;  
  6.   
  7. else if (Character.isUpperCase(ch[i])) {  
  8.   
  9.     char temp = Character.toLowerCase(ch[i]);  
  10.   
  11.     ch[i] = temp;  
  12.   
  13. }  

[java]  view plain copy
  1. while (true) {<BR>
  2. flag = 0;<BR>
  3. result = tc.getNum();<BR>
  4. >
  5. input = Integer.parseInt(br.readLine());<BR>
  6. >
  7. while (flag == 0) {<BR>
  8. if (input == result) {<BR>
  9. System.out.println("very good!");<BR>
  10. flag = 1;<BR>
  11. else {<BR>
  12. flag = 0;<BR>
  13. System.out.println("no,please try again.");<BR>
  14. input = Integer.parseInt(br.readLine());<BR>
  15. }<BR>
  16. }<BR>
  17. }
[java]  view plain copy
  1. while (true) {  
  2.   
  3.     flag = 0;  
  4.   
  5.     result = tc.getNum();  
  6.   
  7.   
  8.   
  9.     input = Integer.parseInt(br.readLine());  
  10.   
  11.   
  12.   
  13.     while (flag == 0) {  
  14.   
  15.         if (input == result) {  
  16.   
  17.             System.out.println("very good!");  
  18.   
  19.             flag = 1;  
  20.   
  21.         } else {  
  22.   
  23.             flag = 0;  
  24.   
  25.             System.out.println("no,please try again.");  
  26.   
  27.             input = Integer.parseInt(br.readLine());  
  28.   
  29.         }  
  30.   
  31.     }  
  32.   
  33. }  

[java]  view plain copy
  1. L1: while (true) {<BR>
  2. int question = new Times().question();<BR>
  3. L2: while (true) {<BR>
  4. int answer = scanner.nextInt();<BR>
  5. if (answer == question) {<BR>
  6. System.out.println("very good!");<BR>
  7. continue L1;<BR>
  8. else {<BR>
  9. System.out.println("no,please try again.");<BR>
  10. continue L2;<BR>
  11. }<BR>
  12. }<BR>
  13. }
[java]  view plain copy
  1. L1: while (true) {  
  2.   
  3.     int question = new Times().question();  
  4.   
  5.     L2: while (true) {  
  6.   
  7.         int answer = scanner.nextInt();  
  8.   
  9.         if (answer == question) {  
  10.   
  11.             System.out.println("very good!");  
  12.   
  13.             continue L1;  
  14.   
  15.         } else {  
  16.   
  17.             System.out.println("no,please try again.");  
  18.   
  19.             continue L2;  
  20.   
  21.         }  
  22.   
  23.     }  
  24.   
  25. }  

[java]  view plain copy
  1. char[] c1 = s1.toCharArray();
[java]  view plain copy
  1. char[] c1 = s1.toCharArray();  

[java]  view plain copy
  1. Map<Integer, String> m =new HashMap<Integer, String>();<BR>
  2. m.put(1"one");<BR>
  3. m.put(2"two");<BR>
  4. m.put(3"three");<BR>
  5. Object o[] = m.values().toArray();
[java]  view plain copy
  1. Map<Integer, String> m = new HashMap<Integer, String>();  
  2.   
  3. m.put(1"one");  
  4.   
  5. m.put(2"two");  
  6.   
  7. m.put(3"three");  
  8.   
  9. Object o[] = m.values().toArray();  

[java]  view plain copy
  1. GregorianCalendar ca = new GregorianCalendar();<BR>
  2. System.out.println(ca.get(GregorianCalendar.AM_PM));
[java]  view plain copy
  1. GregorianCalendar ca = new GregorianCalendar();  
  2.   
  3. System.out.println(ca.get(GregorianCalendar.AM_PM));  

2009  -  02  -  06

Java snippets01

[java]  view plain copy
  1. for (int i =0; i < number.length; i++) {<BR>
  2. for (int j = 0; j < number.length - i - 1; j++) {<BR>
  3. if (number[j] < number[j + 1]) {<BR>
  4. int temp = number[j];<BR>
  5. number[j] = number[j + 1];<BR>
  6. number[j + 1] = temp;<BR>
  7. }<BR>
  8. }<BR>
  9. }<BR>
[java]  view plain copy
  1. for (int i = 0; i < number.length; i++) {  
  2.   
  3.     for (int j = 0; j < number.length - i - 1; j++) {  
  4.   
  5.         if (number[j] < number[j + 1]) {  
  6.   
  7.             int temp = number[j];  
  8.   
  9.             number[j] = number[j + 1];  
  10.   
  11.             number[j + 1] = temp;  
  12.   
  13.         }  
  14.   
  15.     }  
  16.   
  17. }  

[java]  view plain copy
  1. BufferedReader buffer = new BufferedReader(new InputStreamReader(System.in));<BR>
  2. String str = buffer.readLine();
[java]  view plain copy
  1. BufferedReader buffer = new BufferedReader(new InputStreamReader(System.in));  
  2.   
  3. String str = buffer.readLine();  

[java]  view plain copy
  1. Scanner scanner = new Scanner(System.in);<BR>
  2. String line = scanner.nextLine();
[java]  view plain copy
  1. Scanner scanner = new Scanner(System.in);  
  2.   
  3. String line = scanner.nextLine();  


[java]  view plain copy
  1. InputStreamReader in = null;<BR>
  2. OutputStreamWriter out = null;<BR>
  3. BufferedReader br = null;<BR>
  4. <BR>
  5. in = new InputStreamReader(new FileInputStream(System<BR>
  6. .getProperty("user.dir")<BR>
  7. "//old.txt"), "UTF-8");<BR>
  8. br = new BufferedReader(in);<BR>
  9. out = new OutputStreamWriter(new FileOutputStream(<BR>
  10. "C://WINDOWS//new.txt"), "UTF-8");
[java]  view plain copy
  1. InputStreamReader in = null;  
  2.   
  3. OutputStreamWriter out = null;  
  4.   
  5. BufferedReader br = null;  
  6.   
  7.   
  8.   
  9. in = new InputStreamReader(new FileInputStream(System  
  10.   
  11.                     .getProperty("user.dir")  
  12.   
  13.                     + "//old.txt"), "UTF-8");  
  14.   
  15. br = new BufferedReader(in);  
  16.   
  17. out = new OutputStreamWriter(new FileOutputStream(  
  18.   
  19.                     "C://WINDOWS//new.txt"), "UTF-8");  

[java]  view plain copy
  1. String[] temp;<BR>
  2. temp = text.split("//s{1,}");// 按照空格分割字符串,多個空格做爲一個空格對字符串進行分割
[java]  view plain copy
  1. String[] temp;  
  2.   
  3. temp = text.split("//s{1,}");// 按照空格分割字符串,多個空格做爲一個空格對字符串進行分割  

[java]  view plain copy
  1. String s = String.valueOf(1);<BR>
  2. if (s.charAt(i) == '1'){}<BR>
[java]  view plain copy
  1. String s = String.valueOf(1);  
  2.   
  3. if (s.charAt(i) == '1'){}  

[java]  view plain copy
  1. System.nanoTime();
[java]  view plain copy
  1. System.nanoTime();  

[java]  view plain copy
  1. SimpleDateFormat sdt = new SimpleDateFormat("yyyy-MM-DD HH:mm:ss");<BR>
  2. String date = sdt.format(System.currentTimeMillis());
[java]  view plain copy
  1. SimpleDateFormat sdt = new SimpleDateFormat("yyyy-MM-DD HH:mm:ss");  
  2.   
  3. String date = sdt.format(System.currentTimeMillis());  

[java]  view plain copy
  1. DecimalFormat df = (DecimalFormat) NumberFormat.getInstance();<BR>
  2. df.applyPattern("00");
[java]  view plain copy
  1. DecimalFormat df = (DecimalFormat) NumberFormat.getInstance();  
  2.   
  3. df.applyPattern("00");  

[java]  view plain copy
  1. Calendar current_time = new GregorianCalendar();<BR>
  2. Calendar target_time = new GregorianCalendar(2009, Calendar.MAY,1);<BR>
  3. long diffMillis = target_time.getTimeInMillis()<BR>
  4. - current_time.getTimeInMillis();<BR>
  5. long diffDays = diffMillis / (24 *60 * 60 * 1000) + 1;<BR>
  6. SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-DD");<BR>
  7. <BR>
  8. System.out.println("距" + sdf.format(target_time.getTimeInMillis())<BR>
  9. "還有:" + diffDays + "天");
[java]  view plain copy
  1. Calendar current_time = new GregorianCalendar();  
  2.   
  3. Calendar target_time = new GregorianCalendar(2009, Calendar.MAY, 1);  
  4.   
  5. long diffMillis = target_time.getTimeInMillis()  
  6.   
  7.         - current_time.getTimeInMillis();  
  8.   
  9. long diffDays = diffMillis / (24 * 60 * 60 * 1000) + 1;  
  10.   
  11. SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-DD");  
  12.   
  13.   
  14.   
  15. System.out.println("距" + sdf.format(target_time.getTimeInMillis())  
  16.   
  17.         + "還有:" + diffDays + "天");  

[java]  view plain copy
  1. Arrays.sort(array);
[java]  view plain copy
  1. Arrays.sort(array);  

[java]  view plain copy
  1. StringBuilder s1 = new StringBuilder(temp);<BR>
  2. // StringBuffer s1 = new StringBuffer(temp);<BR>
  3. System.out.println(s1.reverse());
[java]  view plain copy
  1. StringBuilder s1 = new StringBuilder(temp);  
  2.   
  3. // StringBuffer s1 = new StringBuffer(temp);  
  4.   
  5. System.out.println(s1.reverse());  

2009  -  02  -  06

雙色球算號器

我是個彩民,特別喜歡買雙色球。最近看了幾種算法,寫了一個很簡單的雙色球的算號器,分享給你們,僅供娛樂,呵呵 
[java]  view plain copy
  1. package com.tester.luckly;<BR>
  2. <BR>
  3. import java.util.Random;<BR>
  4. import java.util.Scanner;<BR>
  5. import java.util.Set;<BR>
  6. import java.util.TreeSet;<BR>
  7. <BR>
  8. public class DoubleBall {<BR>
  9. private Set<Integer> hs;<BR>
  10. private static boolean flag = true;<BR>
  11. <BR>
  12. public enum oddOrEven {<BR>
  13. Odd, Even<BR>
  14. }<BR>
  15. <BR>
  16. public enum aOrBOrC {<BR>
  17. A, B, C<BR>
  18. }<BR>
  19. <BR>
  20. public static void main(String[] args) {<BR>
  21. DoubleBall db = new DoubleBall();<BR>
  22. System.out<BR>
  23. .println("====================Red Balls============================");<BR>
  24. String url1 = "http://map.zhcw.com/ssq//html/h7fenqu_ascstr=20.html";<BR>
  25. System.out.println();<BR>
  26. System.err.println(url1);<BR>
  27. Scanner scanner1 = new Scanner(System.in);<BR>
  28. System.out.println("Please select:1.Input your own two numbers");<BR>
  29. System.out<BR>
  30. .println(" 2.Input the range of the two numbers");<BR>
  31. int select = scanner1.nextInt();<BR>
  32. if (select == 1) {<BR>
  33. flag = false;<BR>
  34. else {<BR>
  35. flag = true;<BR>
  36. }<BR>
  37. System.out.println("Please input two numbers like this: 1 2");<BR>
  38. scanner1.nextLine();<BR>
  39. String[] str = scanner1.nextLine().split(" ");<BR>
  40. Set<Integer> redBall = db.calcRedBall(Integer.parseInt(str[0]), Integer<BR>
  41. .parseInt(str[1]));<BR>
  42. <BR>
  43. System.out<BR>
  44. .println("====================Blue Ball============================");<BR>
  45. String url2 = "http://sports.sohu.com/s2007/0445/s252476794/";<BR>
  46. System.out.println();<BR>
  47. System.err.println(url2);<BR>
  48. Scanner scanner2 = new Scanner(System.in);<BR>
  49. <BR>
  50. System.out.println("1.Please select:" + oddOrEven.Odd +" or "<BR>
  51. + oddOrEven.Even);<BR>
  52. String select1 = scanner2.nextLine();<BR>
  53. <BR>
  54. System.out.println("2.Please select:" + aOrBOrC.A +" or " + aOrBOrC.B<BR>
  55. " or " + aOrBOrC.C);<BR>
  56. String select2 = scanner2.nextLine();<BR>
  57. <BR>
  58. int blueBall = db.calcBlueBall(select1, select2);<BR>
  59. <BR>
  60. System.out<BR>
  61. .println("====================The Result============================");<BR>
  62. System.out.println();<BR>
  63. for (int i : redBall) {<BR>
  64. System.err.print(i + " ");<BR>
  65. }<BR>
  66. System.err.println("| " + blueBall);<BR>
  67. String url3 = "http://www.bwlc.net/dhtz/";<BR>
  68. System.err.println(url3);<BR>
  69. }<BR>
  70. <BR>
  71. public Set<Integer> calcRedBall(int begin,int end) {<BR>
  72. hs = new TreeSet<Integer>();<BR>
  73. <BR>
  74. /*<BR>
  75. * 固定恆碼:就是每期都必備的號碼,一般爲2-3個,如02,13,27。 這2-3個號碼長期備選(至少50期)。<BR>
  76. */<BR>
  77. hs.add(10);<BR>
  78. hs.add(27);<BR>
  79. <BR>
  80. /*<BR>
  81. * 邊緣撿「膽」:就是在邊緣碼「0五、十、1五、20、2五、30」及「0一、<BR>
  82. * 0六、十一、1六、2一、2六、31」共13個號碼中巧妙地撿出膽碼。之因此 把邊緣碼做爲「膽」碼的一種選取方法,是由於從歷史中獎號碼來看,<BR>
  83. * 幾乎每一期都會在具有這種特性的號碼中出現2-3個。<BR>
  84. */<BR>
  85. int[] array = { 51520253001061116212631 };<BR>
  86. for (int i = 0; i < 2; i++) {<BR>
  87. Random random = new Random();<BR>
  88. hs.add(array[random.nextInt(array.length)]);<BR>
  89. }<BR>
  90. <BR>
  91. /*<BR>
  92. * 重碼追鄰:在上上期出號的左右選取的上期號碼,這話很差理解,現舉例說明:雙色球2007109期開01 04 07 08 13 14;<BR>
  93. * 110期開02 04 07 15 24 28;其中這期的04<BR>
  94. * 07,恰好是109期2、三位的重碼,那麼111期的重碼該選取哪一個呢?重碼追鄰就是在110期的04 07 的左右選取,110期04 07<BR>
  95. * 的左右是02 15。因此111期的備選號就是02 15 了。實際上111期重碼恰好開的是02。重碼追鄰通常選取2-3個號碼。<BR>
  96. */<BR>
  97. /* ========= 或者========= */<BR>
  98. /* 旺區落「膽」。就是在最近幾期熱號區選擇膽碼。好比,若是最近的5期內,在中區12~22出號比較密集,那麼就要在這個區域裏選取3個膽碼。這樣選擇的理由是熱碼恆熱原理,即號碼老是在某個區域相對集中出現。 */<BR>
  99. if (flag == true) {<BR>
  100. hs.add(begin);<BR>
  101. hs.add(end);<BR>
  102. else {<BR>
  103. Random random = new Random();<BR>
  104. hs.add(begin + random.nextInt(end - begin + 1));<BR>
  105. }<BR>
  106. /* Luck number! */<BR>
  107. while (hs.size() < 6) {<BR>
  108. Random random = new Random();<BR>
  109. hs.add(1 + random.nextInt(33));<BR>
  110. }<BR>
  111. <BR>
  112. return hs;<BR>
  113. }<BR>
  114. <BR>
  115. public int calcBlueBall(String select1, String select2) {<BR>
  116. int begin = 1;<BR>
  117. int end = 16;<BR>
  118. <BR>
  119. if (select2.equals(aOrBOrC.A.toString())) {<BR>
  120. begin = 1;<BR>
  121. end = 5;<BR>
  122. else if (select2.equals(aOrBOrC.B.toString())) {<BR>
  123. begin = 6;<BR>
  124. end = 10;<BR>
  125. else {<BR>
  126. begin = 11;<BR>
  127. end = 16;<BR>
  128. }<BR>
  129. <BR>
  130. Random random = new Random();<BR>
  131. int blueBall = begin + random.nextInt(end - begin +1);<BR>
  132. if (select1.equals(oddOrEven.Odd.toString())) {<BR>
  133. while (blueBall % 2 == 0) {<BR>
  134. blueBall = begin + random.nextInt(end - begin + 1);<BR>
  135. }<BR>
  136. else {<BR>
  137. while (blueBall % 2 == 1) {<BR>
  138. blueBall = begin + random.nextInt(end - begin + 1);<BR>
  139. }<BR>
  140. }<BR>
  141. <BR>
  142. return blueBall;<BR>
  143. }<BR>
  144. }
[java]  view plain copy
  1. package com.tester.luckly;  
  2.   
  3.   
  4.   
  5. import java.util.Random;  
  6.   
  7. import java.util.Scanner;  
  8.   
  9. import java.util.Set;  
  10.   
  11. import java.util.TreeSet;  
  12.   
  13.   
  14.   
  15. public class DoubleBall {  
  16.   
  17.     private Set<Integer> hs;  
  18.   
  19.     private static boolean flag = true;  
  20.   
  21.   
  22.   
  23.     public enum oddOrEven {  
  24.   
  25.         Odd, Even  
  26.   
  27.     }  
  28.   
  29.   
  30.   
  31.     public enum aOrBOrC {  
  32.   
  33.         A, B, C  
  34.   
  35.     }  
  36.   
  37.   
  38.   
  39.     public static void main(String[] args) {  
  40.   
  41.         DoubleBall db = new DoubleBall();  
  42.   
  43.         System.out  
  44.   
  45.                 .println("====================Red Balls============================");  
  46.   
  47.         String url1 = "http://map.zhcw.com/ssq//html/h7fenqu_ascstr=20.html";  
  48.   
  49.         System.out.println();  
  50.   
  51.         System.err.println(url1);  
  52.   
  53.         Scanner scanner1 = new Scanner(System.in);  
  54.   
  55.         System.out.println("Please select:1.Input your own two numbers");  
  56.   
  57.         System.out  
  58.   
  59.                 .println("              2.Input the range of the two numbers");  
  60.   
  61.         int select = scanner1.nextInt();  
  62.   
  63.         if (select == 1) {  
  64.   
  65.             flag = false;  
  66.   
  67.         } else {  
  68.   
  69.             flag = true;  
  70.   
  71.         }  
  72.   
  73.         System.out.println("Please input two numbers like this: 1 2");  
  74.   
  75.         scanner1.nextLine();  
  76.   
  77.         String[] str = scanner1.nextLine().split(" ");  
  78.   
  79.         Set<Integer> redBall = db.calcRedBall(Integer.parseInt(str[0]), Integer  
  80.   
  81.                 .parseInt(str[1]));  
  82.   
  83.   
  84.   
  85.         System.out  
  86.   
  87.                 .println("====================Blue Ball============================");  
  88.   
  89.         String url2 = "http://sports.sohu.com/s2007/0445/s252476794/";  
  90.   
  91.         System.out.println();  
  92.   
  93.         System.err.println(url2);  
  94.   
  95.         Scanner scanner2 = new Scanner(System.in);  
  96.   
  97.   
  98.   
  99.         System.out.println("1.Please select:" + oddOrEven.Odd + " or "  
  100.   
  101.                 + oddOrEven.Even);  
  102.   
  103.         String select1 = scanner2.nextLine();  
  104.   
  105.   
  106.   
  107.         System.out.println("2.Please select:" + aOrBOrC.A + " or " + aOrBOrC.B  
  108.   
  109.                 + " or " + aOrBOrC.C);  
  110.   
  111.         String select2 = scanner2.nextLine();  
  112.   
  113.   
  114.   
  115.         int blueBall = db.calcBlueBall(select1, select2);  
  116.   
  117.   
  118.   
  119.         System.out  
  120.   
  121.                 .println("====================The Result============================");  
  122.   
  123.         System.out.println();  
  124.   
  125.         for (int i : redBall) {  
  126.   
  127.             System.err.print(i + " ");  
  128.   
  129.         }  
  130.   
  131.         System.err.println("| " + blueBall);  
  132.   
  133.         String url3 = "http://www.bwlc.net/dhtz/";  
  134.   
  135.         System.err.println(url3);  
  136.   
  137.     }  
  138.   
  139.   
  140.   
  141.     public Set<Integer> calcRedBall(int begin, int end) {  
  142.   
  143.         hs = new TreeSet<Integer>();  
  144.   
  145.   
  146.   
  147.         /* 
  148.  
  149.          * 固定恆碼:就是每期都必備的號碼,一般爲2-3個,如02,13,27。 這2-3個號碼長期備選(至少50期)。 
  150.  
  151.          */  
  152.   
  153.         hs.add(10);  
  154.   
  155.         hs.add(27);  
  156.   
  157.   
  158.   
  159.         /* 
  160.  
  161.          * 邊緣撿「膽」:就是在邊緣碼「0五、十、1五、20、2五、30」及「0一、 
  162.  
  163.          * 0六、十一、1六、2一、2六、31」共13個號碼中巧妙地撿出膽碼。之因此 把邊緣碼做爲「膽」碼的一種選取方法,是由於從歷史中獎號碼來看, 
  164.  
  165.          * 幾乎每一期都會在具有這種特性的號碼中出現2-3個。 
  166.  
  167.          */  
  168.   
  169.         int[] array = { 51520253001061116212631 };  
  170.   
  171.         for (int i = 0; i < 2; i++) {  
  172.   
  173.             Random random = new Random();  
  174.   
  175.             hs.add(array[random.nextInt(array.length)]);  
  176.   
  177.         }  
  178.   
  179.   
  180.   
  181.         /* 
  182.  
  183.          * 重碼追鄰:在上上期出號的左右選取的上期號碼,這話很差理解,現舉例說明:雙色球2007109期開01 04 07 08 13 14; 
  184.  
  185.          * 110期開02 04 07 15 24 28;其中這期的04 
  186.  
  187.          * 07,恰好是109期2、三位的重碼,那麼111期的重碼該選取哪一個呢?重碼追鄰就是在110期的04 07 的左右選取,110期04 07 
  188.  
  189.          * 的左右是02 15。因此111期的備選號就是02 15 了。實際上111期重碼恰好開的是02。重碼追鄰通常選取2-3個號碼。 
  190.  
  191.          */  
  192.   
  193.         /* ========= 或者========= */  
  194.   
  195.         /* 旺區落「膽」。就是在最近幾期熱號區選擇膽碼。好比,若是最近的5期內,在中區12~22出號比較密集,那麼就要在這個區域裏選取3個膽碼。這樣選擇的理由是熱碼恆熱原理,即號碼老是在某個區域相對集中出現。 */  
  196.   
  197.         if (flag == true) {  
  198.   
  199.             hs.add(begin);  
  200.   
  201.             hs.add(end);  
  202.   
  203.         } else {  
  204.   
  205.             Random random = new Random();  
  206.   
  207.             hs.add(begin + random.nextInt(end - begin + 1));  
  208.   
  209.         }  
  210.   
  211.         /* Luck number! */  
  212.   
  213.         while (hs.size() < 6) {  
  214.   
  215.             Random random = new Random();  
  216.   
  217.             hs.add(1 + random.nextInt(33));  
  218.   
  219.         }  
  220.   
  221.   
  222.   
  223.         return hs;  
  224.   
  225.     }  
  226.   
  227.   
  228.   
  229.     public int calcBlueBall(String select1, String select2) {  
  230.   
  231.         int begin = 1;  
  232.   
  233.         int end = 16;  
  234.   
  235.   
  236.   
  237.         if (select2.equals(aOrBOrC.A.toString())) {  
  238.   
  239.             begin = 1;  
  240.   
  241.             end = 5;  
  242.   
  243.         } else if (select2.equals(aOrBOrC.B.toString())) {  
  244.   
  245.             begin = 6;  
  246.   
  247.             end = 10;  
  248.   
  249.         } else {  
  250.   
  251.             begin = 11;  
  252.   
  253.             end = 16;  
  254.   
  255.         }  
  256.   
  257.   
  258.   
  259.         Random random = new Random();  
  260.   
  261.         int blueBall = begin + random.nextInt(end - begin + 1);  
  262.   
  263.         if (select1.equals(oddOrEven.Odd.toString())) {  
  264.   
  265.             while (blueBall % 2 == 0) {  
  266.   
  267.                 blueBall = begin + random.nextInt(end - begin + 1);  
  268.   
  269.             }  
  270.   
  271.         } else {  
  272.   
  273.             while (blueBall % 2 == 1) {  
  274.   
  275.                 blueBall = begin + random.nextInt(end - begin + 1);  
  276.   
  277.             }  
  278.   
  279.         }  
  280.   
  281.   
  282.   
  283.         return blueBall;  
  284.   
  285.     }  
  286.   
  287. }  

今天遇到了一個極其鬱悶的問題,想寫一段代碼,能夠給windows自動安裝一種字體。 
原理就是將4個ttf字體文件複製到C://WINDOWS//Fonts//目錄下。原本覺得很簡單,但用java I/O複製過去的字體不能使用(將記事本的字體改爲DejaVuSansMono,若是有效果變化,就是正常的),直接手動複製一樣的文件過去,就能夠使用。不知道問題出在哪裏?
哪位朋友幫忙看看,萬分感謝,字體文件在附件中,代碼以下: 
[java]  view plain copy
  1. package com.test;<BR>
  2. import java.io.FileInputStream;<BR>
  3. import java.io.FileOutputStream;<BR>
  4. import java.io.IOException;<BR>
  5. import java.nio.channels.FileChannel;<BR>
  6. <BR>
  7. public class FontInstall {<BR>
  8. <BR>
  9. public staticvoid main(String[] args) {<BR>
  10. try {<BR>
  11. String[] fonts = { "DejaVuSansMono-Oblique.ttf",<BR>
  12. "DejaVuSansMono-BoldOblique.ttf""DejaVuSansMono.ttf",<BR>
  13. "DejaVuSansMono-Bold.ttf" };<BR>
  14. System.out.println();<BR>
  15. for (int i =0; i < fonts.length; i++) {<BR>
  16. // Create channel on the source<BR>
  17. FileChannel srcChannel = new FileInputStream(System<BR>
  18. .getProperty("user.dir")<BR>
  19. "//" + fonts[i]).getChannel();<BR>
  20. <BR>
  21. // Create channel on the destination<BR>
  22. FileChannel dstChannel = new FileOutputStream(<BR>
  23. "C://WINDOWS//Fonts//" + fonts[i]).getChannel();<BR>
  24. <BR>
  25. // Copy file contents from source to destination<BR>
  26. dstChannel.transferFrom(srcChannel, 0, srcChannel.size());<BR>
  27. <BR>
  28. // Close the channels<BR>
  29. srcChannel.close();<BR>
  30. dstChannel.close();<BR>
  31. }<BR>
  32. catch (IOException e) {<BR>
  33. }<BR>
  34. }<BR>
  35. }<BR>
[java]  view plain copy
  1. package com.test;  
  2.   
  3. import java.io.FileInputStream;  
  4.   
  5. import java.io.FileOutputStream;  
  6.   
  7. import java.io.IOException;  
  8.   
  9. import java.nio.channels.FileChannel;  
  10.   
  11.   
  12.   
  13. public class FontInstall {  
  14.   
  15.   
  16.   
  17.     public static void main(String[] args) {  
  18.   
  19.         try {  
  20.   
  21.             String[] fonts = { "DejaVuSansMono-Oblique.ttf",  
  22.   
  23.                     "DejaVuSansMono-BoldOblique.ttf""DejaVuSansMono.ttf",  
  24.   
  25.                     "DejaVuSansMono-Bold.ttf" };  
  26.   
  27.             System.out.println();  
  28.   
  29.             for (int i = 0; i < fonts.length; i++) {  
  30.   
  31.                 // Create channel on the source  
  32.   
  33.                 FileChannel srcChannel = new FileInputStream(System  
  34.   
  35.                         .getProperty("user.dir")  
  36.   
  37.                         + "//" + fonts[i]).getChannel();  
  38.   
  39.   
  40.   
  41.                 // Create channel on the destination  
  42.   
  43.                 FileChannel dstChannel = new FileOutputStream(  
  44.   
  45.                         "C://WINDOWS//Fonts//" + fonts[i]).getChannel();  
  46.   
  47.   
  48.   
  49.                 // Copy file contents from source to destination  
  50.   
  51.                 dstChannel.transferFrom(srcChannel, 0, srcChannel.size());  
  52.   
  53.   
  54.   
  55.                 // Close the channels  
  56.   
  57.                 srcChannel.close();  
  58.   
  59.                 dstChannel.close();  
  60.   
  61.             }  
  62.   
  63.         } catch (IOException e) {  
  64.   
  65.         }  
  66.   
  67.     }  
  68.   
  69. }  

用另外一種寫法試了下,也是不行,複製過去的文件大小是相同的,用比較工具比較也沒問題。 
[java]  view plain copy
  1. package com.test;<BR>
  2. <BR>