一個生物專業學生的內心獨白:我為什麼能去互聯網大廠?

這回,考慮到近期關注了許多新朋友,並且大多都是學生黨,可能對我還不是特別熟悉。因此我決定重新把我從非科班如何通過自學(狗屎運)進入大廠的經歷分享出來,希望能夠給予一些將要面臨秋招,或者將要準備進入互聯網行業的同學一丟丟的幫助。

早期關注我的讀者可能都約莫着記得,我是在華科讀的本碩,專業是生物醫學工程。雖說專業的的確確是帶了生物二字,但是我老實交代,實際上並不是純粹的生物技術方向上的專業。簡單科普一下:

生物醫學工程是屬於交叉程度非常高,主要面向生物醫學領域的工程學科。我們在學校的主要課程包含硬件設計、軟件設計、生化基礎以及儀器科學等。

所以呢,原諒本文的些許標題黨。但是說實話,由於學科高度交叉,我們實際上所習得的技能就是一團漿糊。在計算機科學方面的系統知識積累,與純生物專業相比,也不過是五十步笑百步。

一 啟智階段

雖說大學期間學的都不是計算機,但是我對計算機的興趣萌芽卻是十分的早。那估計都得有二十年前了,嗯誇張了點。不過應該是在小學時候了。

我是在老家鄉下上的小學,你們可能想象不到,那個時候的鄉下小學竟然都有電腦課。不過那時候不叫電腦課,叫做“微機課”。

微機課是幹嘛的呢?就是一群小朋友排排隊,拖鞋進到一個乾淨的房間里,然後幾個人圍着一台那種屁股又大又方的電腦,玩紙牌。沒錯,就是windows上流行多年的紙牌遊戲。

怎麼說呢。我玩紙牌賊溜。 大概天生對這一類東西的接受能力比較強,所以上手很快,並且除了紙牌,還有空當接龍,掃雷,3D彈球。這麼說可能有點暴露年齡了。

最早windows系統普及的這一批遊戲真的讓我對“微機”這麼個東西產生了懵懂的概念和持續的嚮往。

二 本科階段

之後的成長道路中,一直對計算機耍的挺溜。但是有點尷尬的是,沒人領進門。所以一直都是在娛樂,並沒有真正意義上接觸到計算機內部或者代碼編程的世界。

初識代碼

所以在上大學之前,基本上對編程一無所知,但是卻有一種強烈的對計算機的熱愛。不過那時對於計算機的理解僅限於【裝系統】,【裝軟件】和【拆洗主機風扇】。不要問我為什麼沒有去學計算機,要怪就只能怪考試時坐在我旁邊的那位,大概天生就得了瘋狂抖腿病的二貨。氣!

一不小心,還進了生科院。但是緣分這種東西,真的妙不可言。這一切的開始源於一場面試。

所在的大學是一所以工科著稱的高校,其中創業氣氛十分濃厚。學校因此有許多小有名氣的科創團隊,基本上是由老師主導,各專業學生組成的小團體。可不要小看這些小團隊,世界級程序設計大賽的獎牌獲得者經常就出於此類團隊。剛上大學的我們單純稚嫩,自然會被被這些團隊的大幅宣傳報和滿目的獎牌稱號所吸引膜拜。我也不例外。

當時我便懷着澎湃的心情申請了一家曾多次在微軟創新杯奪得金獎的團隊。一個從鄉下來的小伙,第一次參加面試,第一次單獨和碼農小姐姐夜晚座談,第一次參加所謂的通宵測試。

也就是在那一個晚上,開啟了我新世界的大門。

那天晚上給我一群編程小白的任務,是模仿百度首頁,實現整個網頁的設計、布局和基本鏈接。提前給出的提示是w3c的教程網址。

從來沒有接觸過編程的我在此之前,連編程的流程都不清楚,更不必說編譯環境、編譯語言甚至是源代碼閱讀(當然這個任務也涉及不到這些)。

但是也就是那一個晚上,讓我真正意義上的接觸了敲代碼這個事兒。

沒錯,我的編程起點是HTML+CSS。可惜的是,我並沒有通過那個團隊最終的面試。不過從那以後,我就開始了網站開發的自學之路。

個人自學的堅持很大程度上基於興趣,源於在室友面前一頓裝逼后的成就感。但這就是一個生科院的學生在課後的最大樂趣所在。

小試牛刀

在接觸到網站開發之後,從最初的HTML+CSS到後來的HTML5+CSS3+JS+ASP,從靜態頁面的布局到動態網頁的請求。

雖然感覺技術的成長也就是從博客的複製粘貼走向了文檔的複製粘貼。但是終於迎來了小試牛刀的機會。

學校某大型學校組織需要做一個展示網站,朋友拉上了我和幾個人承擔了這個事情。這算是第一次真正意義上的項目開發,不過整個網站的功能不多,主要還是展示為主,後台也直接通過學校網絡平台整合就行了。所以整體下來做的事情並不多。

迷茫困惑

一直以來,都是自己通過博客自學,東拼西湊的建立起知識架構。但是其實技術基礎十分不牢固,不懂計算機基礎、計算機網絡,更別說編譯原理、操作系統等基本的知識。因此在很長一段時間內,覺得好像也沒有會什麼,一直對自己的能力保持懷疑。

在這段時間內,有過跑去搞嵌入式,硬件開發,甚至是產品設計、界面設計,視頻製作。但都不一而終。

一段迷茫,一段頹廢。一不小心就成為校園裡的學長,於是開始緊緊茫茫的尋找實驗室。

新的方向

好在我們專業與生科院其它專業相比,還是帶有工科氣質的。醫學影像學本身就是這個專業最為重要的一個方向。因此懷着對編程的興趣,加入了一個專門做醫學影像的實驗室。

進入實驗室,不再是之前的漫無目的,隨處拾荒,但卻也並不會接觸到前沿新興的技術。畢竟在實驗室里,工程技術更多的只是工具。

不過值得一提的是,在實驗室里,我接觸到了算法思想。醫學圖像本來就是圖像處理領域的一大分支,因此圖像處理算法的了解同樣也是至關重要。

從這個時候開始,我已經不再搞網站開發那一套東西,專心使用C++寫我的算法。那時候深度學習還沒那麼熱門,大多數的圖像處理方式還是基於傳統的算法進行。雖然算法能力薄弱,但是倒也是我所求。

同時,為了獲得數據,還接觸到Linux系統以及一些腳本,在做研究的過程中也大大增加自己的技術面。

與此同時,為了鞏固自己的一些技術基礎,也為了督促自己的學習,我報考了計算機等級考試和國家軟考。可能對於計算機專業的學生來說,沒有什麼含金量,輕而易舉。但是對於一個非科班的學生而言,這樣的考試可以很大程度上幫助自己去重新組織零碎的知識。畢竟不是所有人都有足夠的精力去跟着計算機系的人上課。

本科階段的經歷讓我知道自己與計算機系的差距,雖然接觸了許多東西,但是也都不夠精,甚至沒有底氣去獨立承擔一個小的開發任務。

因此最終選擇了讀研。希望讓自己的技術都夠在某一個點上精進,能夠獨立的做出點東西來。當然最終的結果可能並不是自己當初所想,但是說到底還是得感謝在研究生期間所做出的努力。

三 碩士階段

我研究生的生活是從大四就開始的。因為是本校保研生,所以在大三下確定好實驗室后,基本就直接開始搬磚的苦逼生活了。當然舍友和同學在為畢業而慶祝歡快的時候,我就開始在實驗室早出晚歸。

讀研的開始

進入實驗室之後,剛開始一段時間也是沒有人帶。這能靠自己去多多實驗室專業方向的文章,然後學一點基本技能。更重要的其實是為了在實驗室混個臉熟。

實驗室的研究方向主要是核醫學成像系統,整個系統的搭建涉及到核科學研究、物理數學模型的建立、电子信息的數據獲取、自動化控制設計、机械結構設計、軟件和算法處理以及醫學實驗驗證等一系列的過程。

但對我們個人來說,主要是做某一個方向即可。當時我還是自認有一些編程基礎,於是計劃去做軟件開發或者數據處理的方向。但是最初期是沒有人帶的,所以就花三天時間自學了python3,把廖雪峰的python教程從頭到尾走了一遍。

可惜的是,學完之後也並沒有派上用場。

之後實驗室新項目確立,我被導師安排到了一個新項目組裡。在項目組中,主要負責的是圖像重建的部分。圖像重建是醫學影像領域非常重要的一個研究方向,目的是將影像系統採集到的多維多尺度的信息根據成像原理,依照不同算法還原成二維或三維的斷層圖像。所以本質上來說,圖像重建的重點也是在於算法設計和優化。

方向的多變

開始所在的項目組內,主要的工作還是基於軟件編程和算法開發,涉及到的技術棧主要還是以C++為主,然後加上一些圖型庫,如QtopenGLVTK等等。不過都是處於調用函數調包的階段,也沒有很深入的研究算法原理和實現機制。實話說其實個人提升不大。

過了一段時間后,實驗室師兄拉我去幫他做事。師兄本身能力非常出眾,科研水平不容置疑,所以當時就過去了。之後在他手下做的事就很多變了,不只是軟件開發,還涉及到数字電路編程,PCB制板,系統仿真等。

那個時候還來實驗室沒多久,沒有仔細的想過自己之後的就業方向,只想着能夠在研究生期間多做些成果,多發文章。因此,跟着師兄搬磚的時候也沒有過多考慮對之後的求職是否有幫助,只是想把事情做好,做出有意義的成果。

不過幸運的是,在大四暑假前,也就是研究生入學之前。根據師兄的指導,將一個軟件開發的工作給擴充,投了一篇領域內的頂會。雖然覺得所作的工作沒什麼特別的,但是最終文章被錄還是非常開心的。也正因為這個事,之後更想着能夠多發文章多出成果。同時,師兄也比較會熬雞湯,各種說辭讓我放佛感覺到即將成為科研巨人,登上學校官網,走上人生巔峰。

