狀態機模式 與 ajax 的結合運用

太神奇了,昨晚做了個夢,夢中我悟出一個道理:凡是涉及到異步操作而且需要返回值的函數,一定要封裝成 Promise 的形式,假如返回值取決於多個異步操作的結果,那麼需要對每個異步操作進行狀態的設計,而且需要封裝一個 next 函數。,到了晚上才覺到很有意思,所以結合 ajax 設置最短返回時間和最大返回時間進行實踐:

  const PENDING = 'PENDING'
  const RESOLVED = 'RESOLVED'
  const REJECTED = 'REJECTED'
  const FULLFILLED = 'FULLFILLED'

  /**
   * @desc 異步操作模擬
   * @param time 響應時間
   * @param isError 是否拋錯
   */
  const mock = (time, isError) => {
    return new Promise((resolve, reject) => {
      setTimeout(() => {
        if (!isError) {
          resolve({ user: 'ManbaX' })
        } else {
          reject('request error')
        }
      }, time)
    })
  }

  /**
   * @desc 生產不同類型請求的工廠函數
   * @param time 響應時間
   * @param isError 是否拋錯
   */
  var RequestFactory = function (time, isError) {
    var request = function () {
      return new Promise((resolve, reject) => {
        var min = PENDING
        var max = PENDING
        var state = PENDING
        var res = null

        var next = function (name) {
          const cb = function () {
            if (state === RESOLVED) {
              resolve(res)
            } else {
              reject(res)
            }
          }
          if (name === 'res' && min === FULLFILLED) {
            cb()
          }

          if (name === 'min' && (state === RESOLVED || state === REJECTED)) {
            cb()
          }

          if (name === 'max' && state === PENDING) {
            reject('timeout')
          }
        }

        setTimeout(() => {
          min = FULLFILLED
          next('min')
        }, 500)

        setTimeout(() => {
          max = FULLFILLED
          next('max')
        }, 1000)

        mock(time, isError).then(data => {
          res = data
          state = RESOLVED
          next('res')
        }).catch(error => {
          res = error
          state = REJECTED
          next('res')
        })
      })
    }

    return request
  }

  // 不超時, 不返回錯誤
  console.time('r1')
  RequestFactory(200)().then(res => {
    console.log('data: ', res)
  }).finally(() => {
    console.timeEnd('r1')
  })
  
  // 不超時, 返回錯誤
  console.time('r2')
  RequestFactory(200, true)().catch(err => {
    console.log('error', err)
  }).finally(() => {
    console.timeEnd('r2')
  })

  // 超時
  console.time('r3')
  RequestFactory(2000)().catch(res => {
    console.log('error: ', res)
  }).finally(() => {
    console.timeEnd('r3')
  })

上面的運行結果符合預期,本來夢中還有另外一個有意思的東西,但是太模糊了就搞忘記了,下次一定早點記錄。

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

【其他文章推薦】

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

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

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

※幫你省時又省力,新北清潔一流服務好口碑

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

四川綿陽2020年產15萬輛新能源車 總產值達5059億

中國四川省綿陽市政府常務會議審議並原則通過了《綿陽市新能源汽車產業發展規劃(2015—2020年)》。規劃提出欲在綿陽科技城集中發展區建設集新能源汽車核心技術研發、核心零件生產製造、整車製造與體驗、國家級專業孵化器、中國國家級工程技術實驗與檢測中心為一體的國家新能源汽車研究與產業發展基地。到2020年,實現年產15萬輛新能源汽車的產能,新能源汽車及關鍵零部件產業總產值1000億元人民幣(折合新台幣約5059億元)。   綿陽新能源汽車產業已擁有川汽、華晨汽車南方基地、中國重汽綿陽分公司等整車製造企業,還擁有長虹、安縣英志鋰電池等一批新能源汽車零配件企業。規劃提出,綿陽要「全域規劃」,加快新能源汽車在公共交通、公務、出租等領域的示範應用,政府採購的特種車輛也要優先選擇新能源汽車;大力發展農用低速電動車,不斷擴大新能源汽車應用範圍。

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

【【其他文章推薦】

※帶您來了解什麼是 USB CONNECTOR  ?

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

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

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

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

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

LG Chem 開發新技術 電動車充電後可行駛 500 公里

電動車續航力有望加倍,南韓電池巨擘 LG Chem 宣布開發出新技術,電動車充電一次可行駛 400 至 500 公里,預計不久後就能量產。   韓國先驅報(Korea Herald)1 日報導,目前一般電動車充電後僅能行駛不到 200 公里。LG Chem 副會長兼執行長朴鎮洙表示,已研發出新技術,電動車行駛里程能增至 400至 500 公里。他說,產品不久就能投產,但拒絕透露更多細節。   LG Chem 砸錢投入開發,宣稱 2018 年研發費用將由當前的 6,000 億韓圜,提高到 9,000 億韓圜;未來 3 年研發人員也將增至 4,100 人。  

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

