10月收穫與體會

平時都會在印象筆記寫日報和週報,現在嘗試寫一寫月報,總結10月份的收穫與體會,具體的內容如下:

自我學習: 本月在工作之餘,學習了什麼知識

收穫體會: 本月在工作學習過程中,有哪些收穫或者感悟體會,有哪些優秀點,繼續堅持。

待改進的地方: 本月工作學習過程中,有哪些地方做的不好,以後需要改進。

自我學習

學習清單

  • 1、Glide學習
  • 2、完成《第一代碼》(第2版)的重溫,用Kotlin寫書中例子
  • 3、JAVA多線程——線程安全之原子性,有序性和可見性
  • 4、實現勻速加載的進度條的方法
  • 5、學習單元測試
  • 6、學習Flutter

1、 Glide學習

主要跟着郭霖的Glide專欄系列學習,最後自己總結輸出一篇博客

Glide的使用與解析

2、 完成《第一代碼》(第2版)的重溫,用Kotlin寫書中例子

在寫kotlin時印象較深的地方有

  • 沒有Java的switch,Kotlin用when代替

例如

override fun onOptionsItemSelected(item: MenuItem?): Boolean {
    when (item?.itemId) {
        android.R.id.home -> {
            mDrawerLayout?.openDrawer(GravityCompat.START)
        }
        R.id.backup -> {
            Toast.makeText(this, "You clicked Backup", Toast.LENGTH_SHORT).show()
        }
        R.id.delete -> {
            Toast.makeText(this, "You clicked Delete", Toast.LENGTH_SHORT).show()
        }
        R.id.setting -> {
            Toast.makeText(this, "You clicked Setting", Toast.LENGTH_SHORT).show()
        }
    }
    return true
}
  • 多用Kotlin的內聯函數美化代碼,如letrunapply等等

let:函數塊用it指代該對象,返回值是函數塊的最後一行

run: 函數塊不需要it,返回值是函數塊的最後一行

apply: 函數塊不需要it,返回值是傳入對象的本身 (多用於初始化實例賦值)

推薦閱讀: Kotlin系列之let、with、run、apply、also函數的使用

  • Kotlin的數組表示
val fruits: Array<Fruit> = arrayOf(
      Fruit("Apple", R.drawable.apple),
      Fruit("Banana", R.drawable.banana))
      
或者

var fruitList = ArrayList<Fruit>()      

3、JAVA多線程——線程安全之原子性,有序性和可見性

  • 原子性:指操作是不可分的,如a++操作,實際是取a、++、賦值a三個操作,這三個操作要不可分。

  • 可見性:指一個操作執行的結果需要對另一個操作可見,即緩存、主內存同時改變(參考下面推薦文章的內存模型圖)。使用volatile關鍵字實現

  • 有序性:指程序的代碼執行順序和語句的順序是一致的。
    這是因爲在Java內存模型中,允許編譯器和處理器對指令進行重排序,
    但是重排序過程不會影響到單線程程序的執行,卻會影響到多線程併發執行的正確性。

推薦閱讀: JAVA多線程——線程安全之原子性,有序性和可見性

4、實現勻速加載的進度條的方法

方法(1):使用Timer實現網頁勻速加載的進度條

參考 https://blog.csdn.net/qq_33589836/article/details/54616262

方法(2):使用Timer實現網頁勻速加載的進度條

private static final int DURATION_TIME = 2000;
private int mCurrentProcess = 0;

private void startFakeProgress() {
    ValueAnimator anim = ValueAnimator.ofInt(0, 90);
    anim.setDuration(DURATION_TIME);
    anim.setInterpolator(new AccelerateInterpolator());
    anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
        @Override
        public void onAnimationUpdate(ValueAnimator animation) {
            int progress = (int) animation.getAnimatedValue();
            if (progress > mCurrentProcess) {
                mCurrentProcess = progress;
                getView().updateDownloadDialog(progress);
            }
        }
    });
    anim.start();
}

5、學習單元測試

  • 如何創建測試類

可以自己手動在相應目錄創建測試類,AS也提供了一種快捷方式:

選擇對應的類->將光標停留在類名上->按下ALT + ENTER->在彈出的彈窗中選擇Create Test

  • 如何在測試類中獲取Context

如果要獲取Context,那麼需要加儀器化測試,可以採用常用單元測試開源庫Robolectric 配置如下

(1)在app model添加配置

android { 
	... 
	testOptions { 
		unitTests { 
			includeAndroidResources = true 
		} 
	} 
}

dependencies { 
	... 
	testImplementation "org.robolectric:robolectric:3.8” 
}

(2)在app/src/test/java/添加這個類,後續類可以繼承這個類,然後調用getContext

@RunWith(RobolectricTestRunner.class)
@Config(manifest = Config.NONE, application = Application.class)
public abstract class RoboBase {
    protected Context getContext() {
        return RuntimeEnvironment.application;
    }
}

推薦閱讀: Android單元測試只看這一篇就夠了

6、學習Flutter

跟着Flutter官網學習

官網:https://flutter.io/get-started/install/