綜合能力鍛煉

在實驗室,除了完成自己的科研任務,還有很重要的一部分,就是寫本子。也就是申請項目基金等等文字工作。

我估計有參与過的項目申請或結題工作不下十餘項,每次都會涉及到大量文字的整理、表達、排版等工作。一般的學生對於這樣的工作都是極度排斥的,覺得很煩又沒什麼用。當然我也是這樣覺得的。

只不過在寫了大量的本子後會發現,其實這也是綜合能力的鍛煉。我們導師常說,博士生一定要會寫項目,碩士生的話盡量寫。說明他把這也是當作一種能力的培養。在師兄手下,我也經常性的寫本子,甚至於超過了敲的代碼。那時候也沒有很明確的技術培養規劃,所以倒也覺得還行。

獨自前行

只不過好景不長。帶我的師兄由於過於優秀,將要離開實驗室去其它高校就職。這對當時的我來說,處境有些許尷尬。因為我的研究方向是與師兄的工作有交叉的,同時一些設備和材料也需要師兄的支持。

實驗室本身的氛圍是以博士帶頭,碩士輔助進行項目開展的,而我的研究方向是我自己獨立出來的一個題目。說白了就是實驗室就我一個人在搞這個,但是這個方向不是導師關注的方向。

因此,在這之後,我又回歸到了一個人做事的階段。大概是研一下開始,我就只能自己一個人去想自己的研究課題,偶爾會跟老師討論,但是也沒有很確定的工作路線。具體的工作內容也只能靠自己去思索。

在這段期間,我寫過verilog,調過FPGA,畫過板子,畫過工程圖,當然也寫過軟件做過算法。一個人做事的話,可以說是很自由,沒有老師管,也沒有報告的壓力。只是很多時候發現有一些想法沒辦法實現,也無法對前沿領域有很深的洞察。空有一腔發文章報效實驗室的熱血,卻發現像是站在水中的浮木上,搖搖欲墜。當然這其中,個人的問題佔有很大比重。

摸魚的日子

不敢說自己的有多麼自律,多麼出色。可能世上大多人都是芸芸眾生,我也不過一個普通人。在自己做研究的同時,每次到臨近頂會收集文章摘要之時,我都會很积極的熬個一兩個月,將自己的想法和結果寫成一到兩篇的會議文章。我自己也大概知道其實工作沒有太大的突破點,但也是希望能夠賭一把。

只不過兩年來,一共整理出數篇會議摘要,都沒有被同意投稿。每一次還是會有些灰心,也有些不服。會時刻回想起導師的反饋,而後想到一堆反駁的理由。只不過都沒用。

每一次之後,都會有一段時間的消沉。不太想去實驗室,不太想看論文,在實驗室可能也就是摸摸魚罷了。很多時候覺得鬥志滿滿,又會瞬間像泄了氣的皮球,沒有精力去完成任何事。

職業方向

到如今,算是大四的時光,在實驗室已經呆了快四年。平心而論,沒有做過什麼突出的成果,也沒有練就什麼出色的技術。研究生活高開低走,一度以為自己是什麼科研巨星,後來僅剩的一絲熱情也在導師的「也沒看出你有什麼天分」中黯然消逝。不過還好,在這之前,我找到了自己的職業方向。

我本身就是一個比較後知后覺的人,一方面是懶,另一方面又對自己有一種迷之自信。我真正意義上開始準備校招還是在去年六月底七月初的時候,也就是研二下學期快結束的時候吧。我們實驗室的碩士生出去基本就是兩個方向,軟件或者硬件。搞電路的基本都選擇去做硬件開發,其它的大部分都會選擇做軟件。我也沒啥可想的,雖然做過硬件,但是技術水平根本不敢出手。所以求職的方向直接就定在了軟件開發相關。

當時還不知道應聘互聯網還要刷題,還要複習,以為上去介紹下自己,講講自己做的跟互聯網沒有半毛錢關係的項目就可以顯得很有想法的樣子。後來真正開始準備的時候才發現,自己原來還差得有點遠。

老實說在研究生期間,主要使用C++Matlab,主要的項目就是用Qt寫了一個客戶端,裏面有網絡通信的模塊可以對數據做一些處理,並且能夠显示圖譜。用Matlab主要就是做了一些比較基礎的圖像處理和機器學習的算法。光這項目再加上非科班帶「生物」二字的專業,的確讓不清楚的人會十動然拒。

不過其實也沒得選擇。生醫專業對口的公司都是做醫療器械,比如聯影、邁瑞等。但是其實去這些公司也是做軟件開發工程師。相對來說,互聯網公司技術好,待遇好,發展好,自然就成為大部分的選擇去向。

說是跨行,但是其實也沒有別的更好的選擇。我們老師常說希望我們學生以後能夠在我們這個領域發光發熱。這倒是真的,國家的發展還是離不開這些能夠在某個領域深耕的人,而不是為了一昧追求熱點和高薪而忘記了初心。

四 求職經歷

講講我的秋招經歷吧。我的秋招雖然準備的晚,但是其實還是挺順利的。從19年8月開始接到面試,2個月內已經拿到了15+的offer,基本平均薪資都在30w+。包括抖音美團華為小米等等。那段時間真的是狀態上來了,就是佛擋殺佛,神擋殺神。

不過剛開始的時候,由於實驗室的原因,沒有辦法出去實習。甚至由於一些原因,一直拖到暑期前才開始準備複習。

那時已經快七月初了。急匆匆的登上各種學習網站,發現這也太多要看了的吧,還得刷題。關鍵一看面經,這都啥呀。還要手撕代碼的嗎?

這一看當時不要緊,關鍵晚上就焦慮的快睡不着了。每天都在想應該怎樣複習,怎麼寫簡歷,沒有項目該怎麼辦。

剛開始的時候連簡歷都不敢投,因為老覺得簡歷一過去就會安排面試。後來發現這完全就是多慮了。大概從七月初我就開始投簡歷,因為七八月是一些公司提前批招聘的階段。

許多非科班的學生,在投遞簡歷的時候才能發現自己的無助。我在簡歷投遞初期,基本沒有任何反饋。提前批階段,許多公司都會去爭奪更優秀的簡歷候選者,對於生物專業的學生真的沒有什麼優勢。

但是沒有關係,既然選擇了這條路,那麼就要堅持下去。投一家無人應答,那麼就投十家,投五十家。我在整個秋招階段,總共投遞過近一百家公司。許多在提前批沒有給予反饋的公司,後期大部分都有電話聯繫重新開啟面試流程。所以,就算認為自己的簡歷再不夠出色,也要相信總會有瞎了眼的HR(誤)。

我當時一直在堅持投簡歷,只要看到的招聘信息都會去投遞。還記得第一次做測評題的時候都非常緊張,以為這就是筆試題。非常認真的拿紙筆在計算,慌的不行。

後來直到八月初才收到第一份面試邀請,多益網絡。當時約了面試之後簡直怕死了,雖然說複習了一個月大部分的 C++ 基礎知識都看得差不多了,但是肯定是不夠的。面試的時候面試小哥全程就低頭照着題庫念,也不看我。我這邊的音頻信號也不太行,他那邊說話都聽不清楚。兩個人就在無數次的重複和確認。關鍵是面試完之後我自我感覺還非常良好。

最終結果還是掛了,說實話打擊挺大的,感覺因此對面試產生了恐懼。不過後來試着自己跟自己講解,慢慢的也習慣了面試的感覺。

隨後在八月底的時候,終於收穫了第一家 ihandy 的 offer。並且在進行總管面的時候,跟面試官進行了深入的交談。面完之後讓我有一種都不好意思拒絕這家公司的念頭。這也是第一次感受到了面試官的認可。

隨後,便一發不可收拾。這個時候,已經準備了大概兩個月,基本的技術知識我都看完了,劍指 offer 上的66題以及 leetcode 上基本的題也大概刷了兩次。同時獲得了一個 offer 之後,對自己的認可度非常高,使得面試的狀態非常好。

後來給了面試機會的公司基本都拿到了 offer。像字節跳動、美團、虎牙等等公司,面完的感覺就是基本穩了。不過可惜的是阿里簡歷面后,內推人開始說通過了,後來不知道什麼情況流程就拖到結束了。

騰訊也一直沒有撈過我面試。感覺如果在狀態頂峰的情況下能有面試機會的話,還是很有希望的。不過也說明簡歷依然不夠出色,非科班沒有實習經歷,項目也比較水,導致AT大廠連面試機會都沒給。這也是秋招比較遺憾的地方。

另外,記住面試過程,跟投遞簡歷一樣,一定要多面多總結。

如果你的表達能力不好,沒有別的好的辦法,只能多練。自己在面試前問自己問題,然後用自己的話陳述出來。甚至是錄音自己聽,感覺一下面試官聽到你的回答是做何感想。

心態要好。面試官也是人,不可能所有人都能夠絕對公平的跟你面試,所以遇到人品不好的面試官,做好自己就行了。

要善於總結。每一次的面試都可以做好記錄,錄音或者筆記都可以。面試完之後需要多回顧,發現自己的錯誤,感受面試官對你的引導,然後下次面試注意。我一般喜歡用印象筆記記錄東西,每一次的面試記錄我都記錄在印象筆記上。電腦手機都可以看,即使是出門現場面試也不怕。

最後就是一定要堅持下去。金九銀十,金三銀四。把握好機會,要善於規劃自己的成功。

五 複習準備

