比学习新技术更重要的是思维的改变
程序員是一個(gè)苦逼的行業(yè),其中重要的一點(diǎn)就是行業(yè)專業(yè)知識(shí)更新的速度非???#xff0c;超過其他絕大部分行業(yè),尤其是前臺(tái)開發(fā),這些天各種框架思想如雨后春筍層出不窮,有時(shí)候買了一本書,書還沒有學(xué)完,技術(shù)可能已經(jīng)更新或者被淘汰。那么,作為程序員的我們,怎么樣才能不被爆炸的知識(shí)擊昏,切實(shí)掌握真正屬于自己的技術(shù)呢?
從我個(gè)人的心得來說,學(xué)習(xí)技術(shù)應(yīng)該重點(diǎn)學(xué)習(xí)那種新思想新角度的技術(shù),并使用新的思維來寫新學(xué)習(xí)的技術(shù)。大部分技術(shù)人員的問題不在于前者,而在于學(xué)習(xí)了新技術(shù),卻還是使用老的思維來寫新技術(shù),就好比用馬拉火車一樣,寫者落淚看者傷心!
舉例,在前臺(tái)開發(fā)中,MVVM框架的出現(xiàn),相對(duì)于jquery天下的前臺(tái)是一個(gè)非常大的改變,我們學(xué)習(xí)mvvm框架的時(shí)候,首先第一步要從思維上認(rèn)識(shí)到這2種技術(shù)的不同,要理解數(shù)據(jù)驅(qū)動(dòng)概念,理解 “jquery是死的,mvvm是活的” 這點(diǎn),而不是只是把mvvm框架當(dāng)作一個(gè)模板框架來使用。而在實(shí)際工作中,出現(xiàn)過有些水平較差的開發(fā)人員,還在使用jquery的思維來寫vue的框架,結(jié)果是vue的好處沒有享受到,整個(gè)開發(fā)部署過程還變得復(fù)雜。
后臺(tái)開發(fā)里面,jdk8由于接口默認(rèn)實(shí)現(xiàn)特性,絕對(duì)算得上是一個(gè)里程碑,其中最重要的函數(shù)式編程的思想。lambda表達(dá)式和stream流的學(xué)習(xí)不算復(fù)雜,但你學(xué)會(huì)了api的使用,你就真的掌握了函數(shù)式編程嗎?我看未必!
我們來看一道題目,計(jì)算 集合中 DeptId 和 Type 相同的數(shù)據(jù)的num總和。需求很常見,看著很簡(jiǎn)單,各位寫寫看?
import?lombok.Data;import?java.util.ArrayList; import?java.util.List; import?java.util.stream.Collectors;/***??計(jì)算?集合中?DeptId?和?Type?相同的數(shù)據(jù)的num總和*/ public?class?Test?{public?static?void?main(String[]?args)?{List<DataBean>?totalStocks?=?new?ArrayList<>();DataBean?stock1?=?new?DataBean();stock1.setDeptId(2);stock1.setType(2);stock1.setNum(2);totalStocks.add(stock1);DataBean?stock2?=?new?DataBean();stock2.setDeptId(2);stock2.setType(2);stock2.setNum(3);totalStocks.add(stock2);DataBean?stock3?=?new?DataBean();stock3.setDeptId(3);stock3.setType(3);stock3.setNum(5);totalStocks.add(stock3);DataBean?stock4?=?new?DataBean();stock4.setDeptId(3);stock4.setType(3);stock4.setNum(4);totalStocks.add(stock4);DataBean?stock5?=?new?DataBean();stock5.setDeptId(4);stock5.setType(4);stock5.setNum(10);totalStocks.add(stock5);}}@Data class?DataBean?{private?int?type;private?int?deptId;private?int?num; }這條題目是我群里的人問的,他自己用stream寫了一個(gè),覺得寫的不好,問我應(yīng)該怎么樣寫,我當(dāng)時(shí)把這道題目發(fā)在群里面,結(jié)果發(fā)現(xiàn)大部分寫得都不太好(建議大家先不要往下看,自己打開ide寫寫試試)。其中一個(gè)常見錯(cuò)誤是stream操作中修改了數(shù)據(jù),如
//group Map<String,?List<DataBean>>?gourps?=?totalStocks.stream().collect(Collectors.groupingBy(e?->?e.getDeptId()?+?":"?+?e.getType()));//?reduce(錯(cuò)誤的寫法) List<DataBean>?result?=?gourps.values().stream().reduce(list?->?list.stream().reduce((e1,?e2)?->?{e2.setNum(e1.getNum()?+?e2.getNum());return?e2; }).get()) //?toList .collect(Collectors.toList());System.out.println(result);還有一種是,自己new了一個(gè)ArrayList,然后再流操作之中往list里面加數(shù)據(jù)的。至于group2次的就不評(píng)論了。
我們學(xué)習(xí)函數(shù)式編程里面,函數(shù)式強(qiáng)調(diào)函數(shù)必須是純函數(shù),不能修改數(shù)據(jù),而且是冪等,在stream里面,任何修改數(shù)據(jù)的行為都是不應(yīng)該的,修改數(shù)據(jù)的時(shí)候應(yīng)該返回新對(duì)象。所以在里面set數(shù)據(jù)的,或者往list里面增加數(shù)據(jù)的,都是不好的寫法!我們學(xué)習(xí)了函數(shù)式編程,就應(yīng)該遵守他的規(guī)則和思想。上面的題目,我的寫法如下:
List<DataBean>?result?=?totalStocks.stream()//group.collect(Collectors.groupingBy(e?->?e.getDeptId()?+?":"?+?e.getType()))//?分組后的list做reduce.values().stream().map(list?->?list.stream().reduce(Test::combine).get())//?收集到list.collect(Collectors.toList());System.out.println(result);private?static?DataBean?combine(DataBean?e1,?DataBean?e2){DataBean?e?=?new?DataBean();e.setDeptId(e1.getDeptId());e.setType(e1.getType());e.setNum(e1.getNum()?+?e2.getNum());return?e; }我們?cè)诳戳硗庖环N場(chǎng)景,由于不按照函數(shù)式思維編寫代碼,在不同的jdk版本中,結(jié)果不一樣,可能導(dǎo)致bug
import?java.lang.management.ManagementFactory; import?java.util.ArrayList; import?java.util.Collections; import?java.util.List;class?Demo{public??String?msg?=?"初始值"; }public?class?LambdaDemo2?{public?static?void?main(String[]?args)?{System.out.println("jdk版本:"+ManagementFactory.getRuntimeMXBean().getVmVersion());List<Demo>?demos??=?new?ArrayList<Demo>();demos.add(new?Demo());demos.add(new?Demo());//?這里peek中修改了對(duì)象,產(chǎn)生了副作用(side-effects)long?count?=?demos.stream().peek(demo?->?demo.msg?=?"peek中修改了").count();System.out.println(count);//?jdk8下下面的demo已經(jīng)改變//?jdk10下沒有demos.stream().forEach(demo?->?System.out.println(demo.msg));} }peek函數(shù),按照函數(shù)式編程的規(guī)范,是調(diào)試用的,是個(gè)中間操作,如果你在里面修改了對(duì)象,看上去沒有問題,但是在JDK8和JDK10中,2種運(yùn)行結(jié)果不一致,JDK10種peek方法直接跳過了。
所以,我們學(xué)習(xí)一個(gè)新技術(shù),可以從下面幾個(gè)層次了解推進(jìn),產(chǎn)生的背景?和之前的技術(shù)有什么區(qū)別?他的思想(風(fēng)格)是什么?主要的API和套路。如函數(shù)式編程,要了解和命令式編程的區(qū)別,一開始可能不太理解,多看幾個(gè)貼,先有個(gè)模糊的概念。然后再看看函數(shù)式是怎么樣的風(fēng)格?而不是當(dāng)作一個(gè)新的類庫/工作類來使用(很多人是當(dāng)作工具類使用的想法)。最后系統(tǒng)學(xué)習(xí)api。當(dāng)然最重要的還是多寫,寫完之后看看是不是符合函數(shù)式編程的風(fēng)格,如果看著別扭那就是那個(gè)環(huán)節(jié)出現(xiàn)了問題。
總結(jié),我們學(xué)習(xí)新技術(shù)的同時(shí),除了API的使用之外,最重要的是改變思維,使用新技術(shù)的思維來寫新的代碼,一開始可能有點(diǎn)痛苦,但多寫幾次之后就會(huì)適應(yīng),就會(huì)感覺到新的技術(shù)給我們帶來的好處,這是成長(zhǎng)的必經(jīng)之路!
總結(jié)
以上是生活随笔為你收集整理的比学习新技术更重要的是思维的改变的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 2019年我建议你做好三件事情
- 下一篇: 漫画:通俗易懂的进程与线程解释