这是“我”的故事 —— 董彬
點擊藍字 關注我們
作者:董彬
校對/文章優化:劉軼民
排版:Rani
視頻地址:
https://www.bilibili.com/video/BV1NK4y1p7Ys
與世界周旋的程序員
大家好,我叫董彬 ,現就職于野村信息,??? Title 是 Senior Developer。回頭看看過去,我覺得還蠻神奇的。雖然我已經 30 歲了,但作為一名全職的軟件工程師也僅有一年的時間。有的人會有一些疑問。為什么這么晚才開始做軟件工程師?主要是因為我從 2018 年開始才以邊工作邊讀書的方式,通過遠程教育的方法拿到了我人生中的第二個碩士學位,也就是 UIUC 的 Master Ofcomputer Science。
在我上學的這段期間發生過一個非常有趣的事情,在我上學的這段時間發生過一個非常有趣的事情:我的老師曾經在一個期末的時候單獨表揚了我,說我們的董斌同學每次期末作業,每次的作業都會提前很早就交上來。這讓我感到非常的奇怪。
因為我分別記得我遲交了很多次,后來在和老師核對了之后,才發現事情的原因。因為老師每次在留作業的時候,他都會說我們的截止時間是 2018年10月1號 CST,那我就想當然的以為 CST 和網站上的時間一樣,被自動轉換成了東 8 區的時間,也就是 China Standard Time。但實際上老師用的是當地的時間,也就是美國的中部標準時間(CST)。所以我以為的截止時間要比老師真正上留的這個時間要早上到 14 個小時,這也就是為什么我每次交作業都要比真正的截止時間要提前很久,不知道有沒有其他的同學產生了同樣的錯誤(笑)。
CST 同樣還有其他的意思,包括澳大利亞中部時間 (Central Standard Time) 和古巴標準時間(Cuba StandardTime-AUS),時間是一個很美妙的東西,人類為了描述它,引入了很多工具,時區就是其中之一,時區是很復雜的,當大家在一個跨國公司工作需要和不同的國家的員工一起協作,或者是公司本身的產品就服務于世界各地不同的用戶的話,那么時區通常情況下都是一個非常令人頭疼的問題,時區不是以精度進行完美的劃分,它有很多種情況。
它既有可能像中國一樣橫跨好幾個時區,但使用的是統一的時區。也有可能像美國一樣,在同一個國家使用不同的時區。甚至有可能在印度一樣,雖然只有同一樣的時區,但是它是一個非整數的時區,而且還有一些國家現在在使用夏令時。這些所有的可能性讓時間的轉換變得尤為復雜。
我所在公司曾經有這樣一個 RestfullAPI,它以 Json 的數據格式來返回日期,但它返回的日期比數據庫中存儲的時間要早上一天。這種情況讓我們感到非常奇怪。在我們調試的過程中,我們找到了錯誤的原因:首先這個日期是 Java 中的 Date 數據類型,當它使用 Jdbc 從 Sql Server 中取出這個數據的時候,它會被初始化成為一個本地的時間,然后在序列化的時候,他調用 getTime 方法,得到的是 UTC(1970年1月1日到現在的毫秒數),所以錯誤產生的原因就是這個本地時間。
雖然他這個服務器真的就在英國,但是它的時區是 BST,也就是 Britain Summer Time,它比 UTC 要早上一個小時,所以當數據庫中的2020年10月1號被 Jdbc 取出來之后,它就變成了2020年9月30號的晚上11點。然而作為 API 消費者的我并不知道這個 API 真正的服務器的時區在哪里,所以在對其反序列化后就成了2020年9月30號。錯誤就是這樣產生的。為了解決這個問題,我們應該怎么辦呢?
一個最普遍的方法當然就是把日期以一個格式化的字符串的方式來傳輸出來,那么以格式化的字符串來傳輸,究竟是不是一個很好的選擇呢?在有些情況下其實也不是。因為我們還有另外一個服務,它需要用戶上傳一個 Excel 模板,在這個 Excel 模板里面,我們規定日期要以 mm/dd/yyyy 的格式來進行傳輸,我們在本地調試的時候是完全沒有問題的,但是交付給用戶的時候,我們就發現有些用戶總是把日和月寫反,無論怎么樣告訴他他都是寫反。
后來我們仔細研究了一下,才發現這個問題出現在 Excel 上面,因為 Excel 它的日期的默認時間格式是與你本機的語言有關的,我們在用美式英語來進行調試的時候,mm/dd/yyyy 是完全沒有問題的,但是我們有相當一部分內部的用戶用的是英式英語,對他們來說,他們的短日期格式就是 dd/mm/yyyy,像這種與語言非常相關的日期格式,我們在軟件當中被稱為 Global Realization 或者是 Internal Realization。我們作為程序員,能力非常有限,不可能了解全世界每一種語言文化的使用習慣,所以我們是非常依賴于軟件的基礎庫的。?
在2020年11月發布的 .Net5 當中,就有一個與之相關的破壞性更新。我之所以對這個東西非常有印象,是因為我在開日歷控件的時候,遇到了這樣一個問題,就是當我們在用 Server Side 模式托管我們的控件庫的時候,我們發現它的日期格式與我們以 WebAssernbly 來托管的時間格式不同。為什么我們同樣的代碼放在不同的托管模式下,會出現這樣的不同。
在請教了 .Net 的官方的工作人員后,他們給我的回復是這樣的:因為當我們在本機調試的時候以Server Side 端渲染,我們使用的是 Windows 上的 .Net Run Time,它所使用的 i18n 跟 API 是 NLS (National Language Support)。
而當我們以 Webassernbly 進行托管的時候,他所使用的 Run Time 是 Mono。Mono 作為 .Net 最初的開源實現,它所使用的 i18n 的 API 就是 ICU。ICU是 International Component for Unicode。它是一個被廣泛使用的國際化組件庫,它可以為軟件提供非常好的國際化支持和 Unicode 的支持。
作為中國的用戶,我們可能對于編碼這件事情有非常深刻的理解。比如說我們經常打開一些很古老的軟件,它的界面上會有很多亂碼,而且我們也聽說過“燙燙燙”或者是“錕斤拷”,這樣的笑話對吧?那這樣編碼和解碼的錯誤究竟是怎么樣產生的呢?
我們就以“錕斤拷”這個例子來說一下,在 Unicode 中有很多字符是沒有辦法被顯示或者沒有辦法被定義的。在這種情況下,Unicode 的官方為我們提供了一個專門的字符用來解決這種問題,大家可能現在看不到這個字符。這個字符它在 Unicode 中它的編碼是 U+FFD,然后變成二進制之后就是下面的這一串。
當我們以 UTF8 來進行傳輸的時候,它就變成第三行的樣子。它的16進制格式表示就是下劃線下我們看到的樣子。當我們有一連串這樣的字符傳輸過來的時候,如果我們以 GB2312 或者是 GBK 來進行反解析的話,我們就會得到"錕斤拷"三個字。
Unicode 是從1990年開始研發到1994年正式發布的,而 GB2312 是從1980年就已經開始使用了,我們不能說 GB2312 沒有很好的兼容 Unicode,對吧?事實上的情況就是在 Unicode 正式出現之前,各個國家都有屬于自己的不同的編碼方案,導致各個國家之間的計算機系統相互交流有非常大的阻礙。所以 Unicode 的出現很方便的解決了大家的這種跨平臺跨語言之間的通信和交流。
而且中文是受益非常多的,因為在 Unicode 中差不多有9萬個中文字符。包括在日本、韓文以及越南正在使用的一些和中國大陸簡體不一樣的字形。而且 Unicode 本身也是在不斷發展的,它在不斷的吸納新的字符進來。比如2019年為了響應日本新的年號,他就加入了“令和”,到 Unicode 中。在2020年3月發布的 Unicode13 當中,他收錄了 4000 多個生僻字,其中也包括我們萬眾期待的 “biangbiang面” 的 “biang” 字。
而在隨著互聯網時代的發展,由于后者的更新,還有一個更加大的驅動力,那就是 emoji,又叫繪文字,他起源自日本,在 iPhone 上大放異彩之后迅速的風靡全球,之后就被 Unicode 的官方所接納,成為了它的一個標準之一。emoji 的出現讓大家認識到 Unicode 還有非常多的技術可以挖掘,比如說在人物的 emoji 后面加上 face pattern 的標志,我們就可以讓人物呈現不同的膚色????????????????????????????????????????????。
比如說我們可以在嗯嗯,emoji 之間通過零寬連接符進行連接,就可以讓不同的人物,不同的性別、不同膚色的人一起組成一個完全不一樣的家庭????????????????????????????????????????????????????????????????????????????????,而這些全部都是 Unicode 本身就能實現的,emoji 可以說是互聯網時代人們交流方式改變的一個縮影,通過 emoji 一些語言毫不相通的人也能夠進行互相的交流,它也算是一種全新的表意文字了,現在大家可能已經習慣在自己的平常的微信交流中夾雜著幾個 emoji 。這完全沒有問題,對不對??
像這種文化的融合,其實從新文化運動開始,對于中文改革創新來就從來沒有停止過,我們不斷的吸納白話文,簡體字,標點。但其實這些都對中文本身的固有認知產生了極大的挑戰。其中一個最大的挑戰就是排版。
對于古人來說,每一個字都是方塊字,從上到下書寫非常的齊整。但是到了現在,我們的中文之間可以夾雜著半寬的數字,可以夾雜著不等寬的英文字母,還可以帶著標點,雖然國標認為標點應該和字符同寬,但是我們對于標點的排版就有額外的要求。比如說我們要避開頭尾、點號不能出現在一行的首部、標號的開始不能出現在一行的尾,結束不能出現在一行的頭。
這些綜合起來看,就對我們軟件的排版產生了一個巨大的挑戰。這里我給大家舉一個微信的例子,這是我自己在微信上進行的測試,大家如果看第一行和第二行的話,我會發現這兩行的字符數量并不相等,但是他們視覺上看起來長度是一樣的,原因在于為了實現標點的擠壓,微信自動的縮短了每個字之間的間隙。
如果大家看到第二行和第三行的話,就會發現這種擠壓是因為標點而引起的,他們擁有相同的字符數,但是因為句號因為第三行它不是以標點結尾,所以他就可以換行,但是第二行并不可以換行。而第4行就說明這個句號,如果不是出現在行尾的話,它真的就是一個完整的字符串,而不是一個短短的字符。
那么對于英文來說,排版同樣不是輕松的事情,雖然沒有標準懸掛這樣的問題,但是比如說較長的字單詞可能需要按音節來階段,或者是字母之間,因為不能有太大間隙,所以我們只能調節單詞之間的間隙。大家可以意識到僅僅是對于顯示一段文字這樣簡單的一個任務,對于不同的語言來說,就已經有如此復雜的問題出現了,那么其實還有更多的語言,它在固有認知上就已經在挑戰我們對于排版,對于軟件界面的這種固有的認知。
比如說阿拉伯文,它是從右向左書寫的,那么這就要求很多軟件的界面都要適這種模式。現在大家看到的就是阿拉伯文的 Windows8 的開始界面,大家可以看到與我們常用的 WindowsOS 是完全鏡像的。但由于伊斯蘭教是目前世界上的三大宗教之一,所以對于阿拉伯文的排版依然有非常巨大的市場。那么對于一些非常小眾的語言,我們又該怎么辦呢?
我是一名內蒙古呼倫貝爾人,所以我這里要不得不提一下,我們的回鶻式蒙古文。大家看到這段論文是我在網上隨便看到的,他的意思我并不明白,所以它不代表我的立場,也不代表 MSReactor 的立場。回鶻式蒙古文是從上到下書寫,每個單詞都有不同的長度,那么對于我們現在的這種 UI 的架構,它就是完全不適用的。至今為止內蒙古自治區依然使用回鶻式蒙古文作為我們的官方語言之一,對于蒙古國而言,他們也將在 2025 年之前完全恢復使用回鶻式蒙古文。
但是對于現在的各大操作系統軟件來說,回鶻式蒙古文的顯示依然是一個巨大的問題,至今各大操作系統都沒有一個完美的解決方案,只能退而求其次使用西里爾蒙文。
我今天的演講差不多也就到這里結束了,在故事的最后我想講圣經上的一個小故事。在大洪水之后,人們其實是講著同樣的語言的,大家想齊心協力建造了無與倫比的巴比倫城,想去建造了一座高塔直通云霄。
這讓上帝感到非常的震驚,所以他就來到了人間,教會了人們使用不同的語言,把人們分散在世界各地。所以這個偉大的巴別塔也就無疾而終了。直到今日我們依然分散在世界的各地,說著不同的語言,用著不同的文字、傳承著不同的文化。但是作為程序員的我們其實是在通過另一種方式打破這種屏障,與“上帝”進行周旋。
我們一方面試圖打破屏障,把世界各地不同的人們聯系在一起,另一方面我們又在極力的竭盡所能的維護著這個世界的多樣性。最后我也感謝這個互相連接的世界,能夠給我這個機會,讓我在遠14個小時時區之外的中國能夠完成這個學業,一起參與到這個偉大的事業當中。
球分享
球點贊
球在看
總結
以上是生活随笔為你收集整理的这是“我”的故事 —— 董彬的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: BeetleX.WebFamily针对W
- 下一篇: BeetleX之Web网关1.5.7安装