想進互聯網的技術崗,基本都是要提前準備的。當然某些大佬及大大佬除外。無論是校招還是社招,都需要針對自己的求職崗位進行必要的理論知識複習、項目經歷反思和算法能力訓練。只不過校招會偏向於基礎和算法能力,社招可能都會重點考察。

除項目經歷外,複習的階段主要分為語言基礎、數據結構和算法、計算機網絡、操作系統、數據庫以及算法刷題。

語言基礎:

以 C++ 為主。我不喜歡看又厚又重的語言書,因此複習全程是以博客、開發文檔和實踐相結合的方式進行技術點複習。C++ 的技術點相對於其它語言來說,不算多,也不算難。技術重點的篩選可以從面經中提取而來。當然每一屆都差不多,所以找找別人總結好的資料看就行。(想要我複習資料的,可關注公眾號後台回復秋招領取)

數據結構和算法:

這應該是編程的基礎,重要需要了解的數據結構不出10種。花點時間弄清楚它們的原理、結構和使用方法,常用的操作也需要掌握。最難不過紅黑樹。

這裏的算法指的是常用的算法,比如排序、遍歷,與數據結構相結合的數據操作方式。需要保證手寫才行。

計算機網絡:

網絡部分的內容其實可以算是最重要的,無論是前端後端都需要掌握網絡通信過程中的操作和機制。技術點可參考網絡服務器的請求和響應過程。將其中所有涉及到的協議、機制了解清楚,就可以掌握大部分了。

操作系統:

如果有Linux使用經歷和腳本編程基礎在面試中會很加分。對於操作系統的理解建議按照Linuxwindos系統的區分進行。

數據庫:

SQL基本操作必須要掌握,還包括一些關係型數據庫的基本原理和機制,內容不多,多看看就可以掌握。

Redis同樣也是加分項,有能力的可去研究下源碼。

算法刷題

這一部分不多說,普通人只能勤能補拙。無論是劍指offer66題還是leetcode都可以,劍指刷兩遍,leetcode兩百題,基本沒有問題了。刷題時不要死刷,可以根據類型刷,比如鏈表操作、二叉樹操作、動態規劃等。相同類型重複做,能夠更好的培養算法思想。

六 感想體會

說起求職的過程,其實真要我來評價的話,估計運氣是佔了一大部分,連我這樣都行,你們也可以的。不過最終能夠獲得一些互聯網公司認可的原因,我認為主要有以下幾點原因吧:

1.本科階段接觸互聯網行業比較早,對於這個行業有自己的見解。

2.本科階段有考過一些計算機水平的證書,大概系統的學了一下計算機相關的基礎知識。

3.用C++比較多,對語言基礎的理解比較好。

4.面試狀態比較好,比較會表達自己的想法。

5.學習能力還行,能夠在面試官的引導下找到他想問的技術點。

6.準備過程比較有規劃,能夠快速的掌握面試的重點。

7.人長得老實,比較容易獲得信任感。(這個你們可能學不了^_^)

8.比較幸運。

前天剛碩士答辯完,這两天也把學位申請的各種材料提交上去了。一不小心,七年的大學校園時光真的要結束了,兜兜轉轉感覺好像依舊是一無是處,一事無成。但是依舊希望以後能夠:

二龍騰飛、三羊開泰、四季平安、 五福臨門、六六大順、七星高照、八方來財、九九同心、十全十美、百事亨通、千事吉祥、萬事如意

人生無常,活在當下,且行且珍惜!

本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

※為什麼 USB CONNECTOR 是電子產業重要的元件?

網頁設計一頭霧水該從何著手呢? 台北網頁設計公司幫您輕鬆架站!

※台北網頁設計公司全省服務真心推薦

※想知道最厲害的網頁設計公司"嚨底家"!

※推薦評價好的iphone維修中心

希臘野火竄燒 波及著名邁錫尼古城遺址

摘錄自2020年8月31日中央社報導

希臘青銅時代的著名遺址邁錫尼古城附近野火延燒,當局緊急疏散遊客,消防官員表示,火勢已獲得控制。

希臘消防部門官員表示,野火下午從阿卡曼儂(Agamemnon)古墓附近竄起,「部分已獲得控制」。

伯羅奔尼梭(Peloponnese)南部的消防局局長科利維拉斯(Thanassis Koliviras)告訴「雅典通訊社」(Athens News Agency),大火波及「考古遺址的一個區塊,並燒毀些許乾草,但沒有損及博物館」。

希臘文化部發表聲明說,根據初步調查,「大火沒有破壞古蹟」,並說之後「一組專家將評估受損情況」。

乾燥的夏季氣候期間,希臘每年都得應付燒不盡的野火,並且高溫時常超過攝氏30度。

氣候變遷
國際新聞
希臘
野火

本站聲明:網站內容來源環境資訊中心https://e-info.org.tw/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

※為什麼 USB CONNECTOR 是電子產業重要的元件?

網頁設計一頭霧水該從何著手呢? 台北網頁設計公司幫您輕鬆架站!

※台北網頁設計公司全省服務真心推薦

※想知道最厲害的網頁設計公司"嚨底家"!

※推薦評價好的iphone維修中心

海神挾風雨今晨登陸 南韓一核電廠2機組突停止運轉

摘錄自2020年9月7日自由時報報導

中度颱風「海神」已於台灣時間今(7日)上午8點登陸南韓蔚山沿海,海神颱風威力強大,傳出位於慶尚北道慶州市的月城核電廠有兩個核電機組暫停運轉。

據《韓聯社》報導,韓國水電與核電公司總部宣布,擁有四個核子反應爐發電的月城核電廠的2號機組在當地時間8點38分停止運作,而3號機組則在上午9點18分停止運轉,這兩機組設備容量都達70萬千瓦(kW),另外兩機組則正常運作,維持60%發電量,總部強調,沒有輻射外洩問題。

韓國水電與核電公司總部一名官員表示,目前正在檢查停機原因,研判可能是由於颱風造成電線短路問題;月城核電廠供應約5%的南韓用電量。

能源轉型
國際新聞
南韓
核電廠

本站聲明:網站內容來源環境資訊中心https://e-info.org.tw/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

※為什麼 USB CONNECTOR 是電子產業重要的元件?

網頁設計一頭霧水該從何著手呢? 台北網頁設計公司幫您輕鬆架站!

※台北網頁設計公司全省服務真心推薦

※想知道最厲害的網頁設計公司"嚨底家"!

※推薦評價好的iphone維修中心

主動安全很重要 8萬元以下帶ESP家用轎車選這些!

最初的遙控泊車着實讓我們驚艷的一把。速銳在7萬多的車型上就已經配備了ESp車身穩定系統。除了ESp此外,速銳身上還有許多實用配置,表現可圈可點。動力上速銳採用了1。5升的自然吸氣發動機。搭配5擋手動或者6擋雙離合變速箱,最大功率109馬力最大扭矩145牛米,這樣的動力輸出只能說夠用,但是這也為速銳帶來了非常親民的價格。

昨天小編美美走路一不小心,摔了個狗吃屎;這時候二貨同事說,你這種十八年的老車沒有ESp,肯定容易摔跤啊,主動安全性不行嘛。

的確,對於十八歲的小編美美來說,如果我媽生我的時候附帶了ESp技能,興許就不會摔跤了。

看↓↓↓

帶ESp的狗狗穩定性多好。

當然這都是玩笑,不過ESp對於汽車來說還真有這麼神奇的功效。它能夠通過對單獨車輪進行制動、切斷動力等方法來控制車身動態,減少車輛的失控機率。憑藉優異的主動安全表現,ESp榮獲了NCAp全球獎項,這也足以證明ESp在安全性上的巨大作用。

我們看看在時速40km的情況下汽車在冰面上做一個變線的情況

可以看到帶ESp的車輛很好的保持了正常行駛,而沒帶ESp的車,呵呵~

那麼多少錢的車會搭載ESp呢?一般來說10萬以上的自主車輛都配備了ESp,12萬以上的合資車都配備了ESp,如果你買了個合資車花了十幾萬還沒有ESp那你來找我,我來幫你罵它。那麼10萬內有沒有帶ESp的車呢?當然有,這幾台車不到8萬裸車的配置就帶有ESp了,而且綜合表現也不錯哦。

長安悅翔V7

指導價:5.99-8.79萬

長安悅翔V7是我們非常熟悉的一位車型。而最近它又增加了1.0T的動力系統。除了低配車型之外,中高配開始就搭載了ESp車身穩定系統,在安全性方面還是十分厚道的。

悅翔V7的外觀設計在同級別中數一數二,而在內飾上設計的也十分恰到好處。簡約的內飾清晰的功能分區以及不錯的人機設計。都值得豎個大拇指,但是對於悅翔V7來說最大的問題是我為什麼不加一點錢買逸動呢?

比亞迪速銳

指導價:6.99-9.59萬

比亞迪速銳是我們非常熟悉的一款車型,它以超高的配置和大空間作為主要的賣點。最初的遙控泊車着實讓我們驚艷的一把。速銳在7萬多的車型上就已經配備了ESp車身穩定系統。除了ESp此外,速銳身上還有許多實用配置,表現可圈可點。

動力上速銳採用了1.5升的自然吸氣發動機。搭配5擋手動或者6擋雙離合變速箱,最大功率109馬力最大扭矩145牛米,這樣的動力輸出只能說夠用,但是這也為速銳帶來了非常親民的價格。

雪佛蘭樂風RV

指導價:7.49-9.99萬

樂風RV雖然定位為小型車,但是由於兩廂的造型設計以及不錯的空間設計理念,樂風RV在內部空間表現上還是十分值得表揚的,樂風RV使用1.5升自然吸氣發動機匹配5擋手動或者4擋自動變速箱。

樂風RV在同價位的車型中十分罕見的全系標配ESp車身穩定系統,這也显示了通用對於安全性的重視以及嚴謹的造車態度,樂風RV可以說是一位不折不扣的實力选手。不過沒那麼主流的外觀可能會讓不少人拒絕它。