【其他文章推薦】

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

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

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

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

※新北清潔公司,居家、辦公、裝潢細清專業服務

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

福特攜兩款新智慧電動車 亮相MWC2015

在巴賽隆納舉辦的2015世界移動通信大會上,福特汽車公司宣佈了「智慧騎行」的試驗專案,首推智慧電動車,這也是一項通過在車載連接技術、移動出行、自動駕駛汽車、消費者體驗以及大資料方面的創新,説明改變世界出行方式的計畫。   首推的倆款智能電動車為MoDe:Pro與MoDe:Me。MoDe:Pro由福特團隊打造完成,用於商業用途。MoDe:Me在自行車製造商Dahon的協助下打造完成,便於摺疊存放。    

(圖片來源:騰訊)

    這兩款電動自行車都配備了200瓦的馬達和9安培小時的電池,提供電動踏板輔助,最高時速可達2萬5千公尺。原型電動自行車的技術可實現行車預警系統,在汽車超車時,透過車把手的震動向騎士們發出警告,還可通過開啟把手上的警示燈,提醒汽車司機注意電動自行車的存在。   MoDe:Me和MoDe:Pro可與一款名為MoDe:Link的原型應用程式配合使用,此款應用程式可與iPhone 6手機相容。通過應用程式中的即時資訊,電動自行車可實現導航、線路選擇、速度和舒適度調整等功能。

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

【其他文章推薦】

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

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

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

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

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

※超省錢租車方案

e-bike 新北正式上路 持悠遊卡就能租借

e-bike 電動自行車正式在新北市上路!台灣城市動力公司從 2014 年開始設立租借站,經過 3 個多月試營運期,近日 7 個站點陸續正式上路,目前板橋有 3 站、鶯歌 2 站、蘆洲及中和各 1 站,租借人次已逾 7,000 人次。   e-bike 為公共電動二輪車租借系統,車內附有鋰電池,可透過電池交換站系統,隨時取得電能,最大速率為 25 公里,行駛里程也為 25 公里,民眾只要持有悠遊卡就能租賃,前 30 分鐘費率為 1 元,之後每 15 分鐘 15 元。   全台第 1 站 2 月 14 日在鶯歌正式營運,至今租借次數已達 2,000 人次,但仍有部分民眾不清楚 e-bike 為何物,看到一排電動自行車停靠在老街口,還誤以為是廠商在賣車。

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

【其他文章推薦】

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

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

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

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

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

兩會進行時:關於新能源汽車的提案,都有什麼?

  3月3日,來自汽車行業的人大代表和政協委員再次聚首北京,為當今的汽車產業建言獻策,而新能源汽車仍將是2015年全國“兩會”汽車界熱議的焦點,政協委員和人大代表等也紛紛為新能源汽車的發展建言獻策。  
