支援 M1 Mac 的 Microsoft Edge Beta 預覽版來囉_網頁設計公司

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

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

換了 Apple M1 Mac 後還暫時找不到可以代替 Chrome 的瀏覽器?還是你還不知道為什麼大家最近都考慮把 Chrome 斷個乾淨(傳送門低家啦)?總而言之,隨著 Google 將對三方 Chromium 瀏覽器祭出的私有 Chrome API 限制政策後,眼看之後比較能接近 Chrome 的瀏覽器就剩下微軟的 Edge 了。但剛買 M1 MacBook Air / M1 MacBook Pro / M1 Mac mini 的你,卻不太想安裝 Canary / Dev 版本的 Edge?現在,更接近正式版的預覽版本也許真的可以成為屬於你的及時雨。繼續閱讀支援 M1 Mac 的 Microsoft Edge Beta 預覽版來囉報導內文。

▲圖片來源:Microsoft

M1 Mac 版 Microsoft Edge Beta 預覽版來囉,不趁 Keystone 換個瀏覽器?

▲圖片來源:Microsoft

眼看 Google 還沒打算將「壞壞」的 Keystone 從 Chrome 中排除,早已經習慣使用以 Chromium 為基礎所打造的瀏覽器的你,更因為剛換到 M1 Mac 而苦尋不找可以長久使用下去的替代瀏覽器(如果不是 Keystone 相信大家也不會想要一直換)。

雖說直接切換到了原本工作專用的 Firefox 的小編自己是用的很開心啦,但顯然許多人應該都把希望放在了先前已經宣佈,將會推出 Apple Silicon 版本 Edge 瀏覽器的微軟身上。

▲圖片來源:Microsoft

現在雖說正式版本還沒推出,但也真的只差一步之遙的 Microsoft Edge Beta 預覽版,倒是已經開放在 Insider 頻道提供下載了(點我前往頁面)。雖然名為 Beta,但它相對每日 / 每週更新的 Canary / Dev 版本,是以 2 個月為更新週期,雖說穩定度仍然有疑慮,但相對來講已經是最接近正式版本的了。

所以如果你已經等不及想跳槽或想試試微軟的 Edge 瀏覽器,在 M1 Mac 上是否有更強悍的表現的話(應該會吧,畢竟少了 Keystone ~ 嗯… 好地獄的梗),那可以考慮安裝 Beta 版本試試囉。

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

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

本篇圖片 / 引用來源

延伸閱讀:

好用的 Chrome 為何炎上被抵制?神人直指「它壞壞」還做了個懶人包網頁

借鑑食品、飲料等產業 Tesla 電池生產影片大公開,看了覺得莫名療癒…

您也許會喜歡:

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

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

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

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

數據加密 第五篇:非對稱密鑰_如何寫文案

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

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

非對稱密鑰(Asymmetric Keys)跟對稱密鑰相對,它使用一對密鑰(算法),一個密鑰用於加密,另一個密鑰用於解密,加密的密鑰稱為私鑰(private key),解密的密鑰稱為公鑰(public key)。私鑰由一方安全保管,不能外泄,而公鑰則可以發給任何請求它的人。比如,你向銀行請求公鑰,銀行將公鑰發給你,你使用公鑰對消息加密,那麼只有私鑰的持有人——銀行才能對你的消息解密。與對稱加密不同的是,銀行不需要將私鑰通過網絡發送出去,因此安全性大大提高。

跟對稱密鑰相比,非對稱密鑰提供的安全級別更高,付出的代價是消耗的資源更多。我們建議開發者避免使用非對稱密鑰對大量的數據進行加密和解密操作,推薦的做法是:對數據進行壓縮,使用對稱密鑰來加密壓縮之後的數據,由於對稱密鑰可能在數據傳遞過程中被竊取和破譯,因此,推薦使用非對稱密鑰來保護對稱密鑰。

舉個例子,發送方把對稱加密的密鑰使用非對稱加密的公鑰進行加密,發送出去;接收方使用私鑰進行解密得到對稱加密的密鑰,這樣,雙方使用對稱加密來進行溝通。

ENCRYPTBYASYMKEY()函數使用非對稱密鑰來加密數據,該函數加密的數據字節長度是有限度的,根據算法的不同,加密的長度限制不同:

  • 對於RSA_512算法,最多加密53bytes;
  • 對於RSA_1024算法,最多加密117bytes;
  • 對於RSA_2048算法,最多加密245bytes;

在SQL Server中,證書和非對稱密鑰都使用RSA密鑰,是RSA密鑰的包裝(wrapper)。

非對稱密鑰是數據庫級別的安全實體。 默認情況下,該實體同時包含公共密鑰和私有密鑰。默認情況下,私鑰受數據庫主密鑰保護。 如果尚未創建數據庫主密鑰,則需要密碼來保護私鑰。

一,創建非對稱密鑰

非對稱密鑰可以通過文件來導入,也可以在SQL Server中創建。

CREATE ASYMMETRIC KEY asym_key_name    
   [ FROM FILE = 'path_to_strong-name_file'   ]  
   [ WITH ALGORITHM = <algorithm>  ] 
   [ ENCRYPTION BY PASSWORD = 'password' ] 
  
<algorithm> ::=  
      { RSA_4096 | RSA_3072 | RSA_2048 | RSA_1024 | RSA_512 }   
     

參數註釋:

FROM FILE = ‘path_to_strong-name_file’:從文件導入已有的密鑰對,或從程序集或DLL文件導入公共密鑰。

在不使用FROM子句的情況下執行時,CREATE ASYMMETRIC KEY會生成一個新的密鑰對。加密的算法,推薦使用RSA_4096、RSA_3072和RSA_2048,而RSA_1024 和 RSA_512已經過時了。

對於新建的非對稱密鑰,可以使用密碼來保護私鑰,這需要在ENCRYPTION BY PASSWORD = ‘password’ 設置,如果省略該子句,那麼使用數據庫主密鑰來保護私鑰。

舉個例子,創建一個新的非對稱密鑰,使用密碼保護密鑰:

CREATE ASYMMETRIC KEY PacificSales09   
    WITH ALGORITHM = RSA_2048   
    ENCRYPTION BY PASSWORD = '<enterStrongPasswordHere>';   
GO  

二,修改非對稱密鑰

修改非對稱密鑰,可以移除密鑰的私鑰,也可以修改保護私鑰的密碼。修改非對稱密鑰的語法如下:

ALTER ASYMMETRIC KEY Asym_Key_Name <alter_option>  
 
<alter_option> ::=  
      <password_change_option>   
    | REMOVE PRIVATE KEY   

<password_change_option> ::=  
    WITH PRIVATE KEY ( <password_option> [ , <password_option> ] )  

<password_option> ::=  
      ENCRYPTION BY PASSWORD = 'strongPassword'  
    | DECRYPTION BY PASSWORD = 'oldPassword'

參數註釋:

  • REMOVE PRIVATE KEY:移除私鑰,但是保留公鑰
  • ENCRYPTION BY PASSWORD =’strongPassword‘: 用於指定一個新的密鑰來保護私鑰
  • DECRYPTION BY PASSWORD =’oldPassword‘:用於指定解密私鑰的舊密碼,如果私鑰被DMK保護,那麼不需要改子句。

舉個例子,修改保護私鑰的密碼:

ALTER ASYMMETRIC KEY PacificSales09   
    WITH PRIVATE KEY (  
    DECRYPTION BY PASSWORD = '<oldPassword>',  
    ENCRYPTION BY PASSWORD = '<enterStrongPasswordHere>');  
GO

三,使用非對稱密鑰來加密和解密數據

用非對稱密鑰來加密和解密數據,需要用到以下函數:

ASYMKEY_ID ( 'Asym_Key_Name' )  
EncryptByAsymKey ( Asym_Key_ID , { 'plaintext' | @plaintext } ) 
DecryptByAsymKey (Asym_Key_ID , { 'ciphertext' | @ciphertext } [ , 'Asym_Key_Password' ] )   

在解密數據時,如果私鑰是用密碼來保護的,需要提供密碼(設置參數’Asym_Key_Password’)來解密,如果密鑰是用DMK來解密的,那麼不需要提供解密私鑰的密碼。

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

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

示例1,用非對稱密鑰來加密:

EncryptByAsymKey(AsymKey_ID('JanainaAsymKey02'), @cleartext)

示例2,用非對稱密鑰來解密,密鑰用密碼來解密。

 DecryptByAsymKey( AsymKey_Id('JanainaAsymKey02'), CipherData, N'pGFD4bb925DGvbd2439587y' )

四,舉個例子

雖然非對稱加密很安全,但是和對稱加密比起來,它非常的慢,所以我們還是要用對稱加密來傳送消息,但對稱加密所使用的密鑰我們可以通過非對稱加密的方式發送出去。為了解釋這個過程,請看下面的例子:

(1) Alice需要在銀行的網站做一筆交易,她的瀏覽器首先生成了一個隨機數作為對稱密鑰。

(2) Alice的瀏覽器向銀行的網站請求公鑰。

(3) 銀行將公鑰發送給Alice。

