1614年蘇格蘭人約翰·納皮爾(JohnNapier)發表了一篇論文,其中提到他發明了一種可以計算四則運算和方">
7世紀之前,中國的算盤+口訣合起來應該是最早的計算機。
1614年 | 蘇格蘭人約翰·納皮爾(John Napier)發表了一篇論文,其中提到他發明了一種可以計算四則運算和方根運算的精巧裝置。 |
1623年 | 威廉·契克卡德(Wilhelm Schickard)制作了一個通過轉動齒輪來進行操作,能進行六位以內數加減法,并能通過鈴聲輸出答案的“計算鐘”。 |
1625年 | 威廉·奧特雷德(William Oughtred) 發明計算尺。 |
1642年 | 法國數學家 布萊士·帕斯卡(Blaise Pascal) 在計算尺的基礎上加以改進,能進行八位計算。 |
1668年 | 英國人薩繆爾·莫爾(Samuel Morl)制作了一個非十進制的加法裝置,適宜計算錢幣。 |
1671年 | 德國數學家戈特弗里德·萊布尼茨(Gottfried Leibniz)設計了一架可以進行乘法,最終答案可以最大達到16位。 |
1725年 | 法國人巴斯勒·布喬(Basile Bouchon)發明了打孔卡(穿孔卡),用于織布機。 |
1775年 | 英國 查理斯(Charles)制作成功了一臺與萊布尼茨(Leibniz)計算機類似的機器,但更先進一些。 |
1776年 | 德國人馬修·汗(Mathieus Hahn)成功制作了一臺乘法器。 |
1801年 | 約瑟夫·瑪麗·雅卡爾(Joseph Marie Jacquard)開發了一臺能用穿孔卡片控制的自動織布機。 |
1820年 | 法國人 查爾斯·澤維爾·托馬斯·德·科爾馬(Charles Xavier Thomas de Colmar)制作成功第一臺成品機械式計算機。 |
1822年 | 英國人查爾斯·巴貝奇(Charles Babbage)設計了差分機。 |
1832年 | 查爾斯·巴貝奇(Charles Babbage)和約瑟夫·克萊梅特(Joseph Clement) 制成了一個差分機的成品,可以進行6位數的運算。 |
1834年 | 瑞典斯德哥爾摩的喬治·朔伊茨(George Scheutz)用木頭做了一臺差分機。 |
1834年 | 查爾斯·巴貝奇(Charles Babbage)設想制造一臺通用的分析機。 |
1842年 | 查爾斯·巴貝奇(Charles Babbage)的差分機項目因為研制費用昂貴,被政府取消,但他自己仍花費大量的時間精力于分析機研究。 |
1843年 | 喬治·朔伊茨(George Scheutz)和他的兒子愛德華·朔伊茨(Edvard Scheutz) 制造了一臺差分機,瑞典政府同意繼續支持他們的研究工作。 |
1846年 | 傳真機和電傳電報機的發明人亞歷山大·貝恩(Alexander Bain)將穿孔紙帶技術引入自己的電報機,大幅提升了工作效率。 |
1848年 | 英國數學家喬治·布爾(George Boole)創立了布爾代數。 |
1853年 | 喬治·朔伊茨(George Scheutz)和他的兒子愛德華·朔伊茨(Edvard Scheutz) 制造成功了真正意義上的比例差分機,能進行15位數的運算。 |
1878年 | 美國紐約的西班牙人拉蒙·維里亞(Ramon Verea)制造成功桌面計算器。 |
1886年 | 美國芝加哥的多爾·菲爾特(Dorr Eugene Felt)制造了第一臺用按鍵操作的計算器。 |
1888年9月8日 | 在英國《電氣世界》雜志上,奧伯林·史密斯(Oberlin Smith)發表了最早的關于磁記錄的觀點,他建議:“采用磁性介質來對聲音進行錄制”。 |
1889年 | 多爾·菲爾特(Dorr Eugene Felt)推出桌面印表計算器。 |
1890年 | 赫爾曼·霍勒里斯( Herman Hollerith)借鑒了巴貝奇(Babbage)的發明,用穿孔卡片存儲數據,并設計了機器。 |
1892年 | 圣多美和普林西比的威廉·巴勒斯(William S. Burroughs)成功制作了一臺比費爾特(Felt)的功能更強的機器,真正開創了辦公自動化工業。 |
1896年 | 赫爾曼·何樂禮( Herman Hollerith)創辦了制表機器公司(Tabulating Machine Company),也就是IBM公司的前身。 |
1898年 | 丹麥工程師瓦蒂瑪·保爾森(Valdemar Poulsen)在自己的電報機中首次采用了磁線技術,使之成為人類第一個實用的磁聲記錄和再現設備。 |
1904年 | 英國物理學家約翰·安布羅斯·弗萊明(John Ambrose Fleming)發明了世界上第一只真空電子二極管。 |
1906年 | 查爾斯·巴貝奇的兒子亨利·巴貝奇(Henry Babbage)在門羅(R. W. Munro)的支持下,完成了父親設計的分析機,但也僅能證明它能工作,而沒有將其作為產品推出。 |
1906年 | 美國科學家德·福雷斯特(Lee De Forest)發明了真空三極電子管。 |
1924年 | IBM公司正式成立。 |
1928年 | 德國工程師弗里茨·普弗勒默(Fritz Pfleumer)發明了錄音磁帶,可以存儲模擬信號,標志著磁性存儲時代的正式開啟。 |
1932年 | 磁存儲技術再次有了重大突破,奧地利工程師古斯塔夫·陶謝克(Gustav Tauschek)發明了磁鼓存儲器。 |
1935年 | IBM推出IBM 601機。這是一臺能在一秒鐘算出乘法的穿孔卡片計算機,大約造了1500臺。這臺機器無論在自然科學還是在商業意義上都具有重要的地位。 |
1937年 | 英國劍橋大學的艾倫·圖靈(Alan M. Turing )出版了他的論文,并提出了被后人稱之為"圖靈機"的數學模型。 |
1937年 | 貝爾實驗室的喬治·斯蒂比茨(George Stibitz)展示了用繼電器表示二進制的裝置。盡管僅僅是個展示品,但卻是第一臺二進制電子計算機。 |
1938年 | 貝爾實驗室的克勞德·香農(Claude E. Shannon)發表了用繼電器進行邏輯表示的論文。 |
1938年 | 德國柏林的康拉德·楚澤(Konrad Zuse)和他的助手們完成了一個機械可編程二進制形式的計算機,并將其命名為Z1。 |
1939年1月1日 | 美國加利福尼亞的大衛·休利特(David Hewlet)和威廉·帕卡德(William Packard) 在他們的車庫里創辦了惠普公司(Hewlett-Packard)。 |
1939年11月 | 美國的約翰·阿塔那索夫(John V. Atanasoff)和他的學生克利福特·貝瑞(Clifford Berry) 完成了一臺16位的加法器,這是第一臺真空管計算機。 |
1939年 | 楚澤(Zuse)和施萊爾(Schreyer)開始在他們的Z1計算機的基礎上發展Z2計算機,并用繼電器改進它的存儲和計算單元。 |
1939/1940年 | 施萊爾(Schreyer)利用真空管完成了一個10位的加法器,并使用了氖燈做存儲裝置。 |
1940年1月 | 貝爾實驗室的塞繆爾·威廉(Samuel Williams)和斯蒂比茲(Stibitz)制造成功了一個能進行復雜運算的計算機,大量使用了繼電器。 |
1941年 | 阿塔那索夫(Atanasoff)和學生貝瑞(Berry)完成了能解線性代數方程的計算機,取名叫"ABC"(Atanasoff-Berry Computer)。 |
1941年12月 | 德國祖斯(Zuse)制作完成了Z3計算機的研制,這是第一臺可編程的電子計算機。 |
1943年1月 | 自動順序控制計算機Mark I在美國研制成功。 |
1943年4月 | 馬克斯·紐曼(Max Newman)、溫·威廉斯(Wynn-Williams)和他們的研究小組研制成功"Heath Robinson"。這是一臺密碼破譯機,嚴格來說這不是一臺計算機。 |
1943年12月 | 最早的可編程計算機在英國推出,包括2400個真空管,目的是為了破譯德國的密碼。 |
1946年2月14日 | 美國人莫克利(JohnW.Mauchly)和艾克特(J.PresperEckert)在美國賓夕法尼亞大學研制成功世界上第一臺通用電子計算機“ENIAC”。 |
1946年 | 波蘭發明家揚·亞歷山大·拉奇曼(Jan A. Rajchman)發明了一種選擇性靜電記憶管——Selectron Tube。 |
1947年 | 貝爾實驗室的威廉·肖克利(William B. Shockley)、 約翰·布拉頓(John Bardeen) 和沃爾特·巴丁(Walter H. Brattain)發明了晶體管,開辟了電子時代新紀元。 |
1947年 | 弗雷迪·威廉姆斯(Freddie Williams)和湯姆·基爾伯恩(Tom Kilburn)發明了威廉姆斯-基爾伯恩管(Williams–Kilburn tube)并商用。 |
1947年 | 美國工程師弗雷德里克·菲厄(Frederick Viehe)第一個申請了磁芯存儲器的專利。 |
1948年 | 華裔傳奇科學家王安發明了“脈沖傳輸控制裝置(Pulse transfer controlling device)”,實現了對磁芯存儲器的讀后寫(Write-after-Read)。 |
1949年 | 劍橋大學的威爾克斯(Wilkes)和他的小組建成了一臺存儲程序的計算機 EDSAC,但輸入輸出設備仍是紙帶。 |
1950年 | 軟磁盤由東京帝國大學的中松義郎(Yoshiro Nakamats)發明,其銷售權由IBM公司獲得,由此開創了存儲時代新紀元。 |
1950年 | 英國數學家和計算機先驅艾倫·圖靈(Alan M. Turing )發表《計算機器與智能》,最先討論計算機與智能的關系,并提出認定機器智能的“圖靈測試”。 |
1951年 | 磁帶首次被用于商用計算機上存儲數據,在UNIVAC計算機上作為主要的I/O設備。 |
1951年 | 格蕾絲·莫瑞·霍珀(Grace Murray Hopper)完成了高級語言編譯器。 |
1951年 | 美國空軍的第一個計算機控制實時防御系統Whirlwind研制完成。 |
1951年 | 普雷斯伯·埃克特(J. Presper Eckert) 和約翰·莫奇利(John Mauchly)設計了第一臺商用計算機系統 UNIVAC-1,用于人口普查。 |
1952年 | IBM發布了一臺全新的磁帶存儲設備(型號726),與IBM 701計算機一起銷售。 |
1952年 | 約翰·馮·諾依曼(Von Neumann)領導設計并完成電子離散變量計算機EDVAC (Electronic Discrete Variable Computer)。 |
1953年 | 磁芯存儲器被開發出來。 |
1954年 | IBM的約翰·巴克斯(John Backus)開始牽頭開發FORTRAN (FORmula TRANslation),后于1957年完成。這是一種適合科學研究使用的計算機高級語言。 |
1955年 | 美國麻省理工學院(MIT)的約翰·麥卡錫(John McCarthy)教授提出了time-sharing(分時)的技術理念,希望借此可以滿足多人同時使用一臺計算機的訴求。 |
1956年 | 第一次有關人工智能的會議在美國達特茅斯學院召開。計算機科學家約翰·麥卡錫說服與會者接受“人工智能”一詞作為本領域的名稱。人工智能正式誕生。 |
1956年 | 美國Bosch Arma公司的華裔科學家周文俊(Wen Tsing Chow),正式發明了PROM(Programmable ROM,可編程ROM)。 |
1956年9月14日 | 人類歷史上第一塊硬盤的IBM 350 RAMAC發布。 |
1957年 | IBM開發成功第一臺點陣打印機。 |
1957年 | 羅森布拉特(Frank Rosenblatt)提出了模擬人腦神經網絡的感知機模型。 |
1957年9月18日 | 羅伯特·諾伊斯(Robert Noyce)等八個年輕人一起向肖克利提交辭呈,被稱為“叛逆八人幫”(traitorous eight)。后來,他們創辦了仙童半導體。 |
1958年9月12日 | 德州儀器的杰克·基爾比(Jack St. Clair Kilby)發明了基于鍺基底擴散工藝的集成電路。 |
1959年1月 | 羅伯特·諾伊斯(Robert Noyce)發明了硅基底平面工藝的集成電路。 |
1959年 | 格蕾絲·莫瑞·霍珀(Grace Murray Hopper)開始開發COBOL (COmmon Business-Orientated Language)語言,完成于1961年。 |
1959年 | 貝爾實驗室的工程師Mohamed M. Atalla(默罕默德·阿塔拉,埃及裔)與Dawon Kahng(姜大元,韓裔)共同發明了金屬氧化物半導體場效應晶體管(MOSFET)。 |
1960年 | 第一個結構化程序設計語言 ALGOL 推出。 |
1961年 | IBM的肯尼斯·艾佛森(Kennth Iverson)推出APL編程語言。 |
1961年 | 約翰·麥卡錫(John McCarthy)在麻省理工學院一百周年紀念慶典上,首次提出了Utility Computing(公共計算服務)的概念 |
1962年 | IBM發布了第一個可移動硬盤驅動器1311,它有六個14英寸的盤片,可存儲2.6MB數據。 |
1963年1月1日 | IEEE協會誕生。它的前身是AIEE(美國電氣工程師協會,成立于1884年)和IRE(無線電工程師協會,成立于1912年)。 |
1963年 | DEC公司推出第一臺小型計算機 PDP-8。 |
1964年 | IBM公司發布PL/1編程語言。 |
1964年 | IBM公司發布IBM 360首套系列兼容機。 |
1964年 | DEC公司發布PDB-8小型計算機。 |
1964年 | 美國電話電報公司(AT&T)、通用電器公司(GE)及麻省理工學院(MIT)合作,提出了一個超級分時操作系統Multics OS的開發計劃。 |
1964年 | 德裔美國科學家約瑟夫 維森鮑姆(Joseph Weizenbaum)開發了一個名為ELIZA的機器人,是最早的聊天機器人,實現了計算機與人通過文本的交流。 |
1965年4月19日 | 仙童半導體公司戈登·摩爾(Gordon Moore)提出“摩爾定律”,處理器的性能每年提高一倍。后來其內容又發生了改變。 |
1965年 | 美國加州大學工程師扎德(Lofti Zadeh)創立模糊邏輯,用來處理近似值問題。 |
1965年 | 托馬斯·庫爾茨(Thomas E. Kurtz)和約翰·凱門尼(John Kemeny)完成 BASIC(Beginners All Purpose Symbolic Instruction Code)語言的開發。 |
1965年 | 道格拉斯·恩格爾巴特(Douglas Englebart)提出鼠標器的設想,但沒有進一步的研究。 |
1965年 | 第一臺超級計算機 CD6600 開發成功。 |
1965年 | 美國物理學家羅素(Russell)發明了第一個Compact Disk/CD(數字-光學記錄和回放系統) |
1966年 | 美國計算機協會(ACM)設立了圖靈獎(Turing Award),被稱為“計算機界的諾貝爾獎”。 |
1967年 | 姜大元與Simon Min Sze(施敏,華裔)提出,基于MOS半導體器件的浮柵,可用于可重編程ROM的存儲單元。 |
1967年 | 尼古拉斯·沃斯(Niklaus Wirth)開始開發 PASCAL 語言,于1971年完成。 |
1968年 | 羅伯特·諾伊斯和戈登·摩爾創辦了英特爾(INTEL)公司。 |
1968年 | 西蒙·派珀特(Seymour Papert)和他的研究小組在麻省理工學院開發了LOGO語言。 |
1968年 | 美國斯坦福國際咨詢研究所研發成功世界上第一臺智能機器人Shakey。 |
1969年 | 美國超微半導體公司(AMD)成立。 |
1969年 | ARPANET計劃開始啟動,這是現代Internet的雛形。 |
1969年4月7日 | 第一個網絡協議標準RFC推出。 |
1970年 | 第一塊RAM芯片由INTEL推出,容量1K。 |
1970年 | 貝爾實驗室肯·湯普森(Ken Thomson)和丹尼斯·里奇(Dennis Ritchie)開始開發UNIX操作系統。 |
1970年 | Forth編程語言開發完成。 |
1970年 | Internet的雛形ARPAnet (Advanced Research Projects Agency network) 基本完成。開始向非軍用部門開放,許多大學和商業部門開始接入。 |
1970年 | IBM公司的研究員埃德加·弗蘭克·科德(Edgar Frank Codd),通過一篇名為《大型共享數據庫數據的關系模型》的論文,開啟了關系數據庫時代。 |
1971年 | 英特爾公司的多夫·弗羅曼(Dov Frohman,以色列裔),率先發明了EPROM(user-erasable PROM,可擦除可編程只讀存儲器)。 |
1971年 | PASCAL語言開發完成。 |
1971年 | 英特爾推出了自己的2048位EPROM產品——C1702,采用p-MOS技術。 |
1971年11月15日 | 特德·霍夫(Marcian E. Hoff)在INTEL公司開發成功第一塊微處理器4004。 |
1972年 | 日本電工實驗室的Yasuo Tarui、Yutaka Hayashi和Kiyoko Naga,共同發明了EEPROM(電可擦除可編程ROM)。 |
1972年 | C語言的開發完成。其主要設計者是UNIX系統的開發者之一 丹尼斯·利奇 (Dennis Ritche)。 |
1972年 | 惠普(Hewlett-Packard)發明了第一個手持計算器。 |
1972年4月1日 | INTEL推出8008微處理器。 |
1973年 | 肯·湯普森(Ken Thomson)和丹尼斯·里奇(Dennis Ritchie)正式發表論文,宣布了UNIX的存在。 |
1973年 | IBM發明了Winchester(溫徹斯特)硬盤3340,使用了密封組件、潤滑主軸和小質量磁頭。 |
1974年 | 第一個具有并行計算機體系結構的CLIP-4推出。 |
1974年 | INTEL發布其8位的微處理器芯片8080。 |
1974年12月 | MITS發布Altair 8800,是第一臺商用個人計算機,價值397美元,內存有256個字節。 |
1975年 | 比爾·蓋茨(Bill Gates)和保羅·艾倫(Paul Allen)完成了第一個在MITS 的Altair計算機上運行的BASIC程序。 |
1975年 | IBM公司發布了自己的激光打印機技術。 |
1975年 | 比爾·蓋茨(Bill Gates)和保羅·艾倫(Paul Allen)創辦微軟(Microsoft)公司。 |
1975年 | IBM公司正式發布IBM 5100。 |
1975年 | MITS電腦公司推出了基于Intel 8080芯片的Altair 8800微型計算機。 |
1976年 | 美國的DR公司成功研制出CP/M(Control Program/Monitor,控制程序/監控)操作系統,專門用于搭載了8080芯片的微型計算機(包括Altair 8800)。 |
1976年 | 斯蒂夫.沃茲 尼亞克(Stephen Wozinak)和 斯蒂夫.喬布斯(Stephen Jobs)聯合創辦蘋果計算機公司。并推出其Apple I計算機。 |
1976年 | Zilog公司推出Z80處理器,是8位微處理器。CP/M就是面向其開發的操作系統。許多著名的軟件如:Wordstar 和dBase II基于此款處理器。 |
1976年 | 6502,8位微處理器發布,專為Apple II計算機使用。 |
1976年 | Cray 1誕生。它是第一臺商用超級計算機,集成了20萬個晶體管,每秒進行1.5億次浮點運算。 |
1977年 | 伯克利大學的研究生比爾·喬伊(Bill Joy),將UNIX程序整理到磁帶上,推出了BSD版本。BSD,就是Berkeley Software Distribution(伯克利軟件發行版)。 |
1977年5月 | Apple II型計算機發布。 |
1978年 | Cambridge Processor Unit在英國劍橋誕生,它是ARM公司的前身。 |
1978年 | Commodore Pet發布,8K RAM,盒式磁帶機,9英寸顯示器。 |
1978年6月8日 | 英特爾發布16位微處理器8086。 |
1979年 | 讓·伊克比亞(Jean Ichbiah)開發完成Ada計算機語言,以世界上第一位程序員阿達·奧古斯塔(Ada Augusta)命名。 |
1979年6月1日 | 英特爾發布了8位的8088微處理器。 |
1979年 | Commodore PET發布了采用1MHz的6502處理器。 |
1979年 | 摩托羅拉公司發布68000微處理器,主要供應Apple公司的Macintosh,后繼產品68020用在Macintosh II機型上。 |
1979年 | Oracle數據庫誕生。 |
1980年 | 日本索尼開發了3.5寸軟盤,并成為市場標準。 |
1980年 | IBM推出了第一塊GB級別的存儲硬盤。 |
1980年 | 成立于1979年的希捷(Seagate)發明了一款便宜的硬盤產品。 |
1980年10月 | MS-DOS/PC-DOS開發工作開始了。 |
1981年 | 英特爾發布的80186/80188芯片。 |
1981年4月 | 美國奧斯本計算機公司推出世界第一臺便攜式計算機“奧斯本1(Osborne 1)”。 |
1981年7月27日 | 微軟正式推出了MS-DOS系統(DOS是Disk Operating System,磁盤操作系統)。 |
1981年8月12日 | IBM發布其個人計算機IBM-PC,售價2880美元。 |
1981年8月12日 | MDA(Mono Display Adapter, text only)能夠顯示文本的單色顯示器隨IBM-PC機發布。 |
1981年 | MS-DOS 1.0,PC-DOS1.0發布。 |
1981年 | ISA(Industry Standard Architecture)總線標準發布。 |
1982年 | 索尼(Sony)和飛利浦(Phillips)發布了世界上第一部商用CD音頻播放器CDP-101,光盤開始普及。 |
1982年 | 基于TCP/IP協議的INTERNET初具規模。 |
1982年 | 基于6502微處理器的計算機大受歡迎,特別是在學校大量普及。 |
1982年1月 | Commodore 64計算機發布,價格為595美元。 |
1982年2月 | Intel 80286正式發布。時鐘頻率提高到20MHz。 |
1982年 | 康柏(Compaq)公司發布了其IBM-PC兼容機。 |
1982年 | MIDI(Musical Instrument Digital Interface)標準制定,允許計算機連接標準的類似鍵盤數字樂器。 |
1982年 | 索尼(Sony)和飛利浦(Phillips)公布了壓縮音頻的紅皮書,很快得到歐美的認同。 |
1982年4月 | Sinclair ZX Spectrum發布,基于Z80芯片,時鐘頻率3.5MHz。能顯示8種顏色。 |
1982年5月 | IBM推出雙面320K的軟盤驅動器。 |
1983年 | 全球首款采用GUI界面的商業計算機產品Apple Lisa正式推出。 |
1983年 | 蘇格蘭公司Rodime發布了世界上第一款3.5英寸硬盤。 |
1983年 | 經過長達十年的開發與測試,IBM正式發布了Database2(DB2)數據庫。 |
1983年3月8日 | IBM推出增強版IBM PC/XT,第一次在PC上配備了硬盤。 |
1984年 | 英國Psion公司發布了自己的袖珍電腦產品——Psion Organizer。 |
1984年1月24日 | 蘋果公司發布Macintosh(麥金托什,麥金塔)。 |
1984年 | IBM推出IBM PC/AT,搭配MS-DOS 3.0版。 |
1984年 | 理查德·馬修·斯托曼發起了自由軟件體系GNU(GNU is not unix)。他還組織成立了FSF(自由軟件基金會),起草了GPL(通用公共許可證)。 |
1984年 | 日本科學家舛岡富士雄在IEEE國際電子元件會議上,正式公開發表了自己的發明(NOR Flash)。 |
1984年 | SUN公司聯合創始人約翰·蓋奇(John Gage)提出 “網絡就是計算機(The Network is the Computer)”的重要猜想,用于描述分布式計算技術帶來的新世界。 |
1984年 | DNS(Domain Name Server)域名服務器發布,互聯網上有1000多臺主機運行。 |
1984年 | 惠普(Hewlett-Packard)發布了優異的激光打印機,HP也在噴墨打印機上保持領先技術。 |
1984年1月 | 蘋果公司的Macintosh發布。基于Motorola 68000微處理器,可以尋址16M。 |
1984年3月 | RIM公司正式成立,旗下品牌有BlackBerry(黑莓)。 |
1984年9月 | 蘋果公司發布了有 512Kb 內存的Macintosh。 |
1984年 | 康柏公司(Compaq)開始開發IDE接口,可以更快的速度傳輸數據,并被許多同行采納。 |
1985年 | 喬布斯被趕出蘋果公司后,創辦了NeXT公司。 |
1985年 | 索尼(Sony)和飛利浦(Phillips)合作推出CD-ROM驅動器。 |
1985年 | EGA標準(增強圖形適配器)推出。 |
1985年3月 | MS-DOS 3.1、PC-DOS 3.1,這是第一個提供部分網絡功能支持DOS版本。 |
1985年10月17日 | Intel 80386 DX推出。 |
1985年11月 | 微軟正式發布Windows 1.0。 |
1986年1月 | 蘋果公司發布較高性能的Macintosh,有四兆內存,和SCSI適配器。 |
1986年9月 | Amstrad Announced發布便宜且功能強大的計算機Amstrad PC 1512。 |
1987年 | 荷蘭阿姆斯特丹自由大學計算機系的安德魯·塔能鮑姆教授(Andrew S. Tanenbaum,也譯為譚寧邦)自行開發與Unix兼容的操作系統MINIX。 |
1987年 | Connection Machine超級計算機發布,采用并行處理,每秒鐘2億次運算。 |
1987年 | 英國數學家邁克爾·巴恩 斯利(Michael Barnsley)找到圖形壓縮的方法。 |
1987年 | 蘋果公司發布Macintosh II,基于Motorola 68020處理器。 |
1987年4月2日 | IBM推出PS/2系統。 |
1987年 | IBM發布VGA技術。 |
1987年 | IBM發布自己設計的微處理器8514/A。 |
1987年 | 舛岡富士雄繼NOR Flash之后,又發明了NAND Flash。 |
1987年8月 | AD-LIB 聲卡發布。 |
1987年10月 | Compaq DOS (CPQ-DOS) v3.31發布。 |
1988年 | 英特爾基于舛岡富士雄的發明,生產了第一款商用型256KB NOR Flash閃存產品,用于計算機存儲。 |
1988年 | 諾貝爾物理學獎得主艾爾伯·費爾(Albert Fert)和彼得·格林貝格(Peter Grunberg)發現了巨磁電阻效應。 |
1988年 | 艾利·哈拉里(Eli Harari)等人,正式創辦了SanDisk公司(閃迪,當時叫做SunDisk)。 |
1988年 | XMS標準(擴展內存標準,eXtended Memory Standard)建立。 |
1988年 | EISA標準(擴展工業標準結構,Enhanced Industry Standard Architecture)建立。 |
1988年6月6日 | 80386 SX為了迎合低價電腦的需求而發布。 |
1988年9月 | IBM PS/20 286發布,基于80286處理器,沒有使用其微通道總線,但其他機器仍然繼續使用這一總線。 |
1988年10月 | Macintosh Iix發布,基于Motorola 68030處理器。 |
1989年 | SunDisk公司提交了系統閃存架構專利(“System Flash”),結合嵌入式控制器、固件和閃存來模擬磁盤存儲。 |
1989年 | 日本東芝公司發布了世界上第一個NAND Flash產品。 |
1989年 | 閃存行業知名公司M-Systems公司誕生。他們首次提出了閃存盤的概念,也就是后來的閃存SSD硬盤。 |
1989年 | 蒂姆·伯納斯-李(Tim Berners-Lee)創立World Wide Web雛形,這大大促進了Internet的發展。 |
1989年 | 索尼(Sony)和飛利浦(Phillips)發布CD-I標準。 |
1989年1月 | Macintosh SE/30 發布,基于新型68030處理器。 |
1989年3月 | E-IDE標準確立,可以支持超過528MB的硬盤容量,可達到 33.3 MB/s 的傳輸速度,并被許多CD-ROM所采用。 |
1989年4月10日 | 80486 DX發布,集成120萬個晶體管。其后繼型號時鐘頻率達到100MHz。 |
1989年11月 | Sound Blaster Card(聲卡)發布。 |
1990年 | SVGA標準確立。 |
1990年 | Acorn公司為了和蘋果合作,專門成立了一家公司,名叫ARM。 |
1990年3月 | Macintosh Iifx發布,基于68030CPU,主頻40MHz,使用了更快的SCSI接口。 |
1990年5月22日 | 微軟發布Windows 3.0,兼容MS-DOS模式。 |
1990年10月 | Macintosh Classic發布,有支持到256色的顯示適配器。 |
1990年11月 | 第一代MPC(多媒體個人電腦標準)發布。 |
1991年 | 芬蘭赫爾辛基大學的林納斯·托瓦茲(Linus Torvalds)成功編寫出了擁有10000行代碼的Linux內核(Linux kernel)。 |
1991年 | SunDisk公司推出了世界上首個基于FLASH閃存介質的ATA SSD固態硬盤(solid state disk),容量為20MB,尺寸為2.5英寸。 |
1991年5月 | Sound Blaster Pro發布。 |
1991年6月 | 比爾·蓋茨表示DOS5.0是DOS終結者,今后將不再花精力于此。 |
1992年 | Windows NT發布,可尋址2G RAM。 |
1992年4月 | Windows 3.1發布。 |
1992年6月 | Sound Blaster 16 ASP發布。 |
1993年 | 數碼設備公司Palm在美國正式成立,致力于PDA的研發和生產。 |
1993年 | 美國蘋果公司正式推出了Newton PDA產品。 |
1993年 | Internet開始商業化運行。 |
1993年 | Novell并購Digital Research, DR-DOS成為Novell DOS。 |
1993年 | 英偉達(Nvidia)公司在美國硅谷成立。美籍華人Jensen Huang(黃仁勛)是創始人兼CEO。 |
1993年3月22日 | Pentium發布,集成了300多萬個晶體管。初期工作在60-66MHz。每秒鐘執行1億條指令。 |
1993年5月 | MPC標準2發布。CD-ROM傳輸率要求300KB/sec,在320*240的窗口中每秒播放15幀圖像。 |
1993年7月27日 | Windows NT正式發布。 |
1994年3月7日 | 英特爾發布90-100 MHz Pentium(奔騰)處理器。 |
1994年4月 | MS-DOS 6.22版發布。這是一個經典的版本。 |
1994年 | 閃迪公司第一個推出CF存儲卡(Compact Flash)。 |
1994年 | Netscape 1.0 瀏覽器發布。 |
1995年 | M-Systems發布了基于NOR Flash的閃存驅動器——DiskOnChip。 |
1995年 | IBM牽頭將高容量光盤標準統一合并成為DVD,重新定義為Digital Versatile Disc(數字多用途光盤)。 |
1995年8月23日 | 微軟公司正式發布Windows 95。 |
1996年 | 史蒂夫·喬布斯回歸蘋果公司。 |
1996年 | 東芝推出了SmartMedia卡,也稱為固態軟盤卡。 |
1996年 | 微軟正式推出了Windows CE 1.0。 |
1996年1月 | Netscape Navigator 2.0發布,這是第一個支持JavaScript的瀏覽器。 |
1996年 | 康柏(Compaq)公司的一群技術主管在討論計算業務的發展時,首次使用了Cloud Computing這個詞,他們認為商業計算會向Cloud Computing的方向轉移。 |
1996年 | Windows 95 OSR2發布,修復了部分BUG,擴充了部分功能。 |
1997年1月8日 | Intel發布Pentium MMX,對游戲和多媒體功能進行了增強。 |
1997年4月 | IBM的深藍(Deep Blue)計算機戰勝人類國際象棋世界冠軍卡斯帕羅夫。 |
1997年5月7日 | Intel發布Pentium II處理器,增加了更多的指令和更多CACHE。 |
1998年 | VMware公司成立,并首次引入X86的虛擬技術。 |
1998年6月 | Psion Software與諾基亞、愛立信和摩托羅拉聯合,共同成立了Symbian Ltd.(塞班公司)。 |
1998年6月25日 | 微軟公司發布Windows 98。 |
1998年9月4日 | 谷歌公司(Google)成立。 |
1999 年 | salesforce.com公司成立。 |
1999年1月25日 | Linux Kernel 2.2.0發布。 |
1999年2月22日 | AMD公司發布K6-III 400MHz,集成2300萬個晶體管、socket 7結構。 |
1999年7月 | 蘋果公司在其推出的新一代iBook筆記本電腦中首次引入Wi-Fi。 |
1999年8月 | 因為MMC可以輕松盜版音樂,東芝公司對其進行了改裝,添加了加密硬件,并將其命名為SD(Secured Digital)卡。 |
2000年 | 微軟公司推出了32位計算機操作系統——Windows 2000(內核版本號Windows NT 5.0)。 |
2000年 | M-Systems和Trek公司發布了世界上第一個商用USB閃存驅動器,也就是我們非常熟悉的U盤。 |
2000年3月10日 | 全球互聯網泡沫破裂。 |
2000年9月14日 | 微軟發布了Windows Me(Windows Millennium Edition)。 |
2001年6月 | 塞班公司發布了Symbian S60(Series60)平臺,主要面向智能機。 |
2001年10月25日 | 微軟推出Windows XP。 |
2002年 | 亞馬遜啟用了Amazon Web Services(AWS)平臺。 |
2003年6月23日 | 微軟正式推出了Windows Mobile 2003(最初命名為Pocket PC 2003,基于Windows CE 4.x內核)。 |
2003年10月 | 安迪·魯賓等人在加州硅谷共同創立了Android Inc.。 |
2004年2月4日 | Facebook(臉書)成立。 |
2006年 | Google高級工程師克里斯托夫·比希利亞第一次向Google董事長兼CEO埃里克·施密特提出“云端計算”的想法。 |
2006年 | 深度學習(多層神經網絡+機器學習新方法)被提出,帶動整個人工智能領域快速發展。 |
2006年3月21日 | Twitter(推特)成立。 |
2006年8月 | 英特爾公司正式發布了第一代Core架構處理器,產品命名也正式更改為酷睿。 |
2006年8月9日 | 在搜索引擎大會(SES San Jose 2006)上,埃里克·施密特提出了“云計算(Cloud Computing)”的概念。 |
2007年 | 日立(2003年收購了IBM硬盤事業部)率先推出了TB級別的硬盤,是存儲技術的一個重要里程碑。 |
2007年1月9日 | 在Macworld 2007大會上,史蒂夫·喬布斯正式發布了第一代iPhone。 |
2007年11月5日 | Google公司正式向外界展示了Android操作系統。 |
2008年 | 從MMC開始發展起來的eMMC,成為智能手機存儲的主流技術。 |
2010年 | 惠普以12億美元收購Palm,HP品牌取代Palm,webOS也成為惠普PDA的操作系統之一。 |
2010年 | 伯克利分校的David Patterson教授牽頭完成了RISC-V的指令集開發。 |
2010年2月 | 微軟正式向外界展示了Windows Phone操作系統。 |
2011年 | UFS(Universal Flash Storage,通用閃存存儲)1.0標準誕生。 |
2011年10月5日 | 蘋果公司前首席執行官史蒂夫·喬布斯(Steve Jobs)因病去世。 |
2012年 | 三星推出了第一代3D NAND閃存芯片。 |
2012年4月 | Facebook以10億美元的價格收購Instagram。 |
2012年6月21日 | 微軟發布Windows Phone 8。 |
2013年6月1日 | 美國“棱鏡計劃”曝光。 |
2013年9月2日 | 微軟宣布收購諾基亞手機部門。 |
2014年 | 谷歌公司(Google)收購DeepMind。 |
2014年2月1日 | Facebook收購WhatsApp。 |
2015年7月29日 | 微軟在全球發布了Windows10操作系統。 |
2016年 | 微軟宣布將262億美元收購LinkedIn。 |
2016年 | 西部數據收購了閃迪。 |
2016年7月 | 日本軟銀正式宣布將以320億美元收購ARM。 |
2016年3月 | 谷歌旗下DeepMind公司開發的阿爾法圍棋(AlphaGo)以總比分4:1戰勝圍棋世界冠軍李世石。 |
2020年1月 | Wi-Fi聯盟正式公布了Wi-Fi 6E標準,從現有的2.4GHz和5GHz頻段擴展至6GHz頻段。 |
2021年 | 美國IBM提出“存儲級內存〞(SCM, Storage-Class Memory)的概念。 |
2021年6月24日 | 微軟公司(Microsoft)發布Windows 11操作系統。 |
2021年5月1日 | Facebook表示將轉型成一家元宇宙公司。 |
2022年10月27日 | 埃隆·馬斯克以440億美元收購Twitter的交易完成。 |
2022年11月30日 | OpenAI研發的聊天機器人程序ChatGPT發布。 |
內容比較多,難免錯漏。還請大家多多指正!
另外,后續我會再整理一份中國計算機發展史,敬請關注。
者:marinewu,騰訊PCG客戶端開發工程師
| 導語基于 Readability 的出題閱卷經驗的一些不完全的具體的命名指南。
There are only two hard things in Computer Science: cache invalidation and naming things.
-- Phil Karlton
軟件開發中一個著名的反直覺就是“起名兒”這個看上去很平凡的任務實際上很有難度。身邊統計學顯示,越是有經驗的程序員,越為起名頭痛。給小孩起名兒都沒這么費勁,對吧,王浩然?
命名的困難可能來自于以下幾個方面:
命名就像寫作,會寫字不等于會寫作。而且,命名更多像是一門藝術[注](此處藝術的含義取自于 Knuth -- 命名會訴諸品味和個人判斷。),不存在一個可復制的命名操作手冊。
本文描述一些實用主義的、可操作的、基于經驗的命名指南,并提供了一個代碼詞匯表,和部分近義詞辨析。本文沒有涉及討論名字的形而上學,例如如何做更好的設計和抽象以利于命名,也沒有涉及如何劃分對象等,也無意討論分析哲學。
命名是一門平衡準確性和簡潔性的藝術 -- 名字應該包含足夠的信息能夠表達完整的含義,又應該不包含冗余的信息。
名字最重要的屬性是準確。名字應該告訴用戶這個對象/方法的意圖 -- “它是什么” 和 “它能做什么”。 事實上,它是體現意圖的第一媒介 -- 名字無法表現含義時讀者才會閱讀文檔。
名字應該是有信息量的、無歧義的。以下一些策略可以增加名字的準確度:
最基本的語法原理,是一個類(Class/Record/Struct/... 隨你喜歡)應該是一個名詞,作為主語。一個方法應該是動詞,作為謂語。 換言之,類“是什么”,方法“做什么”, 它們應該是可讀的,應該是 [Object] [Does ...] 式的句子。
可讀是字面意思,意味著它應該是通順的,所以應該:
就像是給老板的匯報中不會把商業計劃寫成 Busi Plan 一樣,也不應該在公開 API 中使用一些奇怪的縮寫。現在已經不是 1970 年了,沒有一個方法不能超過 8 個字符的限制。把類/方法的名字寫全,對讀者好一點,可以降低自己被同事打一頓的風險。
creat 是個錯誤,是個錯誤,是個錯誤!
但是,首字母縮略詞的術語是可行并且推薦的,如 Http, Id, Url。
以下是可用的、得到普遍認可的縮寫:
未得到普遍認可的縮寫:
req/resp/svr 在服務名稱中很常見。這非常糟糕。請使用全稱。
再次說明:以上的說明是針對 API 名稱,具體包括公開對象/函數名字、RPC/Web API 名字。在局部變量使用縮寫不受此影響。
對類/方法的命名,不要使用 2 表示 To, 4 表示 For。
func foo2Bar(f *Foo) *Bar // BAD
func fooToBar(f *Foo) *Bar // GOOD
func to(f *Foo) *Bar // Good if not ambiguous.
2/4 這種一般只有在大小寫不敏感的場合才會使用,例如包名 e2e 比 endtoend 更可讀。能區分大小寫的場合,不要使用 2/4。
雖然不能完全符合語法(例如通常會省略冠詞),但是,方法的命名應該盡量符合語法。例如:
class Car {
void tireReplace(Tire tire); // BAD, reads like "Car's tire replaces"
void replaceTire(Tire tire); // GOOD, reads like "replace car's tire"
}
關于命名的語法見“語法規則”一章。
命名本質上是分類(taxonomy)。即,選擇一個單一的分類,能夠包含類的全部信息,作為名字。
考慮以下的角度:
例如,把大象裝進冰箱,需要有三步 -- 打冰箱門打開,把大象放進去,把冰箱門關上。但是,這可以用單一的概念來描述:“放置”。
class Fridge {
public void openDoorAndMoveObjectIntoFridgeAndCloseDoor(Elephant elphant); // BAD
public void put(Elephant elphant); // GOOD
}
避免使用過于寬泛的類別。例如,這世界上所有的對象都是“對象”,但顯然,應該使用能夠完整描述對象的、最細顆粒度的類別。
class Fridge {
public put(Elephant elephant); // GOOD.
public dealWith(Elephant elephant); // BAD: deal with? Anything can be dealt with. How?
}
簡而言之,名字應該是包含所有概念的分類的下確界。
名字長通常會包含更多信息,可以更準確地表意。但是,過長的名字會影響可讀性。例如,“王浩然”是一個比“浩然·達拉崩吧斑得貝迪卜多比魯翁·米婭莫拉蘇娜丹尼謝莉紅·迪菲特(defeat)·昆圖庫塔卡提考特蘇瓦西拉松·蒙達魯克硫斯伯古比奇巴勒·王”可能更好的名字。(來自于達啦崩吧)
在此,我提出一個可能會有爭議的觀點:所有的編程語言的命名風格應該是趨同的。不同于通常認為 Java 的命名會傾向于詳盡,Go 的命名會傾向于精簡,所有的語言對具體的“名字到底有多長”的建議應該是幾乎一樣的 -- 對外可見應該更詳細,內部成員應該更精簡。具體地:
上述規則像是 Go 的風格指南。但是,并沒有規定 Java 不能這樣做。事實上,Java 的冗長是 Java 程序員的自我束縛。即使在 Java 的代碼里,也可以這樣寫:
public class BazelRuntime {
public boolean exec(Command cmd) {
String m=cmd.mainCommand(); // YES, you can use single-letter variables in Java.
// ...
}
}
同樣,在 Go 的代碼中也不應該出現大量的無意義的縮寫,尤其是導出的結構體和方法。
type struct Runtime {} // package name is bazel, so bazel prefix is unnecessary
type struct Rtm {} // BAD. DO NOT INVENT ABBREVIATION!
當然,由于語言特性,在命名風格上可能會有差異。例如,由于 Go 的導入結構體都需要加包前綴,所以結構名中通常不會重復包前綴;但 C++/Java 通常不會依賴包名。但是,上述的原則仍然是成立的 -- 可見度越高,應該越少依賴上下文,并且命名越詳盡。
Google Go Style Guide 是唯一詳盡討論命名長度的風格指南,非常值得參考,并且不限于 Go 編程: https://google.github.io/styleguide/go/decisions#variable-names
另一個容易被忽略的命名的黃金原則是一致性。換言之,名字的選取,在項目中應該保持一致。遵守代碼規范,避免這方面的主觀能動性,方便別人閱讀代碼。通常情況下,一個差的、但是達成共識的代碼規范,也會遠好于幾個好的、但是被未達成共識的規范。
這個圖我能用到下輩子: [xkcd 927]()
但是僅符合代碼規范是不夠的。如同所有的語言,同一個概念,有多個正確的寫法。
考慮以下的例子:
message Record {
int32 start_time_millis=1; // OK
int32 commited_at=2; // Wait. Why not commit_time? Anything special?
int32 update_time=3; // What unit? Also millis?
google.types.Timestamp end_time=4; // WTF? Why only end_time is typed?
}
幾種都是合理的(雖然不帶單位值得商榷)。但是,如果在一個代碼中出現了多種風格,使用起來很難預測。您也不想使用這樣的 API 吧?
所以,在修改代碼的時候,應該查看上下文,選擇已有的處理方案。一致性大于其它要求,即使舊有的方案不是最好的,在做局部修改時,也應該保持一致。
另一個可考慮的建議是項目的技術負責人應該為項目準備項目的專有詞匯表。
類應該是名詞形式,通常由單個名詞或名詞短語組成。其中,主要名詞會作為名詞短語的末尾。例如 Thread, PriorityQueue, MergeRequestRepository。
接口的命名規則和類相同。除此之外,當接口表示可行動類型時,可使用另一個語法,即 Verb-able。例如:
public interface Serializable {
byte[] serialize();
}
public interface Copyable<T> {
T copy();
}
public interface Closable {
void close();
}
(Go 通常不使用這個命令風格。只在 Java/C++ 中使用。)
只在 Java(注1)中使用。一個類或概念所有的輔助方法應該聚合在同一個輔助類。這個類應該以被輔助類的復數形式出現。不推薦使用 Helper/Utils 后綴表示輔助類。尤其不推薦使用 Utils/Helpers 做類名,把所有的輔助方法包進去。如:
class Collections {} // For Collection
class Strings {} // For String
class BaseRuleClasses {} // For BaseRuleClass
class StringUtils {} // WORSE!
class StringHelper {} // WORSE!
注1: 客觀來說,這適用于所有強制 OOP 的語言(所有強制把方法放在類里的語言)。但是除了 Java, 沒有別的語言這么煩啦。
方法通常是謂語(動詞),或是 謂賓(動詞+名詞) 結構。注意以上語法中,動詞都在最前端。例如:
class Expander {
String expand(String attribute); // 主-謂
String expandAndTokenizeList(String attribute, List<String> values); // 主-謂-賓
}
除此之外,有以下特例值得注意:
直接使用所 Get 的對象的名詞形式,即 Foo()。不要使用 GetFoo()。
Java: 所有的 Getter 都需要一個 get 前綴是來自于過時的 Java Beans Specification,以及 Javaer 的思想鋼印。
func Counts() int; // GOOD
func GetCounts() int; // BAD: UNNECESSARY.
斷言函數指返回結果是布爾型(即真偽值)的函數。它們通常有以下命名格式:
即 isAdjective() 或 areAdjective() 格式,表示是否具有某個二元屬性。類似于 Getter,可以省略系語,只使用表語,即: adjective()。
func IsDone() bool {} // OK-ish. But could be better.
func Done() bool {} // GOOD. Why bother with is/are?
func CheckEnabled() bool { // BAD. Nobody cares if it is "checked". Just tell the user if it is enabled.
return enabled;
}
func Enabled() bool {} // GOOD.
情態動詞也是常見的斷言形式。常見的是以下三個:
func Compile(s string) Regexp, error // Returns error upon failure
func MustCompile(s string) Regexp // Panics upon failure
func (r Regexp) CanExpand(s string) bool // Whether s is legal and can be expanded
func (r Regexp) Expands(s string) bool // Whether r expands s, i.e. r can expand s.
func (r Regexp) ShouldReset() bool // Whether the state requires reset. Does not perform de-facto reset.
func (r Regexp) Reset() // De-facto reset.
上文 "must" 的反面,表示嘗試性的執行,并且失敗不會造成嚴重后果:
void maybeExecute() {
if (!predicate()) {
return;
}
// execute
}
std::unique_ptr<DateTime> ParseOrDie(std::string_view dateTime);
bool TryParse(string_view dateTime, DateTime* dateTime);
另一個常見場景是我們希望表示類擁有某些屬性,但是使用助動詞并不合適。如果前文描述,常見的選擇是使用第三人稱單數的靜態動詞(Stative verb)(注1) 表示類滿足給定斷言。
func (l *List) Contains(e interface{}) bool
func (r Regexp) Expands(s string) bool
注1: 簡單地說,靜態動詞是表示狀態的動詞,與動態動詞(Dynamic verb)表示動作對應。或言“持續性動詞”。
一階邏輯量詞也是常見的前綴:
語法: <一階量詞><動詞|形容詞>
class Stream {
// Returns whether all elements of this stream match the provided predicate.
boolean allMatch(Predicate<? super T> p);
// Returns whether any elements of this stream match the provided predicate.
boolean anyMatch(Predicate<? super T> p);
// Returns whether no elements of this stream match the provided predicate.
boolean noneMatch(Predicate<? super T> predicate)
}
介詞經常與某些動詞固定搭配,因此,通常可以省略動詞,而只使用介詞作為方法名稱。
class Foo {
public List<T> toList(); // Convert to (Construct a new instance of) a new List. Creates a new list.
public List<T> asList(); // Return a List as a different **view**. Holds reference of the original reference.
static Foo of(); // Construct Foo as a factory method.
static Foo from(Bar); // Construct Foo from Bar.
Foo with(Bar); // Construct a new Foo by replacing Bar with new Bar.
void onClick(ClickEvent e); // Act upon click event.
}
參考資料:
下文按用途歸類了常見動詞和名詞,并對同義近義詞進行了辨析。
Abstract/Base
Impl
Default
// https://github.com/bazelbuild/bazel with some fake examples
public interface SkyFunction {}
public abstract class AbstractFileChainUniquenessFunction implements SkyFunction {}
public class DefaultSkyFunction implements SkyFunction {}
public class BazelModuleInspectorFunction implements SkyFunction {}
public interface VisibilityProvider {}
public final class VisibilityProviderImpl {}
// levelDB
// includes/db.h
class DB {
public:
virtual ~DB(); // MUST!
virtual Status Delete(const WriteOptions&, const Slice&)=0;
}
// db/db_impl.h
class DBImpl : public DB {}
// rocksDB
// Base class
class CacheShardBase {}
Exception/Error
所有的異常擴展應該以 Exception 為后綴。所有的錯誤應該以 Error 為后綴。 對異常和錯誤的區別請參見 https://docs.oracle.com/javase/7/docs/api/java/lang/Throwable.html
public class IllegalArgumentException;
public class OutOfMemoryError;
C++ 的 exception 通常指語法特性,與 throw 對應,而 error 可以用來表示具體的異常錯誤。
// stdlib
std::exception;
std::runtime_error
所有的錯誤都是 error。因此,所有自定義的對 error 的擴展都以 Error 作為后綴。
os.PathError
Test
Java/Go/C++ 均使用 Test 作為測試類的后綴。
Module/Component
Module/Component 通常會在框架中使用。不同的語言/框架對于 Module/Component 有不同的定義。 在非框架代碼中應該減少使用 Module/Componenet 等命名,因為可能與已有框架沖突,并且 Module/Componenet 過于寬泛而缺少實質意義。
Module/Component 是意義相近的詞,都可以表示“模塊”或者“組件”。兩者雖然有細微的分別,但是框架通常都顯式(即在文檔中指定,或者通過框架語義約束)地把它們定義為框架語境下的某些結構層級。
總結,Module/Component 命名應該注意:
Service
Service 通常用于作為 C-S 架構下的服務提供者的名稱的后綴,如:
HelloService
但除此之外,Service 可以表示任何長期存活的、提供功能的組件。例如:
BackgroundService // Android 后臺服務
ExecutorService // 線程池執行服務,也是服務
BAD: 不要使用 Svr 縮寫。使用全稱。
Holder/Container/Wrapper
Holder/Container/Wrapper 都表示“容器”,具有同一個意圖:為一個類增加額外的數據/功能,例如:
通常的結構如下:
class ObjectHolder {
private final Object object;
// other stuff ...
public Object object() {}
// Other methods
}
這三個詞沒有區別。在同一個項目中,應該保持一致。
Manager/Controller
Manager 和 Controller 是同義詞。它們通常用來表示專門控制某些類的類。
這兩個詞有以下幾個常見場景:
即使如此,Manager/Controller 是無意義詞匯,出現時充滿了可疑的味道 -- 類應該管理它們自己。 Controller/Manager 多了一層抽象,而這很可能是多余的。 認真考慮是否需要 Manager/Controller。
Util/Utility/Utils/Helper/{ClassName}s
輔助類是強制 OOP 的語言(i.e. Java) 所需要的特殊類。通常它們是一些輔助方法的合集。
將與某個類型相關的輔助方法放在一個類中,并且以復數形式命名輔助類。如:
// Java std lib
public final class Strings {}
public final class Lists {}
public final class Collections {}
避免使用 Util/Utility/Utils/Helper。它們是無意義詞匯。
使用全局方法。如果擔心命名污染,將之置入更細粒度的 namespace。
使用全局方法。
Function/Predicate/Callback
Function 通常表示任意函數。 Predicate 表示命題,即通常返回類型為 bool。 Callback 指回調函數,指將函數作為參數傳遞到其它代碼的某段代碼的引用。換言之, Function 可以作為 Callback 使用。因此,Callback 在現代函數式編程概念流行后,通常很少使用。
熟悉 Java 8 開始提供的函數式語義。如果可以使用標準庫的語義,不要自己創建名詞。 注意 Function 指單入參、單出參的函數。如果是多入參的函數,直接定義 FunctionalInterface 并且按用途命名,例如 OnClickListener.listen(Context, ClickEvent)。
// java.util.function
Predicate<T> // f(T) -> bool
Function<T, R> // f(T) -> R
Consumer<T> // f(T) -> void
Supplier<T> // f() -> T
first-class 函數的標準類型為 std::function。
C++ 表示命名函數對象的慣用法是 fun。Stdlib 中會縮寫 function 為 fun,如 pmem_fun_ref,因此與 stdlib 一致,在代碼中不要使用 fn 或是 func 。
Go 通常使用 Func 或是 Fn 表示函數類型。
type ProviderFunc func(config ConfigSource, source PassPhraseSource) (Provider, error)
type cancelFn func(context.Context) error
在同一個項目中,應該保持一致。
作為參數時,函數不會特意標明 Fn,而是遵從普通的參數命名方式:
func Sort(less func(a, b string) int)
換言之,函數是一等公民。
類/方法通常都按它們的行為模式來命名。恰好,設計模式就歸類抽象了很多行為模式。所以設計模式提供了很多好的名字。
Factory: 工廠模式。通常,使用工廠方法即可,不需要一個額外的工廠類。只有當工廠特別復雜,或者工廠有狀態時再考慮使用工廠類。
Builder:構建者模式。一般來說 Builder 都是作為 inner class,如
class Foo {
static class FooBuilder {}
}
在 GoF 中 Adapter 本來是將一個類封裝以可以被作為另一個類型被調用,這樣調用方不需要額外改變代碼。這種用途通常被內化到容器上,見上文[容器類]部分。
在現代,Adapter 更多地被作為 數據類 -> 數據類的轉化,如常見的 pb -> pb:
class ProtoAdapter<S, T extends Message> {}
在 GoF 中 Decorator 本來是將一個類作為抽象類,通過組合+繼承實現添加功能。實際上現代的編程實踐中往往通過直接提供一個容器的封裝提供裝飾功能,見上文 [容器類]部分。 所以 GoF 式 Decorator 并不常見,除非像 Python 在語法層面提供了裝飾器。在 Java 中類似的功能是注解。
GoF 中是非常基本的模式:由一個類負責接受請求,并把請求轉發到合適的實例類中執行。
class RealPrinter {}
class Printer {
RealPrinter printer;
}
Delegate 非常常見,也提供了兩個名字,請注意區分:
GoF 中 Facade Pattern 通常是指為子系統提供一個更高層的統一界面,屏蔽子系統的獨有的細節。 在現實中,Facade 通常用來為非常復雜的類/系統定義一個較為簡化的界面,如:
// proto, extremely complicated TripResponse
message TripResponse {
// ...
// ...
string last_message=3279;
}
class TripResponseFacade {
private final TripResponse response;
Trip trip();
Endpoint source(); // Abstracted and processed
Endpoint target(); // Abstracted and processed
}
Facade 與 Adapter 的主要區別在于 Facade 的主要目的是為了簡化,或者說更高層次的抽象,并且通常簡化的界面不服務于專門的對接類。 Adapter 通常是為了一個特定的對接類實現。
注意 Facade 命名通常可以省略。僅當你的意圖是明確告知用戶這是關于某個類的外觀時使用。
GoF 中代理模式用來添加一層抽象,以對實際類進行控制,并添加某些行為(如 lazy/memoized),或是隱藏某些信息(例如可見性或是執行遠程調用)。
Proxy 與 Facade 的區別在于 Proxy 通常是為了額外的控制/記錄等行為,而非只是為了更高的抽象/簡化。
注意 Proxy 作為代碼模式時,通常不應該出現在命名之中。使用具體的 Proxy 的目的作為命名,如 LazyCar 或是 TracedRuntime,而非 CarProxy 或是 RuntimeProxy。
Proxy 還有另一個含義就是真正的“代理”,如代理服務器。在這種情況下,使用 Proxy 是合適且應該的。這也是另一個為什么代理模式不應該用 Proxy 命名的原因。
時至今日仍然最常見的模式之一。Interator 有以下兩個術語,不要混淆:
訪問者模式用來遍歷一個結構內的多個對象。對象提供 accept(Visitor) 方法,調用 Visitor.visit 方法。
即使如此,Visitor 應該并不常見,因為它可以簡單地被函數式的寫法替換:
class Car {
void accept(Consumer<Car> visitor); // No longer need to define Visitor class.
}
Observer/Publisher/Subscriber/Producer/Consumer
時至今日最常見的模式之一。和事件驅動編程(Event-based)有緊密關系 -- Oberservable 發布消息,所有注冊的 Obeserver 會接收消息。 Publisher/Subscriber 也是類似的,它們的區別在于 Observer 模式往往是強綁定的 -- 注冊和分發通常在 Observable 類中實現; 而 PubSub 模式通常有專門的 Message Broker,即 Publisher 與 Subscriber 是完全解耦的。
PubSub 與 Producer/Consumer 的區別是:
所有的消息注冊的模式由三部分組成:
關于命名參見 [事件] 部分。
Strategy/Policy
策略模式在 GoF 中用以指定某個行為在不同場景下的不同實現,作為“策略”。
Strategy 模式往往不是很顯式。現代通常使用 Strategy 表示實際的“策略”,即對信息不同的處理策略,而不采取 Strategy 模式的含義。
在“策略”這個語義中,Strategy/Policy 沒有區別。在同一個項目中,應該保持一致。
命令模式在 GoF 中以類開代表實際行動,將行動封裝,以支持重復、取消等操作。
Command 在現代編程實踐中可以通過簡單的函數式方案替換,如:
Function<T, T> command; // Java
std::function<const T&(const T&)> command; // C++
type Command func(T*) T* // Go
現代通常使用 Command 表示實際的“命令”,而不采取 Command 模式的含義。
Tombstone
Null Object 模式不在 GoF 當中。它是一個用來代替 null 的 object,對其所有的操作都會被吞掉。 Null Object 主要是為了避免空指針。 合理的零值,例如 go time.Time=0,也可以理解為一種 Null Object。
通常會有一個專門的對象表示 Null Object。可以借用 Tombstone 表示 Null Object。
Pool
對象池模式不在 GoF 當中。它是將一系列昂貴的對象創建好放在一個池子中,并使用戶通過向池子申請對象,而不再自己手動地創建/銷毀對象。最著名的池化的例子是線程池,即 ThreadPool。
Pool 通常用來表示對象池子,例如 ThreadPool, ConnectionPool。
Arena
Arena 是指 Region-based memory management,是指一片連續的內存空間,用戶在其中分配創建對象,管理內存。
Concurrent
Synchronized
Async
有時候我們需要特別標明一個類是線程安全的。通常這是特意為了與另一個線程不安全的實現做區分。典型的例子是 HashMap 和 ConcurrentHashMap。如果一個類只是單純是線程安全的,那么通常不需要在名字里特意說明,在文檔里說明即可。
例如:
/** This class is designed to be thread safe. */
class SomeClassThreadSafe {}
/** This class is immutable thus thread safe. */
class SomeClassImmutable {}
Concurrent 通常是用來說明該類是線程安全的前綴。Synchronized 是另一個在 Java 中可用的標明類是線程安全的前綴。但是,這通常說明這個類是通過 synchronized 機制來保證線程安全的,所以只在 Java 中使用。
另一個常見的場景是同一個方法有兩種實現:同步阻塞和異步不阻塞的。在這種情況下,通常會命名異常不阻塞的方法為 {synchronizedMethod}Async,例如:
public T exec();
public Future<T> execAsync();
如果一個異步的方法并沒有對應的同步方法,通常不需要加 Async 后綴。
在 Go 中,如果一個方法是意圖在其它協程中異步執行,不需要加 Async 后綴。
Cached/Buffered
Lazy
Memoized
名詞辨析:
注意 Buffered 不應該與 Buffer 混淆。 Buffer 作為名詞專指“緩沖區”。
注意 Cached 不應該與 Cache 混淆。 Cache 作為名詞專指“緩存”。
Cached/Buffered 應該在項目中是一致的。 Cached/Lazy/Memoized 取決于對象是被獲取的,還是創建的,還是計算獲得的。
Mutable
Immutable
Mutable 顯式地聲明一個類是可變的,Immutable 顯式地聲明一個類是不可變的。 通常情況下,類似于并發安全性,是否可變應該在類文檔中說明,而不應該在類名中,顯得臃腫。只有當一個類同時有可變/不可變版本時,可以使用 Class/ImmutableClass。
Object
Data
Value
Record
Entity
Instance
上面幾個都可以用來表示一個表示數據的類。但是這些詞是典型的“無意義詞匯”,如果把它們從名字中刪除,仍然可以表示完整意義,那么應該刪掉。
class CarObject {} // Bad
class CarEntity {} // Bad
class CarInstance {} // Bad
class Car {} // Good
class MapKey {}
class MapValue {} // OK. Couldn't be shortened.
class LoggingMetricsData {} // Bad
class LoggingMetricsValue {} // Bad
class LoggingMetricsRecord {} // Bad
class Logging Metrics {} // Good
class DrivingRecord {} // OK. Couldn't be shortened.
Statistics/Stats
表示“統計數據”。 Stats 是公認的可用的 Statistics 的縮寫,Java/C++/Go 均可。
Storage
Database
Store
DB
Cache
Verbs:
- save/store/put
Storage/Database/Store/DB 都可以作為“存儲服務”,即廣義上的“數據庫”(不是必須是完整的 DBMS)。 其中,在 C++/Go 中 DB 是常見且可接受的。在 Java 中通常使用全稱。
項目內應該選擇一個術語保持一致。
save/store/put 在數據庫類中是同義詞。同一個項目中應該保持一致。
Schema
Index
Format
Pattern
名詞辨析:
Hash/Digest/Fingerprint/Checksum
Hash/Digest 哈希是一種將任何數據映射到一個較小的空間的方法。映射通常被稱為哈希函數(Hash Function),映射值通常被稱為摘要(Digest)。
Hash(Data)=Digest
Checksum 出自編碼論,可以理解為一種特殊的哈希函數,用來檢查文件的完整性。換言之,如果一份數據出現了任何變動,Checksum 應該期待會改變。(但是 Checksum 實際上并不要求唯一性,見 Fingerpint)
Fingerprint 類似于 Checksum,但是 Fingerprint 通常更嚴格,它通常要求最少有 64-bit,使得任何兩個文件只要不同,幾乎(概率意義上接近 2^-64)不可能有同一份指紋,即唯一性。(但是 Fingerprint 的定義不要求密碼安全性即 cryptographic)
所以 Checksum 只是作為文件變更校驗,而 Fingerprint 可以作為數據的唯一標記。
在命名時,優先使用 Fingerprint/Checksum,或其它特定指定用途的術語。當以上均不合適時,回退到更泛化的概念,即 Digest。
Stream
Source/Sink
Pipe/Piped
流式編程通常有自己的專有詞匯表。具體地:
原則是:選擇你的團隊里最常使用的流式處理系統所使用的詞匯表。
State/Status
很諷刺地,很多人認為這兩個詞有區別,但是他們認為區別的點各不相同。見下文參考文獻。筆者傾向于認為它們其實沒什么本質區別。
鼓勵使用 State 表示狀態。因為 HTTP 和 RPC 已經占用了 Status 這個術語,為了避免誤解,使用 State 表示自定義狀態。
參考:
Num/Count/Size/Length/Capacity
動詞是句子的精髓。選擇精準的動詞是代碼可讀性的關鍵。 本章對動作做了分類,并且提供了部分備選。如果動詞有反義詞,它們會被聚合在一個詞條中。 本章的詞匯有兩種:
Producer/Provider/Supplier/Generator/Constructor/Factory
Builder.build
Verbs:
創建/提供名詞辨析:
動詞辨析:
Consumer.accept/consume/poll
消費名詞:
注意區分輪 xun 中文的歧義:
注意輪詢是 poll 不是 pull,雖然后者直覺上是“拉取,但 poll 強制間斷性地主動地采樣/獲取數據,是正式的計算機術語。
Verbs:
- find/search/query
同義詞。推薦在項目中保持一致。 具體地,這幾個詞實際上有細微的不一致。通常情況下它們可能有以下區分:
參考 https://stackoverflow.com/questions/480811/semantic-difference-between-find-and-search
Verbs:
- copy/clone
同義詞。遵循語言慣例。
Java 使用 clone。 Go/C++ 使用 copy。
Verbs:
- add/append/put/insert/push
動詞辨析:
對于自定義的可添加 api,應該貼近底層的標準庫的數據結構所使用的動詞。作為泛用的添加,使用 add。
Verbs:
- set/update/edit
同義詞。在代碼 API 中使用 set,在 RPC API 中使用 update。
Verbs:
- remove/delete/erase/clear/pop
動詞辨析:
Scheduler/Dispatcher/Coordinator/Orchestrator/Delegator
- Verb: schedule/dispatch/orchestrate
Scheduler/Dispatcher 均借用于操作系統概念。
名詞辨析:
Validator/Checker/Verifier
- Verb: validate/check/verify/assert
Validation/Verification 的明確區分來自于軟件測試。
在程序中,不沿用這種區分。通常:
具體地:
public void process(String s, ComplicatedObject co) {
checkNotNull(s); // check
validateComplicatedObject(co); // validate
}
@Test
public void testProcess() {
process("ss", co);
Truth.assertThat(...); // assert
verifyZeroInvocations(co); // verify
}
Task/Job/Runnable
Executor/Operator/Processor/Runner
- Verb: exec/execute/do/process/run
名詞辨析:
但是,推薦不做區分,認為它們都是同義詞。使用 Task 或者 Job 作為類名。
名詞辨析: Processor/Executor/Operator 是從計算機架構借用的概念。
但是,推薦不做區分,認為它們都是同義詞。日常編程中,使用 Executor 作為 Job 執行器。
toggle/switch/enable/disable/turnOn/turnOff/activate/deactivate
二元狀態的開啟關閉。上述全是同義詞。
在項目中保持統一。注意比起 toggle(bool) 和 switch(bool),更推薦分離的 enable/disable。
Reader/Prefetcher/Fetcher/Downloader/Loader
- Verb: read/get/fetch/load/retrieve
Writer/Uploader
- Verb: write/upload
Lifecycle:
- open/close
名詞辨析:
優先使用 read/fetch/download,當均不合適時,回退到 load。
Serializer
- Verb: serialize/pack/marshal
Deserializer
- Verb: deserialize/unpack/unmarshal
動詞辨析:
但是,不需要做這個區分。可以認為它們都是同義詞。按語言慣例使用:
注意反序列化是 deserialize, 比 unserialize 更常見。 但 pack -> unpack, marshal -> unmarshal。
Applier/Converter/Transformer/Mapper
- Verb: apply/convert/transform/map/to/translate
可以認為它們都是同義詞。在項目中應該保持一致。 嚴格來說,Mapper 更多指同一數據的兩種形式的雙向映射,例如數據庫存儲和運行時對象。 在 Applier/Converter/Transformer 中,Applier 最為常見,因為源自設計模式。 Mapper 在框架中較常見。
Filter/Matcher
- Verb: query/filter/match
可以認為它們都是同義詞。 在項目中應該保持一致。
Event
Listener/Notifier Verbs: notify
Observer/Observable Verbs: observe
Handler Verbs: handle
Publisher/Subscriber
Publisher/Consumer
在 [Observer Pattner: 觀察者模式] 中已經解釋。
見 https://stackoverflow.com/questions/42471870/publish-subscribe-vs-producer-consumer
Regex/Pattern/Template
Pruner/Stripper/Trimmer
Formatter/Prettier
Resolver/Parser/Expander
- Verb: compile/parse/resolve/expand
- Verb: format/split/separate/merge/join
通常,一個程序中有 20% 的代碼在處理字符串。所以與文本相關的內容非常多。這里沒有列出全部。
“模板”名詞解析:
“修剪”動名詞解析:
但是,Prune/Strip/Trim 在編程中通常認為是同義詞。它們通常情況下:
語言可能會為之賦予特殊含義,例如在 Java 11 中,Trim 會清理掉所有的普通空格,而 Strip 會清理掉所有的 Unicode 空格。
“格式化”動名詞解析:
“解析”動名詞解析:
Lifecycle
Initializer/Finalizer
Verb:
- init/setup/prepare
- pause/resume
- start/begin
- end/terminate/stop/halt
- destroy/release/shutdown/teardown
生命周期解析: 一個對象的生命周期,稱為 Lifecycle,通常有以下流程:
Calculator
Verb:
- compute/calculate/calc
使用 Calculator 而非 Computer 表示某個運算的執行器。Computer 雖然也是“計算器”,但是在代碼語境下有歧義。
compute/calculate/calc 可以認為是同義詞。如果是 Calculator,使用 calculate。其它情況下,使用 compute。
Option/Config/Configuration/Setting/Preference/Property/Parameter/Argument
Context/Environment
Info/Metadata/Manifest/Version
配置名詞解析: 這個有類似的名詞辨析,但是它們在編程時通常認為都是“配置”的同義詞。它們還會出現在用戶界面,尤其是 Settings/Options/Preferences。
在編程的角度,Option/Config/Configuration 是同義詞,均表示配置。慣例使用 Options 作為子類定義一個類所需的配置,尤其是作為依賴注入時。
使用 Property 表示單個屬性, 而且通常是 k-v 結構。換言之,Option/Config 通常由多個 Properties 組織。只有當 Property 是動態屬性時,才定義特殊的 Property 類,否則,在 Option 中定義具體的域表示 Property。
struct Options {
int fur_layer_count; // Good
int fur_layer_count_property; // Bad! Property unnecessary
struct ColorProperty {
int a;
int r;
int g;
int b;
} // Bad! Prefer Color.
ColorProperty color;
}
參數解析:
例如:
func foo(param string)
foo(arg)
https://stackoverflow.com/questions/156767/whats-the-difference-between-an-argument-and-a-parameter
上下文名詞辨析:
元數據辨析:
安徽省量子計算工程研究中心介紹,截至6月17日上午9時,中國第三代自主超導量子計算機“本源悟空”已吸引全球范圍內124個國家超1000萬人次訪問,共完成23.6萬個量子運算任務。
China's independently developed third-generation superconducting quantum computer, Origin Wukong, has received more than 10 million remote visits globally. As of 9 am on June 17, people from 124 countries and regions have remotely accessed Origin Wukong, which has completed nearly 236,000 quantum computing tasks globally, according to the Anhui Quantum Computing Engineering Research Center.
“本源悟空”超導量子計算機。安徽省量子計算工程研究中心供圖
【知識點】
超導量子計算機是基于超導電路量子芯片的量子計算機。“本源悟空”匹配了本源第三代量子計算測控系統“本源天機”,在國內首次真正落地了量子芯片的批量自動化測試,量子計算機的整機運行效率提升了數十倍。“悟空”搭載的是72位超導量子芯片“悟空芯”。這款芯片在中國首條量子芯片生產線上制造,共有198個量子比特,其中包含72個工作量子比特和126個耦合器量子比特。
中國第三代72比特超導量子計算機取名“悟空”,來源于中國傳統文化中的神話人物孫悟空,寓意如孫悟空般“72變”。
【重要講話】
堅持面向世界科技前沿、面向經濟主戰場、面向國家重大需求、面向人民生命健康,加快實現高水平科技自立自強。以國家戰略需求為導向,集聚力量進行原創性引領性科技攻關,堅決打贏關鍵核心技術攻堅戰。
Setting our sights on the global frontiers of science and technology, national economic development, the major needs of the country, and the health and safety of the people, we should speed up efforts to achieve greater self-reliance and strength in science and technology. To meet China's strategic needs, we will concentrate resources on original and pioneering scientific and technological research to achieve breakthroughs in core technologies in key fields.
——2022年10月16日,習近平在中國共產黨第二十次全國代表大會上的報告
【相關詞匯】
算力基礎設施
computing power infrastructure
量子革命
quantum revolution
中國日報網英語點津工作室(本文于“學習強國”學習平臺首發)
來源:中國日報網