柳崇禧:加大基礎設施補貼力度 推動新能源車發展   全國政協委員、中國汽車工業工程公司副總經理柳崇禧帶來了《關於加大充換電基礎設施建設,推動新能源汽車市場應用的提案》。   針對電動汽車的發展受動力電池技術制約,充電設施網路不完善、充電不方便等問題,柳崇禧委員建議,加大充換電基礎設施建設,包括支援國家電網、南方電網等傳統電力供應央企加大充換電基礎設施建設,鼓勵中石化、中石油等傳統汽車能源供應央企參與充換電基礎設施建設。同時,還應鼓勵民營資本進入基礎設施建設,制定法規保障其權益,加大充換電基礎設施建設財政補貼力度,減免稅收。  
李書福:電動汽車不一定環保 呼籲放開汽車限購   全國政協委員、吉利集團董事長李書福共帶來”關於推動計程車體制改革”和”加強資訊化技術下經營交易稅收管理”兩個提案,就推進和深化計程車體制改革提出建議:關鍵要打破計程車牌照的壟斷式管理;建議根據不同城市規模,設立相應計程車體制改革試點城市,對各項改革措施,進行分類指導、科學評估。   另外李書福在接受採訪時呼籲放開汽車限購。他認為,目前某些地方實行的限購政策只是權宜之計。李書福表示,吉利今年會發力新能源汽車。但他認為電動汽車也不一定有利於環境,因為發電要耗費大量的非清潔能源。  
景柱:五大因素致使新能源汽車推廣艱難   全國人大代表、海馬集團董事長景柱認為,電動汽車商業化推廣存在五大癥結:一是以電池為靈魂的四大技術障礙,即功率密度、轉化效率、充電時間、系統安全。二是難以克服的兩大社會障礙:使用習慣、使用環境。三是非規模生產造成的高成本、高故障。四是以高成本為前提的兩大市場因素:特定環境和特定用戶。五是政策導向的四個誤區。   景柱認為,目前我國發展新能源汽車的最佳路徑,是汽車輕量化、節能減排和新能源技術齊頭並進。首先經過深混和插混技術,最終過渡到電動汽車或燃料電池汽車。  
鐘發平:建議國家大力發展混合動力汽車減少汽車污染   全國人大代表、科力遠董事長鐘發平建議國家通過大力發展混合動力汽車來減少汽車尾氣污染,解決當下的霧霾問題。鐘發平認為,相較動力鋰電池,鎳氫動力電池雖然能量密度不如,卻足夠穩定和安全。  
劉義發:小型電動車應成為國民車 實行分類管理   全國人大代表、山東時風集團董事長劉義發建議,綜合小型電動車的種種優勢,順應市場趨勢,將小型電動車作為“國民車”,實行分類管理,引導和規範行業科學發展。  
張天任:建議對微型電動車適當放開政策   全國人大代表、天能集團董事長張天任:建議國家對微型電動車適當放開政策,實行“產品准入從嚴,企業准入從寬”的管理原則,鼓勵和支援多種電池路線、不同電池搭配的新能源電動汽車相容發展,並針對微型電動車建立起科學的技術標準體系。他建議國家將微型電動車納入我國道路交通規劃之中,列入法定交通工具,允許符合標準的微型電動車上牌上路。  
王麒:推廣新能源汽車是治霾重要途徑之一   全國人大代表、啟陽(成都)投資管理有限公司董事長王麒認為推廣新能源汽車是汽車行業對治理霧霾做出貢獻的重要途徑之一,新能源汽車的使用推廣環節應當與生產研發的進度相匹配,要加快新能源汽車的推廣力度,完善新能源汽車相關配套設施建設。  
民進中央:可在有條件的省份率先開展低速電動車試點   民進中央提案呼籲,工信部、發改委和公安部應儘快出臺行業准入辦法,對具有汽車生產資質、產品通過檢測的低速電動車企業實行准入管理。建議將低速電動汽車和燃油汽車、新能源汽車進行分類管理。針對低速電動汽車制定一套嚴格的管理辦法,包括車輛生產、檢測、保險、上路管理等多個環節。在道路資源和安全可控範圍內,將低速電動車納入現行的道路交通管理體系,除高速公路和限行道路外,所有鄉村公路和城鎮的部分道路應向低速電動汽車開放。車輛可採用專用明顯標誌的車牌便於識別,駕照可考慮使用C4/C5駕照。   同時,民進中央提案建議,在有條件的省份率先開展低速電動車試點工作,探索一種以市場需求為拉動,政府不投資和補貼,技術路線由低到高、先易後難、自主研發,在發展中規範、在規範中提高的發展模式。  
全國工商聯:建議儘快廢除計程車專營制度   全國工商聯向大會遞交提案,建議儘快廢除計程車專營制度,讓計程車行業回歸市場經濟的軌道。政府應明確職責定位,徹底斬斷與行業之間的利益關聯,從行業中完全退場。此外,計程車市場應對社會開放,破除“數量管制”、建立“品質管制”體系。  
丁金宏:國家應出臺統一的城市限車標準   全國政協委員、人口學家丁金宏教授此次帶來了“限制大城市汽車消費”的提案,建議國家出臺統一標準,“城市規模達到多大,汽車擁有量達到多高時,就採取不同的措施,包括限購、重點區域限行、擁擠收費等,綜合採取多項措施,而不是多個城市單獨去做。”他說,限車如果僅僅從消費者權利和汽車發展利益出發,不能保證城市健康發展。  
施傑:應嚴管佔用應急車道 加大處罰   全國政協委員、國浩律師(成都)事務所律師施傑在提案中建議,對違反交規的駕駛行為,除了加大處罰力度以外,還應搭建一個公共監督平臺,讓公眾在履行自己監督義務時有暢道的管道。   施傑認為,對佔用應急車道行為除了加大罰款、扣分力度以外,同時還可實行“責任形式多元化”,用法律的“籠子”把佔用高速應急車道的行為給牢牢關住。 他認為,相關交通管理部門可以通過公眾微信帳號、微博平臺,收集公眾提供的照片、錄影等證據,一經核實便納入交管系統。對違規車輛進行處罰。同時對舉報者給予一定獎勵,當然,若發生虛報謊報情形也會加以懲處。讓公眾成為“移動電子眼”,以便做到無縫監督。  
宗慶後:建議儘快取消汽車限購限行   全國人大代表、娃哈哈集團董事長宗慶後:建議取消限購限行,加強對尾氣排放的檢測監管和交通基礎設施改善,從而減輕汽車帶來的環境壓力和交通壓力。   在宗慶後看來,現在限行限購都存在不合理的地方。“有些地方想用限購限行解決堵車問題、空氣污染問題,但限了購也限了行,路依舊在堵,空氣依舊污染,只是給老百姓造成了一些困惑而已。”他指出,目前汽車尾氣排放存在三個問題,一個是汽油的品質問題;二是噴油嘴的問題,噴油嘴不好不能噴得很均勻,不能充分燃燒,尾氣就大了;三是尾氣過濾問題。  
蔡繼明:計程車行業可試點放開平等競爭   全國人大代表、清華大學政治經濟學研究中心主任蔡繼明指出,專車和計程車一樣是平等競爭,而打破計程車行業壟斷的改革,需要改變現行法規,至少應試點在某個區域、一定時間內暫時停止執行相關法律檔。  
王鳳英:應加強交通綜合治理法制建設   全國人大代表、長城汽車總裁王鳳英提出要加強城市交通綜合治理法制建設。她建議站在國家法律、制度層面進行具有前瞻性的頂層設計,建立健全具有中國特色的、符合國情的相關法律和配套制度體系,保障各項交通治理政策措施的推出有法可依、有法必依;並在符合法律框架的前提下,積極採用最新的資訊技術、智慧交通等科技手段,對城市發展規劃、道路路網建設、市政交通管理等進行系統性創新管理,從而全面、高效地從根本上解決城市交通擁堵難題。     文章來源:第一電動網

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