(4) Alice的瀏覽器使用銀行的公鑰將自己的對稱密鑰加密。

(5) Alice的瀏覽器將加密后的對稱密鑰發送給銀行。

(6) 銀行使用私鑰解密得到Alice瀏覽器的對稱密鑰。

(7) Alice與銀行可以使用對稱密鑰來對溝通的內容進行加密與解密了。

 

 

 

參考文檔:

CREATE ASYMMETRIC KEY (Transact-SQL)

ENCRYPTBYASYMKEY (Transact-SQL)

DECRYPTBYASYMKEY (Transact-SQL)

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

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

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

我終於看懂了HBase,太不容易了…_網頁設計公司

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

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

前言

只有光頭才能變強。

文本已收錄至我的GitHub精選文章,歡迎Star:https://github.com/ZhongFuCheng3y/3y

在我還不了解分佈式和大數據的時候已經聽說過HBase了,但對它一直都半知不解,這篇文章來講講吧。

在真實生活中,最開始聽到這個詞是我的一場面試,當年我還是個『小垃圾』,現在已經是個『大垃圾』了。

面試官當時給了一個場景題問我,具體的題目我忘得差不多了,大概就是考試與試題的一個場景,問我數據庫要如何設計。

我答了關係型數據庫的設計方案,他大概說:這個場景比較複雜多變,為什麼不考慮一下HBase這種NoSQL的數據庫來存儲呢

我就說:“對對對,可以的” (雖然我當時不知道HBase是什麼,但是氣勢一定要有,你們說是不是)

最後面試官還是給我發了offer,但我沒去,原因就是離家太遠了。

一、介紹HBase

Apache HBase™ is the Hadoop database, a distributed, scalable, big data store.

HBase is a type of “NoSQL” database.

Apache HBase 是 Hadoop 數據庫,一個分佈式、可伸縮的大數據存儲

HBase是依賴Hadoop的。為什麼HBase能存儲海量的數據?因為HBase是在HDFS的基礎之上構建的,HDFS是分佈式文件系統

二、為什麼要用HBase

截至到現在,三歪已經學了不少的組件了,比如說分佈式搜索引擎「Elasticsearch」、分佈式文件系統「HDFS」、分佈式消息隊列「Kafka」、緩存數據庫「Redis」等等…

能夠處理數據的中間件(系統),這些中間件基本都會有持久化的功能。為什麼?如果某一個時刻掛了,那還在內存但還沒處理完的數據不就涼了?

Redis有AOF和RDB、Elasticsearch會把數據寫到translog然後結合FileSystemCache將數據刷到磁盤中、Kafka本身就是將數據順序寫到磁盤….

這些中間件會實現持久化(像HDFS和MySQL我們本身就用來存儲數據的),為什麼我們還要用HBase呢?

雖然沒有什麼可比性,但是在學習的時候總會有一個疑問:「既然已學過的系統都有類似的功能了,那為啥我還要去學這個玩意?」

三歪是這樣理解的:

  • MySQL?MySQL數據庫我們是算用得最多了的吧?但眾所周知,MySQL是單機的。MySQL能存儲多少數據,取決於那台服務器的硬盤大小。以現在互聯網的數據量,很多時候MySQL是沒法存儲那麼多數據的。
    • 比如我這邊有個系統,一天就能產生1TB的數據,這數據是不可能存MySQL的。(如此大的量數據,我們現在的做法是先寫到Kafka,然後落到Hive中)
  • Kafka?Kafka我們主要用來處理消息的(解耦異步削峰)。數據到Kafka,Kafka會將數據持久化到硬盤中,並且Kafka是分佈式的(很方便的擴展),理論上Kafka可以存儲很大的數據。但是Kafka的數據我們不會「單獨」取出來。持久化了的數據,最常見的用法就是重新設置offset,做「回溯」操作
  • Redis?Redis是緩存數據庫,所有的讀寫都在內存中,速度賊快。AOF/RDB存儲的數據都會加載到內存中,Redis不適合存大量的數據(因為內存太貴了!)。
  • Elasticsearch?Elasticsearch是一個分佈式的搜索引擎,主要用於檢索。理論上Elasticsearch也是可以存儲海量的數據(畢竟分佈式),我們也可以將數據用『索引』來取出來,似乎已經是非常完美的中間件了。
    • 但是如果我們的數據沒有經常「檢索」的需求,其實不必放到Elasticsearch,數據寫入Elasticsearch需要分詞,無疑會浪費資源。
  • HDFS?顯然HDFS是可以存儲海量的數據的,它就是為海量數據而生的。它也有明顯的缺點:不支持隨機修改,查詢效率低,對小文件支持不友好。

上面這些技術棧三歪都已經寫過文章了。學多了你會發現它們的持久化機制都差不太多,有空再來總結一下。

文中的開頭已經說了,HBase是基於HDFS分佈式文件系統去構建的。換句話說,HBase的數據其實也是存儲在HDFS上的。那肯定有好奇寶寶就會問:HDFS和HBase有啥區別阿

HDFS是文件系統,而HBase是數據庫,其實也沒啥可比性。「你可以把HBase當做是MySQL,把HDFS當做是硬盤。HBase只是一個NoSQL數據庫,把數據存在HDFS上」。

數據庫是一個以某種有組織的方式存儲的數據集合

扯了這麼多,那我們為啥要用HBase呢?HBase在HDFS之上提供了高併發的隨機寫和支持實時查詢,這是HDFS不具備的。

我一直都說在學習某一項技術之前首先要了解它能幹什麼。如果僅僅看上面的”對比“,我們可以發現HBase可以以低成本存儲海量的數據並且支持高併發隨機寫和實時查詢。

但HBase還有一個特點就是:存儲數據的”結構“可以地非常靈活(這個下面會講到,這裏如果沒接觸過HBase的同學可能不知道什麼意思)。

三、入門HBase

聽過HBase的同學可能都聽過「列式存儲」這個詞。我最開始的時候覺得HBase很難理解,就因為它這個「列式存儲」我一直理解不了它為什麼是「列式」的。

在網上也有很多的博客去講解什麼是「列式」存儲,它們會舉我們現有的數據庫,比如MySQL。存儲的結構我們很容易看懂,就是一行一行數據嘛。

轉換成所謂的列式存儲是什麼樣的呢?

可以很簡單的發現,無非就是把每列抽出來,然後關聯上Id。這個叫列式存儲嗎?我在這打個問號

轉換后的數據從我的角度來看,數據還是一行一行的。

這樣做有什麼好處嗎?很明顯以前我們一行記錄多個屬性(列),有部分的列是空缺的,但是我們還是需要空間去存儲。現在把這些列全部拆開,有什麼我們就存什麼,這樣空間就能被我們充分利用

這種形式的數據更像什麼?明顯是Key-Value嘛。那我們該怎麼理解HBase所謂的列式存儲和Key-Value結構呢?走進三歪的小腦袋,一探究竟。

3.1 HBase的數據模型

在看HBase數據模型的時候,其實最好還是不要用「關係型數據庫」的知識去理解它。

In HBase, data is stored in tables, which have rows and columns. This is a terminology overlap withrelational databases (RDBMSs), but this is not a helpful analogy.

HBase裡邊也有表、行和列的概念。

  • 表沒什麼好說的,就是一張表
  • 一行數據由一個行鍵一個或多個相關的列以及它的值所組成

好了,現在比較抽象了。在HBase裡邊,定位一行數據會有一個唯一的值,這個叫做行鍵(RowKey)。而在HBase的列不是我們在關係型數據庫所想象中的列。

HBase的列(Column)都得歸屬到列族(Column Family)中。在HBase中用列修飾符(Column Qualifier)來標識每個列。

在HBase裡邊,先有列族,後有列

什麼是列族?可以簡單理解為:列的屬性類別

什麼是列修飾符?先有列族後有列,在列族下用列修飾符來標識一列

還很抽象是不是?三歪來畫個圖:

我們再放點具體的值去看看,就更加容易看懂了:

這張表我們有兩個列族,分別是UserInfoOrderInfo。在UserInfo下有兩個列,分別是UserInfo:nameUserInfo:age,在OrderInfo下有兩個列,分別是OrderInfo:orderIdOrderInfo:money

UserInfo:name的值為:三歪。UserInfo:age的值為24。OrderInfo:orderId的值為23333。OrderInfo:money的值為30。這些數據的主鍵(RowKey)為1

上面的那個圖看起來可能不太好懂,我們再畫一個我們比較熟悉的:

HBase表的每一行中,列的組成都是靈活的,行與行之間的列不需要相同。如圖下:

換句話說:一個列族下可以任意添加列,不受任何限制

數據寫到HBase的時候都會被記錄一個時間戳,這個時間戳被我們當做一個版本。比如說,我們修改或者刪除某一條的時候,本質上是往裡邊新增一條數據,記錄的版本加一了而已。

比如現在我們有一條記錄:

現在要把這條記錄的值改為40,實際上就是多添加一條記錄,在讀的時候按照時間戳讀最新的記錄。在外界「看起來」就是把這條記錄改了。

3.2 HBase 的Key-Value

