分類: 3C資訊

  • LG印度廠毒氣外洩致死案 韓籍執行長等12人被捕_台中搬家公司

    台中搬家公司教你幾個打包小技巧,輕鬆整理裝箱!

    還在煩惱搬家費用要多少哪?台中大展搬家線上試算搬家費用,從此不再擔心「物品怎麼計費」、「多少車才能裝完」

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

    韓國樂金聚合物公司(LG Polymers)設在印度的一家化工廠兩個月前化學氣體外洩,造成12人死亡。事發所在地警察局長今(8日)說,警方已逮捕這家工廠12名幹部,包括韓籍執行長。

    事發工廠位於印度港市維沙哈巴南(Visakhapatnam),當地警察局長米納(Rajiv Kumar Meena)說,逮捕行動是依據5月事故發生時針對樂金聚合物母公司樂金化學(LG Chem)所成立的刑事殺人案。

    ※推薦台中搬家公司優質服務,可到府估價

    台中搬鋼琴,台中金庫搬運,中部廢棄物處理,南投縣搬家公司,好幫手搬家,西屯區搬家

    樂金聚合物化工廠的有毒苯乙烯(styrene)氣體5月7日凌晨外洩,造成許多還在睡夢中的人們窒息。韓國樂金化學尚未回應媒體的採訪電郵。

    公害污染
    污染治理
    國際新聞
    印度
    有毒氣體外洩

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

    ※推薦台中搬家公司優質服務,可到府估價

    台中搬鋼琴,台中金庫搬運,中部廢棄物處理,南投縣搬家公司,好幫手搬家,西屯區搬家

  • Redmi K40 系列 S888 旗艦新機確定將於 2 月發表,官方提前公布售價約 12,912 元起_網頁設計公司

    Redmi K40 系列 S888 旗艦新機確定將於 2 月發表,官方提前公布售價約 12,912 元起_網頁設計公司

    ※如何讓商品強力曝光呢? 網頁設計公司幫您建置最吸引人的網站,提高曝光率!

    以設計的實用美學觀點,規劃出舒適、美觀的視覺畫面,有效提昇使用者的心理期待,營造出輕鬆、愉悅的網站瀏覽體驗。

    今日除了 iQOO7 將發表,包括 Redmi 、黑鯊以及紅魔都陸續開始新機預吿宣傳,其中備受矚目的 Redmi K40 系列也終於由 Redmi 總經理盧偉冰宣布將在下個月發表,除了直接宣稱 2021 旗艦性價比之王,同時也預告 K40 系列將搭載高通 Snapdragon 888 旗艦處理器、可能是最貴的平面螢幕,甚至是直接將起售價提前公開。

    ▲圖片來源:盧偉冰(微博)

    Redmi K40 系列 S888 旗艦新機確定將於 2 月發表,官方提前公布售價約 12,912 元起

    在去年底高通發表 Snapdragon 888 處理器、並由小米11 首發搭載此旗艦處理器後,也有許多人接著將目光放在更主打性價比的 Redmi K 系列旗艦新機。前段時間,不僅疑似 Redmi K40 系列的工程機曝光,也有人製作了 Redmi K40 系列的新機渲染圖(點我前往複習)。
    今日稍早,小米集團副總裁、 Redmi 紅米品牌總經理盧偉冰無預警在個人微博開始了 Redmi K40 系列的新機預告宣傳,除了之前大家都知道 K40 系列將有搭載高通 Snapdraon 888 處理器的旗艦手機,盧偉冰在微博更直接將 Redmi K40 系列的起售價直接公開,建議售價為人民幣 2,999 元起(約合新台幣 12,912 元起)的價格,此價格和去年搭載高通 Snapdragon 865 處理器的 Redmi K30 Pro 維持不變。

    ▲圖片來源:盧偉冰(微博)

    雖然發表前直接由品牌總經理直接爆雷還是十分罕見,但各位也不必看到價格就高興太早,因為目前公佈的價錢預計是 Redmi K40 標準版的售價, Redmi K40 系列預計將不會「全系列」都搭載高通 Snapdragon 888 處理器,可能只會在高階的 Redmi K40 Pro 搭載。

    ▲圖片來源:盧偉冰(微博)

    螢幕方面,盧偉冰提到可能是最貴的平面螢幕,這也與之前我們報導過疑似 Redmi K40 工程機洩漏的傳聞相符,據悉 Redmi K40 全系列將採用 120Hz 更新率的 OLED 居中挖孔全螢幕,電量部分確定大於 4000mAh ,而快充速度目前尚未揭曉。

    ▲圖片來源:酷安網

    在今(12)日中午前,聯發科預告將於 1 月 20 日舉行 MediaTek 天璣新品發表會,傳聞將發表最新的 6nm 旗艦處理器,按照「往例」和這段時間的各方消息,這款聯發科新的旗艦處理器預計將由 Redmi 首發搭載,至於那款機型預計就是 Redmi K40 。

    ▲圖片來源:聯發科技官方微博(微博)

    之前在 Geekbench 資料庫也出現疑似為聯發科新旗艦處理器的跑分數據,其 CPU 效能表現超越當前聯發科天璣 1000+ 、直逼高通 Snapdragon 865 。
    筆者個人推測屆時 Redmi K40 系列發表時,也將以搭載 6nm 聯發科旗艦處理器的 Redmi K40 標準版來對比去年 Redmi K30 Pro 的性能作為宣傳,以強調這次 Redmi K40 系列的性價比。

    ▲圖片來源:Geekbench

    回顧去年底至上週之間數碼閒聊站之前的爆料, Redmi K40 和 K40 Pro 皆採用 120Hz 更新率 OLED 螢幕,不過處理器和相機規格略有不同。前相機方面,Redmi K40 系列捨棄上一代的升降式前鏡頭,全面改採用居中的挖孔全螢幕。相機方面, Redmi K40 將配備 6400 萬像素主相機,而 Redmi K40 Pro 則為 1.08 億像素主相機。

    ▲圖片來源:數碼閒聊站(微博)

    ※自行創業缺乏曝光? 網頁設計幫您第一時間規劃公司的形象門面

    網站的第一印象網頁設計,決定了客戶是否繼續瀏覽的意願。台北網動廣告製作的RWD網頁設計,採用精簡與質感的CSS語法,提升企業的專業形象與簡約舒適的瀏覽體驗,讓瀏覽者第一眼就愛上它。

    消息來源:盧偉冰(微博)

    延伸閱讀:
    小米11 Pro 最新高清晰概念渲染圖曝光!傳聞搭載 50MP 四鏡頭主相機,支持 120x 混合變焦

    POCO M3 即將在台發表:6000mAh 超大電量,規格重點搶先看!

    您也許會喜歡:

    【推爆】終身$0月租 打電話只要1元/分

    立達合法徵信社-讓您安心的選擇

    ※綠能、環保無空污,成為電動車最新代名詞,目前市場使用率逐漸普及化

    台中景泰電動車行只是一個單純的理由,將來台灣的環境,出門可以自由放心的深呼吸,讓空氣回歸自然的乾淨,減少污染,留給我們下一代有好品質無空污的優質環境

  • LG 2021 電視陣容加入亮度再創高峰的全新 OLED Evo 面板機型_如何寫文案

    LG 2021 電視陣容加入亮度再創高峰的全新 OLED Evo 面板機型_如何寫文案

    ※廣告預算用在刀口上,台北網頁設計公司幫您達到更多曝光效益

    擁有後台管理系統的網站,將擁有強大的資料管理與更新功能,幫助您隨時新增網站的內容並節省網站開發的成本。

     CES 2021 正式揭開序幕,今年以線上模式來進行展示,LG 打前鋒舉辦整個展會中的第一場發表會,其中在 2021 年的新電視陣容中花了很大的篇幅,這次最受關注的就是為自家 OLED 電視進步極具象徵性的 OLED Evo 面板,為消費者帶來更優質的視覺體驗。

    LG 2021 電視陣容加入亮度再創高峰的全新 OLED Evo 面板機型

    多年以來,亮度一直是液晶電視領域的重點項目之一,OLED 電視一直有個大家努力想要克服的問題,儘管它具備有深邃的黑與令人讚嘆的可視角,但若是將 OLED 電視放置在非常明亮的環境中,在觀影上還是相當吃力。LG 最新的 OLED Evo 面板以更高的亮度和 HDR,使得其觀賞效果超越過去的 OLED 電視,而 LG 也將這項飛躍的進步視作等同於 4K HDR 與 8K 的歷史性意義。

    2021 年的 G1 系列將有 55、65 與 75 吋三種尺寸,與 C1 同樣搭載第四代 LG Alpha9 處理器,具備更進化的圖像處理能力,可以分析所顯示的影像廠警並且相對應地最佳化影像呈現。

    在去年推出後大受好評,還被許多玩家視為新一代遊戲機好伴侶的 CX OLED,今年得全新型號仍然可支援 VRR、G-Sync 及 FreeSync,並且內建一個遊戲調整功能,將對遊戲玩家來說最重要的所有選項匯集在一起,像是更新率、低延遲等,讓玩家可依照所玩的遊戲類型不同選擇預設數值,也能夠根據自己的喜好來自定所有參數。

    但今次,LG 在 G1 系列上不僅設計,還放上了更亮的顯示面板,並且與 C1 系列同步支援全新設計的 Gallery Stand 支架,對不想將電視壁掛或放在電視櫃上的人來說又多了一個新選擇。

    ※別再煩惱如何寫文案,掌握八大原則!

    什麼是銷售文案服務?A就是幫你撰寫適合的廣告文案。當您需要販售商品、宣傳活動、建立個人品牌,撰寫廣告文案都是必須的工作。

    在音訊方面,最新型號的電視具有虛擬 5.1.2 環繞立體聲功能,LG 表示在你觀賞影音時,可保持聽覺感受的整體性,無論是線上串流、電視頻道或應用程式皆能確保音量大小一致,不會讓你有切換時音量忽大忽小的困擾。

    最入門的產品當屬最新的 A1 系列,可以將它視為去年 BX 系列的後繼者,也是大家想要進入 OLED 領域上價格最平價的方式。配備 LG a7 處理器,HDMI 連接埠較少,但還是可以擁有全部的重點功能,包含 D遭V、HDMI 2.1(支援 VRR、ALLM 等)。至於三種系列的最後定價方面,大家可能要等到春季時才會明朗。

    您也許會喜歡:

    【推爆】終身$0月租 打電話只要1元/分

    立達合法徵信社-讓您安心的選擇

    ※教你寫出一流的銷售文案?

    銷售文案是什麼?A文案是廣告用的文字。舉凡任何宣傳、行銷、販賣商品時所用到的文字都是文案。在網路時代,文案成為行銷中最重要的宣傳方式,好的文案可節省大量宣傳資源,達成行銷目的。

  • LG 首款 QNED MiniLED 電視登場,突破頂級 LCD 電視界線_網頁設計公司

    LG 首款 QNED MiniLED 電視登場,突破頂級 LCD 電視界線_網頁設計公司

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

    RWD(響應式網頁設計)是透過瀏覽器的解析度來判斷要給使用者看到的樣貌

    除了亮度更高的 OLED Evo 外,這次 LG 首款 QNED MiniLED 電視也在展會中亮相,而這也是 LG 在 2021 年推出的頂級 LCD 電視系列的代表作品,採用量子點與 1 奈米顯示技術,並搭配 MiniLED 作為光源,亮度與對比度的表現更勝傳統 LCD 電視。

    LG 首款 QNED MiniLED 電視登場,突破頂級 LCD 電視界線

    以頂級電視之姿降臨的 LG 首款 QNED MiniLED 電視,2021 系列中總共有 3 款 4K 與 8K 機型,涵蓋消費者對各種大螢幕的選擇。全新 LCD 面板結構搭載 LG 進階 MiniLED 背光技術,視覺效果如臨實境。 LG QNED TV 也是首款結合量子點與 NanoCell 技術的產品,呈現令人驚豔的精準色彩,加上進階 LED 背光模組提供更好的對比度,更飽滿深邃的黑色,畫面動感逼真。新款電視更具備 120Hz高更新率,動作倍顯流暢自然。

    LG  MiniLED 背光模組由近 30,000 顆微型 LED 組成,多達 2,500 個調光分區與進階區域調光技術,創造超越以往的峰值亮度,使其達到 1,000,000 : 1 的高對比度。在上述條件的支援下,可呈現優異的 HDR 畫質與卓越的對比度和廣色域及出色的色彩準確度,讓觀影效果栩栩如生、活靈活現。

    這裡提醒大家,不要把 MiniLED 與 MicroLED 之間混淆了,大家可以把 MiniLED 視為 LCD 電視的升級式發展,而 MicroLED 則是另一種完全消除背光的徹底提升,兩者相較之下當然前者的價格比後者便宜些,但這也只是兩相比較罷了,想必 LG QNED MiniLED 電視的售價也不會太容易入手。

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

    透過資料庫的網站架設建置,建立公司的形象或購物系統,並提供最人性化的使用介面,讓使用者能即時接收到相關的資訊

    您也許會喜歡:

    【推爆】終身$0月租 打電話只要1元/分

    立達合法徵信社-讓您安心的選擇

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

    當全世界的人們隨著網路時代而改變向上時您還停留在『網站美醜不重要』的舊有思維嗎?機會是留給努力改變現況的人們,別再浪費一分一秒可以接觸商機的寶貴時間!

  • 管程(Monitor)概念及Java的實現原理_網頁設計公司

    ※自行創業缺乏曝光? 網頁設計幫您第一時間規劃公司的形象門面

    網站的第一印象網頁設計,決定了客戶是否繼續瀏覽的意願。台北網動廣告製作的RWD網頁設計,採用精簡與質感的CSS語法,提升企業的專業形象與簡約舒適的瀏覽體驗,讓瀏覽者第一眼就愛上它。

    目錄

    • 互斥
    • 管程-Monitor
    • 當線程等待資源時
    • Hoare版本
    • Mesa版本
    • Brinch Hanson版本
    • 三種語義對比
    • Java版本的Monitor
    • Java monitor實現生產者/消費者

    互斥

    互斥訪問是併發編程要解決的核心問題之一。
    有許多種方法可以滿足臨界區的互斥訪問。大體上可以分為三種,
    一種是軟件方法,即由用戶程序承擔互斥訪問的責任,而不需要依賴編程語言或操作系統,譬如Dekker算法、Peterson算法等,通常這種方式會有一定的性能開銷和編程難度。
    第二種是操作系統或編程語言對互斥的原生支持,譬如Linux中的mutex、Java語言的synchronized。
    最後是硬件上的特殊指令,譬如著名的CAS。這種方式開銷最少,但是很難成為一種通用的解決方案,通常操作系統或編程語言的互斥是基於此建立起來的。

    管程-Monitor

    管程屬於編程語言級別的互斥解決方案,最早是Brinch Hanson和Hoare於1970s提出的概念,已在Pascal、Java、Python等語言中得到了實現。
    “管程”一詞翻譯自英文Monitor Procedures,字面理解就是管理一個或多個執行過程。(但是個人感覺“管程”這個翻譯有點莫名其妙,看完更迷糊了,所以本文堅持用回原名Monitor。)
    Monitor本質上是對通用同步工具的一種抽象,它就像一個線程安全的盒子,用戶程序把一個方法或過程(代碼塊)放進去,它就可以為他們提供一種保障:同一時刻只能有一個進程/線程執行該方法或過程,從而簡化了併發應用的開發難度
    如果Monitor內沒有線程正在執行,則線程可以進入Monitor執行方法,否則該線程被放入入口隊列(entry queue)並使其掛起。當有線程從Monitor中退出時,會喚醒entry queue中的一個線程。
    為了處理併發線程,Monitor還需要一個更基礎的同步工具,或者說需要一個機制,使得線程不僅被掛起,而且還能釋放Monitor,以便其他線程可以進入。
    Monitor使用條件變量(Condition Variable)支持這種機制,這些條件變量(一個或多個)包含在Monitor中,並且只有在Monitor內才能被訪問 (類似Java對象的private變量)。
    對外開放兩個方法以便用戶程序操作條件變量
    cwait(c):調用該方法的線程在條件c上阻塞,monitor現在可以被其他線程使用。
    csignal(c):恢復在條件c上被阻塞的線程。若有多個這樣的線程,選擇其中一個。
    (通常,為了保證cwait/csignal對條件變量的變更是原子性的,還需要藉助CAS)

    當線程等待資源時

    當Monitor中正在執行的線程無法獲取所需資源時,情況會變得更加複雜。
    如果發生這種情況,等待資源的線程可以先把自己掛起,並且釋放Monitor的使用權,使得其他線程得以進入Monitor。
    那麼問題來了,當第二個線程在執行期間,第一個線程所需的資源可用了,會發生什麼?
    立即喚醒第一個線程,還是第二個線程先執行完?
    對此產生了多個對Monitor的定義。

    Hoare版本

    在Hoare的語義中,當資源可用時,ThreadA立即恢復執行,而ThreadB進入signal queue。

    1.ThreadA 進入 monitor
    2.ThreadA 等待資源 (進入wait queue)
    3.ThreadB 進入monitor
    4.ThreadB 資源可用 ,通知ThreadA恢復執行,並把自己轉移到signal queue。
    5.ThreadA 重新進入 monitor
    6.ThreadA 離開monitor
    7.ThreadB 重新進入 monitor
    8.ThreadB 離開monitor
    9.其他在entry queue中的線程通過競爭進入monitor
    

    Mesa版本

    在Mesa Monitor的實現中,第二個線程會先執行完。
    ThreadA的資源可用時,把它從wait queue轉移到entry queue。ThreadB繼續執行至結束。
    ThreadA最終也會從entry queue中得以執行。

    1.ThreadA 進入 monitor
    2.ThreadA 等待資源 (進入wait queue,並釋放monitor)
    3.ThreadB 進入monitor
    4.ThreadB 資源可用,通知ThreadA。(ThreadA被轉移到entey queue)
    5.ThreadB 繼續執行
    6.ThreadB 離開monitor
    7.ThreadA 獲得執行機會,從entry queue出隊列,恢復執行
    8.ThreadA 離開monitor
    9.其他在entry queue中的線程通過競爭進入monitor
    

    由於ThreadA被轉移到了entry queue,當ThreadB退出monitor后,ThreadA與其他線程平等競爭monitor的進入條件,所以並不能保證立即執行。
    更不幸的是,等到ThreadA重入monitor后,資源可能再次不可用,重複以上過程。

    ※綠能、環保無空污,成為電動車最新代名詞,目前市場使用率逐漸普及化

    台中景泰電動車行只是一個單純的理由,將來台灣的環境,出門可以自由放心的深呼吸,讓空氣回歸自然的乾淨,減少污染,留給我們下一代有好品質無空污的優質環境

    Brinch Hanson版本

    Brinch Hanson Monitor(以下簡稱BH Monitor)只允許線程從monitor退出時發出信號,此時被通知的線程進入monitor恢復執行。

    1.ThreadA 進入 monitor
    2.ThreadA 等待資源a
    3.ThreadB 進入monitor
    4.ThreadB 離開Monitor,並給通知等待資源a的線程,資源可用
    5.ThreadA 重新進入 monitor
    6.ThreadA 離開monitor
    7.其他線程從entry queue中競爭進入monitor
    

    三種語義對比

    Hoare Monitor中,資源可用時,ThreadB調用csignal()后被阻塞,以便ThreadA立即恢復執行。
    這時ThreadB應該被放到哪裡?一種可能是轉移到entry queue,這樣它就必須與其他還未進入Montior的線程平等競爭獲取重入機會。
    但是由於在調用csignal()之前,ThreadB已經執行了一部分,因此使它優先於其他線程是有意義的,
    為此,Hoare Monitor增加了signal queue用於存放阻塞在csignal()上的線程。
    Hoare Monitor的一個明顯缺點是,ThreadB在執行中途被中斷,需要額外的兩次線程切換才能恢復執行。
    不同的是,Mesa Monitor和BH Monitor會保證ThreadB先執行完,因此不需要額外的signal queue。

    Java版本的Monitor

    Java在實現時對最初的Monitor定義做了一些合理的限制。首先,與以上三種都不一樣的是,Java Montior只允許一個條件變量,而不是多個。

    不像BH monitor,signal可以出現在代碼的任何地方。

    也不像Hoare monitor,資源可以時,被通知的線程不會立即執行,而是從BLOCK狀態變成RUNNABLE狀態,被CPU再次調度到時才恢復執行。

    與cwait(c)和csignal(c)對應的是wait()和notify()方法。

    Java monitor機制通過synchronized關鍵字暴露給用戶,syncronized可以修飾方法或代碼塊(兩者本質上都是一個過程)。

    Java monitor實現生產者/消費者

    
    
    //簡化版本,只允許一個生產者和一個消費者
    
    class BoundedBuffer {    
    
       private int numSlots = 0;
    
       private double[] buffer = null;
    
       private int putIn = 0, takeOut = 0;
    
       private int count = 0;
    
    
    
       public BoundedBuffer(int numSlots) {
    
          if (numSlots <= 0) throw new IllegalArgumentException("numSlots<=0");
    
          this.numSlots = numSlots;
    
          buffer = new double[numSlots];
    
          System.out.println("BoundedBuffer alive, numSlots=" + numSlots);
    
       }
    
    
    
       public synchronized void deposit(double value) {
    
          while (count == numSlots)
    
             try {
    
                wait();
    
             } catch (InterruptedException e) {
    
                System.err.println("interrupted out of wait");
    
             }
    
          buffer[putIn] = value;
    
          putIn = (putIn + 1) % numSlots;
    
          count++;                  
    
          if (count == 1) notify();  //喚醒等待的consumer
    
       }
    
    
    
       public synchronized double fetch() {
    
          double value;
    
          while (count == 0)
    
             try {
    
                wait();
    
             } catch (InterruptedException e) {
    
                System.err.println("interrupted out of wait");
    
             }
    
          value = buffer[takeOut];
    
          takeOut = (takeOut + 1) % numSlots;
    
          count--;                           // wake up the producer
    
          if (count == numSlots-1) notify(); // 喚醒等待的producer
    
          return value;
    
       }
    
    }
    
    

    1.Monitors and Condition Variables:https://cseweb.ucsd.edu/classes/sp17/cse120-a/applications/ln/lecture8.html
    2.《操作系統精髓與設計原理》第五章
    3.https://en.m.wikipedia.org/wiki/Monitor_(synchronization)

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

    ※如何讓商品強力曝光呢? 網頁設計公司幫您建置最吸引人的網站,提高曝光率!

    以設計的實用美學觀點,規劃出舒適、美觀的視覺畫面,有效提昇使用者的心理期待,營造出輕鬆、愉悅的網站瀏覽體驗。

  • .NET編程5月小結 – Blazor, Unity, Dependency Injection_如何寫文案

    .NET編程5月小結 – Blazor, Unity, Dependency Injection_如何寫文案

    ※別再煩惱如何寫文案,掌握八大原則!

    什麼是銷售文案服務?A就是幫你撰寫適合的廣告文案。當您需要販售商品、宣傳活動、建立個人品牌,撰寫廣告文案都是必須的工作。

    本文是我在5月份看到的一些有趣的內容的集合。在這裏你可以找到許多有關Blazor、ASPNET Core的學習資源和示例項目,有關在Unity中使用Zenject進行單元測試的博客,有關Unity項目架構的討論,以及對依賴注入感興趣的人的必讀書籍。  

    0x00 Blazor – app building workshop

    • Blazor是一個單頁面應用程序框架,使用.NET和WebAssembly來構建客戶端Web應用程序。在這個workshop中,我們將構建一個完整的Blazor應用程序,並逐步了解Blazor框架的各種功能。

     

    0x01 Blazor – CarChecker

    • 一個BlazorWebAssembly應用程序的樣板工程,演示包括authenticationin-browser data storageoffline supportlocalizationresponsive layouts

      ※教你寫出一流的銷售文案?

      銷售文案是什麼?A文案是廣告用的文字。舉凡任何宣傳、行銷、販賣商品時所用到的文字都是文案。在網路時代,文案成為行銷中最重要的宣傳方式,好的文案可節省大量宣傳資源,達成行銷目的。

      等等功能。

     

    0x02 Modern Web UI with Blazor WebAssembly

    • 上面的Github的樣板工程的視頻教學版本。

     

    0x03 Awesome Blazor

    • 這個應該比較有名了,一個Github倉庫,收集了大量和Balzor有關的資源,這些資源包括示例項目,教程,視頻,文章,書籍,电子書等。

     

    0x04 Practical ASP.NET Core

    • 該項目的目的是使.NET程序員能夠直接從代碼中學習新的ASP.NET Core技術棧。Readme文件包含所有項目的說明。

     

    0x05 Game Programmer Resume Tips

    • 作者Dale Kim目前在Unity工作,在這個文檔中他回顧了過去使用過的實際簡歷。文檔中的技巧適用於具有編程背景並想要在遊戲行業找到第一份工作的學生。

     

    0x06 Clean Architecture Solution Template for Angular 9 and .NET Core 3.1

    • 這是一個按照Clean Architecture原理使用Angular和ASP NET Core創建單頁應用程序(SPA)的解決方案模板。

     

    0x07 Unit testing Unity and UniRX with Zenject and Moq

    • 這篇文章並沒有討論太多單元測試本身,而是提供了使用UniRX和Zenject等出色技術在Unity中創建單元測試的討論。

     

    0x08 A better architecture for Unity projects

    • 來自GameDev Guru的一篇對Unity項目架構的思考和總結。

     

    0x09 Dependency Injection Principles, Practices, and Patterns

    • Dependency Injection Principles, Practices, and Patterns(依賴注入原理,實踐和模式)是經典暢銷書《Dependency Injection in .NET》的修訂版和擴展版。它從頭開始教你DI,是對依賴注入感興趣的人的必讀書籍。

     

    https://zhuanlan.zhihu.com/p/145260777

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

    ※廣告預算用在刀口上,台北網頁設計公司幫您達到更多曝光效益

    擁有後台管理系統的網站,將擁有強大的資料管理與更新功能,幫助您隨時新增網站的內容並節省網站開發的成本。

  • ASP.NET Core 依賴注入最佳實踐與技巧[譯]_網頁設計公司

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

    當全世界的人們隨著網路時代而改變向上時您還停留在『網站美醜不重要』的舊有思維嗎?機會是留給努力改變現況的人們,別再浪費一分一秒可以接觸商機的寶貴時間!

    ASP.NET Core 依賴注入最佳實踐與技巧

    原文地址:https://medium.com/volosoft/asp-net-core-dependency-injection-best-practices-tips-tricks-c6e9c67f9d96 [正(ke)確(xue)上(shang)網(wang)]
    posted by Halil İbrahim Kalkan Jul 12, 2018 · 7 min read

    在這篇文章中,我將分享一下在ASP.NET Core應用程序中使用依賴注入的經驗與建議。
    主要分享的目的,基於以下幾點原則:

    • 有效的設計服務及它們的依賴關係
    • 預防多線程問題
    • 預防內存移除
    • 預防潛在bugs

    這篇文章的前提假設你已經對依賴注入和ASP.NET Core由基本的認識,如果還沒有,首先請閱讀ASP.NET Core Dependency Injection documentation。

    基礎

    構造函數注入

    構造函數注入(Constructor injection)用於聲明和獲取服務對服務構造的依賴關係。

    public class ProductService
    {
        private readonly IProductRepository _productRepository;
        public ProductService(IProductRepository productRepository)
        {
            _productRepository = productRepository;
        }
        public void Delete(int id)
        {
            _productRepository.Delete(id);
        }
    }
    

    ProductService在構造函數中注入了它的依賴IProductRepository,然後使用了它的Delete方法。

    良好實踐

    • 在服務構造函數中顯式定義所需的依賴項。這樣,服務缺失依賴關係就不能構造。
    • 將注入的依賴項賦值給一個只讀(read only)字段/屬性(防止在方法調用過程中無意的賦值了其他值)。

    屬性注入

    ASP.NET Core的標配的依賴注入容器並不支持屬性注入(property injection)。但是你可以使用其他的依賴注入容器支持屬性注入。。

    using Microsoft.Extensions.Logging;
    using Microsoft.Extensions.Logging.Abstractions;
    namespace MyApp
    {
        public class ProductService
        {
            public ILogger<ProductService> Logger { get; set; }
            private readonly IProductRepository _productRepository;
            public ProductService(IProductRepository productRepository)
            {
                _productRepository = productRepository;
                Logger = NullLogger<ProductService>.Instance;
            }
            public void Delete(int id)
            {
                _productRepository.Delete(id);
                Logger.LogInformation(
                    $"Deleted a product with id = {id}");
            }
        }
    }
    
    

    ProductService聲明了一個開放了Setter的日誌(Logger)屬性。依賴注入容器能賦值一個可用的值給這個日誌屬性(前提是已經在依賴注入容器內註冊過)。

    良好實踐

    • 僅對可選依賴項使用屬性注入。這意味着你的服務可以在不提供這些依賴項的情況下正常工作。
    • 盡量使用空對象模式(如實例所示)。否則,在使用依賴項時始終做NULL檢查。

    服務定位(Service Locator)

    服務定位(Service Locator)模式是另一種獲取依賴項的方式。

    public class ProductService
    {
        private readonly IProductRepository _productRepository;
        private readonly ILogger<ProductService> _logger;
        public ProductService(IServiceProvider serviceProvider)
        {
            _productRepository = serviceProvider
              .GetRequiredService<IProductRepository>();
            _logger = serviceProvider
              .GetService<ILogger<ProductService>>() ??
                NullLogger<ProductService>.Instance;
        }
        public void Delete(int id)
        {
            _productRepository.Delete(id);
            _logger.LogInformation($"Deleted a product with id = {id}");
        }
    }
    
    

    ProductService注入了IServiceProvider,並使用它解析了ProdProductServiService的依賴關係。如果在使用之前注入容器的話,使用GetRequiredService方法會拋異常。另一邊,使用GetService則返回NULL。

    當你在構造函數中解析(resolve)依賴服務時,他們隨着服務本身的釋放而釋放,所以你大可不必關係構造函數注入的依賴項的釋放(就像構造函數和屬性注入一樣)。

    良好實踐

    • 盡可能不要使用服務定位(Service Locator)模式。因為這樣使得服務的依賴關係隱式化(譯註,++服務的依賴關係不是显示的注入,導致代碼層面的服務依賴關係不明確,從構造函數看,只有一個IServiceProvider的依賴++)。這意味着在創建服務實例時不能显示的看到服務的依賴項。而這對於單元測試尤其重要,因為你可能想要模擬服務的一些依賴項。
    • 盡可能使用構造函數解析服務依賴項。在服務方法中解析依賴項會讓應用程序變得更複雜,更容易出錯。接下來,我將介紹這些問題和解決方案。

    服務生命周期

    在ASP.NET Core依賴注入概念裏面,有三種服務的生命周期:

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

    透過資料庫的網站架設建置,建立公司的形象或購物系統,並提供最人性化的使用介面,讓使用者能即時接收到相關的資訊

    1. Transient服務,在請求或注入服務的時候,每次都創建新實例。
    2. Scoped服務,在作用域內創建服務。在Web應用程序,每一個web請求都會創建一個新的獨立的服務作用域範圍。這意味着每個web請求通常都創建有作用域的服務
    3. Singleton服務,每個依賴注入容器會創建一次單例服務。在每個應用程序只會創建一次單例服務,在應用的整個生命周期都可用。

    依賴注入容器會跟蹤所有解析出來的服務,在它們的生命周期結束後會釋放掉這些服務。

    • 如果服務有依賴項,這些依賴項也會自動釋放。
    • 如果服務已經實現了IDisposable接口,在服務被釋放的時候也會自動調用Dispose方法。

    良好實踐

    • 盡可能的將你的服務註冊成Transient服務。設計一個Transient服務是相對簡單的,因為你通常不需要關心多線程和內存泄漏的問題,而且這些服務生命周期相對短。
    • 小心使用Scoped服務,因為當你創建子作用域或者在非web應用程序使用Scoped服務,會出現一些棘手的問題。
    • 小心使用Singleton服務,因為你需要正確處理多線程問題和潛在的內存泄露問題。
    • 不要在Singleton服務中依賴一個Transient服務或Scoped服務。因為這時Transient服務會變成Singleton服務,如果Transient服務不支持單例場景,當Singleton服務注入Transient服務時會產生異常問題。ASP.NET Core默認依賴注入容器在這種場景下會拋異常。

    在方法內解析服務

    在某些場景下,你可能需要在服務的方法中解析另外一個服務。這種情況下請確保在使用服務后及時釋放服務。這才是創建範圍作用域服務的最佳方式。

    public class PriceCalculator
    {
        private readonly IServiceProvider _serviceProvider;
        public PriceCalculator(IServiceProvider serviceProvider)
        {
            _serviceProvider = serviceProvider;
        }
        public float Calculate(Product product, int count,
          Type taxStrategyServiceType)
        {
            using (var scope = _serviceProvider.CreateScope())
            {
                var taxStrategy = (ITaxStrategy)scope.ServiceProvider
                  .GetRequiredService(taxStrategyServiceType);
                var price = product.Price * count;
                return price + taxStrategy.CalculateTax(price);
            }
        }
    }
    
    

    PriceCalculator在構造函數里注入了IServiceProvider並賦值給以只讀字段。然後PriceCalculatorCalculate的方法內創建了一個子範圍作用域。使用scope.ServiceProvider來解析服務依賴,而不是用_serviceProvider實例。這樣,在子範圍作用域內被解析的所有服務會在using的聲明結束后自動釋放。

    良好實踐

    • 如果在方法內解析服務,請始終創建子範圍作用域,以確保已解析的服務被正確釋放。
    • 如果一個方法使用IServiceProvider作為參數,那麼可以直接使用它解析服務依賴,而不需要關心依賴服務是否釋放。創建/管理服務範圍作用域是調用方法代碼的職責。遵循這一原則可以使代碼更簡潔。
    • 不要保存對已解析服務的引用!否則,在使用對象引用時訪問已釋放的服務可能會導致內存泄漏(除非已解析的服務是單例的)。

    單例服務 Singleton Services

    單例服務通常為了保持應用程序狀態而設計。緩存是一個應用程序狀態的最好示例。

    public class FileService
    {
        private readonly ConcurrentDictionary<string, byte[]> _cache;
        public FileService()
        {
            _cache = new ConcurrentDictionary<string, byte[]>();
        }
        public byte[] GetFileContent(string filePath)
        {
            return _cache.GetOrAdd(filePath, _ =>
            {
                return File.ReadAllBytes(filePath);
            });
        }
    }
    

    FileService只是簡單的緩存了文件內容來減少磁盤讀取。像這樣的服務應該設計成單例服務。否則緩存將不能正常工作。

    良好實踐

    • 如果一個服務持有某種狀態,應該以線程安全的方式訪問這個狀態。因為所有的請求將併發的訪問同一個實例,使用ConcurrentDictionary而不是Dictionary來確保線程安全。
    • 不要在單例服務內使用Scoped/Transient服務,因為Transient服務可能不是線程安全的設計。如果確實需要使用,請注意多線程(例如使用Lock)。
    • 引起內存泄漏的通常是由單例服務引起的。在應用程序結束之前,單例服務不會被釋放。它們實例化類(或注入實例)也不會提前被釋放,它們也會一直留在內存中,直到應用程序結束。確保在適當的時候釋放服務,請參閱在方法內解析服務。
    • 如果使用緩存數據(例如上述代碼示例中文件內容的緩存),應該創建一種機制當原始數據發生變更的時候去更新或淘汰已緩存的數據(示例中當磁盤的文件變更時應該更新緩存)。

    範圍作用域服務Scoped Services

    範圍作用域服務似乎是一個為每個web請求存儲數據的候選方式。因為ASP.NET Core為每一個Web請求都會創建一個服務範圍作用域。因此一個服務註冊成Scoped服務,在Web請求過程可以共享這個服務。

    public class RequestItemsService
    {
        private readonly Dictionary<string, object> _items;
        public RequestItemsService()
        {
            _items = new Dictionary<string, object>();
        }
        public void Set(string name, object value)
        {
            _items[name] = value;
        }
        public object Get(string name)
        {
            return _items[name];
        }
    }
    

    如果RequestItemsService註冊成範圍作用域的服務,並將RequestItemsService注入到兩個不同的服務中,這兩個服務可以訪問到另外一個服務添加的數據,因為這兩個服務在一個Web請求中是共享RequestItemsService實例的。

    但是,現實情況可能不完全是這樣的。如果你創建了子範圍作用域並在子作用域範圍內解析RequestItemsService,你會得到一個全新的RequestItemsService,而這並非我們所期望的那樣。所有Scoped服務並非一個Web請求時共享一個服務實例。

    你可能會認為你不會犯這樣明顯的錯誤(在子作用域內解析服務依賴)。但是這不是錯誤(一個常規用法而已)並且情況並沒有那麼簡單。假設在你的服務中有龐大的服務依賴關係,你可能不知道是否有人會這麼做(在子作用域內解析服務依賴)。

    良好實踐

    • Scoped服務可以視作一種優化手段(在一個web請求中不想注入太多服務)。這樣在同一個Web請求中所有的服務使用同一個實例。
    • Scoped服務不需要設計線程安全。因為Scoped服務通常在一個線程或Web請求中使用,但是,這種場景下,不應該在不同線程之間共享Scoped服務。
    • 如果要設計一個作用域服務來在web請求中的其他服務之間共享數據,小心上述問題。你可以使用HttpContext(通過IHttpContextAccessor來訪問它)來存儲每一個Web請求需要存儲的數據,這是安全的處理方式。HttpContext生命周期並不是Scoped。實際上並沒有注入到依賴注入的容器內(這是為什麼使用IHttpContextAccessor訪問它而不是注入到容器內的原因)。++在一個Web請求中,HttpContextAccessor使用AsyncLocal來共享相同的HttpContext++。

    結論

    依賴注入在最初使用的時候好像是挺簡單的。如果不遵循嚴格的使用原則,依然會有潛在的多線程和內存泄漏問題。我在開發ASP.NET Boilerplate框架過程中,基於我的實踐體會分享了這些實踐原則。

    總結

    在使用ASP.NET Core 依賴注入時需要注意幾項:

    1. 在構造函數中显示的注入依賴關係。
    • 在依賴關係眾多時,職責單一原則,考慮拆分職責
    • 更有利於單元測試。
    1. 屬性注入,適用於可選依賴項,不影響服務正常運行,考慮空實現模式。
    • 通常我們在設計框架/基類時,可以適當引入屬性注入,這樣可以使得繼承類代碼更簡潔。
    • 必要時,屬性提供懶加載方式,提高服務啟動速度。
    1. 選擇合適的服務生命周期。順序依次Transient > Singleton > Scoped,不確定時使用Transient ,明確使用場景的時候考慮Singleton和Scoped。同需要需要考慮服務的構建成本。
    • Transient服務的生命周期短,可以有效的規避多線程和內存泄漏問題,同時也引起應用程序的內存使用量上升,帶了部分性能問題。
    • 在Singleton服務中,禁止依賴Transient/Scoped服務,一方面,Transient/Scoped服務也會變成單例服務。另一方面,Transient/Scoped服務沒有考慮多線程問題。
    • 在使用Singleton服務時,多注意潛在的線程安全和內存泄漏問題。
    • 在非Web應用場景和子作用服務場景,Scoped服務,並不能正確處理一個線程內共享實例。

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

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

    RWD(響應式網頁設計)是透過瀏覽器的解析度來判斷要給使用者看到的樣貌

  • MVVM 小雛形 knockout_網頁設計

    MVVM 小雛形 knockout_網頁設計

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

    擁有專業的維修技術團隊,同時聘請資深iphone手機維修專家,現場說明手機問題,快速修理,沒修好不收錢

    前言

    knockout學過的當工具腳本用,就像jquery一樣使用,學習成本15分鐘,沒學過的可學可不學。

    knockout 是上古神器,話說在遠古開天闢地,前端到處是飛禽走獸,一片混亂。

    這時候人類開始人類開始誕生了,因為惡劣的環境備受煎熬,在生存角逐中,人們通過智慧寫了各種js腳本,進入了石器時代,但是人類只有兩條腿和兩隻手切換工具的速度限制了人類的發展。

    這時候John Resig 整理了各種工具,注入熔爐,一件草莽神器誕生了,jquery。人們開始利用jquery,在html上開墾大地,馬力十足,這是一個被jquery奴隸的時代,史稱奴隸時代。

    後來人們就發現了一個問題,在html中這塊廣袤的大地上,js不同腳本是衝突的,部落與聯盟之間的戰爭一觸即發。隨着因為衝突,調試繁瑣,js的部落與部落之間在戰爭中,被require.js等模塊管理所統治,不同的部落得到分封,進入了封建時代。

    但是幾乎在同一時間,mvvm思想開始萌芽,他們提出有一個假設,如果可以修改數據就能對html產生驅動變化,那麼是不是可以解放生產力?這個實現不斷得到驗證與實際,工業革命誕生了。這是一次沒有流血的革命,因為以前的技術誕生往往充滿着爭議,這個是真的解放人類的雙手,蒸汽時代開始來臨。

    knockout 就是蒸汽時代的產物,它是mvvm模式在js實現的前驅,是現在電力時代3大框架的基石。好了,故事模式結束。

    正文

    首先說明一下什麼是mvvm,它是一種模式,還有一些其他模式比如說mvc,mvp等等。

    他們其實是一個重的問題,偏向於哪一塊。

    mvc的c很重,那麼它的重點功能在於控制器,可以說是c連接了視圖和model。

    mvp的p很重,他們的視圖和model完全分離,中間p的其實相當於c,操作層,但是和mvc不同的是隔離了model層和視圖。比如說window form開發。

    mvvm,偏向view,和mvp完全相反,他的視圖和數據層相當緊密,兩者不可分割。knockout就是一個例子,包括現在比較成熟的框架vue。

    knockout它的作用就是一個重要功能在於監聽,監聽數據的變化,然後從新部分渲染。

    台北網頁設計公司這麼多該如何選擇?

    網動是一群專業、熱情、向前行的工作團隊,我們擁有靈活的組織與溝通的能力,能傾聽客戶聲音,激發創意的火花,呈現完美的作品

    那麼開始實踐一下吧:

    public class Product
    {
    	public int Id { get; set; }
    	public string Name { get; set; }
    	public string Category { get; set; }
    	public decimal Price { get; set; }
    }
    

    一個model類,裏面存放這id,name,category,price,對應數據庫。

    然後編輯控制器:

    public class HomeController : Controller
    {
    	static List<Product> productsList = new List<Product>();
    	public IActionResult Index()
    	{
    		return View();
    	}
    
    	[HttpGet]
    	public IActionResult products() {
    
    		productsList = new List<Product>() {
    			new Product{Id=1,Category="哈哈",Name="張三",Price=10 },
    			new Product{Id=2,Category="哈哈",Name="李小二",Price=10 }
    		};
    		return Json(productsList);
    	}
    }
    

    這裏面只是提供一些數據:

    前台:
    html部分

    <table id="products">
        <thead>
            <tr><th>ID</th><th>Name</th><th>Category</th><th>Price</th></tr>
        </thead>
        <tbody data-bind="foreach: products">
            <tr>
                <td data-bind="text: id"></td>
                <td data-bind="text: name"></td>
                <td data-bind="text: category"></td>
                <td data-bind="text: price"></td>
            </tr>
        </tbody>
    </table>
    

    js 部分:

    function ViewModel() {
    	var self = this;
    	//創建綁定
    	self.products = ko.observableArray(); // 創建數組綁定。
    	self.product = ko.observable();//單個產品
    	self.status = ko.observable();//單個錯誤提示
    	// 得到全部的產品
    	self.getAll = function () {
    		self.products.removeAll();
    		$.getJSON("/Home/products", function (products) {
    			self.products(products);
    		});
    	}
    	//更新
    	self.update = function () {
    		self.status("");
    		var id = $('#productId').val();
    		var product = {
    			Name: $('#name').val(),
    			Price: $('#price').val(),
    			Category: $('#category').val()
    		};
    		$.ajax({
    			url: '/Home/products/' + id,
    			cache: false,
    			type: 'PUT',
    			contentType: 'application/json; charset=utf-8',
    			data: JSON.stringify(product),
    			success: self.getAll
    		})
    			.fail(
    				function (xhr, textStatus, err) {
    					self.status(err);
    				});
    	}
    	//新增
    	self.create = function () {
    		self.status("");
    		var product = {
    			Name: $('#name2').val(),
    			Price: $('#price2').val(),
    			Category: $('#category2').val()
    		};
    		$.ajax({
    			url: '/Home/products',
    			cache: false,
    			type: 'POST',
    			contentType: 'application/json; charset=utf-8',
    			data: JSON.stringify(product),
    			statusCode: {
    				201 /*Created*/: function (data) {
    					//得到返回結果然後返回添加添加
    					self.products.push(data);
    				}
    			}
    		})
    			.fail(
    				function (xhr, textStatus, err) {
    					self.status(err);
    				});
    	}
    	//初始化
    	self.getAll();
    }
    
    $(function () {
    	var viewModel = new ViewModel();
    	ko.applyBindings(viewModel);
    })
    

    在裏面配置增刪改查即可,裏面配置的方法可以在html這樣寫自動綁定:

    <button data-bind="click: $root.create">添加</button>
    

    就會觸發裏面的create 方法。

    這裏只是作為一個綁定用例,其實在真正的編輯中是全部綁定的,不會出現這種$(‘#productName’).val();

    而是使用:

    <input data-bind="value: $root.Name" type="text" title="Name" />
    

    在此就不多複述。

    效果:

    總結

    感覺 knockout 也不是完全過時,小型的開發速率還是非常快的,綁定就完事,源碼也少,vs 編輯器也支持提示。

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

    網頁設計最專業,超強功能平台可客製化

    窩窩以「數位行銷」「品牌經營」「網站與應用程式」「印刷品設計」等四大主軸,為每一位客戶客製建立行銷脈絡及洞燭市場先機。

  • 怎樣實現登錄?| Cookie or JWT_貨運

    怎樣實現登錄?| Cookie or JWT_貨運

    ※智慧手機時代的來臨,RWD網頁設計為架站首選

    網動結合了許多網際網路業界的菁英共同研發簡單易操作的架站工具,及時性的更新,為客戶創造出更多的網路商機。

    先問小夥伴們一個問題,登錄難嗎?“登錄有什麼難得?輸入用戶名和密碼,後台檢索出來,校驗一下不就行了。”凡是這樣回答的小夥伴,你明顯就是產品思維,登錄看似簡單,用戶名和密碼,後台校驗一下,完事了。但是,登錄這個過程涵蓋的知識點是非常多的,絕不是檢索數據,校驗一下這麼簡單的事。

    那麼登錄都要哪些實現方式呢?i最傳統的就要是Cookie-Session這種方式了,最早的登錄方式都是這樣實現的。但是隨着手機端、H5端的興起,前後端分離的模式越來越流行,基於Cookie-Session這種登錄方式不是很方便,漸漸的JTW開始流行,現在大部分項目的登錄方式都是基於JWT的了。那麼Cookie和JWT都是怎樣實現登錄的呢?這兩種方式有什麼區別呢?我們在做登錄的x時候該怎麼選擇呢?咱們先看看這兩種方式的原理。

    Cookie方式

    因為Http協議是無狀態的,我們後台的服務(如Tomcat)在接收到前端發送過來的Http請求時,是區分不出哪個請求是誰發出的,這和我們的登錄功能是相違背的,登錄的功能就是要區分每一個請求是由哪個用戶發出的,這就變成了有狀態,那怎麼辦呢?Cookie應運而生,Cookie是存儲在瀏覽器端的,在Cookie中存儲的內容是鍵值對,也就是name-value。瀏覽器在向後台發送請求的時候,會把Cookie放在請求頭中,傳送給後台的服務,後台的服務會從請求頭中取到Cookie,再從Cookie中取出鍵值對中jsessionid對應的值。這個jsessionid的值就是你這次會話的id,對應着服務端的一個session。

    好了,到這裏session這個概念出來了,session是什麼呢?session是存儲在服務端的,每一個會話對應服務中的一個session。咱們可以把session理解為一個Map,它的key存儲的session的id,value存儲的東西就隨便了,我們在寫程序時想存啥就存啥。它的key存儲的值就是Cookie中存儲的jsessionid的值,這樣,瀏覽器發送請求到後台服務,後台才能根據Cookie中的jsessionid取到對應的session,再從session中取到之前存儲的狀態,如存儲在session中的登錄狀態、用戶id等。Cookie-Session機制是通用的,所有的瀏覽器都支持Cookie,就連最低端的IE都支持,你說他普遍不普遍。Session是後端容器必須支持的,如Tomcat,還有像其他的如Resin、jetty等。這些對開發人員都是透明的,無需過多關注。

    Cookie-Session的由來給大家說完了,我們看看基於Cookie這種方式的登錄流程,

    • 用戶在瀏覽器輸入用戶名、密碼,點擊登錄,發送請求到後台服務;
    • 後台服務校驗用戶名、密碼,將登錄狀態狀態和用戶id存儲在session中;
    • 將session的id存儲在Cookie中,通過響應頭返回到瀏覽器;
    • 當用戶點擊其他功能時,向後台發送的請求中會自動帶上Cookie;
    • 後台通過Cookie中的jsessionid找到對應的session,開發人員可從session中取出當前會話的登錄狀態和用戶id。

    基於Cookie-Session機制的登錄實現方式的整體流程就是這個樣子。看上去很完美,但還是存在不少問題的,我們來看看這些問題。

    分佈式會話

    上面的示例,我們的後台服務只有一個,一個服務往往很難支撐服務,為了保障可靠性,最少都是部署兩個後台服務。但是當部署多個後台服務時,我們的session就會出現問題,看看下面的圖,

    • 假如用戶登錄的請求,分配到了後台服務1,後台服務1的session存了用戶的登錄狀態和用戶id。
    • 用戶在點擊其他功能時,請求分配到了後台服務2,可是後台服務2的session並沒有存儲登錄狀態和用戶id。

    我們怎麼解決這個問題呢?其實也很簡單,第一,session集中管理,比如使用Redis;第二,所有的後台服務在獲取session時,統一從Redis中獲取。如下所示,

    我們可以使用中間件Spring-Session和Redis就可以解決這個問題。

    CORS

    使用Cookie實現登錄的另外一個問題就是跨域,現在往往都採用前後端分離的方式進行開發,在開發的過程中,前端和後端通常不在一個域下,由於瀏覽器的同源策略,Cookie不能傳入到後端。至於同源策略,不明白的小夥伴可以問一下度娘,這裏不過多介紹了。要解決這個問題,在前端、後端都要進行設置,在我的另一篇文章《前後端分離|關於登錄狀態那些事》中有詳細的介紹。總體歸納為:

    • 後端設置CORS允許跨域的域名,並且withCredentials設置為true;
    • 前端在向後端發送請求時,也需要設置withCredentials = true;

    這樣,我們的Cookie就可以實現跨域了。不進行這些設置,Cookie跨域是不可能的,同源策略保證了我們Cookie的安全。

    ※回頭車貨運收費標準

    宇安交通關係企業,自成立迄今,即秉持著「以誠待人」、「以實處事」的企業信念

    CSRF

    CSRF,這個CORS是不一樣的,長的比較像,也比較容易混。CSRF往往和系統的安全扯上聯繫,也是等保測試中比較重要的測試內容,它也是和Cookie有關的,大體的流程是這樣的,

    • 用戶登錄了A網站,並沒有退出;
    • 此時,用戶又訪問了B網站;
    • 在B網站有個隱藏的請求,請求了A網站的一個重要的接口,比如:轉賬、支付等。
    • 在請求A網站的同時,帶上了A網站的Cookie,所以一些危險的操作就成功了。

    關於CSRF的攻防,在我前面的文章《CSRF的原理與防禦 | 你想不想來一次CSRF攻擊?》中有詳細的介紹。總之,使用Cookie實現登錄是需要重點防範一下CSRF攻擊的。

    JWT方式

    近年來,由於手機端的興起,前後端分離開發方式的流行,JWT這種登錄的實現方式悄然興起,那麼什麼是JWT呢?JWT是英文JSON Web Token的縮寫,它由3部分組成,

    • header,一般情況下存儲兩個信息,1類型,一般都是JWT;2加密算法,比如:HMAC、RSA等;
    • payload,這裏就存儲登錄的相關信息了,比如:登錄狀態、用戶id、過期時間等。
    • signature,簽名,這個是將header、payload和密鑰的信息做一次加密,後台在接收到JWT的時候,一定要驗簽,謹防JWT的偽造。

    下面咱們看看JWT的登錄實現,

    我們看到整體的流程和Cookie的實現方式是一樣的,只不過是沒有用到Cookie、Session。那麼它與Cookie-Session的區別是什麼呢?

    • 登錄狀態、用戶id並沒有存儲到session,而是存在JWT的payload里,返回給了前端。
    • 在前端JWT不會自動存儲到Cookie中,前端開發人員要處理JWT的存儲問題,比如LocalStorage
    • 再次發起請求,JWT不會自動放到請求頭中,需前端同學手動設置
    • 後端從請求頭中取出JWT,驗簽通過後,拿到登錄狀態、用戶id,不是從session中取

    相比Cookie的方式,JWT的方式需要更多的開發工作量。那麼其他的問題存在嗎?我們一個一個看。

    分佈式會話

    我們後台部署多個服務,會有分佈式會話的問題嗎?

    無論請求被分配到哪一個後台服務中,登錄狀態和用戶id都是從JWT中取出來的,不會出現分佈式會話的問題。我們在後台部署集群的時候,根本不用care這個問題。

    CORS

    Cookie的跨域受到同源策略的保護,不經過特殊的設置,是不能夠跨域的。那麼JWT呢?JWT是前端同學手動在請求頭中設置的,如果向其他的域發送請求要注意,稍不注意,在請求的時候,調用了封裝的公共方法,就會把JWT發送給其他域的後台,前端的小夥伴要打起精神啊。

    CSRF

    Cookie的方式,B訪問A網站,會把A的Cookie帶上,從而造成了安全隱患。那麼JWT呢?JWT在前端存儲在A網站的域下,B在訪問A網站時,是拿不到A網站的JWT的,那麼也不可能在請求頭中設置JWT,A網站的後台拿不到JWT,也不會做其他操作。所以,JWT可以很好的防止CSRF攻擊。

    總結

    通過前面我們對Cookie和JWT的分析,可以總結成如下的表格,

    Cookie-Session JWT
    工作量 瀏覽器和容器天然支持 需要額外開發,有一定工作量
    分佈式會話 需要藉助中間件 無需關心,登錄信息從JWT解出
    CORS 不支持跨域、需特殊設置 開發人員設置請求頭,可以跨域
    CSRF 需特殊防範 無需防範,第三方拿不到JWT

    好了,Cookie和JWT的特點都總結出來了,大家在實現登錄的時候,就各取所需吧。結合自己的項目,選擇適合自己項目的實現方式吧。

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

    ※評比南投搬家公司費用收費行情懶人包大公開

    搬家價格與搬家費用透明合理,不亂收費。本公司提供下列三種搬家計費方案,由資深專業組長到府估價,替客戶量身規劃選擇最經濟節省的計費方式

  • 上位機C#通過OPCUA和西門子PLC通信_網頁設計公司

    上位機C#通過OPCUA和西門子PLC通信_網頁設計公司

    網頁設計公司推薦不同的風格,搶佔消費者視覺第一線

    透過選單樣式的調整、圖片的縮放比例、文字的放大及段落的排版對應來給使用者最佳的瀏覽體驗,所以不用擔心有手機版網站兩個後台的問題,而視覺效果也是透過我們前端設計師優秀的空間比例設計,不會因為畫面變大變小而影響到整體視覺的美感。

    寫在前面:

    很多人在學習OPCUA的時候,有個非常苦惱的問題,就是沒有OPCUA服務器的環境,這時候,有些人可能會想到通過類似於KepServer這樣的軟件來實現。那麼,有沒有一種方式,實現快速搭建OPCUA環境呢?答案是有的,今天繼續給大家分享S7-PLCSIM Advanced,S7-PLCSIM Advanced是SIEMENS推出的一款高功能仿真器,它的顯著特點是除了可以仿真一般的PLC邏輯控製程序外還可以仿真通信,功能是非常強大的,今天主要講述如何基於S7-PLCSIM Advanced搭建OPCUA通信仿真環境。

    01.PLCSIM-Advanced安裝

    對於該軟件的獲取,大家可以去西門子相關網站下載,也可以直接關注喜科堂上位機官方公眾號-dotNet工控上位機,然後發送關鍵詞PLCSIM-Advanced,即可下載使用。

    圖表 1 PLCSIM Advanced軟件

     

    PLCSIM-Advanced的安裝也比較簡單,基本上是一路NEXT即可,但是主要的是PLCSIM-Advanced會依賴WinPcap軟件,所以大家可以提前安裝好WinPcap,即使不提前安裝,安裝過程中也會提示你安裝的。

    安裝完成后,電腦中會額外多出一個虛擬網卡,名稱為Siemens PLCSIM Virtual Ethernet Adapter,如下圖:

    圖表 2網卡列表

     

     02.PLCSIM-Advanced使用

    安裝完成后,桌面上會多出一個圖標,即S7-PLCSIM Advanced V3.0,如下圖所示:

      圖表 3 PLCSIM Advanced圖標

     

    該軟件的使用可以按照下方的步驟執行和確定,一定要記住以下需要注意的地方,否則一個很小的問題,可能會讓你浪費半天的時間,這樣就得不償失了。

    (1)軟件要以管理員權限運行:可以直接每次右擊,以管理員權限運行,如果想一勞永逸,可以點擊圖標,右擊屬性,在兼容性中,將以管理員身份運行此程序的選項勾選。

     圖表 4設置管理員權限運行

     

    (2)將本地網卡及虛擬網卡的IP地址獲取設置為自動獲取。

    (3)設置PG/PC接口:

    通過控制面板,打開設置PG/PC接口界面,按照下圖所示設置應用程序訪問點:

     圖表 5設置PG/PC接口

     

    (4)打開PLCSIM-Advanced,依次按照步驟進行設置:

    圖表 6設置PLCSIM-Advanced

     

    (5)使用博圖創建一個簡單項目,一定要選擇1500PLC,PLCSIM-Advanced只支持1500PLC,但是對學習通信來說,沒什麼影響。

    (6)勾選允許Put/Get訪問:

    圖表 7設置允許PUT GET訪問

     

    (7)點擊項目,右擊屬性,將保護中的塊編譯時支持仿真選項勾選:

    ※想知道購買電動車哪裡補助最多?台中電動車補助資訊懶人包彙整

    節能減碳愛地球是景泰電動車的理念,是創立景泰電動車行的初衷,滿意態度更是服務客戶的最高品質,我們的成長來自於你的推薦。

    圖表 8設置塊編譯支持仿真

     

    (8)下載PLC程序時,將PG/PC接口設置成Siemens PLCSIM Virtual Ethernet Adapter。

    圖表 9選擇PG/PC接口

     

    (9)選擇显示所有兼容的設備,點擊開始搜索,搜索到之後,點擊下載即可。

    圖表 10搜索設備下載

     

     03.OPCUA配置

    上述過程和搭建S7通信環境完全一樣,OPCUA其實就是在S7的基礎上,需要先增加一些DB存儲區,然後在DB塊中添加一些變量,這裏不需要去除優化訪問,如下圖所示:

    圖表 11新建DB塊

     

           增加完成之後,雙擊CPU,在OPCUA選項中,將激活OPCUA服務器勾選,如下圖示所示:

    圖表 12激活OPCUA服務器

     

    激活OPCUA服務器之後,選擇運行系統許可證選項,選擇一個OPCUA許可證:

    圖表 13選擇OPCUA許可證

     

    以上操作完成之後,將PLC程序重新下載,下載步驟如上述一致。

     04.UAExpert通信測試

    上述操作完成之後即完成了整個環境搭建的過程,下面先使用官方的UAExpert進行測試。

    圖表 14 UAExpert通信測試

     

     05.通信測試平台測試

    接着,我們使用新閣的通信測試平台軟件進行通信測試,設置服務器節點為opc.tcp://192.168.1.20:4840(根據實際情況修改),點擊連接,連接成功后,點擊變量管理,即可看到OPCUA服務器中的所有節點,通過選擇DataBlockGlobal下的KYJDB,找到了我們剛剛配置的變量,選擇想要讀取的變量,然後讀取即可。

    圖表 15變量選擇

     

    圖表 16新閣通信測試平台

     

    寫在最後:

    本文旨在結合SIEMENS推出的一款高功能仿真器PLCSIM-Advanced軟件實現快速搭建OPCUA通信仿真環境,對於從事上位機開發,想要學習OPCUA通信,手頭又沒有硬件的學員來說,無疑是一大利好,基於OPCUA與西門子PLC通信,可以通過變量名稱訪問,而不需要去除DB的優化訪問,這一點非常方便。

     

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

    南投搬家公司費用,距離,噸數怎麼算?達人教你簡易估價知識!

    搬家費用:依消費者運送距離、搬運樓層、有無電梯、步行距離、特殊地形、超重物品等計價因素後,評估每車次單