東風風行景逸S50

指導價:6.99-10.29萬

風行景逸S50外觀上就比較的平庸了,在內飾設計上則是東風風行家族的標準化設計,沒什麼亮點但是風行景逸S50在低配車型上也已經配備了ESp,而且加上較大的尺寸和完善的動力系統。風行景逸還是值得推薦的。

風行景逸S50採用1.5L和1.6L/2.0L 3款自然吸氣發動機自動車型匹配CVT變速箱。動力方面風行景逸S50表現平平,但是它的車身尺寸比較大,軸距長達兩米七,行李箱容積也達到了500升,對於家用車來說這樣的空間表現十分寬裕了。而我唯一需要考慮的是我要不要等即將上市的外觀更大氣內飾更加精緻的新款呢?

總結:

對於家用車來說,安全舒適是十分重要的,有ESp能夠大大提升你在下雨天、環島行駛等多種情況下的安全性,因此對於ESp小編美美是十分推薦的,當然更重要的還在於謹慎駕駛安全開車,如果你100km/h打死方向,神仙也救不了你。本站聲明:網站內容來源於http://www.auto6s.com/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

※為什麼 USB CONNECTOR 是電子產業重要的元件?

網頁設計一頭霧水該從何著手呢? 台北網頁設計公司幫您輕鬆架站!

※台北網頁設計公司全省服務真心推薦

※想知道最厲害的網頁設計公司"嚨底家"!

※推薦評價好的iphone維修中心

【實戰】基於OpenCV的水表字符識別(OCR)

目錄

  • 1. USB攝像頭取圖
  • 2. 圖像預處理:獲取屏幕ROI
    • 2.1. 分離提取屏幕區域
    • 2.2. 計算屏幕區域的旋轉角度
    • 2.3. 裁剪屏幕區域
    • 2.4. 旋轉圖像至正向視角
    • 2.5. 提取文字圖像
    • 2.6. 封裝上述過程
  • 3. 字符分割,獲取單個字符的圖像
  • 4. 模板匹配:確定字符內容
    • 4.1. make_template
    • 4.2. 模板修復
    • 4.3. 重新加載模板數據
    • 4.4. 模板匹配

1. USB攝像頭取圖

由於分辨率越高,處理的像素就越多,導致分析圖像的時間變長,這裏,我們設定攝像頭的取圖像素為(240,320):

cap = cv2.VideoCapture(0)  # 根據電腦連接的情況填入攝像頭序號
assert cap.isOpened()

# 以下設置显示屏的寬高
cap.set(cv2.CAP_PROP_FRAME_WIDTH, 320)
cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 240)
cap.set(cv2.CAP_PROP_FOURCC, cv2.VideoWriter.fourcc('M', 'J', 'P', 'G'))

這裏提幾個常用的標準分辨率:

  • VGA (Video Graphics Array): 640×480
  • QVGA (QuarterVGA): 240×320
  • QQVGA: 120×160

接下來可以捕獲一幀數據看一下狀態:

# %% 捕獲一幀清晰的圖像
def try_frame():
    while True:
        ret, im_frame = cap.read()
        cv2.imshow("frame", im_frame)  # 显示圖像

        # im_gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)  # 可選擇轉換為灰度圖
        if cv2.waitKey(1) & 0xFF == ord('q'):
            break

    cv2.destroyAllWindows()
    return im_frame

im_frame = try_frame()
env.imshow(im_frame)

ps: 鏡頭角度會存在一定的歪斜,沒有關係,我們後面會進行處理。

2. 圖像預處理:獲取屏幕ROI

利用屏幕的亮度,通過簡單的閾值操作和輪廓操作,獲取屏幕輪廓,然後將圖像角度校正,最後獲得正向的文字內容。

2.1. 分離提取屏幕區域

通過OTSU的閾值化操作,將圖像處理為二值狀態。這個很重要,因為如果直接使用彩圖或灰度圖,會由於外部光線的變化,導致後期字符匹配時整體灰度值與模板的差別而降低置信度,導致較大的誤差。而二值圖可以避免這個問題。

然後利用開運算(白底黑字,如果黑底白字則為閉運算),消除噪點。

im_latest = try_frame()
im_gray = mvlib.color.rgb2gray(image)
im_bin = mvlib.filters.threshold(im_gray, invert=False)
# im_erosion = mvlib.morphology.erosion(im_bin, (11, 11))
# im_dilation = mvlib.morphology.dilation(im_erosion, (5, 5))
im_opening = mvlib.morphology.opening(im_bin, (11, 11))
env.imshow(im_opening)

2.2. 計算屏幕區域的旋轉角度

提取圖像的最大輪廓,然後獲取其包絡矩形。

list_cnts = mvlib.contours.find_cnts(im_opening)
if len(list_cnts) != 1:
    print(f"非唯一輪廓,請通過面積篩選過濾")
    # assert 0
    cnts_sorted = mvlib.contours.cnts_sort(list_cnts, mvlib.contours.cnt_area)
    list_cnts = [cnts_sorted[0]]

box, results = mvlib.contours.approx_rect(list_cnts[0], True)
angle = results[2]  # 此處的角度是向逆時針傾斜,記作:-4
if abs(angle) > 45:
    angle = (angle + 45) % 90 - 45
print(angle, box)

上述過程輸出:

1.432098388671875
[[282 173]
 [ 29 167]
 [ 32  41]
 [285  47]]

2.3. 裁剪屏幕區域

至此可以丟棄im_opening以及im_bin的圖像了。我們重新回到im_gray上進行操作(需要重新進行閾值化以獲取文字的二值圖)。

list_width = box[:,0]
list_height= box[:,1]
w_min, w_max = min(list_width), max(list_width)
h_min, h_max = min(list_height), max(list_height)

im_screen = im_gray[h_min:h_max, w_min:w_max]
env.imshow(im_screen)

2.4. 旋轉圖像至正向視角

im_screen_orthogonal = mvlib.transform.rotate(im_screen, angle, False)
# env.imshow(im_screen_orthogonal)
im_screen_core = im_screen_orthogonal[20:-20, 20:-20]
env.imshow(im_screen_core)

2.5. 提取文字圖像

第二次執行閾值化操作,但這一次是在屏幕內部,排除了屏幕外複雜的背景后,可以很容易的獲取到文字的內容。由於我們只關心数字,所以通過閉運算將細體字過濾掉。

im_core_bin = mvlib.filters.threshold(im_screen_core, invert=False)
im_closing = mvlib.morphology.closing(im_core_bin, (3,3))
env.imshow(im_closing)

2.6. 封裝上述過程

瑣碎的預處理過程就告一段落了,我們可以將上述的內容封裝成一個簡單的函數:

def preprocess():
    # 獲取屏幕區域
    im_latest = try_frame()
    ...
    im_closing = mvlib.morphology.closing(im_core_bin, (3,3))
    return im_closing

3. 字符分割,獲取單個字符的圖像

字符分割,一方面是製作模板的需要(當然,你也可以直接用畫圖工具裁剪出一張模板圖像);另一方面是為了加速模板匹配的效率。當然,你完全可以在整張圖像上利用 match_template() 查找模板,但如果進行多模板匹配,重複的掃描整張圖像,效率就大打折扣了。

先提供完整的代碼

char_width_min = 7
gap_height_max = 5

def segment_chars(im_core):
    list_char_img = []
    # 字符區域
    raw_bkg = np.all(im_core, axis=0)
    col_bkg = np.all(im_core, axis=1)

    # 計算字高
    ndarr_char_height = np.where(False == col_bkg)[0]
    char_height_start = ndarr_char_height[0]
    item_last = ndarr_char_height[0]
    for item in ndarr_char_height:
        if item - item_last > gap_height_max:
            char_height_start = item
        item_last = item
    char_height_end = ndarr_char_height[-1] +1
    print(f"字高【{char_height_end - char_height_start}】")

    ndarr_chars_pos = np.where(False == raw_bkg)[0]
    ndarr_chars_pos = np.append(ndarr_chars_pos,
                                im_core.shape[1] + char_width_min)

    last_idx = ndarr_chars_pos[0]
    curr_char_width = 1
    for curr_idx in ndarr_chars_pos:
        idx_diff = curr_idx - last_idx
        # 這裏應該限制最小寬度>=2,否則認為是一個粘連字
        if idx_diff <= 2:
            curr_char_width += idx_diff
        else:  # 新的字符
            char_width_end = last_idx +1
            char_width_start = char_width_end - curr_char_width
            im_char_last = im_core[char_height_start:char_height_end,
                                char_width_start:char_width_end]
            list_char_img.append(im_char_last)
            curr_char_width = 0
        last_idx = curr_idx
    return list_char_img

按照行列,獲取圖像中的文字像素點集:

raw_bkg = np.all(im_core, axis=0)
col_bkg = np.all(im_core, axis=1)

由此,可以知道255(黑色)的區域從大約 39 到 75,那麼 75 - 29 = 36 就是字高。

另外,圖像中有可能存在噪點,去掉就是了(我這裏只是簡單粗暴的處理下,請見諒)。

行的處理同樣。如果發現間隔,那麼就可以分離字符。最後,輸出每個字符的圖像。

檢驗下效果:

list_char_imgs = segment_chars(im_core)
env.imshow(list_char_imgs[1])

4. 模板匹配:確定字符內容

利用模板匹配,實現字符識別的過程。這裏不再細說OpenCV的 cv2.matchTemplate() 函數,只描述應用過程。

4.1. make_template

首先,有必要把字符先作為模板存儲下來。