HBase本質上其實就是Key-Value的數據庫,上一次我們學Key-Value數據庫還是Redis呢。那在HBase裡邊,Key是什麼?Value是什麼?

我們看一下下面的HBaseKey-Value結構圖:

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

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

Key由RowKey(行鍵)+ColumnFamily(列族)+Column Qualifier(列修飾符)+TimeStamp(時間戳–版本)+KeyType(類型)組成,而Value就是實際上的值。

對比上面的例子,其實很好理解,因為我們修改一條數據其實上是在原來的基礎上增加一個版本的,那我們要準確定位一條數據,那就得(RowKey+Column+時間戳)。

KeyType是什麼?我們上面只說了「修改」的情況,你們有沒有想過,如果要刪除一條數據怎麼做?實際上也是增加一條記錄,只不過我們在KeyType裡邊設置為“Delete”就可以了。

3.3 HBase架構

扯了這麼一大堆,已經說了HBase的數據模型和Key-Value了,我們還有一個問題:「為什麼經常會有人說HBase是列式存儲呢?」

其實HBase更多的是「列族存儲」,要談列族存儲,就得先了解了解HBase的架構是怎麼樣的。

我們先來看看HBase的架構圖:

1、Client客戶端,它提供了訪問HBase的接口,並且維護了對應的cache來加速HBase的訪問。

2、Zookeeper存儲HBase的元數據(meta表),無論是讀還是寫數據,都是去Zookeeper裡邊拿到meta元數據告訴給客戶端去哪台機器讀寫數據

3、HRegionServer它是處理客戶端的讀寫請求,負責與HDFS底層交互,是真正幹活的節點。

總結大致的流程就是:client請求到Zookeeper,然後Zookeeper返回HRegionServer地址給client,client得到Zookeeper返回的地址去請求HRegionServer,HRegionServer讀寫數據后返回給client。

3.4 HRegionServer內部

我們來看下面的圖:

前面也提到了,HBase可以存儲海量的數據,HBase是分佈式的。所以我們可以斷定:HBase一張表的數據會分到多台機器上的。那HBase是怎麼切割一張表的數據的呢?用的就是RowKey來切分,其實就是表的橫向切割。

說白了就是一個HRegion上,存儲HBase表的一部分數據。

HRegion下面有Store,那Store是什麼呢?我們前面也說過,一個HBase表首先要定義列族,然後列是在列族之下的,列可以隨意添加。

一個列族的數據是存儲在一起的,所以一個列族的數據是存儲在一個Store裡邊的。

看到這裏,其實我們可以認為HBase是基於列族存儲的(畢竟物理存儲,一個列族是存儲到同一個Store里的)

Store裡邊有啥?有Mem Store、Store File、HFile,我們再來看看裡邊都代表啥含義。

HBase在寫數據的時候,會先寫到Mem Store,當MemStore超過一定閾值,就會將內存中的數據刷寫到硬盤上,形成StoreFile,而StoreFile底層是以HFile的格式保存,HFile是HBase中KeyValue數據的存儲格式。

所以說:Mem Store我們可以理解為內存 buffer,HFile是HBase實際存儲的數據格式,而StoreFile只是HBase里的一個名字。

回到HRegionServer上,我們還漏了一塊,就是HLog

這裏其實特別好理解了,我們寫數據的時候是先寫到內存的,為了防止機器宕機,內存的數據沒刷到磁盤中就掛了。我們在寫Mem store的時候還會寫一份HLog

這個HLog是順序寫到磁盤的,所以速度還是挺快的(是不是有似曾相似的感覺)…

稍微總結一把:

  • HRegionServer是真正幹活的機器(用於與hdfs交互),我們HBase表用RowKey來橫向切分表
  • HRegion裡邊會有多個Store,每個Store其實就是一個列族的數據(所以我們可以說HBase是基於列族存儲的)
  • Store裡邊有Men Store和StoreFile(HFile),其實就是先走一層內存,然後再刷到磁盤的結構

3.5 被遺忘的HMaster

我們在上面的圖會看到有個Hmaster,它在HBase的架構中承擔一種什麼樣的角色呢?讀寫請求都沒經過Hmaster呀

那HMaster在HBase里承擔什麼樣的角色呢??

HMaster is the implementation of the Master Server. The Master server is responsible for monitoring all RegionServer instances in the cluster, and is the interface for all metadata changes.

HMaster會處理 HRegion 的分配或轉移。如果我們HRegion的數據量太大的話,HMaster會對拆分后的Region重新分配RegionServer。(如果發現失效的HRegion,也會將失效的HRegion分配到正常的HRegionServer中)

HMaster會處理元數據的變更和監控RegionServer的狀態。

四、RowKey的設計

到這裏,我們已經知道RowKey是什麼了。不難理解的是,我們肯定是要保證RowKey是唯一的,畢竟它是行鍵,有了它我們才可以唯一標識一條數據的。

在HBase裡邊提供了三種的查詢方式:

  1. 全局掃描
  2. 根據一個RowKey進行查詢
  3. 根據RowKey過濾的範圍查詢

4.1 根據一個RowKey查詢

首先我們要知道的是RowKey是會按字典序排序的,我們HBase表會用RowKey來橫向切分表。

無論是讀和寫我們都是用RowKey去定位到HRegion,然後找到HRegionServer。這裡有一個很關鍵的問題:那我怎麼知道這個RowKey是在這個HRegion上的

HRegion上有兩個很重要的屬性:start-keyend-key

我們在定位HRegionServer的時候,實際上就是定位我們這個RowKey在不在這個HRegion的start-keyend-key範圍之內,如果在,說明我們就找到了。

這個時候會帶來一個問題:由於我們的RowKey是以字典序排序的,如果我們對RowKey沒有做任何處理,那就有可能存在熱點數據的問題。

舉個例子,現在我們的RowKey如下:

java3y111
java3y222
java3y333
java3y444
java3y555
aaa
bbb
java3y777
java3y666
java3y...

Java3yxxx開頭的RowKey很多,而其他的RowKey很少。如果我們有多個HRegion的話,那麼存儲Java3yxxx的HRegion的數據量是最大的,而分配給其他的HRegion數量是很少的。

關鍵是我們的查詢也幾乎都是以java3yxxx的數據去查,這會導致某部分數據會集中在某台HRegionServer上存儲以及查詢,而其他的HRegionServer卻很空閑。

如果是這種情況,我們要做的是什麼?對RowKey散列就好了,那分配到HRegion的時候就比較均勻,少了熱點的問題。

HBase優化手冊:

建表申請時的預分區設置,對於經常使用HBase的小夥伴來說,HBase管理平台里申請HBase表流程必然不陌生了。

給定split的RowKey組例如:aaaaa,bbbbb,ccccc;或給定例如:startKey=00000000,endKey=xxxxxxxx,regionsNum=x

第一種方式:

是自己指定RowKey的分割點來劃分region個數.比如有一組數據RowKey為[1,2,3,4,5,6,7],此時給定split RowKey是3,6,那麼就會劃分為[1,3),[3,6),[6,7)的三個初始region了.如果對於RowKey的組成及數據分佈非常清楚的話,可以使用這種方式精確預分區.

第二種方式 :

如果只是知道RowKey的組成大致的範圍,可以選用這種方式讓集群來均衡預分區,設定始末的RowKey,以及根據數據量給定大致的region數,一般建議region數最多不要超過集群的rs節點數,過多region數不但不能增加表訪問性能,反而會增加master節點壓力.如果給定始末RowKey範圍與實際偏差較大的話,還是比較容易產生數據熱點問題.

最後:生成RowKey時,盡量進行加鹽或者哈希的處理,這樣很大程度上可以緩解數據熱點問題.

4.2根據RowKey範圍查詢

上面的情況是針對通過RowKey單個查詢的業務的,如果我們是根據RowKey範圍查詢的,那沒必要上面那樣做。

HBase將RowKey設計為字典序排序,如果不做限制,那很可能類似的RowKey存儲在同一個HRegion中。那我正好有這個場景上的業務,那我查詢的時候不是快多了嗎?在同一個HRegion就可以拿到我想要的數據了

舉個例子:我們會間隔幾秒就採集直播間熱度,將這份數據寫到HBase中,然後業務方經常要把主播的一段時間內的熱度給查詢出來。

我設計好的RowKey,將該主播的一段時間內的熱度都寫到同一個HRegion上,拉取的時候只要訪問一個HRegionServer就可以得到全部我想要的數據了,那查詢的速度就快很多。

最後

最後三歪再來帶着大家回顧一下這篇文章寫了什麼:

  1. HBase是一個NoSQL數據庫,一般我們用它來存儲海量的數據(因為它基於HDFS分佈式文件系統上構建的)
  2. HBase的一行記錄由一個RowKey和一個或多個的列以及它的值所組成。先有列族後有列,列可以隨意添加。
  3. HBase的增刪改記錄都有「版本」,默認以時間戳的方式實現。
  4. RowKey的設計如果沒有特殊的業務性,最好設計為散列的,這樣避免熱點數據分佈在同一個HRegionServer中。
  5. HBase的讀寫都經過Zookeeper去拉取meta數據,定位到對應的HRegion,然後找到HRegionServer