【其他文章推薦】

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

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

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

※南投搬家公司費用需注意的眉眉角角,別等搬了再說!

※新北清潔公司,居家、辦公、裝潢細清專業服務

法國將提高純電動車補貼 增至一萬歐元

據京華時報報導,法國政府正在醞釀進一步提高電動汽車的購買補貼,計畫將純電動汽車的補貼從6300歐元增加到1萬歐元,插電式混合動力車的購買補貼從4000歐元增加到6500歐元。   如果消費者家中有開了13年或者時間更長的柴油車,還可以舊換新,在所有補貼的基礎上再額外獲得3700歐元或者2500歐元的獎勵。而依然購買新柴油車(歐6車輛排放低於110克/CO)的消費者,只能獲得500歐元的獎勵。目前相關補貼方案正在制定中,並有望於今年4月1日起實行。

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

【其他文章推薦】

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

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

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

※幫你省時又省力,新北清潔一流服務好口碑

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

解惑3:時間頻度,算法時間複雜度

一、概述

先放百科上的說法:

算法的時間複雜度(Time complexity)是一個函數,它定性描述該算法的運行時間。這是一個代表算法輸入值的字符串的長度的函數。

時間複雜度常用大O符號表述,不包括這個函數的低階項和首項係數。使用這種方式時,時間複雜度可被稱為是漸近的,亦即考察輸入值大小趨近無窮時的情況。

例如,如果一個算法對於任何大小為 n (必須比 n0 大)的輸入,它至多需要 5n3 + 3n 的時間運行完畢,那麼它的漸近時間複雜度是 O(n3).

二、時間頻度

要理解時間複雜度,需要先理解時間頻度,而時間頻度簡單的說,就是算法中語句的執行次數。

舉個例子:

要計算1+2+…+100,現在有兩種算法

public int fun1(int n){
    int total;
    for(int i = 0; i <= n; i++){
        total+=i;
    }
    return total;
}

public int fun2(int n){
    int total = (1 + n)*n/2;
    return total;
}

我們可以看見,對於fun1()這個方法,不管n多大,永遠需要執行n+1次,也就是說他的時間頻度是T(n)=n+1,

而對與fun2()來說,不管n多大都只需要執行1次,所以他的時間頻度T(n)=1。

當n趨向無窮大時,有三個忽略:

1.忽略常數項

比如T(n)=2n+1,當n趨向無窮大時,可以忽略常數項1;

參見下圖:

  • 2n+20 和 2n 隨着n 變大,執行曲線無限接近, 20可以忽略
  • 3n+10 和 3n 隨着n 變大,執行曲線無限接近, 10可以忽略

2.忽略低次項

比如T(n)=2n+3n^8,當n趨向無窮大時,可以忽略低次項及其係數2n;

參見下圖:

  • 2n^2+3n+10 和 2n^2 隨着n 變大, 執行曲線無限接近, 可以忽略 3n+10
  • n^2+5n+20 和 n^2 隨着n 變大,執行曲線無限接近, 可以忽略 5n+20

3.忽略係數

比如T(n)=2n^8,當n趨向無窮大時,可以忽略係數2。

參見下圖:

  • 隨着n值變大,5n^2+7n 和 3n^2 + 2n ,執行曲線重合, 說明 這種情況下, 5和3可以忽略。
  • 而n^3+5n 和 6n^3+4n ,執行曲線分離,說明多少次方式關鍵

三、時間複雜度