def make_tpls(list_tpl_imgs, dir_save, dict_tpl=None):
    if not dict_tpl:
        dict_tpl = {}

    str_items = input("請輸入模板上的文本內容,用於校對(例如215801): ")

    assert len(str_items) == len(list_tpl_imgs)
    for i, v in enumerate(str_items):
        filename = v
        if v in dict_tpl:
            filename = v + "_" + str(random.random())
        else:
            dict_tpl[v] = list_tpl_imgs[i]
        path_save = os.path.join(dir_save, filename + ".jpg")
        mvlib.io.imsave(path_save, list_tpl_imgs[i])

    return dict_tpl

這裏,同一字符有必要多存儲幾張,最後擇優(或者一個字符通過多個模板匹配的結果來確定)。

4.2. 模板修復

這個過程,雖然沒啥子技術含量,但卻對結果影響很大。在前一步驟中,我們每一個字符都收集了多張模板圖像。現在,從中擇優錄取。還有,可以手動編輯模板的圖片,去除模板多餘的白邊(邊並不是文字內容的一部分,而且會降低字符的匹配度)。

4.3. 重新加載模板數據

def load_saved_tpls(dir_tpl):
    saved_tpls = os.listdir(dir_tpl)

    dict_tpl = {}  # {"1": imread("mvdev/tmp/tpl/1.jpg"), ...}
    for i in saved_tpls:
        filename = os.path.splitext(i)[0]
        path_tpl = os.path.join(dir_tpl, i)

        im_rgb = cv2.imread(path_tpl)
        im_gray = mvlib.color.rgb2gray(im_rgb)
        dict_tpl[filename] = im_gray
    return dict_tpl

dir_tpl = "tpl/"
dict_tpls = load_saved_tpls(dir_tpl)

4.4. 模板匹配

def number_ocr_matching(im_char):
    most_likely = [1, ""]
    for key, im_tpl in dict_tpls.items():
        try:
            pos, similarity = mvlib.feature.match_template(im_char, im_tpl, way="most")
            if similarity < most_likely[0]:
                most_likely = [similarity, key]
        except:
            im_char_old = im_char.copy()
            h = max(im_char.shape[0], im_tpl.shape[0])
            w = max(im_char.shape[1], im_tpl.shape[1])
            im_char = np.ones((h,w), dtype="uint8") * 255
            # im_char2 = mvlib.pixel.bitwise_and(z, im_char)
            im_char[:im_char_old.shape[0], :im_char_old.shape[1]] = im_char_old

            pos, similarity = mvlib.feature.match_template(im_char, im_tpl, way="most")
            if similarity < most_likely[0]:
                most_likely = [similarity, key]

    print(f"字符識別為【{most_likely[1]}】相似度【{most_likely[0]}】")
    return most_likely[1]

def application(list_char_imgs):
    str_ocr = ""
    for im_char in list_char_imgs:
        width_img = im_char.shape[1]
        # 判斷字符
        match_char = number_ocr_matching(im_char)
        str_ocr += match_char
    return str_ocr

str_ocr2 = application(list_char_imgs)
print(str_ocr2)

過程中,opencv出現了報錯,是由於模板的shape大於當前分割字符的shape。這個很正常,採集圖像時由於距離的微調(注意,距離變化不能太大,OpenCV的默認算子不支持模板縮放)可能導致字符尺寸更小。解決方案也很簡單,直接把字符圖像拓展到大於模板的狀態就OK了。

額,忘了刪除debug信息了……再來一次~

本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

※為什麼 USB CONNECTOR 是電子產業重要的元件?

網頁設計一頭霧水該從何著手呢? 台北網頁設計公司幫您輕鬆架站!

※台北網頁設計公司全省服務真心推薦

※想知道最厲害的網頁設計公司"嚨底家"!

※推薦評價好的iphone維修中心

Redis的持久化設計

Redis 持久化設計

持久化的功能:Redis是內存數據庫,數據都是存儲在內存中的,為了避免進程退出導致數據的永久丟失,要定期將Redis中的數據以某種形式從內存保存到硬盤,當下次Reids重啟時,利用持久化文件實現數據恢復。

RDB:將當前數據保存到硬盤

AOF:將每次執行的寫命令保存到硬盤(類似MySQL的binlog)

1. RDB持久化

RDB持久化是將當前進程中的數據生成快照保存到硬盤(因此也稱作快照持久化),保存的文件後綴是rdb;當Redis重新啟動時,可以讀取快照文件恢複數據。

  1. 觸發條件

    • 手動觸發 save 命令和bgsave命令都可以生成RDB文件, save命令會阻塞Redis服務進程,知道RDB文件創建完畢,bgsave命令則是創建一個子進程,由子進程來負責創建RDB文件,父進程繼續處理請求,bgsave命令執行過程中,只有fork子進程時會阻塞服務器,而對於save命令,整個過程都會阻塞服務器,因此save已基本被廢棄,線上環境要杜絕save的使用;後文中也將只介紹bgsave命令。此外,在自動觸發RDB持久化時,Redis也會選擇bgsave而不是save來進行持久化

    SAVE 執行期間,AOF 寫入可以在後台線程進行,BGREWRITEAOF 可以在子進程進行,所以這三種操作可以同時進行 ,為了避免性能問題,BGSAVE 和 BGREWRITEAOF 不能同時執行

  2. 自動觸發

save m n

在配置文件中通過 save m n 命令,指定當前m秒內發生n次變化時,觸發bgsave。

​ 其中save 900 1的含義是:當時間到900秒時,如果redis數據發生了至少1次變化,則執行bgsave;save 300 10和save 60 10000同理。當三個save條件滿足任意一個時,都會引起bgsave的調用.

Redis的save m n,是通過serverCron函數、dirty計數器、和lastsave時間戳來實現的-

  • serverCron函數,是Redis服務器的周期性操作函數,默認每隔100ms執行一次,該函數對服務器的狀態進行維護,其中一項工作就是檢測save m n 配置是否滿足條件,如果滿足就執行bgsave.
  • dirty計數器 記錄服務器進行了多少起操作,修改,不是客戶端執行了多少修改數據的命令
  • lastsave時間戳也是Reids服務器維持的一個狀態,記錄上一次成功執行bgsave的時間

save m n的原理如下:每隔100ms,執行serverCron函數;在serverCron函數中,遍歷save m n配置的保存條件,只要有一個條件滿足,就進行bgsave。對於每一個save m n條件,只有下面兩條同時滿足時才算滿足:

  • 當前時間-lastsave > m

  • dirty >= n

在主從複製場景下,如果從節點執行全量複製操作,則主節點會執行bgsave命令,並將rdb文件發送給從節點。

在執行shutdown命令時,自動執行rdb持久化

1.2 RDB文件

設置存儲路徑

- 配置文件:dir配置指定目錄,dbfilename指定文件名。默認是Redis根目錄下的dump.rdb文件
- 動態設置: 

config set dir {newdir} /// config set dbfilename {newFileName}

RDB文件 是經過壓縮的二進制文件,默認採用LZF算法對RDB文件進行壓縮,雖然壓縮耗時,但是可以大大減小文件體積,默認是開啟的,可以通過命令關閉:

config set rdbcompression no

RDB文件的壓縮並不是針對整個文件進行的,而是對數據庫中的字符串進行的,且只有在字符串達到一定長度(20字節)時才會進行

格式:

字段說明:

  1. REDIS常量,保存‘REDIS’5個字符

  2. db_version RDB文件的版本號

  3. SELECTDB 表示一個完整的數據庫(0號數據庫),同理SELECTDB 3 pairs表示完整的3號數據庫;只有當數據庫中有鍵值對時,RDB文件中才會有該數據庫的信息(上圖所示的Redis中只有0號和3號數據庫有鍵值對);如果Redis中所有的數據庫都沒有鍵值對,則這一部分直接省略。其中:SELECTDB是一個常量,代表後面跟着的是數據庫號碼;0和3是數據庫號碼;

  4. KEY-VALUE-PAIRS: pairs則存儲了具體的鍵值對信息,包括key、value值,及其數據類型、內部編碼、過期時間、壓縮信息等等

  1. EOF 標志著數據庫內容的結尾(不是文件的結尾),值為 rdb.h/EDIS_RDB_OPCODE_EOF (255)

  2. CHECK-SUM RDB 文件所有內容的校驗和,一個 uint_64t 類型值, REDIS 在寫入 RDB 文件時將校驗和保存在 RDB 文件的末尾,當讀取時,根據它的值對內容進行校驗

。如果這個域的值為 0 ,那麼表示 Redis 關閉了校驗和功能。

1.3 啟動時加載

​ RDB文件的載入工作是在服務器啟動時自動執行的,並沒有專門的命令。但是由於AOF的優先級更高,因此當AOF開啟時,Redis會優先載入AOF文件來恢複數據;只有當AOF關閉時,才會在Redis服務器啟動時檢測RDB文件,並自動載入。服務器載入RDB文件期間處於阻塞狀態,直到載入完成為止

2. AOF持久化

AOF(Append Only File) 則以協議文本的方式,將所有對數據庫進行過寫入的命令(及其參數)記錄到 AOF
文件,以此達到記錄數據庫狀態的目的

2.1 開啟AOF

Redis服務器默認開啟RDB,關閉AOF;要開啟AOF,需要在配置文件中配置:

appendonly yes

2.2 執行流程

2.2.1 命令寫入緩衝區