參考資料:

  • https://blog.csdn.net/bitcarmanlee/article/details/78979836
  • https://hbase.apache.org/book.html#arch.overview
  • https://zhuanlan.zhihu.com/p/54184168
  • 硬核乾貨長文!Hbase來了解一下不?
  • https://www.jianshu.com/p/569106a3008f
  • 趣談Hbase架構
  • https://www.cnblogs.com/BIG-BOSS-ZC/p/11807304.html
  • 一條數據的HBase之旅,簡明HBase入門教程-開篇
  • https://chenhy.com/post/hbase-quickstart/
  • https://www.cnblogs.com/zmoumou/p/10292676.html
  • https://www.cnblogs.com/duanxz/p/3154487.html
  • https://www.jianshu.com/p/4e412f48e820
  • HBase 基本入門篇
  • 什麼是列式存儲?

各類知識點總結

下面的文章都有對應的原創精美PDF,在持續更新中,可以來找我催更~

  • 92頁的Mybatis
  • 129頁的多線程
  • 141頁的Servlet
  • 158頁的JSP
  • 76頁的集合
  • 64頁的JDBC
  • 105頁的數據結構和算法
  • 142頁的Spring
  • 58頁的過濾器和監聽器
  • 30頁的HTTP
  • 42頁的SpringMVC
  • Hibernate
  • AJAX
  • Redis
  • ……

涵蓋Java後端所有知識點的開源項目(已有8K+ star):

  • GitHub
  • Gitee訪問更快

給三歪點個贊,對三歪真的非常重要!

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

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

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

震驚!Windows Service服務和定時任務框架quartz之間原來是這種關係……_網頁設計

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

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

過場CG:   接到公司領導的文件指示,“小熊”需要在6月底去海外執行一個行動代號為【定時任務】的營救計劃,這個計劃關係到公司某個項目的生死(數據安全漏洞),作戰部擬定兩個作戰方案:   方案一:使用務定時任務框架quartz;   方案二:使用windows Service服務。   最終的作戰方案為:兩者配套使用。

 
前言:項目開發完成后,對接的項目有很多個模塊,由於其中的一個環節疏忽,現在需要在原有的基礎上把缺失的數據自動寫入數據庫存儲起來。
重新修改程序邏輯已然不現實,現在需要一個補丁來進行邏輯更正。
補丁邏輯:兩個入口控制,

  • 入口一:點擊【更新】按鈕同步邏輯后的數據;
  • 入口二:每天晚上18:00進行執行同步邏輯后的數據;

 
現在我們先使用window服務進行入口二的編寫(入口一隻需要一個按鈕調用入口二的邏輯即可)
windows服務

一、開發環境

操作系統:Windows 7 X64/32

開發環境:VS2017

編程語言:C#

.NET版本:.NET Framework 4.6.1

二、創建Windows Service

1、新建一個Windows Service,並將項目名稱改為“MyWindowsService”,如下圖所示:

 

 2、在解決方案資源管理器內將Service1.cs改為MyWindowsService.cs后並在左邊頁面空白處點擊鼠標右鍵,添加安裝程序,如下圖所示:

 

添加安裝程序:

 

 

3、 此時軟件會生成兩個組件,分別為“serviceInstaller1”及“serviceProcessInstaller1”,點擊“serviceInstaller1”,右鍵—>屬性,

將ServiceName改為MyWindowsService,Description改為“我的服務”,如下圖:

 

 

 4、點擊“serviceProcessInstaller1”,在“屬性”窗體將Account改為LocalSystem(服務屬性系統級別),如下圖所示:

   
 5、點擊MyWindowsService.cs,在左邊空白位置右鍵,“查看代碼”,然後編寫代碼,代碼我編寫好了,直接拷貝即可使用  

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Linq;
using System.ServiceProcess;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace MyWindowsService
{
    public partial class MyWindowsService : ServiceBase
    {
        public MyWindowsService()
        {
            InitializeComponent();
        }

        //創建進程
        public static Thread threadStartConfirmActualTime;  //創建一個時間進程
        public static Thread threadDoCheck;                 //檢查日誌時間進程

        //開啟服務
        protected override void OnStart(string[] args)
        {
            Console.WriteLine(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + "\t服務啟動!\n");
            StartServer();
        }

        //停止服務
        protected override void OnStop()
        {
            Console.WriteLine(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + "\t服務停止!\n");
        }

        //啟動服務操作
        private void StartServer()
        {
            try
            {
                threadStartConfirmActualTime = new Thread(new ThreadStart(new SingleClass().BeginConfirmMessageTime));//在進程下面創建線程
                threadStartConfirmActualTime.Start();
                threadDoCheck.Start();
            }
            catch (Exception ex)
            {
                threadStartConfirmActualTime.Abort();//關閉線程
                Console.WriteLine(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + "\t服務停止!"+ex.Message+"\n");
            }
        }


        /// <summary>
        /// Aouth:xiongze
        /// Time:2020/06/02
        /// Details:單例模式_建立一個單例類,保證只有一個對象被實例化,然後開啟服務
        /// </summary>
        public class SingleClass  //單例模式_建立一個單例類,保證只有一個對象被實例化
        {
            public static SingleClass _SingleClass;
            public static object onlock = new object();  //實例化一個鎖

            public static SingleClass Singleton
            {
                get
                {
                    if (_SingleClass == null)
                    {
                        lock (onlock)
                        {
                            _SingleClass = new SingleClass();
                        }
                    }
                    return _SingleClass;
                }
            }
            public void BeginConfirmMessageTime()  //開啟服務
            {
                while (true)
                {
                    //每天晚上18這一個小時內檢測執行
                    if (DateTime.Now.Hour.ToString("18") == "18")
                    {
                        try
                        {
                            //同步數據
                            Console.WriteLine(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + "我在"+ DateTime.Now + "同步了數據哦!\n");
                        }
                        catch (Exception ex)
                        {
                            //記錄錯誤日誌(記錄到相應的文件下面)
                            Console.WriteLine(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + "\t我是錯誤日誌!" + ex.Message + "\n");
                        }
                    }
                    Thread.Sleep(1800000);  //半個小時執行一次,注意,1000毫秒=1秒,具體需要多少時間可以自由換算 1800000半小時
                }

            }
        }

    }
}

 
6、至此,Windows服務已經創建完畢。  
 三、創建安裝、啟動、停止、卸載服務的Windows窗體  
1、點擊項目,右鍵,重新生成
在桌面上創建一個文件夾,命名為“我的服務”,將MyWindowsService項目項目生成的bin文件夾Debug文件夾的內容全部複製到新建的文件夾裏面;
然後去百度拷貝三個文件到“我的服務”文件裏面,分別為Install.bat(安裝)、UnInstall.bat(卸載)、InstallUtil.exe(執行),
打開文件,分別打開Install.bat和UnInstall.bat文件,將後面一個xxx.exe修改為你的文件程序,我們的是MyWindowsService.exe。如下圖

 

 

 

 

操作完后雙擊Install.bat進行安裝windows服務,安裝成功後點擊【計算機】–>右鍵–>管理–>服務裏面找到“我的服務”,啟動服務並修改為自動啟動;如下圖:  

 

 

 

 

 這樣就實現了windows服務入口二每天晚上18:00進行執行同步邏輯后的數據,只要代碼不報錯就一直執行;  
優點:每天指定時間自動執行指定邏輯
缺點:程序在每次設置的時間內無限執行,消耗資源(CPU等)    
 quartz定時任務  

一、開發環境

操作系統:Windows 7 X64

開發環境:VS2017

編程語言:C#

.NET版本:.NET Framework 4.6.1

二、創建quartz定時任務
1、創建一個控制台任務程序進行演示,命名為MyQuartz,創建如下:  

 

 2、引入quartz框架動態鏈接庫

在NuGet管理裏面搜索quartz進行安裝,注意:
Quartz高版本的存在兼容性,建議使用低版本的(2.5.0) 如下圖:  

 

 

3、創建一個執行的類,用於執行後台數據邏輯,命名為TestJob,並且繼承Quartz框架的IJob接口,這個累的內容如下,可以直接拷貝

using Quartz;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace MyQuartz
{
    public class TestJob: IJob
    {
        public void Execute(IJobExecutionContext context)//指定調用的方法
        {
            try
            {
                //在這裏寫代碼(寫自己的業務邏輯)
                Console.WriteLine("任務執行啦" + DateTime.Now);
            }
            catch (Exception ex)
            {
                Console.WriteLine("定時任務出錯" + ex.Message);
            }
        }
    }
}

4、在Program.cs文件裏面進行調用編寫,編寫內容主要如下:

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

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

  1. 創建一個作業調度池;
  2. 創建出來一個具體的作業;
  3. 創建並配置一個觸發器;
  4. 加入作業調度池中;
  5. 開始運行。

 首先我們看完成代碼,然後進行講解(代碼可以直接拷貝):