我們現在理解了時間頻度的T(n)的含義,假設當有一個輔助函數f(n),使得當n趨近無窮大時,T(n)/f(n)的極限值為不等於0的常數,就叫f(n)為T(n)的同量級函數,記作T(n)=O(f(n)),

稱O(f(n))為算法的時間漸進複雜度,也就是時間複雜度。

又根據時間頻度T(n)的“三個忽略”原則,我們可以知道時間複雜度是這樣得到的:

  1. 忽略所有常數
  2. 只保留函數中的最高階項
  3. 去掉最高階項的係數

舉個例子:

某算法T(n)=2n^3+4n-5,按步驟走:

  1. T(n)=2n^3+4n
  2. T(n)=2n^3
  3. T(n)=n^3

即可得該算法時間複雜度為O(n^3)

四、常見時間複雜度

這裏按複雜度從低到高列舉常見的時間複雜度:

  1. 常數階O(1)

    // 無論代碼執行了多少行,只要是沒有循環等複雜結構,那這個代碼的時間複雜度就都是O(1) 。
    public void fun(int n){
        n+=1;
    }
    
  2. 對數階O(log2n)

    // 根據公式有 n = 2^x,也就是 x = log2n,x即為循環代碼執行次數,所以時間複雜度為O(log2n)
    public void fun(int n){
        int i = 1;
        while(i < n){
            i = i *2
        }
    }
    
  3. 線性階O(n)

    // 一般來說,只要代碼里只有一個循環結構,即輸入規模和執行次數呈線性相關,那這個代碼的時間複雜度就都是O(n) 。
    public void fun(int n){
        for(int i = 0; i < n; i++){
            n+=i;
        }
    }
    
  4. 線性對數階O(nlogn)

    // 可以簡單理解為對數階的程序被放入了循環結構中,也就是n*O(logn),下面的代碼的複雜度就是O(nlog2n)
    public void fun(int n){
        int j = 1;
        for(int i = 0; i < n; i++){
            while(i < n){
                j = j *2
            }
        }
    }
    
  5. 平方階O(n²),立方階O(n3),K次方階O(nk)

    // 平方階可以簡單理解為線性階中嵌套一個線性階,也就是O(logn)*O(logn),下面的代碼複雜度就是O(n^2)
    // 立方階同理,就是三個線性階的嵌套,K次方階同理
    public void fun(int n){
        for(int i = 0; i < n; i++){
            for(int j = 0; j < n; i++){
    			i=i+j;
            } 
        }
    }
    

五、複雜度的四個概念

  1. 最壞情況時間複雜度:代碼在最理想情況下執行的時間複雜度。
  2. 最好情況時間複雜度:代碼在最壞情況下執行的時間複雜度。
  3. 平均時間複雜度:用代碼在所有情況下執行的次數的加權平均值表示
  4. 均攤時間複雜度:在代碼執行的所有複雜度情況中絕大部分是低級別的複雜度,個別情況是高級別複雜度且發生具有時序關係時,可以將個別高級別複雜度均攤到低級別複雜度上。基本上均攤結果就等於低級別複雜度。

舉個例子:

長度為n的數組查找一個給定元素k

public void fun(int[] arr,int k){
    for(int i = 0; i < arr.length; i++){
        if(arr[i] == k){
            //找到了
        }
    }
}

上面這個方法,最好的情況下元素k就在數組第一位,複雜度為O(1),但是最壞的情況下,元素k在數組最後一位,複雜度為O(n)。

同一段代碼在不同情況下時間複雜度會出現量級差異,為了更全面,更準確的描述代碼的時間複雜度,我們引入這4個概念,當然,在大多數時候我們是不用特意區分這四種情況的。

六、總結

總結一下如何快速判斷程序的時間複雜度:

  • 只關注循環最多的那部分代碼
  • 總複雜度等於量級最大的那段代碼的複雜度
  • 嵌套代碼的複雜度等於嵌套內外代碼複雜度的乘積

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

【【其他文章推薦】

※帶您來了解什麼是 USB CONNECTOR  ?

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

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

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

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

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

深入理解JVM(③)虛擬機的類加載過程

前言

上一篇我們介紹到一個類的生命周期大概分7個階段:加載、驗證、準備、解析、初始化、使用、卸載。並且也介紹了類的加載時機,下面我們將介紹一下虛擬機中類的加載的全過程。主要是類生命周期的,加載、驗證、準備、解析和初始化這五個階段所執行的具體動作。

加載

類加載過程的第一個階段就是加載,在加載階段,Java虛擬機需要完成以下三件事情:

1. 通過一個類的全限定名來獲取定義此類的二進制字節流。
2. 將這個字節流所代表的靜態存儲結構轉化為方法區的運行時數據結構。
3. 在內存中生成一個代表這個類的java.lang.Class對象,作為方法區這個類的各種數據的訪問入口。
《Java虛擬機規範》對這三點要求其實並不是特別具體,這樣留給虛擬機實現和Java應用的靈活度都是相當大的。僅第一條,獲取二進制字節流,並沒有有指出從哪裡獲取,如何獲取。這樣就已經能被我們的Java開發人員玩出各種花樣了。
例如:

  • 從ZIP包中讀取(JAR、EAR、WAR)。
  • 從網絡中獲取(Web Applet)。
  • 運行時計算生成,最典型的就是動態代理技術,在java.lang.reflect.Proxy中,就是用了ProxyGenerator.generateProxyClass()來為特定接口生成形式為“$Proxy”的代理類的二進制字節流。
  • 由其他文件生成(JSP)。
  • 從數據庫中讀取。
  • 從加密文件中獲取(防止被反編譯獲取源碼)。
  • …….. …..

相對於類加載的其他階段,非數組類型的加載階段是開發人員可控性最強的階段。加載階段即可以使用Java虛擬機里內置的引導類加載器完成,也可以由用戶自定義的類加載器去完成。

驗證

驗證這一階段的目的是確保Class文件的字節流中包含的信息符合《Java虛擬機規則》的全部約束要求,保證這些信息被當作代碼運行后不會危害虛擬機自身安全。
驗證階段大致上會完成下面四個階段的檢驗動作:
文件格式驗證、元數據驗證、字節碼驗證和複合引用驗證。

文件格式驗證

這是驗證的第一個階段,主要是驗證字節流是否符合Class文件格式的規範,並且能被當前版本的虛擬機處理。
這一階段的驗證點有:

  • 是否以魔數0xCAFEBABE開頭。
  • 主、次版本號是否在當前Java虛擬機接受範圍之內。
  • 常量池的常量中是否有不被支持的常量類型。
  • 指向常量的各種索引值是否有指向不錯在的常量或不符合類的常量。
  • … …

這個階段的驗證是基於二進制字節流進行的,只有通過了這個階段的驗證之後,這段字節流才被允許進入Java虛擬機內存的方法區中進行存儲,後面的階段都是基於方法區的存儲結構進行的,不會再直接讀取、操作字節流了。

元數據驗證

第二階段是對字節碼描述的信息進行語義分析,以保證其描述的信息符合《Java虛擬機規則》的要求,這個階段主要有以下一些驗證點:

  • 當前類是否有父類(除java.lang.Object外,所有類都應當有父類)。
  • 當前類的父類是否繼承了不允許被繼承的類(被final修飾的類)。
  • 如果當前類非抽象類,是否實現了父類或接口要求實現的所有方法。
  • 類中的字段、方法是否與父類產生矛盾。
  • … …
字節碼驗證

第三階段是整個驗證過程最複雜的一個階段,主要目的是通過數據流分析和孔劉分析,確定程序語義是合法的、符合邏輯的。
為了保證被校驗的方法在運行時不會做出危害虛擬機的安全的行為,主要做了如下一些校驗:

  • 保證任意時刻操作棧的數據類型與指令代碼序列都能配合工作,例如不會出現類似於“在操作放置了一個int類型數據,使用時卻按long類型來加載如本地變量表中”這樣的情況。
  • 保證任何跳轉指令都不會跳轉到方法體以外的字節碼指令上。
  • 保證方法體中的類型轉換總是有效的。例如:一個子類對象賦值給父類數據類型,這是安全的,但是把父類對象賦值為子類數據類型,獲取賦值給另外一個毫無關係的數據類型,則是不合法的。
  • … …

如果一個類型中有方法體的字節碼沒有通過字節碼驗證,那它肯定是有問題的;但如果一個方法體通過了字節碼驗證,也仍然不能保證它一定就是安全的。因為字節碼驗證也是在程序中進行的,即不能通過程序準確地檢查出程序是否能在有限時間之內結束運行。

符號引用驗證

最後一個階段的校驗行為發生在虛擬機將符號引用轉化為直接引用的時候,這個轉化動作將在連接的第三個階段——解析階段發生。
本階段通常需要校驗下列內容:

  • 符號引用中通過字符串描述的全限定名是否能找到對應的類。
  • 在指定類中是否存在符合方法的字段描述符及簡單名稱所描述的方法和字段。
  • 符合引用中的類、字段、方法的可訪問性,是否可被當前類訪問。

驗證階段對於虛擬機的類加載機制來說,是一個非常重要的、但卻不是必須要執行的階段,因為如果程序運行的全部代碼都已經被反覆使用和驗證過,在生成環境的實施階段就可以考慮使用-Xverify:none參數來關閉大部分的類驗證措施,來縮短類加載的時間。

準備

