HOME 首頁(yè)
SERVICE 服務(wù)產(chǎn)品
XINMEITI 新媒體代運(yùn)營(yíng)
CASE 服務(wù)案例
NEWS 熱點(diǎn)資訊
ABOUT 關(guān)于我們
CONTACT 聯(lián)系我們
創(chuàng)意嶺
讓品牌有溫度、有情感
專注品牌策劃15年

    算法優(yōu)化要考慮的內(nèi)容(算法優(yōu)化要考慮的內(nèi)容不包括)

    發(fā)布時(shí)間:2023-04-19 08:30:25     稿源: 創(chuàng)意嶺    閱讀: 124        

    大家好!今天讓創(chuàng)意嶺的小編來(lái)大家介紹下關(guān)于算法優(yōu)化要考慮的內(nèi)容的問(wèn)題,以下是小編對(duì)此問(wèn)題的歸納整理,讓我們一起來(lái)看看吧。

    開(kāi)始之前先推薦一個(gè)非常厲害的Ai人工智能工具,一鍵生成原創(chuàng)文章、方案、文案、工作計(jì)劃、工作報(bào)告、論文、代碼、作文、做題和對(duì)話答疑等等

    只需要輸入關(guān)鍵詞,就能返回你想要的內(nèi)容,越精準(zhǔn),寫出的就越詳細(xì),有微信小程序端、在線網(wǎng)頁(yè)版、PC客戶端

    官網(wǎng):https://ai.de1919.com。

    創(chuàng)意嶺作為行業(yè)內(nèi)優(yōu)秀的企業(yè),服務(wù)客戶遍布全球各地,如需了解SEO相關(guān)業(yè)務(wù)請(qǐng)撥打電話175-8598-2043,或添加微信:1454722008

    本文目錄:

    算法優(yōu)化要考慮的內(nèi)容(算法優(yōu)化要考慮的內(nèi)容不包括)

    一、SEO算法基礎(chǔ)優(yōu)化有哪些

    這是櫻花總結(jié)的,你可以看一下

    1、網(wǎng)站結(jié)構(gòu)是否屬于扁平化和立體化

    扁平化,URL是否具有可讀性,是否符合SEO優(yōu)化規(guī)則

    立體化,網(wǎng)站有推薦閱讀,面包屑,網(wǎng)站導(dǎo)航,網(wǎng)站地圖,內(nèi)鏈部署模塊,友鏈模塊,網(wǎng)站404頁(yè)面等

    2、用戶需求

    3、診斷頁(yè)面SEO元素,TDK,H1,Alt(代替標(biāo)簽),首頁(yè)部署品牌詞,產(chǎn)品頁(yè)面部署產(chǎn)品詞,評(píng)論頁(yè)面部署問(wèn)答詞等,以及頁(yè)面內(nèi)關(guān)鍵詞的部署密度。

    4、robots文件合理編寫

    5、診斷數(shù)據(jù)統(tǒng)計(jì)工具,確保我們分析網(wǎng)站流量數(shù)據(jù)

    6、分析行業(yè)現(xiàn)狀,分析競(jìng)爭(zhēng)對(duì)手SEO指標(biāo),競(jìng)爭(zhēng)對(duì)手關(guān)鍵詞詞庫(kù),SEO產(chǎn)品建設(shè),行業(yè)所處的位置,提升空間,同行的差距

    分析競(jìng)對(duì)手的優(yōu)勢(shì)和劣勢(shì),制定相應(yīng)的策略及方案

    8、SEO效果預(yù)估,在一定時(shí)間內(nèi)實(shí)現(xiàn)什么樣的效果,比如0-1個(gè)月網(wǎng)站收錄,外鏈,挖掘長(zhǎng)尾關(guān)鍵詞,重點(diǎn)熱點(diǎn)關(guān)鍵詞

    9、外鏈建設(shè)

    二、如何把握算法多樣化和優(yōu)化?

    隨著課堂教學(xué)改革的深化和《數(shù)學(xué)課程標(biāo)準(zhǔn)》出臺(tái),對(duì)計(jì)算教學(xué)提出了新要求,“應(yīng)重視口算,加強(qiáng)估算,提倡算法多樣化”的理念,給計(jì)算教學(xué)的課堂帶來(lái)了新的活力,在不少老師的課堂上,算法多樣化的理念能得到很好的體現(xiàn),一道計(jì)算題通過(guò)教師的悉心引導(dǎo),同學(xué)們的積極思考,奇思妙想層出不窮,學(xué)生課堂表現(xiàn)異?;钴S,“算法多樣化”成為小學(xué)數(shù)學(xué)教學(xué)中關(guān)注的一個(gè)熱點(diǎn)。在計(jì)算教學(xué)中,我們?nèi)绾伟盐账惴ǘ鄻踊蛢?yōu)化,不使教學(xué)流于形式呢?

    圍繞這個(gè)問(wèn)題,我們賓陽(yáng)縣也開(kāi)展了教研活動(dòng),教師們?cè)诎阉惴ǘ鄻踊唧w落實(shí)在到教學(xué)實(shí)踐時(shí),出現(xiàn)了不少的困惑和誤區(qū);在我們學(xué)校,老師們也以此確立了一個(gè)校級(jí)課題,進(jìn)行研究, 真正開(kāi)展起來(lái)確實(shí)覺(jué)得對(duì)《數(shù)學(xué)課程標(biāo)準(zhǔn)》中提出的“算法多樣化”這一理念的理解比較模糊,在操作上也有很多疑惑,難以把握好算法多樣化教學(xué)的尺度;通過(guò)教研室組織的培訓(xùn),不斷學(xué)習(xí)、實(shí)踐和反思,摸爬滾打中我們有了一些自己的體會(huì):

    一、算法多樣化不等于算法全面化

    算法多樣化是一個(gè)學(xué)習(xí)共同體為解決某一個(gè)問(wèn)題,通過(guò)動(dòng)手實(shí)踐、自主探索和合作交流后形成的多種計(jì)算方法的集合體。它是針對(duì)一個(gè)學(xué)習(xí)共同體而言的,絕不是針對(duì)某一學(xué)習(xí)個(gè)體而言。多樣化并不意味著追求全面化。

    首先,提倡算法多樣化并不是把所有的算法都要想出來(lái)。如教學(xué)13減9得幾時(shí),學(xué)生只想到了以下四種方法:

    (1)先擺13根小棒,再拿走9根,還剩4根;

    (2)算減法想加法,因?yàn)?加4得13,把以13減9得4; (3)先從10里減9得1,1再加3得4;

    (4)先算13減3得10,再算10減6得4。

    除了學(xué)生想到的四種方法,還有其它方法,如:9減3得6,10再減6等于4。但學(xué)生沒(méi)有說(shuō)出,如果教師刻意追求,反復(fù)啟發(fā),千呼萬(wàn)喚才得了出來(lái),說(shuō)明這種方法遠(yuǎn)離兒童的認(rèn)知最近發(fā)展區(qū),強(qiáng)行讓學(xué)生接受這種方法就會(huì)加重學(xué)生負(fù)擔(dān),無(wú)益于學(xué)生的發(fā)展。算法多樣化教學(xué),是教學(xué)生,不是教教材,不能為了追求全面而讓學(xué)生把大量的時(shí)間花費(fèi)在某些難懂的解題方法上,只要不影響后續(xù)的學(xué)習(xí),最好淡化形式,注重實(shí)質(zhì)。

    其次,算法多樣化不能要求每個(gè)學(xué)生都要想出一種或幾種不同的計(jì)算方法,不能無(wú)原則地降低數(shù)學(xué)思考的要求。每個(gè)學(xué)生都有自己的特點(diǎn),學(xué)生在學(xué)習(xí)數(shù)學(xué)方面的差異是客觀存在的。在算法多樣化教學(xué)中要針對(duì)不同的學(xué)生提出不同的要求。對(duì)已經(jīng)想出一種方法的學(xué)生,教師應(yīng)給予充分的肯定并鼓勵(lì)他們繼續(xù)探索;對(duì)于沒(méi)有想出算法的學(xué)生,在肯定他們已經(jīng)積極動(dòng)腦、努力探索的基礎(chǔ)上,要求他們學(xué)會(huì)傾聽(tīng)別人的想法、聽(tīng)懂別人的方法。同時(shí)要求他們?cè)诮窈蟮膶W(xué)習(xí)中更加努力的探索,期望有更大的進(jìn)步。

    第三、算法多樣化教學(xué)并非要求每個(gè)學(xué)生掌握多種算法。算法多樣化教學(xué)鼓勵(lì)學(xué)生用不同的方法探索和解決問(wèn)題,但決不能要求每個(gè)學(xué)生都掌握多種算法。教學(xué)中,教師可在引導(dǎo)學(xué)生了解不同的解題方法,體驗(yàn)解題策略的多樣性,引導(dǎo)學(xué)生對(duì)各種方法進(jìn)行分析、比較的基礎(chǔ)上,提出不同的要求。對(duì)學(xué)有余力的學(xué)生,可鼓勵(lì)他們掌握兩種或兩種以上自己喜歡的方法,以開(kāi)闊其視野;對(duì)學(xué)困生,只要他們能掌握一種適合自己的方法就可以了。

    認(rèn)識(shí)到算法多樣化并非算法全面化、不是一定要達(dá)到預(yù)期的幾種算法,更不是一定要呈現(xiàn)教材中出現(xiàn)的每一種算法;也不是讓每一個(gè)學(xué)生都得掌握其中的每一種算法,而是從學(xué)生的自身認(rèn)知水平出發(fā),以開(kāi)放、寬容的態(tài)度等待、處理算法多樣化教學(xué),讓學(xué)生盡量獲得成

    功的體驗(yàn),感受到自我探索的價(jià)值和數(shù)學(xué)學(xué)習(xí)的樂(lè)趣,促進(jìn)學(xué)生的可持續(xù)發(fā)展,這才是倡導(dǎo)算法多樣化的目的所在。

    二、多中選優(yōu),擇優(yōu)而用

    “多樣化”后干什么?回答是肯定的:“優(yōu)化!”因?yàn)樗惴ǘ鄻踊⒉皇菃渭円饬x上的計(jì)算方法多樣化,比之更重要的還有 相應(yīng)的優(yōu)化的過(guò)程,“多中選優(yōu),擇優(yōu)而用”的思想方法,是學(xué)生的學(xué)習(xí)和生活中不可缺少的,也是發(fā)展學(xué)生數(shù)學(xué)思維、培養(yǎng)學(xué)生創(chuàng)新意識(shí)的重要方法。在研究中我們有的教師片面的認(rèn)為算法多樣化就是學(xué)生講的方法越多越好,刻意地追求算法的多樣化,忽略了算法的優(yōu)化,從一個(gè)極端走向另一個(gè)極端,造成了計(jì)算教學(xué)的低效;也有的教師認(rèn)為,如果對(duì)算法進(jìn)行優(yōu)化,那就談不上算法多樣化了,似乎多樣化與優(yōu)化之間存在矛盾,其實(shí)不然,算法優(yōu)化是學(xué)生個(gè)體的學(xué)習(xí)、體驗(yàn)和感悟的過(guò)程,如果不對(duì)算法進(jìn)行優(yōu)化,我們的學(xué)生就沒(méi)有收獲、沒(méi)有提高。

    1、構(gòu)筑多樣化與優(yōu)化的橋梁。

    算法多樣化并不是單純意義上的計(jì)算方法多樣化,計(jì)算方法沒(méi)有好壞之分,但有繁簡(jiǎn)之別,我們要清楚, 每一種看似復(fù)雜或簡(jiǎn)單的計(jì)算方法之后,跟我們所要最終優(yōu)化的方案,有哪些潛在的聯(lián)系。如教學(xué)9加幾的計(jì)算方法中,有擺小棒、數(shù)數(shù)、用計(jì)數(shù)器、湊十法等,湊十法是最簡(jiǎn)單也是最實(shí)用的方法,而擺小棒、數(shù)數(shù)、計(jì)數(shù)器都與湊十法有一定聯(lián)系,象擺小棒過(guò)程中,學(xué)生是一根一根數(shù)的,教師就可以引導(dǎo)學(xué)生湊足十根捆成一捆,再數(shù)剩下幾根,讓大家一眼就看出一共是幾根,既簡(jiǎn)單形象又滲透了“湊十”的概念;計(jì)數(shù)器具更是對(duì)湊十法的應(yīng)用,個(gè)位上湊足了十個(gè)珠,再加上個(gè)位剩下的珠子,9+3一共等于幾。此時(shí),教師如果能將這些方法的內(nèi)在含義通過(guò)操作演示給學(xué)生,并適時(shí)小結(jié)9加幾的加法怎么樣算最簡(jiǎn)便,讓學(xué)生對(duì)湊十法從直觀到抽象都有深刻的理解,這樣才能促使學(xué)生對(duì)自己所選擇的方法。

    三、優(yōu)化算法

    動(dòng)量法、AdaGrad、RMSProp、AdaDelta、Adam

    在7.2節(jié)(梯度下降和隨機(jī)梯度下降)中我們提到,目標(biāo)函數(shù)有關(guān)自變量的梯度代表了目標(biāo)函數(shù)在自變量當(dāng)前位置下降最快的方向。因此,梯度下降也叫作最陡下降(steepest descent)。在每次迭代中,梯度下降根據(jù)自變量當(dāng)前位置,沿著當(dāng)前位置的梯度更新自變量。然而,如果自變量的迭代方向 僅僅取決于自變量當(dāng)前位置,這可能會(huì)帶來(lái)一些問(wèn)題

    可以看到,同一位置上,目標(biāo)函數(shù)在豎直方向( 軸方向)比在水平方向( 軸方向)的斜率的絕對(duì)值更大。因此,給定學(xué)習(xí)率,梯度下降迭代自變量時(shí)會(huì)使自變量在豎直方向比在水平方向移動(dòng)幅度更大。那么,我們 需要一個(gè)較小的學(xué)習(xí)率 從而避免自變量在豎直方向上越過(guò)目標(biāo)函數(shù)最優(yōu)解。然而,這會(huì)造成自變量在水平方向上 朝最優(yōu)解移動(dòng)變慢 。

    試著將學(xué)習(xí)率調(diào)大一點(diǎn),此時(shí)自變量在豎直方向不斷越過(guò)最優(yōu)解并逐漸發(fā)散。

    動(dòng)量法的提出是為了解決梯度下降的上述問(wèn)題。

    其中,動(dòng)量超參數(shù) 滿足 。當(dāng) 時(shí),動(dòng)量法等價(jià)于小批量隨機(jī)梯度下降。

    因此,在實(shí)際中,我們常常將 看作是最近 個(gè)時(shí)間步的 的值的加權(quán)平均。

    現(xiàn)在,我們對(duì)動(dòng)量法的速度變量做變形:

    優(yōu)化算法中,⽬標(biāo)函數(shù)⾃變量的每⼀個(gè)元素在相同時(shí)間步都使⽤同⼀個(gè)學(xué)習(xí)率來(lái)⾃我迭代。在“動(dòng)量法”⾥我們看到當(dāng)x1和x2的梯度值有較⼤差別時(shí),需要選擇⾜夠小的學(xué)習(xí)率使得⾃變量在梯度值較⼤的維度上不發(fā)散。但這樣會(huì)導(dǎo)致⾃變量在梯度值較小的維度上迭代過(guò)慢。動(dòng)量法依賴指數(shù)加權(quán)移動(dòng)平均使得⾃變量的更新⽅向更加⼀致,從而降低發(fā)散的可能。 本節(jié)我們介紹AdaGrad算法,它根據(jù)⾃變量在每個(gè)維度的梯度值的⼤小來(lái)調(diào)整各個(gè)維度上的學(xué)習(xí)率,從而避免統(tǒng)⼀的學(xué)習(xí)率難以適應(yīng)所有維度的問(wèn)題。

    AdaGrad算法會(huì)使⽤⼀個(gè)小批量隨機(jī)梯度gt按元素平⽅的累加變量st。在時(shí)間步0,AdaGrad將s0中每個(gè)元素初始化為0。在時(shí)間步t,⾸先將小批量隨機(jī)梯度gt按元素平⽅后累加到變量st:

    其中⊙是按元素相乘。接著,我們將⽬標(biāo)函數(shù)⾃變量中每個(gè)元素的學(xué)習(xí)率通過(guò)按元素運(yùn)算重新調(diào)整⼀下:

    其中η是學(xué)習(xí)率,ϵ是為了維持?jǐn)?shù)值穩(wěn)定性而添加的常數(shù),如10的-6次方。這⾥開(kāi)⽅、除法和乘法的運(yùn)算都是按元素運(yùn)算的。這些按元素運(yùn)算使得⽬標(biāo)函數(shù)⾃變量中 每個(gè)元素都分別擁有⾃⼰的學(xué)習(xí)率

    需要強(qiáng)調(diào)的是,小批量隨機(jī)梯度按元素平⽅的累加變量st出現(xiàn)在學(xué)習(xí)率的分⺟項(xiàng)中。因此,

    然而,由于st⼀直在累加按元素平⽅的梯度,⾃變量中每個(gè)元素的學(xué)習(xí)率在迭代過(guò)程中⼀直在降低(或不變)。 所以,當(dāng)學(xué)習(xí)率在迭代早期降得較快且當(dāng)前解依然不佳時(shí),AdaGrad算法在迭代后期由于學(xué)習(xí)率過(guò)小,可能較難找到⼀個(gè)有⽤的解 。

    當(dāng)學(xué)習(xí)率在迭代早期降得較快且當(dāng)前解依然不佳時(shí),AdaGrad算法在迭代后期由于 學(xué)習(xí)率過(guò)小 ,可能較難找到⼀個(gè)有⽤的解。為了解決這⼀問(wèn)題,RMSProp算法對(duì)AdaGrad算法做了⼀點(diǎn)小小的修改。

    不同于AdaGrad算法⾥狀態(tài)變量st是 截⾄時(shí)間步t所有小批量隨機(jī)梯度gt按元素平⽅和 ,RMSProp算法將這些梯度 按元素平⽅做指數(shù)加權(quán)移動(dòng)平均 。具體來(lái)說(shuō),給定超參數(shù)0 ≤ γ < 1,RMSProp算法在時(shí)間步t > 0計(jì)算:

    和AdaGrad算法⼀樣,RMSProp算法將⽬標(biāo)函數(shù)⾃變量中每個(gè)元素的學(xué)習(xí)率通過(guò)按元素運(yùn)算重新調(diào)整,然后更新⾃變量:

    其中η是學(xué)習(xí)率,ϵ是為了維持?jǐn)?shù)值穩(wěn)定性而添加的常數(shù),如10的-6次方。因?yàn)镽MSProp算法的狀態(tài)變量st是對(duì)平⽅項(xiàng)gt ⊙ gt的指數(shù)加權(quán)移動(dòng)平均, 所以可以看作是最近1/(1 − γ)個(gè)時(shí)間步的小批量隨機(jī)梯度平⽅項(xiàng)的加權(quán)平均。如此⼀來(lái),⾃變量每個(gè)元素的學(xué)習(xí)率在迭代過(guò)程中就不再⼀直降低(或不變)。

    除了RMSProp算法以外,另⼀個(gè)常⽤優(yōu)化算法AdaDelta算法也針對(duì)AdaGrad算法在迭代后期可能較難找到有⽤解的問(wèn)題做了改進(jìn)。有意思的是,AdaDelta算法沒(méi)有學(xué)習(xí)率這⼀超參數(shù)。

    AdaDelta算法也像RMSProp算法⼀樣,使⽤了小批量隨機(jī)梯度gt按元素平⽅的指數(shù)加權(quán)移動(dòng)平均變量st。在時(shí)間步0,它的所有元素被初始化為0。給定超參數(shù)0 ≤ ρ < 1(對(duì)應(yīng)RMSProp算法中的γ),在時(shí)間步t > 0,同RMSProp算法⼀樣計(jì)算:

    與RMSProp算法不同的是,AdaDelta算法還維護(hù)⼀個(gè) 額外的狀態(tài)變量∆xt ,其元素同樣在時(shí)間步0時(shí)被初始化為0。我們使⽤∆xt−1來(lái)計(jì)算⾃變量的變化量:

    最后,我們使⽤∆xt來(lái)記錄⾃變量變化量 按元素平⽅的指數(shù)加權(quán)移動(dòng)平均:

    Adam算法在RMSProp算法基礎(chǔ)上對(duì)小批量隨機(jī)梯度也做了指數(shù)加權(quán)移動(dòng)平均。

    Adam算法使⽤了 動(dòng)量變量vt 和RMSProp算法中 小批量隨機(jī)梯度按元素平⽅的指數(shù)加權(quán)移動(dòng)平均變量st ,并在時(shí)間步0將它們中每個(gè)元素初始化為0。給定超參數(shù)0 ≤ β1 < 1(算法作者建議設(shè)為0.9),時(shí)間步t的動(dòng)量變量vt即小批量隨機(jī)梯度gt的指數(shù)加權(quán)移動(dòng)平均:

    接下來(lái),Adam算法使⽤以上 偏差修正 后的變量 v ˆ t s ˆ t ,將模型參數(shù)中每個(gè)元素的學(xué)習(xí)率通過(guò)按元素運(yùn)算重新調(diào)整:

    其中 η 是學(xué)習(xí)率, ϵ 是為了維持?jǐn)?shù)值穩(wěn)定性而添加的常數(shù),如10的-8次方。和AdaGrad算法、RMSProp算法以及AdaDelta算法⼀樣,⽬標(biāo)函數(shù)⾃變量中每個(gè)元素都分別擁有⾃⼰的學(xué)習(xí)率。最后,使⽤ 迭代⾃變量:

    四、數(shù)據(jù)結(jié)構(gòu)和算法優(yōu)化

    APP的優(yōu)化是任重而道遠(yuǎn)的過(guò)程,必須在意每一個(gè)環(huán)節(jié),否者當(dāng)你想要優(yōu)化的時(shí)候,發(fā)現(xiàn)到處都是坑,已經(jīng)不知道填補(bǔ)哪里了,所以我們必須一點(diǎn)一滴的做起。

    數(shù)據(jù)結(jié)構(gòu)和算法優(yōu)化

    能帶來(lái)什么好處呢?他能使得你程序獲得數(shù)據(jù)更快,內(nèi)存占用更合理。最終體現(xiàn)為響應(yīng)快內(nèi)存占用小。

    我們先看常見(jiàn)的數(shù)據(jù)結(jié)構(gòu)類型特點(diǎn)

    數(shù)組 : 一片物理上連續(xù)的大小確定的儲(chǔ)存空間 。int[num]

    順序表 :物理上連續(xù)、邏輯上連續(xù)、大小可以動(dòng)態(tài)增加。ArrayList (查找快,添加刪除慢)

    鏈表 :物理上不連續(xù)、邏輯上連續(xù)、可以動(dòng)態(tài)增加和刪除節(jié)點(diǎn)。LinkedList (查找慢只能輪尋,增加刪除快)

    物理上連續(xù):數(shù)組或者鏈表在初始化的時(shí)候,會(huì)申請(qǐng)分配內(nèi)存空間:只要存儲(chǔ)空間足夠你申請(qǐng)的大小就分配給你初始化(物理不連續(xù));必須要連續(xù)的存儲(chǔ)空間,我才給你分配,否則失?。ㄎ锢砩线B續(xù))

    那么有沒(méi)有繼承純虛標(biāo)和鏈表的2個(gè)有點(diǎn)的數(shù)據(jù)結(jié)構(gòu)呢?HashMap!     

    HashMap

    它是由數(shù)組和鏈表結(jié)合組成。(HashMap:JDK1.7之前 24 之前: 數(shù)組+ 鏈表; HashMap:JDK1.8 之后:  數(shù)組+ 鏈表 + 紅黑樹(shù))

    下面是HashMap結(jié)構(gòu)圖

    它是怎么操作的呢?為什么他能同時(shí)擁有順序表和鏈表的優(yōu)點(diǎn)呢?  搞清它的實(shí)現(xiàn)方式,我們就可以知道了, 大致可以分為以下的步驟。

    ①put方法,傳入object和value,通過(guò)hash運(yùn)算得到一個(gè)int類型的hashcode,這里假設(shè)為X(后續(xù)X為這個(gè)hashcode)。

    ②hashmap內(nèi)部是有一個(gè)table數(shù)組+鏈表形成的。我們拿到這個(gè)X后,使用X/table.length(hashcode值/table[].length),得到一個(gè)小于table.length的值M,該值就是這個(gè)value應(yīng)該放置的數(shù)組位置。我們準(zhǔn)備把value放入table[M]中。

    ③我們把hashcode和value打包為一個(gè)node節(jié)點(diǎn)(為什么需要這么打包后續(xù)會(huì)提到),準(zhǔn)備存入table[M]中。

    ④出入table數(shù)組的鏈表中有2種方式:

    前插方式:不管數(shù)組table[M]節(jié)點(diǎn)有值與否,都把這個(gè)準(zhǔn)備插入的node節(jié)點(diǎn)作為數(shù)組的根節(jié)點(diǎn)??赡艹霈F(xiàn)2種情況:

    (1)如果table[M]節(jié)點(diǎn)沒(méi)有值,則node節(jié)點(diǎn)作為數(shù)組的根節(jié)點(diǎn)。

    (2)如果table[M]節(jié)點(diǎn)已存在數(shù)據(jù)鏈表,就把這些數(shù)據(jù)鏈表,鏈到這個(gè)準(zhǔn)備插入的node節(jié)點(diǎn)上,以弄得節(jié)點(diǎn)為根節(jié)點(diǎn)放入table[M中]。

    后插方式:可能會(huì)出現(xiàn)的2種情況

      (1)   如果table[M]節(jié)點(diǎn)沒(méi)有值,則node節(jié)點(diǎn)作為數(shù)組的根節(jié)點(diǎn)。

    (2)如果table[M]節(jié)點(diǎn)已存在數(shù)據(jù)鏈表,則把node節(jié)點(diǎn)鏈到該數(shù)據(jù)鏈表的最后一個(gè)節(jié)點(diǎn)上。

    經(jīng)歷以上4個(gè)步驟就完成了hashmap的插入操作,現(xiàn)在解釋一下為什么要打包為node節(jié)點(diǎn)。

    舉個(gè)栗子,假如hashmap.length=16,我們準(zhǔn)備存入ObjectA(OA)和ObjectB(OB),假設(shè)OA經(jīng)過(guò)hash運(yùn)算得到的hashcode是1,OB經(jīng)過(guò)hash運(yùn)算得到hashcode是17,OA和OB進(jìn)行求模運(yùn)算結(jié)果都為1,鏈到鏈表上時(shí),我們get方法的時(shí)候怎么取到正確的值呢,因?yàn)殒湵砩系哪_\(yùn)算都是1.這個(gè)時(shí)候我們就需要通過(guò)hashcode來(lái)識(shí)別這個(gè)鏈表上的哪個(gè)值是OA的value哪個(gè)是OB的value,因?yàn)槲覀円呀?jīng)把hashcode和value打包起來(lái)了。

    補(bǔ)充

    hashmap的table數(shù)組的大小事是2的次冪(不要問(wèn)為什么,源碼定的,他們肯定經(jīng)過(guò)大量的統(tǒng)計(jì)或者運(yùn)算,這是科學(xué))。table數(shù)組默認(rèn)的長(zhǎng)度是16,也就是說(shuō)你new一個(gè)空的hashmap長(zhǎng)度為16,當(dāng)然也提供了一個(gè)給你設(shè)置長(zhǎng)度的方法,但是假如你設(shè)置17,則長(zhǎng)度會(huì)為32,這不難理解。

    hash碰撞

    hash碰撞就是,假如OA、OB...ON經(jīng)過(guò)模運(yùn)算得到的數(shù)組位置相同,那么他們都會(huì)掛在這個(gè)數(shù)組節(jié)點(diǎn)的鏈表上,極端情況想整個(gè)hashmap看起來(lái)像單鏈表。但這種情況這并不是我們想要的結(jié)果。我們可以通過(guò)擴(kuò)容來(lái)盡可能的避免hash碰撞。

    擴(kuò)容 :(意義,在于避免大量的hash碰撞,因?yàn)樵谀承O端情況下,有點(diǎn)像單鏈表)

    閾值 :閾值=table.length* DEFAULT_LOAD_FACTOR (擴(kuò)容系數(shù),默認(rèn)為0.75,也可以自己設(shè)定,一般不做修改)

    hashmap定義:當(dāng)hashmap中的元素個(gè)數(shù)超過(guò)閾值大小時(shí),我們就需要對(duì)table數(shù)組進(jìn)行2倍擴(kuò)容,如從16→32。

    注意:擴(kuò)容后hashmap會(huì)調(diào)用resize(),對(duì)hashmap內(nèi)的數(shù)據(jù)重新計(jì)算所有元素的位置 。 。因?yàn)榧偃缒阒?7/16=1,現(xiàn)在17/32=17,你的位置發(fā)生變化了。

    缺點(diǎn) :

    hashMap因?yàn)橛虚撝档臄U(kuò)容機(jī)制,所以一定會(huì)有空間浪費(fèi),比如0.75的時(shí)候,一定有25%空間被浪費(fèi)掉了??臻g換時(shí)間。

    hashmap是線程不安全的。因?yàn)榭赡茉谝粋€(gè)線程擴(kuò)容(resize()方法執(zhí)行)的情況下,另外一個(gè)線程在get,但是拿不到之前的數(shù)據(jù)了,因?yàn)閿U(kuò)容。所以是線程不安全的。或者線程擴(kuò)容(resize()方法執(zhí)行時(shí),多線程進(jìn)行put的時(shí)候?qū)е碌亩嗑€程數(shù)據(jù)不一致。

    如何線程安全的使用HashMap?使用使用鎖分段技術(shù)或者使用HashTable(Hashtable的方法是Synchronize的,而HashMap不是,其實(shí)也就是鎖機(jī)制起作用)。

    SparseArray(Android為了優(yōu)化內(nèi)存所提供的api)

    特性:key為int,value為object,二分查找的思想,雙數(shù)組,刪除的時(shí)候節(jié)點(diǎn)不刪除,而是把value刪除,避免刪除的時(shí)候數(shù)組還要移動(dòng)。

    SparseArray比HashMap更省內(nèi)存,在某些條件下性能更好,主要是因?yàn)樗苊饬藢?duì)key的自動(dòng)裝箱(int轉(zhuǎn)為Integer類型),它內(nèi)部則是通過(guò)兩個(gè)數(shù)組來(lái)進(jìn)行數(shù)據(jù)存儲(chǔ)的,一個(gè)存儲(chǔ)key,另外一個(gè)存儲(chǔ)value,為了優(yōu)化性能,它內(nèi)部對(duì)數(shù)據(jù)還采取了壓縮的方式來(lái)表示稀疏數(shù)組的數(shù)據(jù),從而節(jié)約內(nèi)存空間,我們從源碼中可以看到key和value分別是用數(shù)組表示。

    為什么是能夠進(jìn)行二分查找呢?從源碼上看key和value分別是用int類型數(shù)組和object數(shù)組表示,所以這也是SparseArray的局限性。

     private int[] mKeys;

     private Object[] mValues;

    為什么說(shuō)SparseArray比HashMap更省內(nèi)存,在某些條件下性能更好?

    因?yàn)镾parseArray有以下一個(gè)特性,首先它是2個(gè)數(shù)組,在數(shù)據(jù)查找的時(shí)候無(wú)疑會(huì)比hashmap快很多,其次在刪除的時(shí)候,SparseArray并不會(huì)把數(shù)組key位置進(jìn)行刪除,而是把key的索引value置位DELETE標(biāo)志(這樣就避免了數(shù)組delete操作后的arraycopy的操作)。當(dāng)我們下次進(jìn)行插入的時(shí)候,若要插入的位置key的索引value為DELETE標(biāo)志,則把數(shù)據(jù)覆蓋給value(只是經(jīng)歷了set操作,并無(wú)其他操作)。否則進(jìn)行add操作(包含arraycopy)。

    所以經(jīng)過(guò)以上的情況,我們可以看出,SparseArray相對(duì)于HashMap,會(huì)越用越快。

    缺點(diǎn)

    (1)SparseArray僅僅能存儲(chǔ)key為int類型的數(shù)據(jù)。

    (2)插入操作需要復(fù)制數(shù)組,增刪效率降低 數(shù)據(jù)量巨大時(shí),復(fù)制數(shù)組成本巨大,gc()成本也巨大。

    (3)數(shù)據(jù)量巨大時(shí),查詢效率也會(huì)明顯下降。

    (4)線程不安全問(wèn)題,類似hashmap

    一般我們?cè)跐M足下面兩個(gè)條件我們可以使用SparseArray代替HashMap:

    (1)數(shù)據(jù)量不大,最好在千級(jí)以內(nèi)

    (2)key必須為int類型,這中情況下的HashMap可以用SparseArray代替:

    ArrayMap(Android為了優(yōu)化內(nèi)存所提供的api)

    ArrayMap和SparseArray差不多,不同的是key類型可以是object類型。

    ArrayMap的2個(gè)數(shù)組,一個(gè)數(shù)組記錄key的hash值,另外一個(gè)數(shù)組記錄Value值。其他存儲(chǔ)方式和運(yùn)行思想和SparseArray一致。

    線程不安全:hashmap、ArrayMap、SparseArray

    以上就是關(guān)于算法優(yōu)化要考慮的內(nèi)容相關(guān)問(wèn)題的回答。希望能幫到你,如有更多相關(guān)問(wèn)題,您也可以聯(lián)系我們的客服進(jìn)行咨詢,客服也會(huì)為您講解更多精彩的知識(shí)和內(nèi)容。


    推薦閱讀:

    算法的五種描述方法(算法的幾種描述方式)

    偽隨機(jī)算法

    快速排名新(快速排名新算法)

    微博推廣(微博推廣平臺(tái))

    重慶一家和興裝飾公司(重慶一家和興裝飾公司案件)