using Quartz;
using Quartz.Impl;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace MyQuartz
{
    class Program
    {
        static void Main(string[] args)
        {
            //1.首先創建一個作業調度池
            ISchedulerFactory schedf = new StdSchedulerFactory();
            IScheduler sched = schedf.GetScheduler();
            //2.創建出來一個具體的作業
            IJobDetail job = JobBuilder.Create<TestJob>().Build();
            //3.創建並配置一個觸發器

            #region(使用SimpleTrigger觸發器,每次3秒執行一次,無上限)
            ISimpleTrigger trigger = (ISimpleTrigger)TriggerBuilder.Create().WithSimpleSchedule(x => x.WithIntervalInSeconds(3).WithRepeatCount(int.MaxValue)).Build();
            #endregion

            #region 每3秒執行一次 總共5次 ,開始執行時間設定在當前時間,結束時間我設定在2小時后,不過5次執行完沒2小時候都不再執行。
            //-------NextGivenSecondDate:如果第一個參數為null則表名當前時間往後推遲2秒的時間點。
            //DateTimeOffset startTime = DateBuilder.NextGivenSecondDate(DateTime.Now.AddSeconds(5), 2);
            //DateTimeOffset endTime = DateBuilder.NextGivenSecondDate(DateTime.Now.AddHours(2), 3);
            //ISimpleTrigger trigger = (ISimpleTrigger)TriggerBuilder.Create().StartAt(startTime).EndAt(endTime)
            //                            .WithSimpleSchedule(x => x.WithIntervalInSeconds(3).WithRepeatCount(5))
            //                            .Build();
            #endregion

            #region (使用CronTrigger觸發器)在每小時的第10,20,25,26,33,54分鐘,每分鐘的第1,10,14秒執行一次
            //DateTimeOffset startTime = DateBuilder.NextGivenSecondDate(DateTime.Now.AddSeconds(1), 2);
            //DateTimeOffset endTime = DateBuilder.NextGivenSecondDate(DateTime.Now.AddYears(2), 3);
            //ICronTrigger trigger = (ICronTrigger)TriggerBuilder.Create().StartAt(startTime).EndAt(endTime)
            //                            .WithCronSchedule("1,10,59 10,20,21,26,33,54 * * * ? ")
            //                            .Build();
            #endregion
            //4.加入作業調度池中
            sched.ScheduleJob(job, trigger);
            //5.開始運行
            sched.Start();
            Console.ReadKey();

        }
    }
}

 

在上面代碼中可以看出,我們主要使用了兩個觸發器:SimpleTrigger觸發器和CronTrigger觸發器;

SimpleTrigger觸發器(簡單觸發器SimpleTrigger)

SimpleTrigger可以滿足的調度需求是:在具體的時間點執行一次,或者在具體的時間點執行,並且以指定的間隔重複執行若干次。比如,你有一個trigger,你可以設置它在2015年1月13日的上午11:23:54準時觸發,或者在這個時間點觸發,並且每隔2秒觸發一次,一共重複5次。

根據描述,你可能已經發現了,SimpleTrigger的屬性包括:開始時間、結束時間、重複次數以及重複的間隔。這些屬性的含義與你所期望的是一致的,只是關於結束時間有一些地方需要注意。

重複次數,可以是0、正整數,以及常量SimpleTrigger.REPEAT_INDEFINITELY。重複的間隔,必須是0,或者long型的正數,表示毫秒。注意,如果重複間隔為0,trigger將會以重複次數併發執行(或者以scheduler可以處理的近似併發數)。

如果你還不熟悉DateBuilder,了解后你會發現使用它可以非常方便地構造基於開始時間(或終止時間)的調度策略。

endTime屬性的值會覆蓋設置重複次數的屬性值;比如,你可以創建一個trigger,在終止時間之前每隔10秒執行一次,你不需要去計算在開始時間和終止時間之間的重複次數,只需要設置終止時間並將重複次數設置為REPEAT_INDEFINITELY(當然,你也可以將重複次數設置為一個很大的值,並保證該值比trigger在終止時間之前實際觸發的次數要大即可)。

 

具體用法我們就不水文了,大家去看Quartz官網文檔的用法即可SimpleTrigger觸發器使用規則:https://www.w3cschool.cn/quartz_doc/quartz_doc-67a52d1f.html,部分截圖显示如下:

  • 指定時間開始觸發,不重複:
  • 指定時間觸發,每隔10秒執行一次,重複10次:
  • 5分鐘以後開始觸發,僅執行一次:
  • 立即觸發,每個5分鐘執行一次,直到22:00:
  • 建立一個觸發器,將在下一個小時的整點觸發,然後每2小時重複一次:

 

 