準備階段是正式為類中定義的變量分配內存並設置類變量的初始值的階段,這些變量所使用的內存都應當在方法區中進行分配,需要注意的是,這裏所說的方法區只是一個概念上的區域,在JDK7以及之前HotpSpot用永久代實現方法區,這個概念是正確的,但是在JDK8以及之後,類變量會隨着Class對象一起存放在Java堆中,這個時候類變量存在於方法區就僅僅是一個概念了。
在準備階段有兩點需要着重強調
1、在準備階段進行內存分配的僅包括類變量,而不包括實例變量,實例變量將會在對象實例化時隨着對象一起分配在Java堆中。
2、這裏所說的為類變量設置初始值,“通常情況”下是數據類的零值。
例如一個類變量定義為:

public static int value = 666;

那變量在準備階段過後的初始值為0而不為666,因為這個時候還未開始執行任何Java方法,而把value賦值為666的putstatic指令是程序被編譯后,存放於類構造器 ()方法之中,所以把value賦值為666的動作要到類的初始化階段才會被執行。

但是如果類字段的屬性表中存在ConstantValue屬性,那在準備階段變量值就會被初始化為ConstantValue屬性所指定的初始值,例如:

public static final int value = 666;

在編譯時Javac將會為value生成ConstantValue屬性,在準備階段虛擬機就會根據ConstantValue的設置將value賦值為666。

解析

解析階段是Java虛擬機將常量池內的符號引用替換為直接引用的過程,符號引用在Class文件中它以CONSTANT_Class_info、CONSTANT_Fieldref_info、CONSTANT_Methodref_info等類型的常量出現。
先來解釋一下什麼是符號引用和直接引用。

  • 符號引用:符號引用以一組符號來描述所引用的目標,符號可以是任何形式的字面量,只要使用時能無歧義地定位到目標即可。
  • 直接引用:直接引用是可以直接指向目標的指針、相對偏移量或者是一個能間接定位到目標的句柄。

解析動作主要針對類或接口、字段、類方法、接口方法、方法類型、方法句柄和調用點限定這7類符號引用進行,分別對應於常量池的CONSTANT_Class_info、CONSTANT_Fieldref_info、CONSTANT_Methodref_info、CONSTANT_InterfaceMethodref_info、CONSTANT_MehodType_info、CONSTANT_MethodHandle_info、CONSTANT_Dynamic_info和CONSTANT_InvokeDynamic_info
這8種常量類型。

初始化

初始化階段是類加載過程的最後一個步驟,之前介紹的幾個類加載的動作里,出了在加載階段用戶應用程序可以通過自定義類加載器的方式局部參与外,其餘動作都完全由Java虛擬機來主導控制。
簡單的來說,初始化階段就是執行類構造器<clinit>()方法的過程。那麼<clinit>()是如何執行的呢?

  • <clinit>()方法是由編譯器自動收集類中所有變量的複製動作和靜態語句塊(stataic{}塊)中的語句合併產生的,編譯器收集的順序是由語句在源文件中出現的的順序決定的,靜態語句塊中只能訪問到定義在靜態語句塊之前的變量,定義在它之後的變量,在前面的靜態語句塊可以賦值,但是不能訪問。
    例如:
  • <clinit>()方法與類的構造函數不同,它不需要顯式地調用父類構造器,Java虛擬機會保證在子類 ()方法執行前,父類 ()方法以及執行完畢。
  • 由於父類的<clinit>()方法先執行,即父類中定義的靜態語句塊要優先於子類的變量賦值操作。
    如下代碼運行結果會是 4
    父類
public class FatherClass {

    public static int fatherObject = 3;

    static {
        fatherObject = 4;
    }
}

子類

public class SonClass extends FatherClass{

    public static int sonObject = fatherObject;

}

測試

@Test
public void testClassLoad(){
    System.out.println(SonClass.sonObject);
}

運行結果

4
  • <clinit>()方法對於類或接口來說並不是必需的。
  • 接口中不能使用靜態語句塊,但仍然有變量初始化的賦值操作,因此接口與類一樣都會生成<clinit>()方法。
  • Java虛擬機必須保證一個類的<clinit>()方法在多線程環境中被正確地加鎖同步,若同時多個線程區初始化一個類,那麼只會有其中一個線程去執行這個類的<clinit>()方法,其他線程都需要阻塞等待,直到活動線程執行完畢<clinit>()方法。

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

【其他文章推薦】

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

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

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

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

※新北清潔公司,居家、辦公、裝潢細清專業服務

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

【秒懂Java】【第1章_初識Java】01_編程語言

各位小夥伴們好哇!從今日起,我將開始更新《秒懂Java》系列文章,從0開始講解Java的方方面面,完全零基礎也可以看懂。後面也將推出配套的視頻版,歡迎大家保持關注!

  • 我會儘力辦到:在保證通俗易懂的同時,不丟失知識的嚴謹性和完整性
  • 不管你是否有編程經驗,只要你感興趣、細心閱讀,就能學會
  • 本文是《秒懂Java》系列的第1篇文章,主要認識幾個基礎概念

