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發布。



    在線版可以通過下面的海報二維碼打開,后續不定期更新。


    內容比較多,難免錯漏。還請大家多多指正!

    另外,后續我會再整理一份中國計算機發展史,敬請關注。

    參考文獻:
    1、《計算機的發展歷史匯總》,網絡;
    2、《算力發展簡史》, 廬山真容;
    3、維基百科、百度百科;

    者:marinewu,騰訊PCG客戶端開發工程師

    | 導語基于 Readability 的出題閱卷經驗的一些不完全的具體的命名指南。

    There are only two hard things in Computer Science: cache invalidation and naming things.

    -- Phil Karlton


    軟件開發中一個著名的反直覺就是“起名兒”這個看上去很平凡的任務實際上很有難度。身邊統計學顯示,越是有經驗的程序員,越為起名頭痛。給小孩起名兒都沒這么費勁,對吧,王浩然?

    命名的困難可能來自于以下幾個方面:

    • 信息壓縮:命名的本質是把類/方法的信息提煉成一個或幾個詞匯,這本身需要對抽象模型的準確理解和概括。
    • 預測未來:類/方法的職責可能會在未來有變化,現在起的名字需要考慮未來可能的變動。
    • 語言能力:缺少正確的語法知識,或是缺少足夠的詞匯量。本來英文就不是大部分中國人的母語,更甚者,計算機的詞匯表不同于日常交流詞匯表,有大量黑話。
    • 不良設計:混亂的職責分布、不清晰的抽象分層、錯誤的實現,都會導致無法起出好的名字。在這個意義上,起名字其實是對設計的測試: 如果起不出名字來,很可能是設計沒做好 -- 重新想想設計吧。

    命名就像寫作,會寫字不等于會寫作。而且,命名更多像是一門藝術[注](此處藝術的含義取自于 Knuth -- 命名會訴諸品味和個人判斷。),不存在一個可復制的命名操作手冊。

    本文描述一些實用主義的、可操作的、基于經驗的命名指南,并提供了一個代碼詞匯表,和部分近義詞辨析。本文沒有涉及討論名字的形而上學,例如如何做更好的設計和抽象以利于命名,也沒有涉及如何劃分對象等,也無意討論分析哲學。

    命名原則

    命名是一門平衡準確性和簡潔性的藝術 -- 名字應該包含足夠的信息能夠表達完整的含義,又應該不包含冗余的信息。

    準確 Precision

    名字最重要的屬性是準確。名字應該告訴用戶這個對象/方法的意圖 -- “它是什么” 和 “它能做什么”。 事實上,它是體現意圖的第一媒介 -- 名字無法表現含義時讀者才會閱讀文檔。

    名字應該是有信息量的、無歧義的。以下一些策略可以增加名字的準確度:

    可讀

    最基本的語法原理,是一個類(Class/Record/Struct/... 隨你喜歡)應該是一個名詞,作為主語。一個方法應該是動詞,作為謂語。 換言之,類“是什么”,方法“做什么”, 它們應該是可讀的,應該是 [Object] [Does ...] 式的句子。

    可讀是字面意思,意味著它應該是通順的,所以應該:

    避免 API 中使用縮寫

    就像是給老板的匯報中不會把商業計劃寫成 Busi Plan 一樣,也不應該在公開 API 中使用一些奇怪的縮寫。現在已經不是 1970 年了,沒有一個方法不能超過 8 個字符的限制。把類/方法的名字寫全,對讀者好一點,可以降低自己被同事打一頓的風險。

    creat 是個錯誤,是個錯誤,是個錯誤!

    但是,首字母縮略詞的術語是可行并且推薦的,如 Http, Id, Url

    以下是可用的、得到普遍認可的縮寫:

    • configuration -> config
    • identifier -> id
    • specification -> spec
    • statistics -> stats
    • database -> db (only common in Go)
    • regular expression -> re/regex/regexp

    未得到普遍認可的縮寫:

    • request -> req
    • response -> resp/rsp
    • service -> svr
    • object -> obj
    • metadata -> meta
    • business -> busi

    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?
    }

    簡而言之,名字應該是包含所有概念的分類的下確界

    簡潔 Simplicity

    名字長通常會包含更多信息,可以更準確地表意。但是,過長的名字會影響可讀性。例如,“王浩然”是一個比“浩然·達拉崩吧斑得貝迪卜多比魯翁·米婭莫拉蘇娜丹尼謝莉紅·迪菲特(defeat)·昆圖庫塔卡提考特蘇瓦西拉松·蒙達魯克硫斯伯古比奇巴勒·王”可能更好的名字。(來自于達啦崩吧)

    在此,我提出一個可能會有爭議的觀點:所有的編程語言的命名風格應該是趨同的。不同于通常認為 Java 的命名會傾向于詳盡,Go 的命名會傾向于精簡,所有的語言對具體的“名字到底有多長”的建議應該是幾乎一樣的 -- 對外可見應該更詳細,內部成員應該更精簡。具體地:

    • public,如 public 類的名字、public 方法的名字 - 應該詳細、不使用縮寫、減少依賴上下文。通常是完整名詞短語
    • non-public,如類成員、私有方法 - 不使用縮寫、可以省略上下文。下界是單詞,不應該使用單字符。
    • local,如函數的局部變量 - 基本上是風格是自由的。不影響可讀性的前提下,例如函數方法長度很短,可以使用單字符指代成員。

    上述規則像是 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

    一致 Consistency

    另一個容易被忽略的命名的黃金原則是一致性。換言之,名字的選取,在項目中應該保持一致。遵守代碼規范,避免這方面的主觀能動性,方便別人閱讀代碼。通常情況下,一個差的、但是達成共識的代碼規范,也會遠好于幾個好的、但是被未達成共識的規范。

    這個圖我能用到下輩子: [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。

    • 名詞短語通常不使用所有格。如,并非 ServiceOfBook,也不是 BooksService (省略 '),而是 BookService

    接口

    接口的命名規則和類相同。除此之外,當接口表示可行動類型時,可使用另一個語法,即 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);  // 主-謂-賓
    }

    除此之外,有以下特例值得注意:

    訪問器 Getter

    直接使用所 Get 的對象的名詞形式,即 Foo()。不要使用 GetFoo()

    Java: 所有的 Getter 都需要一個 get 前綴是來自于過時的 Java Beans Specification,以及 Javaer 的思想鋼印。

    func Counts() int;  // GOOD
    
    func GetCounts() int;  // BAD: UNNECESSARY.
    

    斷言 Predicate

    斷言函數指返回結果是布爾型(即真偽值)的函數。它們通常有以下命名格式:

    系動詞: 主-系-表

    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.
    

    情態動詞: 主-助謂-謂-(賓/表)

    情態動詞也是常見的斷言形式。常見的是以下三個:

    • should: 查詢當前是否應該執行給定的實義動詞。
    • can: 查詢當前類所在狀態是否可以執行給定的實義動詞。某些情況下,也可以使用第三人稱單數作為更簡潔的代替。
    • must: 特殊形式。不同于前兩者,會執行給定的實義動詞。must 表示執行必須成功,否則會拋出不可恢復錯誤 (throw/panic)。類似于 C++ 中常見的 OrDie 后綴。
    
    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.

    表嘗試: 主-maybe/try-謂-(賓/表)

    上文 "must" 的反面,表示嘗試性的執行,并且失敗不會造成嚴重后果:

    • maybe 前綴用以表示指定的行為有前置條件,也在方法中執行。如果前置條件不滿足,不會執行指定行為。通常不會出現在公開 API。
    • try 通常用于 Try-Parse Pattern,用于避免拋出異常。
    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)表示動作對應。或言“持續性動詞”。

    一階邏輯 First-order logic, Predicate Logic

    一階邏輯量詞也是常見的前綴:

    • all 表示所有對象滿足給定要求
    • any 表示任意對象滿足給定要求
    • none 表示沒有任何對象滿足給定要求

    語法: <一階量詞><動詞|形容詞>

    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)
    }

    介詞

    介詞經常與某些動詞固定搭配,因此,通常可以省略動詞,而只使用介詞作為方法名稱。

    • to: 轉換至另一對象,等價于 convertTo。to 會產生一個全新的對象,通常不持有對原對象的引用。
    • as: 返回某個視圖,等價于 returnViewAs。一個“視圖(View)” 通常是對原有對象的另一角度的抽象,通常會持有對原有數據的引用,而不會產生新的數據。
    • of/from/with:構造新對象,等價于 createOutOf/createFrom/createWith。見下文“工廠模式”。
    • on: 監聽事件,等價于 actUpon。見下文“事件”。
    
    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.
    }
    

    參考資料:

    • https://testing.googleblog.com/2017/10/code-health-identifiernamingpostforworl.html
    • https://journal.stuffwithstuff.com/2016/06/16/long-names-are-long/
    • https://journal.stuffwithstuff.com/2009/06/05/naming-things-in-code/
    • https://habr.com/en/post/567870/#names_in_engineering
    • https://medium.com/wix-engineering/naming-convention-8-basic-rules-for-any-piece-of-code-c4c5f65b0c09
    • https://github.com/kettanaito/naming-cheatsheet
    • [[Effective Java]] Item 68: Adhere to generally accepted naming conventions

    詞匯表

    下文按用途歸類了常見動詞和名詞,并對同義近義詞進行了辨析。

    類/名詞

    類繼承

    Abstract/Base
    Impl
    Default

    Java

    • Interface: 通常不需要額外的表示。不要加 I 前綴,或后綴 FooInterface
    • Abstract class: 通常會添加 Abstract/Base 前綴以明確屬性。這是因為 Interface/Impl 是常見的,Class 也是常見的,但是基于繼承的抽象類是特殊的、應該予以避免的,應該給予特殊標記。
    • Implementation:
      • 如果不實現接口,通常不需要任何特殊修飾符。
      • 如果以 "is-a" 的方式實現了某個接口,那么通常實現會以 {InterfaceName}Impl 的方式命名。
      • 如果一個類實現了多個接口,那么通常這個類應該是以作為主要目標的接口為基礎命名。例如 class BazelBuilderImpl implements BazelBuilder, AutoClosable, Serializable
      • 如果一個接口有多個實現,通常會基于它們本身的實現特點命名,并且使用 Impl 后綴。Default 通常用來命名默認的實現,即其它實現如果不存在會 fallback 到的實現。如果所有的實現都是平等地位,那么不要使用 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 {}

    C++

    • C++ 的 interface 是通過抽象類不存在基類成員變量模擬。通常接口所有的成員函數都是公開純虛函數。
    • 使用 Impl 表示實現。
    • Abstract class: 通常會添加 Base 后綴以明確屬性。這是因為 Interface/Impl 是常見的,Class 也是常見的,但是基于繼承的抽象類是特殊的、應該予以避免的,應該給予特殊標記。
    // 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 {}

    Go

    • Go 的 interface 從來不是用來做 "is-a" 定義的。Go 的 interface 契約通過 duck typing 滿足。interface 應該在消費方定義,而非提供方。因此, interface Foo/struct FooImpl 不應該出現
    • Go 也并沒有抽象類,雖然可以將一個結構體嵌入到另一個結構體中。所以 Base/Abstract 也極少出現。
    • 原則上,Go 的類關系更為簡化,命名更強調意義優先,因此在命名時避免使用修飾性前后綴。

    異常

    Exception/Error

    Java

    所有的異常擴展應該以 Exception 為后綴。所有的錯誤應該以 Error 為后綴。 對異常和錯誤的區別請參見 https://docs.oracle.com/javase/7/docs/api/java/lang/Throwable.html

    public class IllegalArgumentException;
    
    public class OutOfMemoryError;

    C++

    C++ 的 exception 通常指語法特性,與 throw 對應,而 error 可以用來表示具體的異常錯誤。

    // stdlib
    std::exception;
    std::runtime_error

    Go

    所有的錯誤都是 error。因此,所有自定義的對 error 的擴展都以 Error 作為后綴。

    os.PathError

    測試

    Test

    Java/Go/C++ 均使用 Test 作為測試類的后綴。

    模塊

    Module/Component

    Module/Component 通常會在框架中使用。不同的語言/框架對于 Module/Component 有不同的定義。 在非框架代碼中應該減少使用 Module/Componenet 等命名,因為可能與已有框架沖突,并且 Module/Componenet 過于寬泛而缺少實質意義。

    Module/Component 是意義相近的詞,都可以表示“模塊”或者“組件”。兩者雖然有細微的分別,但是框架通常都顯式(即在文檔中指定,或者通過框架語義約束)地把它們定義為框架語境下的某些結構層級。

    總結,Module/Component 命名應該注意:

    • 只應該在框架代碼中使用。
    • Module/Component 應該在框架的語境中給出確切的定義。

    服務

    Service

    Service 通常用于作為 C-S 架構下的服務提供者的名稱的后綴,如:

    HelloService

    但除此之外,Service 可以表示任何長期存活的、提供功能的組件。例如:

    BackgroundService // Android 后臺服務
    
    ExecutorService // 線程池執行服務,也是服務

    BAD: 不要使用 Svr 縮寫。使用全稱。

    容器

    Holder/Container/Wrapper

    Holder/Container/Wrapper 都表示“容器”,具有同一個意圖:為一個類增加額外的數據/功能,例如:

    • 添加某些語境下的元數據(Decorator 模式)
    • 做適配以在另一個環境中使用(Adapter 模式)

    通常的結構如下:

    class ObjectHolder {
      private final Object object;
      // other stuff ...
      
      public Object object() {}
    
      // Other methods
    }

    這三個詞沒有區別。在同一個項目中,應該保持一致

    控制類

    Manager/Controller

    Manager 和 Controller 是同義詞。它們通常用來表示專門控制某些類的類。

    這兩個詞有以下幾個常見場景:

    • Manager 管理資源,如 DownloadManager, PackageManager
    • Manager 通常特指管理對象的生命周期,從創建到銷毀。
    • Controller 通常在某些架構中,尤其是 MVC (Model-View-Controller)。

    即使如此,Manager/Controller 是無意義詞匯,出現時充滿了可疑的味道 -- 類應該管理它們自己。 Controller/Manager 多了一層抽象,而這很可能是多余的。 認真考慮是否需要 Manager/Controller。

    輔助類

    Util/Utility/Utils/Helper/{ClassName}s

    輔助類是強制 OOP 的語言(i.e. Java) 所需要的特殊類。通常它們是一些輔助方法的合集。

    Java

    將與某個類型相關的輔助方法放在一個類中,并且以復數形式命名輔助類。如:

    // Java std lib
    public final class Strings {}
    
    public final class Lists {}
    
    public final class Collections {}

    避免使用 Util/Utility/Utils/Helper。它們是無意義詞匯。

    C++

    使用全局方法。如果擔心命名污染,將之置入更細粒度的 namespace。

    Go

    使用全局方法。

    函數式

    Function/Predicate/Callback

    Function 通常表示任意函數。 Predicate 表示命題,即通常返回類型為 bool。 Callback 指回調函數,指將函數作為參數傳遞到其它代碼的某段代碼的引用。換言之, Function 可以作為 Callback 使用。因此,Callback 在現代函數式編程概念流行后,通常很少使用。

    Java

    熟悉 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

    C++

    first-class 函數的標準類型為 std::function

    C++ 表示命名函數對象的慣用法是 fun。Stdlib 中會縮寫 functionfun,如 pmem_fun_ref,因此與 stdlib 一致,在代碼中不要使用 fn 或是 func

    Go

    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 {}
    }

    行為式

    Adapter: 適配器

    在 GoF 中 Adapter 本來是將一個類封裝以可以被作為另一個類型被調用,這樣調用方不需要額外改變代碼。這種用途通常被內化到容器上,見上文[容器類]部分。

    在現代,Adapter 更多地被作為 數據類 -> 數據類的轉化,如常見的 pb -> pb:

    class ProtoAdapter<S, T extends Message> {}

    Decorator:裝飾器

    在 GoF 中 Decorator 本來是將一個類作為抽象類,通過組合+繼承實現添加功能。實際上現代的編程實踐中往往通過直接提供一個容器的封裝提供裝飾功能,見上文 [容器類]部分。 所以 GoF 式 Decorator 并不常見,除非像 Python 在語法層面提供了裝飾器。在 Java 中類似的功能是注解

    Delegation:委派模式

    GoF 中是非常基本的模式:由一個類負責接受請求,并把請求轉發到合適的實例類中執行。

    class RealPrinter {}
    
    class Printer {
      RealPrinter printer;
    }

    Delegate 非常常見,也提供了兩個名字,請注意區分:

    • Delegate被委任的對象。
    • Delegator委任對象。
      所以,通常情況下 Delegator 在命名中會更常見,類似于 DispatcherDelegate 更多作為一個類型或是接口被實現。具體的選擇參見 [編排] 部分。

    Facade: 外觀模式

    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 命名通常可以省略。僅當你的意圖是明確告知用戶這是關于某個類的外觀時使用。

    Proxy:代理模式

    GoF 中代理模式用來添加一層抽象,以對實際類進行控制,并添加某些行為(如 lazy/memoized),或是隱藏某些信息(例如可見性或是執行遠程調用)。

    Proxy 與 Facade 的區別在于 Proxy 通常是為了額外的控制/記錄等行為,而非只是為了更高的抽象/簡化。

    注意 Proxy 作為代碼模式時,通常不應該出現在命名之中。使用具體的 Proxy 的目的作為命名,如 LazyCar 或是 TracedRuntime,而非 CarProxy 或是 RuntimeProxy

    Proxy 還有另一個含義就是真正的“代理”,如代理服務器。在這種情況下,使用 Proxy 是合適且應該的。這也是另一個為什么代理模式不應該用 Proxy 命名的原因。

    Iterator: 迭代器

    時至今日仍然最常見的模式之一。Interator 有以下兩個術語,不要混淆:

    • Iterable: 迭代容器
    • Iterator: 迭代器

    Visitor: 訪問者模式

    訪問者模式用來遍歷一個結構內的多個對象。對象提供 accept(Visitor) 方法,調用 Visitor.visit 方法。

    即使如此,Visitor 應該并不常見,因為它可以簡單地被函數式的寫法替換:

    class Car {
      void accept(Consumer<Car> visitor); // No longer need to define Visitor class.
    }

    Observer/Observable: 觀察者模式

    Observer/Publisher/Subscriber/Producer/Consumer

    時至今日最常見的模式之一。和事件驅動編程(Event-based)有緊密關系 -- Oberservable 發布消息,所有注冊的 Obeserver 會接收消息。 Publisher/Subscriber 也是類似的,它們的區別在于 Observer 模式往往是強綁定的 -- 注冊和分發通常在 Observable 類中實現; 而 PubSub 模式通常有專門的 Message Broker,即 Publisher 與 Subscriber 是完全解耦的。

    PubSub 與 Producer/Consumer 的區別是:

    • Publisher/Subscriber: 在事件流系統中,表示 1:N 廣播/訂閱。
    • Producer/Consumer: 在整個流系統中,專指 1:1 生產/消費。Producer/Consumer 也是 Pub/Sub 系統的組件(廣播也是一對一廣播的)。
      • 有些系統(Kafka)使用 Consumer Group 表示 Subscriber。

    所有的消息注冊的模式由三部分組成:

    • Notification: 消息本身
    • Sender:消息發送者/注冊
    • Receiver: 消息接收者

    關于命名參見 [事件] 部分。

    Strategy:策略模式

    Strategy/Policy

    策略模式在 GoF 中用以指定某個行為在不同場景下的不同實現,作為“策略”。

    Strategy 模式往往不是很顯式。現代通常使用 Strategy 表示實際的“策略”,即對信息不同的處理策略,而不采取 Strategy 模式的含義。

    在“策略”這個語義中,Strategy/Policy 沒有區別。在同一個項目中,應該保持一致

    Command:命令模式

    命令模式在 GoF 中以類開代表實際行動,將行動封裝,以支持重復、取消等操作。

    Command 在現代編程實踐中可以通過簡單的函數式方案替換,如:

    Function<T, T> command; // Java
    
    std::function<const T&(const T&)> command; // C++
    
    type Command func(T*) T* // Go

    現代通常使用 Command 表示實際的“命令”,而不采取 Command 模式的含義。

    Null Object 模式

    Tombstone

    Null Object 模式不在 GoF 當中。它是一個用來代替 null 的 object,對其所有的操作都會被吞掉。 Null Object 主要是為了避免空指針。 合理的零值,例如 go time.Time=0,也可以理解為一種 Null Object。

    通常會有一個專門的對象表示 Null Object。可以借用 Tombstone 表示 Null Object。

    Object Pool 對象池模式

    Pool

    對象池模式不在 GoF 當中。它是將一系列昂貴的對象創建好放在一個池子中,并使用戶通過向池子申請對象,而不再自己手動地創建/銷毀對象。最著名的池化的例子是線程池,即 ThreadPool。

    Pool 通常用來表示對象池子,例如 ThreadPool, ConnectionPool

    Arena

    Arena 是指 Region-based memory management,是指一片連續的內存空間,用戶在其中分配創建對象,管理內存。

    前/后綴

    并發/異步

    Concurrent
    Synchronized
    Async

    有時候我們需要特別標明一個類是線程安全的。通常這是特意為了與另一個線程不安全的實現做區分。典型的例子是 HashMapConcurrentHashMap。如果一個類只是單純是線程安全的,那么通常不需要在名字里特意說明,在文檔里說明即可。

    例如:

    /** 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

    名詞辨析:

    • Cached 表示獲取的對象會被緩存,保留一段時間,在緩存期間不會重新獲取。
    • Buffered 與 Cached 同義。
    • 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

    名詞辨析:

    • Schema 借用數據庫的概念,指數據的結構模式。
    • Index 借用數據庫的概念,專指數據的索引
    • Format/Pattern 通常是泛指的“模式/格式”概念。實際出現時,Format/Pattern 往往和字符串相關,如 Java 使用 Pattern 表示正則表達式。在非公共代碼中,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

    流式編程通常有自己的專有詞匯表。具體地:

    • Stream 表示流式
    • Source 表示數據源(輸入),Sink 表示 數據匯(輸出)。
    • 動詞詞匯表,如 map/reduce/join/filter/iterate/do/window/key/evict/peek/trigger/slide/...

    原則是:選擇你的團隊里最常使用的流式處理系統所使用的詞匯表。

    狀態

    State/Status

    很諷刺地,很多人認為這兩個詞有區別,但是他們認為區別的點各不相同。見下文參考文獻。筆者傾向于認為它們其實沒什么本質區別。

    鼓勵使用 State 表示狀態。因為 HTTP 和 RPC 已經占用了 Status 這個術語,為了避免誤解,使用 State 表示自定義狀態。

    參考:

    • https://stackoverflow.com/questions/1162816/naming-conventions-state-versus-status
    • https://softwareengineering.stackexchange.com/questions/219351/state-or-status-when-should-a-variable-name-contain-the-word-state-and-w
    • 鼓勵使用 State: https://google.aip.dev/216

    計數

    Num/Count/Size/Length/Capacity

    • Num/Count 表示數量,但不強制是某個 collection 的長度。推薦使用 Count。
    • Size/Length 表示容器1的當前容量。遵循語言慣例,通常使用 Size。
    • Capacity 通常表示容器的最大容量。

    方法/動詞

    動詞是句子的精髓。選擇精準的動詞是代碼可讀性的關鍵。 本章對動作做了分類,并且提供了部分備選。如果動詞有反義詞,它們會被聚合在一個詞條中。 本章的詞匯有兩種:

    • 動詞
    • 以執行一個動作為主的某些行為類,即 -er 模式,如 Producer。 -able 模式,如 Writable 是類似的,因為不再贅述。

    創建/提供

    Producer/Provider/Supplier/Generator/Constructor/Factory
    Builder.build

    Verbs:

    • create/from/of/with/valueOf/instance/getInstance/newInstance/getFoo/newFoo
    • get/peek
    • make/generate

    創建/提供名詞辨析:

    • Producer/Supplier/Provider 同義詞,都表示“提供一個對象”。這些提供者可能是惰性的(Lazy)。實例未必由這些提供者創建(雖然通常是)。
      • 它們對應的動詞是工廠方法的常見命名,即:
      • create/from/of/with/valueOf/instance/getInstance/newInstance/getFoo/newFoo
      • 推薦在項目中使用同一種命名。推薦使用 of/from,更短。
    • Generator 通常專指某些需要經過計算的、特殊的對象,例如 ID。
      • 對應的動詞是 generate,強調全新生成。
    • Constructor 通常是指一個復雜對象的構建器,不是指構造函數。它通常用于比 Builder 更復雜的構建 (Builder 通常不會附帶邏輯)。
    • Factory 是專職的工廠類。當工廠方法較為復雜,需要抽出,或者有狀態的工廠時使用。
      • 對應上文工廠方法的常見命名。
    • Builder 見前文 [Builder 構建者模式]

    動詞辨析:

    • get vs peek
      • get 是廣義的“獲取”,在絕大部分場景下適用
      • peek 也是“獲取”對象,但是這里強調的是對原對象無副作用。在函數式編程中會用來作為不破壞數據流的旁路操作。
    • create vs make vs generate
      • 同義詞,表創建。推薦在項目中保持一致

    消費

    Consumer.accept/consume/poll

    消費名詞:

    • Consumer 是最常見的“消費者”,通常表示某個數據流的終端消費方。
      • 對應的動詞是 accept 或是 consume,遵守所使用消息隊列框架的命名風格,否則,項目內保持一致
      • poll 特指數據是通過輪詢(poll),即 Consumer 通常主動獲取消息,而非被推送(push)后處理。

    注意區分輪 xun 中文的歧義:

    • poll 翻譯為輪詢,指一個客戶端間斷性地向外進行獲取數據的行為策略。
    • round-robin 翻譯為輪循,指以單一的方向循環接受信息/資源的分發策略。

    注意輪詢是 poll 不是 pull,雖然后者直覺上是“拉取,但 poll 強制間斷性地主動地采樣/獲取數據,是正式的計算機術語。

    查找

    Verbs:
    - find/search/query

    同義詞。推薦在項目中保持一致。 具體地,這幾個詞實際上有細微的不一致。通常情況下它們可能有以下區分:

    • find 查詢單個結果,search 查詢一列符合條件的結果
    • find 表示“找到”,即終態,search 表“搜索”,即行為。
    • query 表示“查詢”,類似于 search,但是暗示可能會有更高的成本。
      但是,不要做這種程度的細分,大部分人認為它們是同義詞。

    參考 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

    動詞辨析:

    • append 專指添加到列表末。
    • insert 強調可以插入到列表的任何位置。
    • add 是通用的列表添加方案,add(E) 等同于 appendadd(index, E) 等同于 insertaddAll 用于批量添加。
    • put 通常用于列表之外的添加場景。如 map, iostream。
    • push 僅用于某些數據結構,如棧。

    對于自定義的可添加 api,應該貼近底層的標準庫的數據結構所使用的動詞。作為泛用的添加,使用 add。

    更新

    Verbs:
    - set/update/edit

    同義詞。在代碼 API 中使用 set,在 RPC API 中使用 update。

    刪除

    Verbs:
    - remove/delete/erase/clear/pop

    動詞辨析:

    • remove/delete/erase 是同義詞。嚴格來說,remove 指移除,即暫時從容器中取出放置在一邊,delete/erase 指刪除,即將對象整個清除。但是在日常編程中不需要做這種區分。通常,代碼 API 中使用 remove(或依語言慣例),RPC API 中使用 delete 作為標準方法。
    • clear 通常表示 1) 清理列表,等效于 removeAll 2)清理狀態,即恢復類到初始化狀態。
    • pop 只在棧/隊列等數據結構中使用,通常會返回對象并從數據結構中移除。

    編排

    Scheduler/Dispatcher/Coordinator/Orchestrator/Delegator
    - Verb: schedule/dispatch/orchestrate

    Scheduler/Dispatcher 均借用于操作系統概念。

    名詞辨析:

    • Scheduler: 通常 Scheduler 用于分發中長期 Job。換言之,Scheduler 通常涉及到資源分配。
      • 對應動詞為 schedule
    • Dispatcher: 通常只負責接受事件,采用某些固定的策略分發任務,例如 round-robin。不涉及資源分配。
      • 對應動詞為 dispatch
    • Coordinator: 通常作為 Scheduler/Dispatcher 的同義詞。鑒于其模糊性,推薦使用更細化的 Scheduler/Dispatcher
      • 對應動詞為 coordinate
    • Orchstrator:執行比簡單的分發,即 scheduler/dispatcher 更復雜的任務/流程編排。通常,這些任務有前后依賴關系,會形成一個有向無環圖。
      • 對應動詞為 orchestrate。 Orchestrator 的輸出通常是工作流,即 Workflow。
    • Delegator: 專指委任。雖然形式類似,但是 Delegator 強調單純的委任。參見 [Delegation: 委派模式]。
      • 對應動詞為 delegate,但通常不會使用。

    檢查/驗證

    Validator/Checker/Verifier
    - Verb: validate/check/verify/assert

    Validation/Verification 的明確區分來自于軟件測試。

    • Validation 通常指對產品符合用戶/顧客預期的驗證。外部用戶會參與。
    • Verification 通常指產品合規/符合給定規范。通常是內部流程。

    在程序中,不沿用這種區分。通常:

    • Validator 用于輸入檢測
    • Verifier 用于運行的不變量檢測

    具體地:

    • check 用于輸入校驗。 validate 用于復雜的輸入校驗。
    • assert/verify 用于不變量驗證,尤其在單元測試中
    
    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

    名詞辨析:

    • Runnable 是泛用的“帶上文的可執行代碼塊”。
    • Task 粒度比 Job 更細
    • Job 通常是耗時更長的任務

    但是,推薦不做區分,認為它們都是同義詞。使用 Task 或者 Job 作為類名。

    名詞辨析: Processor/Executor/Operator 是從計算機架構借用的概念。

    • Executor: 常見。通常對應 Job/Task
      • 對應 execute。 exec 是可接受的公認的縮寫。
    • Operator: 通常對應某些具體的操作類。更多使用本義,即操作符。
      • 對應 do。
    • Processor:更多在文本文檔(work/document processor)、數據處理(data processor) 語境下使用。
      • 對應 process。
    • Runner: 通常對應 Runnable
      • 對應 run

    但是,推薦不做區分,認為它們都是同義詞。日常編程中,使用 Executor 作為 Job 執行器。

    開啟 vs 關閉

    toggle/switch/enable/disable/turnOn/turnOff/activate/deactivate

    二元狀態的開啟關閉。上述全是同義詞。

    在項目中保持統一。注意比起 toggle(bool)switch(bool),更推薦分離的 enable/disable

    讀取 vs 寫入

    Reader/Prefetcher/Fetcher/Downloader/Loader
    - Verb: read/get/fetch/load/retrieve
    Writer/Uploader
    - Verb: write/upload

    Lifecycle:
    - open/close

    名詞辨析:

    • Reader 通常是從 stdio/文件/其它 Source 中讀取。
      • 對應動詞 read
    • Fetcher 通常是從遠端拉取數據
      • 對應動詞 fetch
    • Downloader 類似于 Fetcher,但是通常內容是文件等 blob,而非結構化數據
      • 對應動詞 download
    • Prefetcher 強調預熱拉取,通常是拉取到緩存中。
      • 對應動詞 prefetch 或是簡單的 fetch
    • Loader 是泛用詞匯,表示廣義的“加載”。通常可以表示上述的任何一種。
      • 對應動詞 load
    • Retrieve 是 Fetch 的同義詞。
    • 具體地,fetch/load 是有語義的細微差別。但是,不需要做具體的細分。

    優先使用 read/fetch/download,當均不合適時,回退到 load。

    序列化 vs 反序列化

    Serializer
    - Verb: serialize/pack/marshal
    Deserializer
    - Verb: deserialize/unpack/unmarshal

    動詞辨析:

    • pack 指打包,將數據打包為一個不可拆分的(通常是不透明的)對象
    • serialize 指序列化,將數據轉換為可以被存儲/傳輸的(通常是二進制)格式。
    • marshal 強調意圖 -- 將一個對象從程序 A 轉移到程序 B 中。

    但是,不需要做這個區分。可以認為它們都是同義詞。按語言慣例使用:

    • C++: Serialize
    • Java: Serialize
    • Go: Marshal
    • Python: Pack

    注意反序列化是 deserialize, 比 unserialize 更常見。 但 pack -> unpack, marshal -> unmarshal。

    • https://en.wikipedia.org/wiki/Marshalling_(computer_science)
    • https://en.wikipedia.org/wiki/Serialization

    轉換

    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: 觀察者模式] 中已經解釋。

    • Observer 是正宗的觀察者
    • Listner/Notifier 通常可以用來作為 Observer/Observable 的同義詞。但是 Listener 也可能表示其它含義,如 TraceListener,視框架而定。
    • Handler 也是同義詞。它與 Listener/Observer 的區別在于,它表示唯一的事件處理器。而 Listener/Observer 可能有多個。
    • Publisher/Subscriber: 在事件流系統中,表示 1:N 廣播/訂閱。
    • Producer/Consumer: 在整個流系統中,專指 1:1 生產/消費。

    見 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% 的代碼在處理字符串。所以與文本相關的內容非常多。這里沒有列出全部。

    “模板”名詞解析:

    • Regex 專指正則表達式。另一個常見的縮寫是 Regexp。應該與語言保持一致。C++ 使用 Regex。Go 使用 Regexp。
      • 編譯使用 compile。 正則本身就是一種 formal language,因此使用 compile 是正統。
      • 匹配對應動詞為 expand/match/match
    • Pattern 在 Java 中表示正則表達式。雖然 Pattern 可能通指“模式”,但是通常不在編程中使用。
      • 編譯使用 compile
      • 對應動詞為 match/split
    • Template 指模板,通常不是正則形式的,而是簡單的匹配替換模板,如 HTML 模板。
      • 對應動詞為 expand

    “修剪”動名詞解析:

    • Pruner.prune: 指清理掉過時的、不應存在的內容
    • Stripper.strip: 指清理掉多余的、過度生長的內容
    • Trimmer.trim: 泛指修剪,使其更好看。

    但是,Prune/Strip/Trim 在編程中通常認為是同義詞。它們通常情況下:

    • Strip/Trim 指去掉頭尾的多余空格
    • Prune 可能會進行其它的裁剪

    語言可能會為之賦予特殊含義,例如在 Java 11 中,Trim 會清理掉所有的普通空格,而 Strip 會清理掉所有的 Unicode 空格。

    • https://stackoverflow.com/questions/51266582/difference-between-string-trim-and-strip-methods-in-java-11

    “格式化”動名詞解析:

    • Formatter.format 是將對象進行格式化。通用名詞。
    • Prettier.pprint 專指將數據整理為便于人類可讀的的輸出格式。典型的例子是 Python 的 pprint。

    “解析”動名詞解析:

    • Expander.expand 通常用于 DSL/Schema 解析,專指將某些 DSL 展開,如變量替換,展開 glob。
    • Parser.parse 類似于 parse,但強調將文本進行句法解析,形成格式化的中間層表示。借用了編譯器術語。
    • Resolver.resolve Resolve 通常指從人類可讀的定義(可能有歧義或不精確)向機器可讀的定義(精確的、可解析的)的轉換。例如,域名 -> ip 的解析,依賴包的版本號的解析(打平)。(!) resolve 不同于 expand/parse 的文本解析。這是一個相同中文不同英文的易混淆例子。

    生命周期

    Lifecycle

    Initializer/Finalizer

    Verb:
    - init/setup/prepare
    - pause/resume
    - start/begin
    - end/terminate/stop/halt
    - destroy/release/shutdown/teardown

    生命周期解析: 一個對象的生命周期,稱為 Lifecycle,通常有以下流程:

    • 創建。通常由語言特性支持,不屬于生命周期管理范圍。
    • 初始化:init。init 是 initialize 的全稱,通常用來初始化一個類到可用狀態。應該盡量避免創建之外的額外初始化步驟,一個對象應該盡可能在創建后就處于已初始化狀態。額外的狀態會讓這個類更難正確使用。
      • setup/prepare 是 init 的同義詞。應該在項目內統一,推薦為 init。setUp 通常在測試中使用,用于作為每個測試用例設計的前置步驟。
      • init vs prepare: 具體地細分,init 的語義通常指“在類生命周期層面處在正常可執行狀態”,prepare 的語義通常指“在業務層面做好準備”
    • 開始: start/begin。通常用于這個對象正式開始正常工作,即切換到 running 狀態。在切換到其它狀態之前這個類會一直保持在 running 狀態。
      • start/begin 是同義詞。通常使用 start 作為動詞“開始”,使用 begin 作為列表的頭。
    • 暫停: pause。pause 應該使得類暫停運行,從 running 狀態切換到 paused 狀態。這段時間這個類應該不再工作。
    • 恢復:resume。resume 與 pause 是成對的。 resume 會恢復 paused 到 running 狀態。通常,pause/resume 可以無限次隨時切換。
    • 停止:stop/end/terminate/halt。停止類運行,與 start 對應。通常情況下,一個類 stop 意味著不會再重新啟動。通常情況下,停止狀態的類應該拒絕任何請求。
      • stop/end/terminate/halt 是同義詞。不要做區分處理,在項目中保持一致。
    • 銷毀:destroy/release/shutdown/teardown/exit。徹底銷毀對象。此后,對象不再處于可用狀態。
      • destroy/release/shutdown/teardown 是近義詞。具體地:
        • destroy 強調銷毀對象。
        • release 強調釋放資源。
        • teardown 通常與 setup 對應。
        • exit 通常指程序退出。
        • shutdown 是通用“徹底關閉”的動詞。當 destroy/release 不合適時,回退到 shutdown。
          • 使用 gracefullyShutdown 表示優雅關閉。這通常意味著是前幾個行為的集合:停止服務、釋放資源、刷新緩沖區、銷毀對象。

    計算

    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; 
    }

    參數解析:

    • Parameter:通常表示在接口處定義的參數
    • Argument:指實際傳入接口的參數

    例如:

    func foo(param string)
    
    foo(arg)

    https://stackoverflow.com/questions/156767/whats-the-difference-between-an-argument-and-a-parameter

    上下文名詞辨析:

    • Context 指上下文,通常用于在 API 之間傳遞與一次執行相關的信息。在 RPC 處理中非常常見,例如 https://pkg.go.dev/context 。
    • Environment 指環境。這個名詞從系統環境變量而來。通常,這表示在程序啟動后保持穩定的環境數據,不隨所執行的內容(如 rpc 請求)變化而變化。

    元數據辨析:

    • Info 泛指信息。而元數據相當于特定的“關于數據”的信息。
    • Metadata 標準用語,專指元數據。避免使用 Info 代表元數據。
    • Manifest 專指文件清單,描述一個模塊中的文件/功能/其它組成結構的列表。Manifest 來自于貨運術語,Ship Manifest 用以列出所有的船員和船隊所有的船只。
    • Version 專指程序的版本元數據,例如 TrpcVersion。如果一個類專指版本,使用 Version 是最精確合適的。

    安徽省量子計算工程研究中心介紹,截至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

    中國日報網英語點津工作室(本文于“學習強國”學習平臺首發)

    來源:中國日報網

網站首頁   |    關于我們   |    公司新聞   |    產品方案   |    用戶案例   |    售后服務   |    合作伙伴   |    人才招聘   |   

友情鏈接: 餐飲加盟

地址:北京市海淀區    電話:010-     郵箱:@126.com

備案號:冀ICP備2024067069號-3 北京科技有限公司版權所有