CronTriggerr觸發器(基於Cron表達式的觸發器CronTriggerr

CronTrigger通常比Simple Trigger更有用,如果您需要基於日曆的概念而不是按照SimpleTrigger的精確指定間隔進行重新啟動的作業啟動計劃。

使用CronTrigger,您可以指定號時間表,例如“每周五中午”或“每個工作日和上午9:30”,甚至“每周一至周五上午9:00至10點之間每5分鐘”和1月份的星期五“。

即使如此,和SimpleTrigger一樣,CronTrigger有一個startTime,它指定何時生效,以及一個(可選的)endTime,用於指定何時停止計劃。

Cron Expressions
Cron-Expressions用於配置CronTrigger的實例。Cron Expressions是由七個子表達式組成的字符串,用於描述日程表的各個細節。這些子表達式用空格分隔,並表示:

Seconds
Minutes
Hours
Day-of-Month
Month
Day-of-Week
Year (optional field)
一個完整的Cron-Expressions的例子是字符串“0 0 12?* WED“ - 這意味着”每個星期三下午12:00“。
單個子表達式可以包含範圍和/或列表。例如,可以用“MON-FRI”,“MON,WED,FRI”或甚至“MON-WED,SAT”代替前一個(例如“WED”)示例中的星期幾字段。
通配符(' '字符)可用於說明該字段的“每個”可能的值。因此,前一個例子的“月”字段中的“”字符僅僅是“每個月”。因此,“星期幾”字段中的“*”顯然意味着“每周的每一天”。
所有字段都有一組可以指定的有效值。這些值應該是相當明顯的 - 例如秒和分鐘的数字0到59,數小時的值0到23。日期可以是1-31的任何值,但是您需要注意在給定的月份中有多少天!月份可以指定為0到11之間的值,或者使用字符串JAN,FEB,MAR,APR,MAY,JUN,JUL,AUG,SEP,OCT,NOV和DEC。星期幾可以指定為1到7(1 =星期日)之間的值,或者使用字符串SUN,MON,TUE,WED,THU,FRI和SAT。
'/'字符可用於指定值的增量。例如,如果在“分鐘”字段中輸入“0/15”,則表示“每隔15分鐘,從零開始”。如果您在“分鐘”字段中使用“3/20”,則意味着“每隔20分鐘,從三分鐘開始” - 換句話說,它與“分鐘”中的“3,243,43”相同領域。請注意“ / 35”的細微之處並不代表“每35分鐘” - 這意味着“每隔35分鐘,從零開始” - 或者換句話說,與指定“0,35”相同。
'' 字符是允許的日期和星期幾字段。用於指定“無特定值”。當您需要在兩個字段中的一個字段中指定某個字符而不是另一個字段時,這很有用。請參閱下面的示例(和CronTrigger JavaDoc)以進行說明。
“L”字符允許用於月日和星期幾字段。這個角色對於“最後”來說是短暫的,但是在這兩個領域的每一個領域都有不同的含義。例如,“月”字段中的“L”表示“月的最後一天” - 1月31日,非閏年2月28日。如果在本周的某一天使用,它只是意味着“7”或“SAT”。但是如果在星期幾的領域中再次使用這個值,就意味着“最後一個月的xxx日”,例如“6L”或“FRIL”都意味着“月的最後一個星期五”。您還可以指定從該月最後一天的偏移量,例如“L-3”,這意味着日曆月份的第三個到最後一天。當使用'L'選項時,重要的是不要指定列表或值的範圍,因為您會得到混亂/意外的結果。
“W”用於指定最近給定日期的工作日(星期一至星期五)。例如,如果要將“15W”指定為月日期字段的值,則意思是:“最近的平日到當月15日”。
''用於指定本月的“第n個”XXX工作日。例如,“星期幾”字段中的“63”或“FRI#3”的值表示“本月的第三個星期五”。
以下是一些表達式及其含義的更多示例 - 您可以在JavaDoc中找到更多的org.quartz.CronExpression

Cron Expressions示例
CronTrigger示例1 - 創建一個觸發器的表達式,每5分鐘就會觸發一次
“0 0/5 * * *?”

CronTrigger示例2 - 創建觸發器的表達式,每5分鐘觸發一次,分鐘后10秒(即上午10時10分,上午10:05:10等)。
“10 0/5 * * *?”

CronTrigger示例3 - 在每個星期三和星期五的10:3011:3012:30和13:30創建觸發器的表達式。
“0 30 10-13?* WED,FRI“

CronTrigger示例4 - 創建觸發器的表達式,每個月5日和20日上午8點至10點之間每半小時觸發一次。請注意,觸發器將不會在上午10點開始,僅在8:008:309:00和9:300 0/30 8-9 5,20 *?”

請注意,一些調度要求太複雜,無法用單一觸發表示 - 例如“每上午9:00至10:00之間每5分鐘,下午1:00至晚上10點之間每20分鐘”一次。在這種情況下的解決方案是簡單地創建兩個觸發器,並註冊它們來運行相同的作業。

 

具體使用方法見CronTrigger觸發器使用規則:https://www.w3cschool.cn/quartz_doc/quartz_doc-lwuv2d2a.html

  • 建立一個觸發器,每隔一分鐘,每天上午8點至下午5點之間:
  • 建立一個觸發器,將在上午10:42每天發射:
  • 建立一個觸發器,將在星期三上午10:42在TimeZone(系統默認值)之外觸發:

 

 

 

執行演示

寫完后我們查看執行結果,我使用的是SimpleTrigger觸發器,每3秒執行一次,無上限,各位可以根據自身的項目需求更改使用不同的觸發器

 

 

注意:

如果定時任務框架quartz這個掛在iis上會被回收掉(默認是20分鐘)

Quartz高版本的存在兼容性,建議使用低版本的(2.5.0)

 

 

總結

到這裏Windows Service服務和定時任務框架quartz都簡單的介紹完了,具體使用哪一個或者配套使用就看本身項目邏輯了;

現在執行的邏輯:

Windows Service服務:程序隨電腦開機啟動,每隔半個小時執行一次,檢測到執行時間等於我設置的時間就去執行後台邏輯;

定時任務框架quartz:如果發布在iis上,默認20分鐘後會被回收(程序不能一直等待執行),程序處於休眠狀態,到指定時候后喚醒(觸發器)程序執行後台邏輯;

 

PS:如果把quartz結合windows服務使用的話就不存在被回收問題;

 

歡迎關注訂閱我的微信公眾平台【熊澤有話說】,更多好玩易學知識等你來取
作者:熊澤-學習中的苦與樂
公眾號:熊澤有話說
出處: https://www.cnblogs.com/xiongze520/p/13031944.html
創作不易,任何人或團體、機構全部轉載或者部分轉載、摘錄,請在文章明顯位置註明作者和原文鏈接。  

 

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

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

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

一文帶你了解js數據儲存及深複製(深拷貝)與淺複製(淺拷貝)_租車

※超省錢租車方案

商務出差、學生出遊、旅遊渡假、臨時用車!GO 神州租賃有限公司!合法經營、合法連鎖、合法租賃小客車!

背景

在日常開發中,偶爾會遇到需要複製對象的情況,需要進行對象的複製。

由於現在流行標題黨,所以,一文帶你了解js數據儲存及深複製(深拷貝)與淺複製(淺拷貝)

理解

首先就需要理解 js 中的數據類型了
js 數據類型包含

  1. 基礎類型:StringNumbernullundefinedBoolean以及ES6引入的Symboles10中的BigInt
  2. 引用類型:Object

由於 js 對變量的儲存是棧內存堆內存完成的。

  • 基礎類型將數據保存在棧內存
  • 引用類型將數據保存在堆內存

由於 js 在數據讀取和寫入的時候,對基礎類型是直接讀寫棧內存中的數據,引用類型是將一個內存地址保存在棧內存中,讀寫都是修改棧內存中指向堆內存的地址

以如下代碼為例

let obj = {
  a:1,
  arr:[1,3,5,7,9],
  b:2,
  c:{
    num:100
  }
}
let num = 10

在內存中的表現為

我們聲明個obj1

let obj1 = obj;
console.log(obj1 == obj);//true

因為這個賦值,把內存變成了這樣

然後,內存中只是給js棧內存新增了一個指向堆內存的地址而已,這種就叫做淺複製。因為如圖可以看到,如果我們修改obj.a的話,實際修改的是堆內存0x88888888中的變量a,由於obj1也指向這個地址,所以obj1.a也被修改了

深複製是指,不單單複製引用地址,連堆內存都複製一遍,使objobj1不指向同一個地址。

代碼

分開來看深複製淺複製

淺複製

由上述圖可知,淺複製只是複製了堆內存的引用地址,通常在業務需求中出現的淺複製是指複製引用對象的第一層,也就是,基本類型複製新值,引用類型複製引用地址

淺複製可以使用的方案有循環賦值擴展運算符object.assign(),

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

有別於一般網頁架設公司,除了模組化的架站軟體,我們的營業主軸還包含:資料庫程式開發、網站建置、網頁設計、電子商務專案開發、系統整合、APP設計建置、專業網路行銷。

let obj = {
  a:1,
  arr:[1,3,5,7,9],
  b:2,
  c:{
    num:100
  }
}
function clone1(obj){ // 使用循環賦值
  let b = {};
  for(let key in obj){
    b[key] = obj[key]
  }
  return b
}
function clone2(obj){ // 使用擴展運算符
  let b = {
    ...obj
  };
  return b
}
function clone3(obj){ // 使用object.assign()
  let b = {};
  Object.assign(b,obj)
  return b
}
let obj1 = clone1(obj);
let obj2 = clone2(obj);
let obj3 = clone3(obj);

console.log(obj1 === obj); //false 代表複製成功了
console.log(obj2 === obj); //false 代表複製成功了
console.log(obj3 === obj); //false 代表複製成功了
console.log('obj0.c.num修改前',obj.c.num); //100
console.log('obj1.c.num修改前',obj1.c.num); //100
console.log('obj2.c.num修改前',obj2.c.num); //100
console.log('obj3.c.num修改前',obj3.c.num); //100
obj0.c.num = 555;
console.log('obj0.c.num修改后',obj.c.num); //555
console.log('obj1.c.num修改后',obj1.c.num); //555
console.log('obj2.c.num修改后',obj2.c.num); //555
console.log('obj3.c.num修改后',obj3.c.num); //555

由於是淺複製,所以引用類型只是複製了內存地址,修改其中一個對象的子屬性后,引用這個地址的值都會被修改。

淺克隆圖解如下

深複製

由於淺複製只是複製第一層,為了解決引用類型的複製,需要使用深複製來完成對象的複製,基本類型複製新值,引用類型開闢新的堆內存

深複製可以使用的方案有JSON.parse(JSON.stringify(obj))循環賦值

JSON.parse(JSON.stringify(obj))

let obj = {
  a:1,
  arr:[1,3,5,7,9],
  c:{
    num:100
  },
  fn:function(){
     console.log(1)
  },
  date:new Date(),
  reg:/\.*/g
}
function clone1(obj){ // 使用JSON.parse(JSON.stringify(obj))
  return JSON.parse(JSON.stringify(obj))
}
let obj1 = clone1(obj);
console.log(obj === obj1); //false 代表複製成功了
obj.c.num = 555;

console.log(obj.c.num,obj1.c.num) // 555,100

看起來是複製成功了!!~地址也變了,修改obj,obj1的引用地址不會跟着變化。

但是我們來console一下obj以及obj1

console.log(obj)
console.log(obj1)

似乎發現了離奇的事情,只有obj.a以及obj.c正確的複製了,日期類型方法正則表達式均沒有複製成功,發生了一些奇怪的事情

循環賦值 deepClone

那麼為了解決這種事情,就需要寫一個deepClone方法來完成深複製了,參考了許多開源庫的寫法,將所有的複製項單獨拆出,方便未來對特殊類型進行擴展,也防止不同功能間的變量互相干擾

 //既然是深複製,一定要傳入一個object,再return 一個新的 Object
function deepClone(obj){
    let newObj;
    if(obj instanceof Array){ // 數組的話,要new一個數組
      newObj = []
    }else if(obj instanceof Object){  // 對象的話,要new一個對象
      newObj = {}
    }
    if(obj === null) {
      return cloneNull(obj)
    }
    if(typeof obj=='function'){
        return cloneFunction(obj)
    }
    if(typeof obj!='object') {
        return cloneOther(obj)
    }
    if(obj instanceof RegExp) {
        return cloneRegExp(obj)
    }
    if(obj instanceof Date){
        return cloneDate(obj)
    }
    if(obj instanceof Array){
        for(let index in obj){
            newObj[index] = deepClone(obj[index]); // 對數組子項進行複製
        }
    }
    if(obj instanceof Object){
        for(let key in obj){
            newObj[key] = deepClone(obj[key]); // 對對象子項進行複製
        }
    }
    return newObj;
}
function cloneNull(obj){ // 複製NULL
  return obj
}
function cloneFunction(obj){ // 複製方法,
  // 複製一個新方法,將原方法轉成字符串,並new一個新的function
  return new Function('return '+obj.toString())()
}
function cloneOther(obj){ // 複製非對象的數據
  return obj
}
function cloneRegExp(obj){ // 複製正則對象
  return new RegExp(obj)
}
function cloneDate(obj){ // 複製日期對象
  return new Date(obj)
}

這樣一個基本上滿足功能的深複製就完成了。先測試一下

let obj = {
  a:1,
  arr:[1,3,5,7,9],
  c:{
    num:100
  },
  fn:function(){
     console.log(1)
  },
  date:new Date(),
  reg:/\.*/g
}

let obj1 = deepClone(obj);
console.log(obj.c === obj1.c); // false  代表複製成功
console.log(obj.fn === obj1.fn);// false  代表複製成功 
console.log(obj.date === obj1.date);// false  代表複製成功
console.log(obj.reg === obj1.reg);// false  代表複製成功

console一下

console.log(obj)
console.log(obj1)

這樣,就完成了deepClone深複製方法

經過深複製后,圖解如下

優化 deepClone

上述代碼還有優化空間,參考了lodash庫,在進行 new 對象時,可以使用 constructor構造函數 來進行創建新的實例,這樣

  1. 可以不用判斷遞歸中,是數組還是對象
  2. 如果深複製的某一項是某個原型的實例,深複製完成后,依然是該原型的實例
function deepClone(obj){
    let newObj = new obj.constructor;
    if(obj === null) {
      return cloneNull(obj)
    }
    if(typeof obj=='function'){
        return cloneFunction(obj)
    }
    if(typeof obj!='object') {
        return cloneOther(obj)
    }
    if(obj instanceof RegExp) {
        return cloneRegExp(obj)
    }
    if(obj instanceof Date){
        return cloneDate(obj)
    }
    if(obj instanceof Array){
        for(let index in obj){
            newObj[index] = deepClone(obj[index]); // 對數組子項進行複製
        }
    }
    if(obj instanceof Object){
        for(let key in obj){
            newObj[key] = deepClone(obj[key]); // 對對象子項進行複製
        }
    }
    return newObj;
}
function cloneNull(obj){ // 複製NULL
  return obj
}
function cloneFunction(obj){ // 複製方法,
  // 複製一個新方法,將原方法轉成字符串,並new一個新的function
  return new Function('return '+obj.toString())()
}
function cloneOther(obj){ // 複製非對象的數據
  return obj
}
function cloneRegExp(obj){ // 複製正則對象
  return new RegExp(obj)
}
function cloneDate(obj){ // 複製日期對象
  return new Date(obj)
}

最終版本 deepClone

然後可以有一個合併版本的,比較節省代碼,將下方區分開的複製方法,合併到deepClone中,可以極大地減少代碼體積

function deepClone(obj){ //
    let newObj = new obj.constructor;
    if(obj === null) return obj
    if(typeof obj=='function') return new Function('return '+obj.toString())()
    if(typeof obj!='object') return obj
    if(obj instanceof RegExp) return new RegExp(obj)
    if(obj instanceof Date) return new Date(obj)
    // 運行到這裏,基本上只存在數組和對象兩種類型了
    for(let index in obj){
        newObj[index] = deepClone(obj[index]); // 對子項進行遞歸複製
    }
    return newObj;
}

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

※Google地圖已可更新顯示潭子電動車充電站設置地點!!

日本、大陸,發現這些先進的國家已經早就讓電動車優先上路,而且先進國家空氣品質相當好,電動車節能減碳可以減少空污

月收入5000也能買車 經濟實惠的家用車買這些夠用了!_如何寫文案

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

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

內飾是長安家族式的設計,風格更加年輕時尚,雙炮台式的儀錶盤非常經典,無鑰匙進入/啟動、ESp、上坡輔助、倒車影像等配置應有盡有。逸動的軸距達到2660mm,空間上面令人滿意,較寬的車身寬度也很好的提升了乘坐舒適性。

一汽奔騰-奔騰B30

指導價:6.98-9.28萬

奔騰B30的誕生無非就是為了細分市場的興起,是一款定位緊湊型車的入門級產品,前兩設計非常的個性誇張,偏向於年輕運動化的設計風格,飄逸的腰線很有特點;內飾看起來很規整,實用為主,沒有太多花哨的地方,胎壓監測、上坡輔助、定速巡航、倒車影像等配置比較齊全;2630mm軸距帶來的空間感受還是蠻寬敞的,儲物空間設計也比較到位,中控台底部空間和杯架深度合理,滿足家用需求;1.6L發動機技術成熟,最大功率109馬力,搭配5擋手動或者6擋手自一體變速箱,日常駕駛很順暢,

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

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

底盤整體感強。

優惠:購置稅全免,尊享1年0零利率分期禮遇,尊享置換補貼3000元

長安汽車-逸動

指導價:8.09-24.99萬

無可否認,長安造車非常符合國人的審美要求,逸動外觀沒有過多花哨的地方,整車線條流暢優雅,門把手與其腰線有機的融合成一體,簡潔耐看,5幅式雙色輪圈視覺效果不錯;內飾是長安家族式的設計,風格更加年輕時尚,雙炮台式的儀錶盤非常經典,無鑰匙進入/啟動、ESp、上坡輔助、倒車影像等配置應有盡有;逸動的軸距達到2660mm,空間上面令人滿意,較寬的車身寬度也很好的提升了乘坐舒適性;動力系統上採用了有缸內直噴技術的1.6L發動機,最大功率128馬力,搭配5擋手動變速箱,在頭段和中段加速時動力很充足,在市區行駛來說游刃有餘,是一輛質優價廉的好車。

優惠:現金優惠5千元左右,享購置稅減半政策優本站聲明:網站內容來源於http://www.auto6s.com/,如有侵權,請聯繫我們,我們將及時處理

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

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

我把勞斯萊斯開到冒煙!怎麼辦?_網頁設計公司

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

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

5,中控面板的花紋則是碳纖維鋁絲材質編製而成的,強調運動的同時卻不乏典雅。動力方面,搭載6。6L雙渦輪增壓V12發動機,最大輸出功率624馬力,峰值扭矩870牛·米,較普通版本提升了70牛。米。與之匹配的則是8速自動變速箱,儘管這是一輛更強調運動的勞斯萊斯,撥片換擋也並沒有出現,負責人表示那些東西不夠“勞斯萊斯”。

勞斯萊斯品牌自誕生之初就是為了打造世界上最奢華的汽車。所以以往我們談起勞斯萊斯,首先聯想到的就是車主肯定是一個超有錢的老頭。

可能連勞斯萊斯他們自己人也發現了這個問題,隨着全球巨富的平均年齡越來越低,勞斯萊斯於2013年正式發布魅影車型。

其英文名稱Wraith則是來自於曾經的勞斯萊斯經典車型Silver Wraith。一款定位於豪華GT型跑車的勞斯萊斯,其目標就是更年輕的消費人群。

而此次我們體驗的則是魅影的Black Badge 特別版本。

Black Badge是勞斯萊斯誕生112年以來,首次將雙R字母LOGO採用黑底色搭配銀色字體的反色設計。

車頭的“歡慶女神”在設計、材質和姿態都沒有轉變的前提下,Black Badge車型採用高光澤度的特別黑色材質,讓“歡慶女神”搖身一變化身為黑夜的“魅惑女郎”,徜徉在夜晚迷人的都市之中。

此外,進氣格柵外框、下進氣口裝飾條、後備箱把手、排氣管等原本使用的高光鍍鉻材質也被更具神秘格調的黑色材質所取代。

以複合碳纖維材質和輕質鋁材結合的新型輪轂,通過輪輞外邊緣的疊層設計,從而達到44片碳纖維式的超高強度,大大減輕了懸挂的簧下質量,保證極佳的觀感同時還擁有更加卓越的性能。

內飾採用了黑色與藍色搭配的內飾設計,顯得十分大膽張揚,

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

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

歡慶女神按鈕經過特殊處理后,始終不會染上指紋,星空車頂讓你忘了什麼是pM2.5,中控面板的花紋則是碳纖維鋁絲材質編製而成的,強調運動的同時卻不乏典雅。

動力方面,搭載6.6L雙渦輪增壓V12發動機,最大輸出功率624馬力,峰值扭矩870牛·米,較普通版本提升了70牛.米 。與之匹配的則是8速自動變速箱,儘管這是一輛更強調運動的勞斯萊斯,撥片換擋也並沒有出現,負責人表示那些東西不夠“勞斯萊斯”。

本以為勞斯萊斯的體驗活動會是在某個高端會所之類的,意想不到的是來到了賽道。低速行駛的時候安靜得像溜車,但你踩下地板油的時候,車頭裡的V12引擎傳來了美妙的引擎聲,一瞬間會讓你忘記了你是在一輛勞斯萊斯裏面。

最為令人稱道的則是那套勞斯萊斯稱為“魔毯”的懸挂系統,感覺就像是你坐在一塊巨大的黃油上被推着走,在保證如此強大的運動特性的同時還能保持如此舒適的感受,讓你不得不深深的佩服。

整個體驗過程結束後會讓你知道,勞斯萊斯的追求不僅限於精湛的手工工藝和對奢華的見解。在人工如此高昂的歐洲,每一個按鍵,每一針縫線,每一塊皮革,每一顆螺絲,都由是手工親自完成。

Black Badge的面世也表明了他們從未放棄過對激越速度、完美工程設計與舒適駕駛體驗的不懈追求,進一步挖掘和展現了其更為神秘、個性的一面。或許這對於勞斯萊斯說是一個變革的開始。

本站聲明:網站內容來源於http://www.auto6s.com/,如有侵權,請聯繫我們,我們將及時處理

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

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

奇瑞瑞虎新成員!6.39萬起居然有10幾萬SUV的高配置_網頁設計

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

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

而手動擋和自動擋的中高配車型配置則“好看”不少,除了常說的ESp,剎車輔助之外,還配備有上坡輔助,真皮方向盤中控彩色大屏等等,無論是安全性還是舒適性的配置都多了不少,中配車型相比低配車型只是相差4000的價格。

源於小型SUV市場的火爆,奇瑞在不久之前重磅推出瑞虎7之後,在這個月的廣州車上也將會推出一款小型SUV—瑞虎3X,預售價:6.39-7.99萬。這是奇瑞2.0戰略下第二款SUV車型。其實剛看到名字時,會以為這是不是瑞虎3的加大版本,但了解過後發現,並非如此,瑞虎3X是一輛全新車型。

外觀:形似瑞虎3,但更年輕

看命名多多少少就知道和瑞虎3有些關聯,從正臉看過去的,整體的造型設計和瑞虎3很相似,只是一些部位的造型不一樣,例如,前大燈,霧燈等等,並且瑞虎3X添加一些硬朗的元素設計,視覺上會比瑞虎3更動感和更硬朗一些。

側面,瑞虎3X比瑞虎3更有運動感,也就是顯得更加年輕,除了車身線條的不同之外,車頂尾部的小鴨尾設計,也是呈現年輕化的流行設計元素之一。尾部的造型有點類似瑞虎7,橫穿尾燈和LOGO的鍍鉻裝飾條算是特色之一,不過,個人是覺得缺了點什麼東西,有點空。不過,蘿蔔青菜各有所愛。

內飾:主打年輕

整體造型布局和瑞虎3大致相同,但視覺上的質感較好,並且在配色和材質上選擇,讓瑞虎3X的車內氣氛更加年輕。對於這個價位車型,大面積的硬塑材質並不意外,先不說觸感,至少視覺上不錯的,特別是中控面板下半部分的碳纖維紋理,讓其看上去不那麼單調,也稍微增加了一些檔次。

儀錶盤並不是傳統的圓形設計,而是類似瑞虎7的另類設計,算是特點之一,中間是行車電腦显示屏。

配置:一如既往的豐富

瑞虎3X的手動擋和自動擋車型都分別有三個車型選擇。手動擋和自動擋的低配車型配置較低,沒有裝配ESp,剎車輔助,牽引力控制,

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

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

舒適性上的配置也比較尷尬。而手動擋和自動擋的中高配車型配置則“好看”不少,除了常說的ESp,剎車輔助之外,還配備有上坡輔助,真皮方向盤中控彩色大屏等等,無論是安全性還是舒適性的配置都多了不少,中配車型相比低配車型只是相差4000的價格。不過有一點奇怪的是,低配配置有配胎壓監測,反而中配沒有,需要選裝。

而高配車型同樣是比中配車型差了4000的差價,多了胎壓監測,電動天窗,后視鏡加熱。總的來說,車型與車型之間差價和多出配置對比起來,還是比較厚道的,要說性價比的話,推薦中配車型。

空間:中等水平

瑞虎3X的車身尺寸為:4200*1760*1570mm,軸距:2555mm,相比瑞虎3,瑞虎3X要短一些,高度上因為造型問題也稍微低一些,相比其他競爭對手,例如,紳寶X25,瑞豐S3等,並沒什麼優勢。由此可知,瑞虎3X的車內空間並不會有太多驚喜了,前後排對於180cm以上的來說會稍微感到壓抑,180cm以下稍微好一些,但並不算寬裕,整體車內空間表現一般。

動力匹配

瑞虎3X搭載了1.5L自然吸氣發動機,最大功率輸出為106馬力,最大扭矩135牛米,匹配5擋手動以及4擋自動。由於瑞虎3搭載是1.6L的發動機,瑞虎3X的1.5L發動機算是“新貨”。至於詳細的動力輸出如何,有待後續評測。

總結:正所謂“兄弟多好打架”,瑞虎3面對越來越多年輕化的小型SUV,實在有些乏力,而瑞虎3X的推出,可以和瑞虎3分化一下小型市場,主打年輕市場,填補了奇瑞這個級別的年輕市場空缺。瑞虎3X整體設計很動感,很時尚,也很符合現代年輕人的審美,並且在這樣的價位能買到這些配置,也是比較值的。至於擔心動力的話,個人覺得,作為一輛代步車,日常使用而言,還是夠用的。本站聲明:網站內容來源於http://www.auto6s.com/,如有侵權,請聯繫我們,我們將及時處理

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

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

“操控之王”大7座SUV國產後要死磕漢蘭達?_租車

※Google地圖已可更新顯示潭子電動車充電站設置地點!!

日本、大陸,發現這些先進的國家已經早就讓電動車優先上路,而且先進國家空氣品質相當好,電動車節能減碳可以減少空污

5T渦輪增壓發動機,最大馬力253匹、峰值扭矩高達420牛米。傳動系統搭載的是一款六速手自一體變速箱。CX-9是馬自達率先針對北美市場研發的7座SUV車型,所以在北美已經率先上市,據悉售價為31000美金,約合人民幣20萬元左右,隨着全球性的SUV熱潮不斷升溫,作為汽車消費大國的中國,不出意外也會分到一杯羹。

眾所周知馬自達旗下的車型幾乎都以優秀的操控性見長,旗下昂克賽拉、阿特茲兩台轎車在同級橫比當中操控性都是非常出眾的典型,而今年所推出的轎跑型SUV——CX-4更是將SUV的操控性提高了一個層次。而根據有關消息,今年早些時候在北美率先上市的全新一代馬自達7座SUV CX-9,將在明年正式由一汽馬自達進行國產。

馬自達近年來的“魂動”設計理念已經深入人心,無論是昂克賽拉、阿特茲、還是CX-4,在很多人眼裡都是“騷的無與倫比”。

全新一代馬自達CX-9依然延續了“魂動”的設計,從已經曝光的圖片我們可以看到,CX-9的外觀將家族化的靈動感進行了一定程度上的柔化,讓視覺侵略性極強的外觀效果和SUV的威武感融合得比較恰當。

全新CX-9採用了七座的作為布局,軸距達到了2930mm,小編猜測不出意外的話,

※超省錢租車方案

商務出差、學生出遊、旅遊渡假、臨時用車!GO 神州租賃有限公司!合法經營、合法連鎖、合法租賃小客車!

國產後的馬自達CX-9軸距會將進一步加長,預計屆時國產後的CX-9車內乘坐空間會更加充裕。

值得注意的是,隨着國際大流下的渦輪增壓發動機大肆普及,在豐田、本田這兩個日系品牌紛紛推出渦輪增壓車型,在動力系統方面頗有一套造詣的馬自達也坐不住了。全新馬自達CX-9搭載了一款創馳藍天的2.5T渦輪增壓發動機,最大馬力253匹、峰值扭矩高達420牛米。傳動系統搭載的是一款六速手自一體變速箱。

CX-9是馬自達率先針對北美市場研發的7座SUV車型,所以在北美已經率先上市,據悉售價為31000美金,約合人民幣20萬元左右,隨着全球性的SUV熱潮不斷升溫,作為汽車消費大國的中國,不出意外也會分到一杯羹。

全文總結:根據小編的猜測,作為馬自達旗下定位高端化的SUV車型,進入國產以後售價應該會向現在的漢蘭達和福特銳界看齊,而2.5T的馬自達CX-9將會是以頂配車型進行銷售,較低的配置應該還會搭載現在阿特茲的2.0L自然吸氣發動機,而2.5L的自然吸氣發動機或許將不會在CX-9車型中搭載。

由於目前官方對於CX-9國產的消息透露的不多,具體投產和上市時間暫時不得而知,作為一款較為值得關注的7座SUV車型,我們也會持續對其保持高度關注並進行消息更新。本站聲明:網站內容來源於http://www.auto6s.com/,如有侵權,請聯繫我們,我們將及時處理

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

有別於一般網頁架設公司,除了模組化的架站軟體,我們的營業主軸還包含:資料庫程式開發、網站建置、網頁設計、電子商務專案開發、系統整合、APP設計建置、專業網路行銷。

哥倫比亞砍伐森林 面積相當一個聖保羅_如何寫文案

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

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

摘錄自2020年7月10日中央廣播電台報導

根據9日公佈的官方報告指出,哥倫比亞2019年砍伐了15萬9千公頃的森林,面積相當於巴西大城聖保羅(Sao Paulo)。儘管如此,相較於2018年遭砍伐的19萬7千公頃,這代表在森林砍伐上減少了19%,而2017年的砍伐面積更高達21萬9千公頃。

哥倫比亞環境與永續發展副部長賈西亞(Maria Claudia Garcia)表示,「我們已設法控制森林砍伐的上升趨勢。」「這項結果顯示大有可為,但這並不是一個勝利的訊息。」

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

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

約有62%的森林砍伐發生在「地球之肺」亞馬遜(Amazon)雨林。造成森林損失的主因在於農田增加、非法砍伐原木、開礦、以及毒品農場。根據聯合國2019年的估算,毒品種植面積達到15萬4千公頃。

生物多樣性
國際新聞
哥倫比亞
亞馬遜
森林砍伐
森林

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

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

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