自己輸出一篇博客:Flutter的安裝與使用

收穫體會

1、完成項目先保證整體流程的完成。怎麼算整體流程?即大部分用戶、大部分機型的可用性。

爲什麼呢?因爲Android的版本很多、各個廠商偶爾還有定製,所以如果糾結太多細節,忽略整個流程的完整度,那麼會導致自己完成項目的效率變慢(直觀看,就是做需求太慢)。

以前自己爲了追求完美,每個細節都追究,結果費力不討好,甚至深陷泥潭,需求開發慢,還加班很晚。這種情況就本末倒置了,只見樹葉不見森林。

因此,以後自己先把握整體進度,完成整體需求框架。如果有細節問題,先記錄下來,等開發完整體流程,再解決細節問題。

2、一個人精力是有限的,晚上很晚回家,就沒有太多精力做其他事情,即便想做,注意力也不集中,還不如早早休息,或者簡單看書。

3、做好一件事件需要時間,比如寫博客,需要一點點完善補充,急不來。也需要自己平時一點點寫。

4、某晚又加班太晚,主要是因爲發版前排查一個問題,最終也沒有什麼結論,停止發版,第二天再發版。

很多事情都無法預測,計劃趕不上變化,想做什麼事情都需要提前做,遇到突發情況就要推遲了。

5、讀完《碼農翻身》,受益匪淺,做了一些摘錄

教訓:讀書太多,而實踐太少

吸取教訓:不僅看書,還去讀JUnit源碼、Spring源碼、Hsqldb源碼、Jive源碼,再加上工作寫的大量代碼

凡事必先騎上虎背,勇敢地邁出去,努力地爭取一下,你就會發現自己登上了更高一層的臺階。逼着自己趕緊進入未知領域,拼命地去學。

養成計算機的思維方式,這個基本功的訓練就是數據結構和算法,劉欣老師的經驗是多做習題,讓這種思維在腦子裏固化,以後的編程就可以信手拈來。

計算機的組成原理、操作系統、編譯原理、計算機網絡、數據庫、彙編語言等等,融會貫通

停下來,思考,纔是進步的本質。

寫出漂亮代碼並不容易,需要思路清晰,有良好的編程基礎,有優秀的抽象能力,以及對一門語言的熟練掌握。

每一個季度定一個小目標,努力達成,獲得成就感,就能刺激自己更進一步。

6、看生老闆的優化分支,體會良多,這就是跟老闆的差距,老闆嘗試不少實踐,想必老闆的技能又提升不少,實踐見真理。

7、終於把以前遺留的一個問題解決了。

出現問題還是一樣解決方式,先分析問題,比如這次是加載慢的問題,那麼需要找出耗時的地方。

剛開始不確定哪裏比較耗時,那麼只能打log來定位。然後不斷縮小範圍,找到最耗時的地方,比如這次是獲取錢包數據時的Json解析耗時。

這個操作大概20ms,而且是在循環裏,有近1000次循環,意味20秒。找到根源,可以把耗時操作放在循環外,減少不必要的耗時操作。

8、堅持解決問題的方法論,避免焦躁,分析問題,找出可能的原因,逐一驗證。

9、主動性,主動跟蹤問題,雖然有些問題不是自己造成,但是自己主動去查找,從錯誤中學習。

10、問題跟到底,針對問題打破砂鍋問到底,跟蹤問題的根本原因,從中學到不少東西。

例如,有一個空指針問題,正常加個判null就行,但是需要找原因,爲什麼會產生null指針,如下最後一行token.getData()空指針

List<Token> tokenList = coinInfo.getTokens()

if(tokenList == null) {
	return;
}

for(Token token: tokenList) {
   TokenData data = token.getData();
}

正常token不爲null,除非list add一個空對象,或者什麼場景導致tokenList有數據,但讀取其中一個數據時token爲空

經排查,發現存在多線程操作,在另外一個線程中存在CoinInfo.addToken,而且沒有加鎖。
在併發情況,可能導致tokenList的size+1,但是數據還沒有添加進去,這時候線程切換時就獲取token爲空。
因此根本解決方法不是加判null處理,而是在addToken時加鎖同步

反思:以後在List add數據時,注意有沒有多線程問題,如有記得加同步,因爲ArrayList的add方法不是線程安全

待改進的地方

1、提高晚上工作的效率。

後續改進:晚上加班很晚的時候,需要評估工作量,不要做太多無所謂的工作,晚上多留些時間給自己充電。

2、提前完成任務,提高計劃執行力。週末因爲一些臨時突發事情,導致事情沒有完成,要推遲。

後續改進:把一些任務提前完成,避免突然情況。

3、某周學習內容比較雜,還是一件一件來好。

後續改進:先專心完成一件事件,再去做另一件事件。

4、時間安排不夠合理,比如週五調休,出去拍景後回家修圖太久,而且晚上只學習了一會(看漫威電影了)。前幾天一直在學習,到週五就放鬆過頭了。

後續改進:以後安排好時間,持續學習,延遲滿足感。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章