什麼是計算機?

一說到計算機(Computer),大家首先想到的可能是電腦(台式電腦、手提電腦)。

實際上,我們日常生活中使用的平板電腦、智能手機也屬於計算機,它們的功能也跟電腦一樣非常強大。

還有KTV的點歌機、超市的自助收銀機等很多設備也都屬於計算機。

毋庸置疑,計算機是人類歷史上最偉大的發明之一,極大地提高了社會的生產力,目前它已經延伸到了生活、學習、工作等各個領域,無處不在。如今,我們會在計算機上安裝各種各樣的軟件(應用、遊戲),學習工作、衣食住行、吃喝玩樂一網打盡,極大地改變了我們的生活、學習、工作方式。

什麼是編程語言?

語言,是雙方進行溝通交流的主要表達方式。

  • 如果我要跟咱們中國人進行交流,應該用漢語
  • 如果我要跟美國人進行交流,應該用英語
  • 如果我要跟韓國人進行交流,應該用韓語

那如果我要跟計算機進行交流呢?那就應該用計算機編程語言。

  • 是的,計算機編程語言,就是用來跟計算機進行溝通交流的語言
  • 一般把計算機編程語言簡稱為:編程語言(Programming Language)

注意:我們要學習的很多IT技術都源自西方國家(比如美國),因此,很多技術名詞,都是從英文翻譯過來的。為了保證描述的嚴謹性,當首次提及某個技術名詞時,我都會在它旁邊標註原本的英文單詞。

與計算機進行交流

那如何利用編程語言與計算機進行交流呢?

編程語言,顧名思義,就是可以用來“編寫程序”的語言。

  • 首先,利用編程語言編寫一段程序。例如上圖所示的程序,只包含了3行代碼,這裏簡單說一下代碼的大概意思(了解一下即可,不用去深究)
    • 第1行:創建了一個播放器
    • 第2行:設置播放器的音量為100
    • 第3行:開始播放某個mp4視頻
  • 最後,將程序運行到計算機上,計算機就會開始識別執行程序中的每一句代碼,完成相應的功能,最後成功播放視頻

我們平時使用的各種軟件(應用、遊戲)都是通過編程語言開發出來的,它們都由一大堆的代碼組成。當打開軟件時(將軟件運行到計算機上時),計算機就會開始識別執行軟件中包含的代碼,完成相應的功能。

所以,編程語言有一個非常重要的作用,那就是:開發軟件!

主流編程語言

世界上有上百種各式各樣的編程語言,目前比較常見的主流編程語言有

  • Java、C、C++、C#、PHP、Python、Go
  • JavaScript(簡稱JS)、TypeScript(簡稱TS)
  • Objective-C(簡稱OC)、Swift、Kotlin
  • Scala、Assembly Language(彙編語言) 等

每一門編程語言的作用都不太一樣,比如

  • Java、Kotlin:可以用來開發Android系統中的軟件
  • Objective-C、Swift:可以用來開發iOS、Mac系統中的軟件
  • C、C++、C#:可以用來開發Windows系統中的軟件

當然,上面列舉的僅僅是它們的部分功能,並沒有說完整。比如:

  • C、C++也可以開發Android、iOS、Mac、Linux等系統中的軟件
  • Java也可以開發Mac、Linux、Windows等系統中的軟件

其他的就不一一說明了,了解一下即可

語法

每當我們要學習一門新的語言時,都要先學習它的語法。

  • 比如,學習英語就要先學習它的語法,英語的語法規定了:英文句子可以怎麼寫、不可以怎麼寫
  • 同樣的,每一門編程語言都有自己的語法,編程語言的語法規定了:你的代碼可以怎麼寫、不可以怎麼寫
    • 比如,Java語言的語法規定:每一句代碼後面都必須以分號(;)結束
    • 代碼一旦出現了語法錯誤,就無法成功運行到計算機上

不同編程語言的語法是不一樣的,每一門編程語言都有自己特有的語法。比如,想讓計算機播放一個視頻,不同編程語言可能會有不同的寫法。

不難看出它們之間的一些差異(了解一下即可,不用去深究)

  • Java、OC都以分號(;)結束,而Python不需要以分號(;)結束
  • Java、Python中都使用了點(.)、小括號(()),而OC中使用了中括號([])、冒號(:)、@符號
  • Java、OC中都使用雙引號(“”),而Python中可以使用單引號(”)

雖然它們的寫法不一樣,但是都完成了一樣的功能:讓計算機播放一個視頻。如果想利用編程語言開發出強大優秀的軟件、控制計算機做更多的事情,首先要踏踏實實學好編程語言的語法。如果你連語法都不懂,怎麼可能寫出正確的代碼呢?

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

【其他文章推薦】

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

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

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

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

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

※超省錢租車方案