//緩衝區的定義 是一個SDS, 可以兼容C語言的字符串
struct redisServer {
    // AOF緩衝區, 在進入事件loop之前寫入
    sds aof_buf;
};
  1. 命令傳播: Redis將執行完的命令、命令的參數、命令的參數個數等信息發送到 AOF 程序中

  2. 緩存追加: AOF程序根據接收到的命令命令數據,將命令轉換為網絡通訊協議的格式,然後將協議內容追加到服務器的 AOF 緩存中。

    • 將命令以文本協議格式保存在緩存中
    • 為什麼使用文本協議格式?兼容性,避免二次開銷,可讀性
    • 為什麼寫入緩存?這樣不會受制於磁盤的IO性能,避免每次有寫命令都直接寫入硬盤,導致硬盤IO成為Redis負載的瓶頸
  3. 文件寫入和保存:AOF 緩存中的內容被寫入到 AOF 文件末尾,如果設定的 AOF 保存
    條件被滿足的話,fsync 函數或者 fdatasync 函數會被調用,將寫入的內容真正地保存到磁盤中。

    為了提高文件寫入效率,在現代操作系統中,當用戶調用write函數將數據寫入文件時,操作系統通常會將數據暫存到一個內存緩衝區里,當緩衝區被填滿或超過了指定時限后,才真正將緩衝區的數據寫入到硬盤裡。這樣的操作雖然提高了效率,但也帶來了安全問題:如果計算機停機,內存緩衝區中的數據會丟失;因此系統同時提供了fsync、fdatasync等同步函數,可以強制操作系統立刻將緩衝區中的數據寫入到硬盤裡,從而確保數據的安全性。

    AOF保存模式:

    • AOF_FSYNC_ALWAYS: 命令寫入aof-buf后立即調用系統的fsync操作同步到AOF文件。因為 SAVE 是由 Redis 主進程執行的,所以在 SAVE 執行期間,主進程會被阻塞,不能接受命令請求。這種情況下,每次有寫命令都要同步到AOF文件,硬盤IO成為性能瓶頸,Redis只能支持大約幾百TPS寫入,嚴重降低了Redis的性能;即便是使用固態硬盤(SSD),每秒大約也只能處理幾萬個命令,而且會大大降低SSD的壽命。
    • AOF_FSYNC_NO: 命令寫入aof_buf后調用系統write操作,不對AOF文件做fsync同步;同步由操作系統負責,通常同步周期為30秒。這種情況下,文件同步的時間不可控,且緩衝區中堆積的數據會很多,數據安全性無法保證。
    • AOF_FSYNC_EVERYSEC: 每一秒鐘保存一次,命令寫入aof_buf后調用系統write操作, write完成后線程返回, fsync同步文件操作由專門線程每秒調用一次

2.2.2. 文件重寫

隨着命令不斷寫入AOF,文件會越來越大,為了解決這個問題,Redis引入AOF重寫機制壓縮文件體積,AOF文件重寫是把Redis進程內的數據轉化為寫命令同步到新AOF文件的過程。

重寫后的AOF文件為什麼可以變小?

  1. 進程內已經超時的數據不再寫入文件
  2. 舊的AOF文件含有無效命令 ,如有些數據被重複設值(set mykey v1, set mykey v2)、有些數據被刪除了(sadd myset v1, del myset)等等, 新的AOF文件只保留最終的數據寫入命令
  3. 多條寫入命令可以合併為一個,如:lpush list a、lpush list b可以轉化為:lpush list a b。為了防止單條命令過大造成客戶端緩衝區溢出,對於list、set、hash等類型操作,以64個元素為邊界拆分為多條

AOF重寫可以手動觸發也可以自動觸發:

  • 手動觸發: 直接調用bgrewriteaof命令
  • 自動觸發:根據auto-aof-rewrite-min-size和auto-aof-rewrite-percentage參數確定自動觸發時機。
    • auto-aof-rewrite-min-size:表示運行AOF重寫時文件最小體積,默認為64MB
    • auto-aof-rewrite-percentage:代表當前AOF文件空間(aof_current_size)和上一次重寫后AOF文件空間(aof_base_size)的比值

流程說明:

1)執行AOF重寫請求。

如果當前進程正在執行AOF重寫,請求不執行。

如果當前進程正在執行bgsave操作,重寫命令延遲到bgsave完成之後再執行。

2)父進程執行fork創建子進程,開銷等同於bgsave過程。

3.1)主進程fork操作完成后,繼續響應其它命令。

  所有修改命令依然寫入AOF文件緩衝區並根據appendfsync策略同步到磁盤,保證原有AOF機制正確性。

3.2)由於fork操作運用寫時複製技術,子進程只能共享fork操作時的內存數據

  由於父進程依然響應命令,Redis使用“AOF”重寫緩衝區保存這部分新數據,防止新的AOF文件生成期間丟失這部分數據。

4)子進程依據內存快照,按照命令合併規則寫入到新的AOF文件。

  每次批量寫入硬盤數據量由配置aof-rewrite-incremental-fsync控制,默認為32MB,防止單次刷盤數據過多造成硬盤阻塞。

5.1)新AOF文件寫入完成后,子進程發送信號給父進程,父進程調用一個信號處理函數,並執行以前操作更新統計信息。

5.2)父進程把AOF重寫緩衝區的數據寫入到新的AOF文件。這時新 AOF 文件所保存的數據庫狀態將和服務器當前的數據庫狀態一致。

5.3)對新的AOF文件進行改名,原子地(atomic)覆蓋現有的AOF文件,完成新舊文件的替換。

在整個 AOF 後台重寫過程中,只有信號處理函數執行時會對服務器進程(父進程)造成阻塞,其他時候,AOF 後台重寫都不會阻塞父進程,這將 AOF 重寫對服務器性能造成的影響降到了最低

參考《Redis-設計與實現:AOF-持久化》

2.2.3 重啟加載

流程說明:

1)AOF持久化開啟且存在AOF文件時,優先加載AOF文件。

2)AOF關閉或者AOF文件不存在時,加載RDB文件。

3)加載AOF/RDB文件成功后,Redis啟動成功。

4)AOF/RDB文件存在錯誤時,Redis啟動失敗並打印錯誤信息。

數據還原的詳細步驟:

  1. 創建一個不帶網絡連接的偽客戶端(fake client): 因為 Redis 的命令只能在客戶端上下文中執行,而載入 AOF 文件時所使用的命令直接來源於 AOF 文件而不是網絡連接,所以服務器使用了一個沒有網絡連接的偽客戶端來執行 AOF 文件保存的寫命令,偽客戶端執行命令的效果和帶網絡連接的客戶端執行命令的效果完全一樣。
  2. 從AOF文件中分析並讀取出一條寫命令,使用偽客戶端執行被讀出的寫命令,重複此操作,直到AOF文件中的所有寫命令都被處理完畢為止。

2.2.4 文件校驗

加載損壞的AOF文件會拒絕啟動,並打印錯誤信息。

注意:對於錯誤格式的AOF文件,先進性備份,然後採用redis-check-aof --fix命令進行修復,修復后使用diff -u對比數據差異,找到丟失的數據,有些可以進行人工補全。

AOF文件可能存在結尾不完整的情況,比如機器突然掉電導致AOF尾部文件命令寫入不全。

Redis為我們提高了aof-load-truncated配置來兼容這種情況,默認開啟

3. 了解MySQL中的binlog

mysql binlog應用場景與原理深度剖析

參考博文與書籍:

  1. 《redis設計與實現》
  2. Redis持久化
  3. [徐劉根-Redis實戰和核心原理詳解(8)使用快照RDB和AOF將Redis數據持久化到硬盤中](https://blog.csdn.net/xlgen157387/article/details/61925524

本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

※為什麼 USB CONNECTOR 是電子產業重要的元件?

網頁設計一頭霧水該從何著手呢? 台北網頁設計公司幫您輕鬆架站!

※台北網頁設計公司全省服務真心推薦

※想知道最厲害的網頁設計公司"嚨底家"!

※推薦評價好的iphone維修中心

8分之1的歐洲人口死於環境污染 空污、噪音通通上榜

摘錄自2020年9月15日自由時報報導

根據歐洲環境署的一項調查研究報告,歐盟人口大約有8分之1的死與環境污染有關;對此,歐洲環境署負責人建議,優先保護社會上最受威脅的族群,解決貧困問題。

歐洲環境署補充,化學物質、過量使用抗生素後對病原體造成的抗藥性以及被污染的飲用水,上述也是導致人們過早死亡的因素,而在許多東歐國家,環境因素導致的過早死亡率比西歐高得多。

根據世衛組織的數據,歐盟國家過早死亡的比例大約為13%,相當於每年有63萬人過早死亡,不幸的是,環境因素(例如:癌症、心臟病和中風)造成的死亡原本是可以避免。

歐洲環境署負責人漢斯.布魯尼克斯(Hans Bruyninckx)建議,必須採取措施來保護社會上最受威脅的族群,而貧困通常是主要問題,因為它會帶來惡劣的環境和影響健康狀況,因此為來歐洲未來可以在此多著墨,如此一來才能真正解決環境與健康的問題。

污染治理
國際新聞
歐洲
空污
噪音

本站聲明:網站內容來源環境資訊中心https://e-info.org.tw/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

※為什麼 USB CONNECTOR 是電子產業重要的元件?

網頁設計一頭霧水該從何著手呢? 台北網頁設計公司幫您輕鬆架站!

※台北網頁設計公司全省服務真心推薦

※想知道最厲害的網頁設計公司"嚨底家"!

※推薦評價好的iphone維修中心

除了思域,這3款10來萬的轎車也能讓你爽到停不下來

但速度上去之後還是很有感覺的,特別是當你跑高速時,沉穩的底盤精準的轉向能給予你足夠的信心,可能不經意間你的時速就上百了,如果你覺得普通版的高爾夫不夠過癮,那就上GTI或R-Line吧,畢竟小鋼炮是不會浪得虛名的。說到這可能很多朋友糊塗了,操控都是它們的主旋律,那到底要選哪款呀。

最近不少網友諮詢想要一輛具有駕駛樂趣的緊湊型轎車該買哪款好,小雅腦中第一個冒出來的當然是思域啦,但是仔細想想思域太火了、等車實在太煎熬,所以今天我推薦另外三款,快來看看有沒有對你口味的:

一、外觀與內飾

如果你說思域是日繫緊湊型轎車的顏值擔當,馬自達車主可要表示不服了,瞧瞧這輛昂克賽拉,我保證在車流中你能一眼就找出來,魂動設計賦予了它獨特的韻律美,盾型進氣格柵、翼型鍍鉻飾條、犀利的前大燈、偏長的引擎蓋、再加上動感的線條,說不驚艷那還真是騙人的。

第二個要介紹的是福克斯,它有着一張略顯囂張的前臉,獠牙狀進氣格柵顯露出十足的攻擊性,鷹眼大燈看上去炯炯有神,車身線條力量感十足,果然很有運動氣息。

相比之下,小雅覺得高爾夫看起來要低調很多,沒有昂克賽拉那嫵媚多姿的車身線條,也沒有福克斯那搶眼的馬丁臉,可偏偏是這樣的大眾家族式設計風格依舊能討得不少人的喜愛,畢竟每個人的審美不一樣。

我們接着來看內飾:

昂克賽拉與福克斯的用料都中規中矩,不過昂克賽拉的中控面板上按鍵比較少,看起來十分簡潔,並且懸浮式的中控显示屏提升不少檔次感。福克斯的中控台佔用空間較多,讓我覺得有點壓迫感,並且做工要粗糙一些。

高爾夫的內飾設計是三車中最有質感的,雖然看起來並沒什麼新鮮味道,但它摸起來軟、做工細緻,而且中控面板的設計整體偏向駕駛席一側,方便駕駛員在行車時進行操作。

二、駕駛感受

關於造型設計就先說到這了,畢竟我們今天的主題是駕駛樂趣 ,那麼三者中誰的駕控最好呢?

昂克賽拉最大的優點主要有兩個,首先自然吸氣發動機動力輸出很線性,變速箱降擋平順,還有一點是轉向特別靈敏。雖然小雅覺得人車合一這個口號略顯誇張,但不可否認它開起來確實很靈活輕快。

對了,補充一點,昂克賽拉還加上了GVC扭矩分配系統,用於改善過彎時車輛的動態表現,集這麼多亮點於一身,我想這也是廣大車迷朋友們喜歡它的主要原因。

再來看看福克斯,這位運動健將近年來慢慢朝舒適性方向有所靠攏了。以前的福克斯動力很猛,還可謂是指哪打哪,但現在略偏舒適的調校讓它變得不那麼純粹了。

但它依舊是這個級別裏面不可忽視的,它的1.5T發動機功率在同排量渦輪增壓發動機中最出色的,最大馬力高達181匹,儘管油耗有點讓人心疼,但是它加速暢快啊。總的來說儘管整體質量口碑一般,但這並不影響年輕人將其作為人生第一部車的首選。

很多高爾夫車主被稱為“神車黨”,不過你要知道高爾夫有很多種,分為普通版、R-Line、GTI,動力的選擇也是多種多樣,其中的1.4T發動機匹配7擋雙離合變速箱可以說是黃金組合了,變速箱換擋快,動力的話初段加速不會太給力,需要你踩深一點油門。

但速度上去之後還是很有感覺的,特別是當你跑高速時,沉穩的底盤精準的轉向能給予你足夠的信心,可能不經意間你的時速就上百了,如果你覺得普通版的高爾夫不夠過癮,那就上GTI或R-Line吧,畢竟小鋼炮是不會浪得虛名的。

說到這可能很多朋友糊塗了,操控都是它們的主旋律,那到底要選哪款呀!別急,我們接着來看它們的配置:

三、裝備率

1、福克斯全系標配前後排頭部氣囊/氣簾,氣囊的重要性想必大家也都知道,所以說福克斯這點做的很厚道,而高爾夫要在指導價為14.49萬的2018款 1.6L 自動舒適型上才開始配備,昂克賽拉就更讓小雅失望了,只有頂配車型才配備有。

2、福克斯與昂克賽拉的頂配車型帶有主動安全系統,高爾夫全系沒有這一配置,而是多出疲勞駕駛提示功能,但小雅覺得有點華而不實。

3、再來看看倒車視頻影像,福克斯又給我了驚喜,做到了全系標配,昂克賽拉要在指導價為12.89萬的2017款 三廂 1.5L 手動豪華型才開始配備,而2018款的高爾夫只有GTI與280TSI 自動旗艦型上才帶有。

4、在燈光配置方面,昂克賽拉的LED大燈普及率高,在12.89萬的2017款 三廂 1.5L 手動豪華型上便可獲得,高爾夫要在15.79萬的2018款 280TSI 手動R-Line型才能買到,福克斯則全系都找不到LED大燈的影子。

5、另外,昂克賽拉全系標配多功能方向盤,福克斯全系標配8英寸中控屏,高爾夫全系支持全車車窗一鍵升降。

小雅覺得三車中福克斯的價格不算高,但配置的普及率卻非常高,再結合上面的表現來看是三車中性價比最高的。

四、結語

當然車無完車,三者最大的不足是空間都不太理想,畢竟這不是它們主攻的方面,另外高爾夫的價格比較高,特別是售價高達20多萬的GTI令不少人望而卻步。

但不管怎樣,手握住它們三中間任何一輛的方向盤,你都會忍不住多跑一會,難道不是嗎?本站聲明:網站內容來源於http://www.auto6s.com/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

※為什麼 USB CONNECTOR 是電子產業重要的元件?

網頁設計一頭霧水該從何著手呢? 台北網頁設計公司幫您輕鬆架站!

※台北網頁設計公司全省服務真心推薦

※想知道最厲害的網頁設計公司"嚨底家"!

※推薦評價好的iphone維修中心

這 10 行比較字符串相等的代碼給我整懵逼了,不信你也來看看

抱歉用這種標題吸引你點進來了,不過你不妨看完,看看能否讓你有所收穫。​(有收穫,請評論區留個言,沒收穫,下周末我直播吃**,哈哈,這你也信)

補充說明:微信公眾號改版,對各個號主影響還挺大的。目前從後台數據來看,對我影響不大,因為我這反正都是小號,閱讀量本身就少的可憐,真相了,狗頭(剛從交流群學會的表情)。

先直接上代碼:

boolean safeEqual(String a, String b) {
   if (a.length() != b.length()) {
       return false;
   }
   int equal = 0;
   for (int i = 0; i < a.length(); i++) {
       equal |= a.charAt(i) ^ b.charAt(i);
   }
   return equal == 0;
}

上面的代碼是我根據原版(Scala)翻譯成 Java的,Scala 版本(最開始吸引程序猿石頭注意力的代碼)如下:

def safeEqual(a: String, b: String) = {
  if (a.length != b.length) {
    false
  } else {
    var equal = 0
    for (i <- Array.range(0, a.length)) {
      equal |= a(i) ^ b(i)
    }
    equal == 0
  }
}

剛開始看到這段源碼感覺挺奇怪的,這個函數的功能是比較兩個字符串是否相等,首先“長度不等結果肯定不等,立即返回”這個很好理解。

再看看後面的,稍微動下腦筋,轉彎下也能明白這其中的門道:通過異或操作1^1=0, 1^0=1, 0^0=0,來比較每一位,如果每一位都相等的話,兩個字符串肯定相等,最後存儲累計異或值的變量equal必定為 0,否則為 1。

再細想一下呢?

for (i <- Array.range(0, a.length)) {
  if (a(i) ^ b(i) != 0// or a(i) != b[i]
    return false
}

我們常常講性能優化,從效率角度上講,難道不是應該只要中途發現某一位的結果不同了(即為1)就可以立即返回兩個字符串不相等了嗎?(如上所示)

這其中肯定有……

再再細想一下呢?

結合方法名稱 safeEquals 可能知道些眉目,與安全有關。

本文開篇的代碼來自playframewok 里用來驗證cookie(session)中的數據是否合法(包含簽名的驗證),也是石頭寫這篇文章的由來。

以前知道通過延遲計算等手段來提高效率的手段,但這種已經算出結果卻延遲返回的,還是頭一回!

我們來看看,JDK 中也有類似的方法,如下代碼摘自 java.security.MessageDigest

public static boolean isEqual(byte[] digesta, byte[] digestb) {
   if (digesta == digestb) return true;
   if (digesta == null || digestb == null) {
       return false;
   }
   if (digesta.length != digestb.length) {
       return false;
   }

   int result = 0;
   // time-constant comparison
   for (int i = 0; i < digesta.length; i++) {
       result |= digesta[i] ^ digestb[i];
   }
   return result == 0;
}

看註釋知道了,目的是為了用常量時間複雜度進行比較。

但這個計算過程耗費的時間不是常量有啥風險? (腦海里響起了背景音樂:“小朋友,你是否有很多問號?”)

真相大白

再深入探索和了解了一下,原來這麼做是為了防止計時攻擊(Timing Attack)。(也有人翻譯成時序攻擊​)​

計時攻擊(Timing Attack)

計時攻擊是邊信道攻擊(或稱”側信道攻擊”, Side Channel Attack, 簡稱SCA) 的一種,邊信道攻擊是一種針對軟件或硬件設計缺陷,走“歪門邪道”的一種攻擊方式。

這種攻擊方式是通過功耗、時序、電磁泄漏等方式達到破解目的。在很多物理隔絕的環境中,往往也能出奇制勝,這類新型攻擊的有效性遠高於傳統的密碼分析的數學方法(某百科上說的)。

這種手段可以讓調用 safeEquals("abcdefghijklmn", "xbcdefghijklmn") (只有首位不相同)和調用 safeEquals("abcdefghijklmn", "abcdefghijklmn") (兩個完全相同的字符串)的所耗費的時間一樣。防止通過大量的改變輸入並通過統計運行時間來暴力破解出要比較的字符串。

舉個,如果用之前說的“高效”的方式來實現的話。假設某個用戶設置了密碼為 password,通過從a到z(實際範圍可能更廣)不斷枚舉第一位,最終統計發現 p0000000 的運行時間比其他從任意a~z的都長(因為要到第二位才能發現不同,其他非 p 開頭的字符串第一位不同就直接返回了),這樣就能猜測出用戶密碼的第一位很可能是p了,然後再不斷一位一位迭代下去最終破解出用戶的密碼。

當然,以上是從理論角度分析,確實容易理解。但實際上好像通過統計運行時間總感覺不太靠譜,這個運行時間對環境太敏感了,比如網絡,內存,CPU負載等等都會影響。

但安全問題感覺更像是 “寧可信其有,不可信其無”。為了防止(特別是與簽名/密碼驗證等相關的操作)被 timing attack,目前各大語言都提供了相應的安全比較函數。各種軟件系統(例如 OpenSSL)、框架(例如 Play)的實現也都採用了這種方式。

例如 “世界上最好的編程語言”(粉絲較少,評論區應該打不起架來)—— php中的:

// Compares two strings using the same time whether they're equal or not.
// This function should be used to mitigate timing attacks; 
// for instance, when testing crypt() password hashes.
bool hash_equals ( string $known_string , string $user_string )

//This function is safe against timing attacks.
boolean password_verify ( string $password , string $hash )

其實各種語言版本的實現方式都與上面的版本差不多,將兩個字符串每一位取出來異或(^)並用或(|)保存,最後通過判斷結果是否為 0 來確定兩個字符串是否相等。

如果剛開始沒有用 safeEquals 去實現,後續的版本還會通過打補丁的方式去修復這樣的安全隱患。

例如 JDK 1.6.0_17 中的Release Notes[1]中就提到了MessageDigest.isEqual 中的bug的修復,如下圖所示:

MessageDigest timing attack vulnerabilities

大家可以看看這次變更的的詳細信息openjdk中的 bug fix diff[2]為:

MessageDigest.isEqual計時攻擊

Timing Attack 真的可行嗎?

我覺得各大語言的 API 都用這種實現,肯定還是有道理的,理論上應該可以被利用的。 這不,學術界的這篇論文就宣稱用這種計時攻擊的方法破解了 OpenSSL 0.9.7 的RSA加密算法了。關於 RSA 算法的介紹可以看看之前本人寫的這篇文章。

這篇Remote Timing Attacks are Practical[3] 論文中指出(我大致翻譯下摘要,感興趣的同學可以通過文末鏈接去看原文):

計時攻擊往往用於攻擊一些性能較弱的計算設備,例如一些智能卡。我們通過實驗發現,也能用於攻擊普通的軟件系統。本文通過實驗證明,通過這種計時攻擊方式能夠攻破一個基於 OpenSSL 的 web 服務器的私鑰。結果證明計時攻擊用於進行網絡攻擊在實踐中可行的,因此各大安全系統需要抵禦這種風險。

最後,本人畢竟不是專研完全方向,以上描述是基於本人的理解,如果有不對的地方,還請大家留言指出來。感謝。

補充說明2:感謝正在閱讀文章的你,讓我還有動力繼續堅持更新原創。

本人發文不多,但希望寫的文章能達到的目的是:佔用你的閱讀時間,就盡量能夠讓你有所收穫。

如果你覺得我的文章有所幫助,還請你幫忙轉發分享,另外請別忘了點擊公眾號右上角加個星標,好讓你別錯過後續的精彩文章(微信改版了,或許我發的文章都不能推送到你那了)。

​原創真心不易,希望你能幫我個小忙唄,如果本文內容你覺得有所啟發,有所收穫,請幫忙點個“在看”唄,或者轉發分享讓更多的小夥伴看到。 ​ 參考資料:

  • Timing Attacks on RSA: Revealing Your Secrets through the Fourth Dimension
  • Remote Timing Attacks are Practical

 

本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

※為什麼 USB CONNECTOR 是電子產業重要的元件?

網頁設計一頭霧水該從何著手呢? 台北網頁設計公司幫您輕鬆架站!

※台北網頁設計公司全省服務真心推薦

※想知道最厲害的網頁設計公司"嚨底家"!

※推薦評價好的iphone維修中心

3dTiles 數據規範詳解[1] 介紹

版權:轉載請帶原地址。https://www.cnblogs.com/onsummer/p/12799366.html @秋意正寒

Web中的三維

html5和webgl技術使得瀏覽器三維變成了可能。

巧婦難為無米之炊,三維數據(三維模型)是三維可視化重要的一環,事實上就是:三維數據眾多,行業跨界廣。

參考資料:http://www.bgteach.com/article/132

three.js的各種加載器實現了大部分通用三維格式的加載,屏蔽了格式不同的數據結構差異。

然而,這樣還是不能滿足日益增長的效果需求,比如場景一大,模型文件體積變大,解析所耗費的時間越來越長。

webgl,包括所有gpu有關的圖形渲染編程,幾乎只認這樣的三維數據:頂點、頂點顏色、頂點法線、着色語言…

所以,三維圖形界的通用格式:glTF應運而生,它面向終點,它按照圖形編程所需的格式來存儲數據,藉以二進制編碼提高傳輸速度。

它不再使用面向對象的思維存儲三維模型、貼圖紋理,而是按顯卡的思維存儲,存的是頂點、法線、頂點顏色等最基礎的信息,只不過組織結構上進行了精心的設計。

它面向終點,就意味着可編輯性差,因為渲染性能的提高犧牲了可編輯性,它不再像3ds、dae甚至是max、skp一樣容易編輯和轉換。

事實上,大多數三維軟件提供了glTF格式的轉換,或多一步,或一步到位。

地理真三維

早年,地理的三維還處於地形三維上,即数字高程模型(DEM)提供地表的高度拉伸。柵格高程數據、等高線、不規則三角網等均是数字高程模型的具體案例。
下圖是不規則三角網,也即所謂的三角面片(圖形渲染中很常見):

隨着學科的融合、計算機技術和硬件的更新換代,使得有模型、有細節的真三維融入到GIS中成為了可能,或者說,計算機技術和硬件的升級,給GIS以更廣闊的視角觀察世界。

cesium.js 號稱是 webgl 封裝的三維地理庫,是支持 gltf 模型的加載的。

面對大規模精細三維數據的加載,還要照顧到GIS的各種坐標系統、分析計算,gltf這種單個模型的方案顯得力不從心。

2016年,Cesium 團隊借鑒傳統2DGIS的地圖規範——WMTS,借鑒圖形學中的層次細節模型,打造出大規模的三維數據標準—— 3d-Tiles,中文譯名:三維瓦片。

它在模型上利用了 gltf 渲染快的特點,對大規模的三維數據進行組織,包括層次細節模型、模型的屬性數據、模型的層級數據等。

3dTiles的設計思想

3dTiles 繼承了 gltf 的優點:貼合圖形渲染 API 的邏輯,討 GPU 喜愛,webgl 對其內部組織起來的三維模型數據,不需要轉換,可以直接渲染(glTF 的功勞)。

關於 glTF 是如何嵌入到 3dTiles 中的,開篇不談,後續精講。

我們區分一組概念:規範和實現。

3dTiles 是一種規範,在規範的指導下,各種資源文件可以是獨立存在於硬盤中的目錄、文件,也可以以二進制形式寫入數據庫中。目前,3dTiles 的官方實現只有 “散列文件”,也就是文件、文件夾的形式存儲在硬盤中,有關如何存儲到數據庫中的討論,官方仍在進行中(截至發博客)。

glTF 也是一種規範,它的數據文件不一定就是後綴名為 .gltf 的文件,也不一定只有一個文件(glTF 的文件還可以是二進制文件、紋理貼圖文件等,扯遠了哈)。
在本文,會嚴格指明是數據還是數據標準,如果我說的是 “XXX文件(例如 Bird.glb 文件)” ,那就是在指特定的文件。

3dTiles還有一個特點:那就是不記錄模型數據,只記錄各級“Tile”的邏輯關係,以及“Tile”自己的屬性信息。所謂的模型數據,是指三維模型的頂點、貼圖材質、法線、顏色等信息。邏輯關係是指,各級Tile是如何在空間中保持連續的,LOD是如何組織的。屬性信息就很簡單啦,門有門的生產商,窗戶有窗戶的使用年限等,往大了說,建築還有它自己的壽命、法人、施工單位等屬性信息。

3dTiles的特點總結如下:

  • 三維模型使用了 glTF 規範,繼承它的渲染高性能
  • 除了嵌入的 glTF,3dTiles 自己 只記錄各級Tile的空間邏輯關係(如何構成整個3dtiles)和屬性信息,以及模型與屬性如何掛接在一起的信息

我覺得你還是雲里霧裡的,下一節將展示3dTiles具體數據,說說3dTiles的組織結構,說說3dTiles中的”Tile”,也就是“三維瓦片數據”中的“瓦片”是什麼。

3dTiles系列博客最終目錄:

01 引入與博客目錄:3dTiles 數據規範詳解

02 Tileset與Tile

03 內嵌在瓦片文件中的兩大數據表

04.1 B3dm 類型

04.2 I3dm 類型

04.3 Pnts 類型

04.4 Cmpt 類型

04.5 未發布的瓦片規範

05 3dTiles強大的擴展能力

06 優缺點

07 與I3S比較

本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

※為什麼 USB CONNECTOR 是電子產業重要的元件?

網頁設計一頭霧水該從何著手呢? 台北網頁設計公司幫您輕鬆架站!

※台北網頁設計公司全省服務真心推薦

※想知道最厲害的網頁設計公司"嚨底家"!

※推薦評價好的iphone維修中心