国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

函數(shù)式編程與面向?qū)ο缶幊蘙2]: 靜態(tài)類型語言的表達(dá)力 靜態(tài)類型語言與動態(tài)類型語言

Betta / 740人閱讀

摘要:動態(tài)類型語言的表達(dá)力動態(tài)語言通常更方便開發(fā)較小的項(xiàng)目,因?yàn)榭梢詿o需聲明類型而節(jié)省了很多麻煩。

函數(shù)式編程與面向?qū)ο缶幊蘙2]: 靜態(tài)類型語言的表達(dá)力 靜態(tài)類型語言與動態(tài)類型語言

之劍

2016.5.3 21:43:20

像Java或者C#這樣強(qiáng)類型的準(zhǔn)靜態(tài)語言在實(shí)現(xiàn)復(fù)雜的業(yè)務(wù)邏輯、開發(fā)大型商業(yè)系統(tǒng)、以及那些生命周期很長的應(yīng)用中也有著非常強(qiáng)的優(yōu)勢

下面我們就來學(xué)習(xí)一下這些知識.

有三個(gè)名詞容易混淆:

Dynamic Programming Language (動態(tài)語言或動態(tài)編程語言)

Dynamically Typed Language (動態(tài)類型語言)

Statically Typed Language (靜態(tài)類型語言)

先定義一下標(biāo)準(zhǔn):

強(qiáng)類型語言(靜態(tài)類型語言)

是指需要進(jìn)行變量/對象類型聲明的語言,一般情況下需要編譯執(zhí)行。例如C/C++/Java/C#

弱類型語言(動態(tài)類型語言)

是指不需要進(jìn)行變量/對象類型聲明的語言,一般情況下不需要編譯(但也有編譯型的)。例如PHP/ASP/Ruby/Python/Perl/ABAP/SQL/JavaScript/Unix Shell等等。

1 靜態(tài)類型語言

靜態(tài)類型語言的類型判斷是在運(yùn)行前判斷(如編譯階段),比如C#、java就是靜態(tài)類型語言,靜態(tài)類型語言為了達(dá)到多態(tài)會采取一些類型鑒別手段,如繼承、接口,而動態(tài)類型語言卻不需要,所以一般動態(tài)語言都會采用dynamic typing,常出現(xiàn)于腳本語言中.

不過,是不是動態(tài)類型語言與這門語言是不是類型安全的完全不相干的,不要將它們聯(lián)系在一起!

沒有單元測試或者單元測試沒有達(dá)到語句覆蓋或者更強(qiáng)的弱條件組合覆蓋,從而導(dǎo)致某些非正常流程發(fā)生時(shí),流經(jīng)這些未被測試的語句導(dǎo)致語法錯(cuò)誤而最終整個(gè)程序都掛掉.對于業(yè)務(wù)系統(tǒng)來說,這是非常嚴(yán)重的事情。

1.1 優(yōu)點(diǎn)

靜態(tài)類型語言的主要優(yōu)點(diǎn)在于其結(jié)構(gòu)非常規(guī)范,便于調(diào)試,方便類型安全

現(xiàn)在有這樣一種趨勢,那就是合并動態(tài)類型與靜態(tài)類型在一種語言中,這樣可以在必要的時(shí)候取長補(bǔ)短(下面在第4節(jié)中:在Scala語言的特色時(shí)介紹).

現(xiàn)在開發(fā)效率比以前高多了,主要原因是因?yàn)殚_發(fā)語言和編譯器的進(jìn)步,這個(gè)趨勢,只會繼續(xù)下去,不要抱著過去的教條不放,java也是在不斷改進(jìn)的,加了reflection, 加了assert,加了泛型,下個(gè)版本,也要加腳本支持了。

其實(shí)靜態(tài)類型語言,除了性能方面的考量之外,最大的優(yōu)勢就是可以提供靜態(tài)類型安全,編譯器可以檢查你的每一個(gè)函數(shù)調(diào)用是不是書寫了正確的名字,是不是提供了正確類型的參數(shù)。這樣一個(gè)系統(tǒng),配合自定義類型的功能,可以讓很多錯(cuò)誤(比許多人想象的要多)在編譯時(shí)就能被發(fā)現(xiàn)和定位。

1.2 缺點(diǎn)

缺點(diǎn)是為此需要寫更多的類型相關(guān)代碼,導(dǎo)致不便于閱讀、不清晰明了。

2 動態(tài)類型語言

所謂的動態(tài)類型語言,意思就是類型的檢查是在運(yùn)行時(shí)做的,比如如下代碼是不是合法的要到運(yùn)行時(shí)才判斷(注意是運(yùn)行時(shí)的類型判斷):

</>復(fù)制代碼

  1. def sum(a, b):
  2. return a + b
2.1 優(yōu)點(diǎn)

動態(tài)類型語言的優(yōu)點(diǎn)在于方便閱讀,不需要寫非常多的類型相關(guān)的代碼;動態(tài)語言代表著更快更簡單的技術(shù)大趨勢,因此它將必然成為未來構(gòu)建軟件和互聯(lián)網(wǎng)技術(shù)的主角。

動態(tài)語言足夠靈活,因此雖然它能夠讓人更集中精力思考業(yè)務(wù)邏輯的實(shí)現(xiàn),同時(shí)也向人工智能的方向走得更近一些,但因此它也更依賴于開發(fā)人員本身的技術(shù)功底,初學(xué)者、中級開發(fā)者,難以很好的利用它。 而靜態(tài)類型語言,與我們計(jì)算機(jī)教學(xué)的基本科目(c/pascal/basic)延續(xù)性比較好,所以對于剛畢業(yè)的學(xué)生而言,更好接受和學(xué)習(xí)。

2.2 缺點(diǎn)

缺點(diǎn)自然就是不方便調(diào)試,命名不規(guī)范時(shí)會造成讀不懂,不利于理解等。

3 動態(tài)類型語言的表達(dá)力

動態(tài)語言通常更方便開發(fā)較小的項(xiàng)目,因?yàn)榭梢詿o需聲明類型而節(jié)省了很多麻煩。另外一個(gè)答案是,動態(tài)類型解除了程序員的束縛,可以最大的 發(fā)揮程序員的編程技能,能最有效的利用編程語言里的各種特征和模式。但這些能力都是一把雙刃劍,更多的依賴于程序員的個(gè)人才能,如果用不好,或用的過度, 都會產(chǎn)生負(fù)面的害處。

觀點(diǎn)一:靜態(tài)類型語言因?yàn)轭愋蛷?qiáng)制聲明,所以IDE可以做到很好的代碼感知能力,因?yàn)橛蠭DE的撐腰,所以開發(fā)大型系統(tǒng),復(fù)雜系統(tǒng)比較有保障。

對于像Java來說,IDEA/Eclipse確實(shí)在代碼感知能力上面已經(jīng)非常強(qiáng)了,這無疑能夠增加對大型系統(tǒng)復(fù)雜系統(tǒng)的掌控能力。但是除了Java擁有這么強(qiáng)的IDE武器之外,似乎其他語言從來沒有這么強(qiáng)的IDE。C#的Visual Studio在GUI開發(fā)方面和Wizard方面很強(qiáng),但是代碼感知能力上和Eclipse差的不是一點(diǎn)半點(diǎn)。至于Visual C++根本就是一個(gè)編譯器而已,更不要說那么多C/C++開發(fā)人員都是操起vi吭哧吭哧寫了幾十萬行代碼呢。特別是像Linux Kernel這種幾百萬行代碼,也就是用vi寫出來的阿,夠復(fù)雜,夠大型,夠長生命周期。

觀點(diǎn)二:靜態(tài)語言相對比較封閉的特點(diǎn),使得第三方開發(fā)包對代碼的侵害性可以降到很低。

也就是說靜態(tài)類型語言可以保障package的命名空間分割,從而避免命名沖突,代碼的良好隔離性。但是這個(gè)觀點(diǎn)也缺乏說服力。

靜態(tài)類型語言中C,VB都缺乏良好的命名空間分割,容易產(chǎn)生沖突,但是并沒有影響他們做出來的系統(tǒng)就不夠大,不夠復(fù)雜。

而動態(tài)類型語言中Ruby/Python/Perl都有比較好的命名空間,特別是Python和Perl,例如CPAN上面的第三方庫成噸成噸的,也從來沒有聽說什么沖突的問題。

誠然像PHP,JavaScript這樣缺乏命名空間的動態(tài)語言很容易出現(xiàn)問題,但是這似乎是因?yàn)樗麄內(nèi)狈O機(jī)制導(dǎo)致的,而不是因?yàn)樗麄儎討B(tài)類型導(dǎo)致的吧?

說到大型系統(tǒng),復(fù)雜業(yè)務(wù)邏輯系統(tǒng),Google公司很多東西都是用python開發(fā)的,這也證明了動態(tài)類型語言并非不能做大型的復(fù)雜的系統(tǒng)。其實(shí)我個(gè)人認(rèn)為:

動態(tài)類型語言,特別是高級動態(tài)類型語言,反而能夠讓人們不需要分心去考慮程序編程問題,而集中精力思考業(yè)務(wù)邏輯實(shí)現(xiàn),即思考過程即實(shí)現(xiàn)過程,用DSL描述問題的過程就是編程的過程,這方面像Unix Shell,ruby,SQL,甚至PHP都是相應(yīng)領(lǐng)域當(dāng)之無愧的DSL語言。而顯然靜態(tài)類型語言基本都不滿足這個(gè)要求。

那靜態(tài)類型語言的優(yōu)勢究竟是什么呢?我認(rèn)為就是執(zhí)行效率非常高。所以但凡需要關(guān)注執(zhí)行性能的地方就得用靜態(tài)類型語言。其他方面似乎沒有什么特別的優(yōu)勢。

4 Java語言的問題 4.1 生產(chǎn)力問題

??開發(fā)調(diào)試慢,整體解決方案復(fù)雜。這只是相對而言,對于熟練的開發(fā)這也許不是問題,作為企業(yè)級解決方案而言,Java語言確實(shí)比較繁重,即使依賴了很多自動編譯、動態(tài)加載、打包并部署的持續(xù)集成工具,調(diào)試速度依然很慢,與現(xiàn)在的快節(jié)奏的開發(fā)要求有明顯矛盾. 不過, Java語言的生態(tài)不僅僅是語言, 而是JVM. 所以java語言只是JVM生態(tài)的一個(gè)語言.后來者, 有Scala, Groovy, Fantom, Clojure, Ceylon, Kotlin 和Xtend–mostly等.
??

??

4.2 表達(dá)力問題

??總體來說Java語言的編寫過程更傾向于過程式的開發(fā),在上一層面上封裝了面向?qū)ο蟮奶卣骱托袨椋Z言的設(shè)計(jì)是上個(gè)世紀(jì)九十年代的風(fēng)格,不是說語言本身不好是其抽象能力不夠,即使到了Java8也只是對Lambda表達(dá)式進(jìn)行了支持,因此引入了Functional Interface也即只有一個(gè)方法的接口,和接口里邊的帶具體實(shí)現(xiàn)的方法(為了兼容以前的代碼不得不作出的讓步)。Java語言發(fā)展到現(xiàn)在其語言特性龐大,如果要完全了解需要幾百頁的文檔,在其發(fā)展過程中又只做加法沒又減法,語言慢慢風(fēng)格混雜,變成了現(xiàn)在這種四不像的狀態(tài),函數(shù)式的特性硬生生的嫁接在原來的面向?qū)ο筇匦灾稀?br>??
????一段Java 實(shí)體類代碼

</>復(fù)制代碼

  1. ??
  2. ??
  3. package com.femon.entity;
  4. import java.util.Date;
  5. import javax.persistence.Entity;
  6. import javax.persistence.GeneratedValue;
  7. import javax.persistence.GenerationType;
  8. import javax.persistence.Id;
  9. import javax.persistence.Table;
  10. /**
  11. * @author 一劍 20151223日 下午4:10:18
  12. */
  13. @Entity
  14. @Table(name = "cm_service")
  15. public class Service {
  16. @Id
  17. @GeneratedValue(strategy = GenerationType.AUTO)
  18. private int id;
  19. private String name;
  20. private String host;
  21. private String requestUrl;
  22. private String responseBody;
  23. private String expect;
  24. private String method;
  25. private int paramsType;// 1 : 普通參數(shù)請求串query str
  26. // 2 : header參數(shù)
  27. // 3: 表單方式提交參數(shù)
  28. // 4: json post請求
  29. private String paramsMap;
  30. private String platform;// H5 Web App
  31. private int todaySuccessTimes;
  32. private int todayFailTimes;
  33. /**
  34. * 0 失敗 1 正常
  35. */
  36. private int state;
  37. private int totalSuccessTimes;
  38. private int totalFailTimes;
  39. private Date gmtCreate;
  40. private Date gmtModify;
  41. /**
  42. * platform.
  43. *
  44. * @return the platform
  45. * @since JDK 1.7
  46. */
  47. public String getPlatform() {
  48. return platform;
  49. }
  50. /**
  51. * platform.
  52. *
  53. * @param platform
  54. * the platform to set
  55. * @since JDK 1.7
  56. */
  57. public void setPlatform(String platform) {
  58. this.platform = platform;
  59. }
  60. public String getParamsMap() {
  61. return paramsMap;
  62. }
  63. public void setParamsMap(String paramsMap) {
  64. this.paramsMap = paramsMap;
  65. }
  66. public Date getGmtCreate() {
  67. return gmtCreate;
  68. }
  69. public void setGmtCreate(Date gmtCreate) {
  70. this.gmtCreate = gmtCreate;
  71. }
  72. public Date getGmtModify() {
  73. return gmtModify;
  74. }
  75. public void setGmtModify(Date gmtModify) {
  76. this.gmtModify = gmtModify;
  77. }
  78. public int getTodaySuccessTimes() {
  79. return todaySuccessTimes;
  80. }
  81. public void setTodaySuccessTimes(int todaySuccessTimes) {
  82. this.todaySuccessTimes = todaySuccessTimes;
  83. }
  84. public int getTodayFailTimes() {
  85. return todayFailTimes;
  86. }
  87. public void setTodayFailTimes(int todayFailTimes) {
  88. this.todayFailTimes = todayFailTimes;
  89. }
  90. public int getTotalSuccessTimes() {
  91. return totalSuccessTimes;
  92. }
  93. public void setTotalSuccessTimes(int totalSuccessTimes) {
  94. this.totalSuccessTimes = totalSuccessTimes;
  95. }
  96. public int getTotalFailTimes() {
  97. return totalFailTimes;
  98. }
  99. public void setTotalFailTimes(int totalFailTimes) {
  100. this.totalFailTimes = totalFailTimes;
  101. }
  102. public int getId() {
  103. return id;
  104. }
  105. public void setId(int id) {
  106. this.id = id;
  107. }
  108. public String getName() {
  109. return name;
  110. }
  111. public void setName(String name) {
  112. this.name = name;
  113. }
  114. public String getHost() {
  115. return host;
  116. }
  117. public void setHost(String host) {
  118. this.host = host;
  119. }
  120. public String getRequestUrl() {
  121. return requestUrl;
  122. }
  123. public void setRequestUrl(String requestUrl) {
  124. this.requestUrl = requestUrl;
  125. }
  126. public String getResponseBody() {
  127. return responseBody;
  128. }
  129. public void setResponseBody(String responseBody) {
  130. this.responseBody = responseBody;
  131. }
  132. public int getState() {
  133. return state;
  134. }
  135. public void setState(int state) {
  136. this.state = state;
  137. }
  138. public String getExpect() {
  139. return expect;
  140. }
  141. public void setExpect(String expect) {
  142. this.expect = expect;
  143. }
  144. public String getMethod() {
  145. return method;
  146. }
  147. public void setMethod(String method) {
  148. this.method = method;
  149. }
  150. public int getParamsType() {
  151. return paramsType;
  152. }
  153. public void setParamsType(int paramsType) {
  154. this.paramsType = paramsType;
  155. }
  156. /**
  157. * TODO
  158. *
  159. * @see java.lang.Object#toString()
  160. */
  161. @Override
  162. public String toString() {
  163. return "Service [id=" + id + ", name=" + name + ", host=" + host + ", requestUrl=" + requestUrl
  164. + ", responseBody=" + responseBody + ", expect=" + expect + ", method=" + method + ", paramsType="
  165. + paramsType + ", paramsMap=" + paramsMap + ", platform=" + platform + ", todaySuccessTimes="
  166. + todaySuccessTimes + ", todayFailTimes=" + todayFailTimes + ", state=" + state + ", totalSuccessTimes="
  167. + totalSuccessTimes + ", totalFailTimes=" + totalFailTimes + ", gmtCreate=" + gmtCreate + ", gmtModify="
  168. + gmtModify + "]";
  169. }}

????
而其實(shí),我們早就知道,雖然這些 getter,setter都是模板化的東西, 可以自動生成的,但是這么冗余的代碼,看起來還是不爽!那些寫Java代碼的牛逼程序員老鳥們里面有一個(gè)叫Martin Odersky的, 就整了一個(gè)基于JVM的支持函數(shù)式又無縫融合OOP的程序設(shè)計(jì)語言Scala. 這樣的實(shí)體類代碼,在Scala中寫作如下:
??

</>復(fù)制代碼

  1. package com.steda.entity
  2. import java.util.Date
  3. import javax.persistence.{Entity, GeneratedValue, GenerationType, Id}
  4. import scala.beans.BeanProperty
  5. @Entity
  6. class TedaCase {
  7. @Id
  8. @GeneratedValue(strategy = GenerationType.AUTO)
  9. @BeanProperty
  10. var id: Long = _
  11. @BeanProperty
  12. var name: String = _
  13. @BeanProperty
  14. var interfaceId: Long = _
  15. @BeanProperty
  16. var paramJsonStr: String = _
  17. @BeanProperty
  18. var expectOutput: String = _
  19. @BeanProperty
  20. var actualOutput: String = _
  21. @BeanProperty
  22. var dataSourceId: Long = _
  23. @BeanProperty
  24. var clearSql: String = _
  25. @BeanProperty
  26. var tddlApp: String = _
  27. @BeanProperty
  28. var state: Integer = _
  29. @BeanProperty
  30. var runTimes: Integer = _
  31. @BeanProperty
  32. var owner: String = _
  33. @BeanProperty
  34. var gmtCreate: Date = _
  35. @BeanProperty
  36. var gmtModify: Date = _
  37. }

?我們再看一個(gè)Controller層的寫作, Scala可以與Java生態(tài)中優(yōu)秀的框架無縫融合, 比如Spring,Junit. 尤其當(dāng)今發(fā)展勢頭正猛的SpringBoot, JPA等框架, 更是大大的提升了開發(fā)測試的生產(chǎn)力.
?
?

</>復(fù)制代碼

  1. package com.steda.controller

  2. import java.util.Date

  3. import com.steda.dao.{DataSourceDao, TedaCaseDao}
    import com.steda.entity.TedaCase
    import org.springframework.beans.factory.annotation.Autowired
    import org.springframework.ui.Model
    import org.springframework.util.StringUtils
    import org.springframework.web.bind.annotation._
    import org.springframework.web.servlet.ModelAndView

  4. @RestController
    @RequestMapping(Array("/tedacase"))
    class TedaCaseController @Autowired()(

  5. </>復(fù)制代碼

    1. private val tedaCaseDao: TedaCaseDao,
    2. private val dataSourceDao: DataSourceDao) {
  6. @RequestMapping(Array("/newPage/{interfaceId}"))
    def goNewPage(@PathVariable(value = "interfaceId") interfaceId: Long, model: Model): ModelAndView = {

  7. </>復(fù)制代碼

    1. model.addAttribute("dataSources", dataSourceDao.findAll())
    2. model.addAttribute("interfaceId", interfaceId)
    3. new ModelAndView("/tedacase/new")
  8. }

  9. @RequestMapping(Array("/editPage/{id}"))
    def goEditPage(model: Model, @PathVariable(value = "id") id: Long): ModelAndView = {

  10. </>復(fù)制代碼

    1. val tedacase = tedaCaseDao.findOne(id)
    2. model.addAttribute("tedacase", tedacase)
    3. model.addAttribute("dataSources", dataSourceDao.findAll())
    4. new ModelAndView("/tedacase/edit")
  11. }

  12. @RequestMapping(Array("/detailPage/{id}"))
    def goDetailPage(model: Model, @PathVariable(value = "id") id: Long): ModelAndView = {

  13. </>復(fù)制代碼

    1. val tedacase = tedaCaseDao.findOne(id)
    2. model.addAttribute("tedacase", tedacase)
    3. new ModelAndView("/tedacase/detail")
  14. }

  15. @RequestMapping(value = {

  16. </>復(fù)制代碼

    1. Array("", "/")
  17. }, method = Array(RequestMethod.GET))
    def list(model: Model, @RequestParam(value = "tedaCaseName", required = false) tedaCaseName: String): ModelAndView = {

  18. </>復(fù)制代碼

    1. var tedaCases: java.util.List[TedaCase] = new java.util.ArrayList[TedaCase]
    2. if (!StringUtils.isEmpty(tedaCaseName)) {
    3. tedaCases = tedaCaseDao.findByName(tedaCaseName)
    4. } else {
    5. tedaCases = tedaCaseDao.findAll()
    6. }
    7. model.addAttribute("tedaCases", tedaCases)
    8. model.addAttribute("tedaCaseName", tedaCaseName)
    9. new ModelAndView("/tedacase/list")
  19. }

  20. @RequestMapping(value = Array("/postnew"), method = Array(RequestMethod.POST))
    @ResponseBody
    def newOne(@RequestParam(value = "name") name: String, @RequestParam(value = "interfaceId") interfaceId: Long,@RequestParam(value = "paramJsonStr") paramJsonStr: String,@RequestParam(value = "expectOutput") expectOutput: String, @RequestParam(value = "owner") owner: String,@RequestParam(value = "clearSql") clearSql: String, @RequestParam(value = "dataSourceId") dataSourceId: Long, @RequestParam(value = "tddlApp") tddlApp: String) = {

  21. </>復(fù)制代碼

    1. val teda = new TedaCase()
    2. teda.clearSql = clearSql
    3. teda.dataSourceId = dataSourceId
    4. teda.interfaceId = interfaceId
    5. teda.tddlApp = tddlApp
    6. teda.expectOutput = expectOutput
    7. teda.owner = owner
    8. teda.paramJsonStr = paramJsonStr
    9. teda.name = name
    10. teda.state = -1 // -1 未執(zhí)行 0 失敗 1 成功
    11. teda.runTimes = 0
    12. teda.gmtCreate = new Date()
    13. teda.gmtModify = new Date()
    14. tedaCaseDao.save(teda)
  22. }

  23. @RequestMapping(value = Array("/postedit"), method = Array(RequestMethod.POST))
    @ResponseBody
    def editOne(@RequestParam(value = "id") id: Long, @RequestParam(value = "name") name: String,@RequestParam(value = "paramJsonStr") paramJsonStr: String,@RequestParam(value = "expectOutput") expectOutput: String, @RequestParam(value = "owner") owner: String,@RequestParam(value = "clearSql") clearSql: String, @RequestParam(value = "dataSourceId") dataSourceId: Long, @RequestParam(value = "tddlApp") tddlApp: String) = {

  24. </>復(fù)制代碼

    1. val teda = tedaCaseDao.findOne(id)
    2. teda.clearSql = clearSql
    3. teda.dataSourceId = dataSourceId
    4. teda.tddlApp = tddlApp
    5. teda.expectOutput = expectOutput
    6. teda.owner = owner
    7. teda.paramJsonStr = paramJsonStr
    8. teda.name = name
    9. teda.gmtModify = new Date()
    10. tedaCaseDao.save(teda)
  25. }

  26. }

4.3 資源消耗問題

??Java語言號稱一次編譯,處處運(yùn)行,就在于它基于一個(gè)需要首先先安裝到他所謂的處處的JDK,通過JVM解析編譯完成后的字節(jié)碼來運(yùn)行,跟操作系統(tǒng)的接口也是在JVM托管的。這樣的好處是JVM可以在實(shí)時(shí)運(yùn)行的時(shí)候?qū)ψ止?jié)碼進(jìn)行進(jìn)一步的優(yōu)化,也就是大名鼎鼎的JIT,問題是所有的機(jī)器上都要安裝可以兼容你的應(yīng)用程序的JDK,同時(shí)JVM啟動消耗的資源不少,起碼數(shù)百M(fèi),且啟動速度緩慢,同樣的直接編譯成目標(biāo)操作系統(tǒng)二進(jìn)制可執(zhí)行程序的服務(wù),啟動起來消耗的資源小很多且速度快了很多。

在當(dāng)前差異化的芯片結(jié)構(gòu)中,像C、GO、RUST這種能直接運(yùn)行于操作系統(tǒng)之上不基于某些龐大繁重的VM之上還是很有必要的,比如物聯(lián)網(wǎng)的控制芯片,通常內(nèi)存也只有幾百K,適用性更強(qiáng)一些,而且現(xiàn)在LLVM架構(gòu)的編譯器能夠帶來性能的大幅優(yōu)化,所以編譯依然是一個(gè)很好的選擇,除非JIT能夠逆天的達(dá)到解釋執(zhí)行的極限,因此假如我們看到某些語言有Java語言的開發(fā)能力和內(nèi)存安全特性,依然是可以考慮的。

5 Haskell, Go, Scala 5.1 Haskell

他雖然很老但是一直是作為學(xué)院派函數(shù)式語言的代表,其純函數(shù)式的特性和簡潔漂亮的語法(糖)讓人看了非常舒服,在接觸了面向過程和面向?qū)ο蟮拈_發(fā)后,如果要學(xué)習(xí)一種新的寫代碼的思路,面向函數(shù)式的語言是目前最好的選擇了,而Haskell有是函數(shù)式語言的先驅(qū)和集大成者,很多函數(shù)式語言的語法都是從Haskell借鑒來的。

作為純函數(shù)式語言,Haskell將必然會產(chǎn)生Side-Effect的代碼比如IO操作放到了一起,也即monad風(fēng)格的部分,而其他的函數(shù)可以保證完全的函數(shù)式特征,對于同樣的輸入無論運(yùn)行多少次結(jié)果都是一樣的,跟數(shù)學(xué)中函數(shù)的定義一樣嚴(yán)格,函數(shù)式是一種CPU友好的語言,在當(dāng)前多核計(jì)算機(jī)發(fā)展?fàn)顩r下,函數(shù)式可以讓程序非常安全的在多個(gè)核心上并發(fā)而不用擔(dān)心大量的數(shù)據(jù)交互和side-effect, 從而在語言編譯過程中能夠針對并發(fā)進(jìn)行大幅的優(yōu)化。語言本身的很多寫法也跟數(shù)學(xué)中的定義很接近,比如定義一個(gè)集合

</>復(fù)制代碼

  1. ghci> [x*2 | x <- [1..10]]
  2. [2,4,6,8,10,12,14,16,18,20]

看起來很像數(shù)學(xué)定義,語言可謂優(yōu)雅漂亮,看著很舒服。作為學(xué)院派語言,語言自身設(shè)計(jì)的要求不可謂不嚴(yán)格,完美的闡述了函數(shù)式是什么意思,但是語言的復(fù)雜度較高,學(xué)習(xí)曲線很陡峭,很難保證團(tuán)隊(duì)成員的接收程度,也很難招到相關(guān)的技術(shù)人才。從效率上來講,Haskell可以優(yōu)化的跟C語言的級別類似,但如果對某些特性不熟悉稍微改動一些就會造成性能的大幅下降,對新手不算友好。

同時(shí)在函數(shù)式不那么擅長的領(lǐng)域Haskell的商業(yè)化程度很低,我們不可能都用Haskell來寫一些語法解釋或者正則解析等,涉及IO的分布式存儲和計(jì)算都相對很初級,尤其是對于我們比較感興趣的數(shù)據(jù)挖掘機(jī)器學(xué)習(xí)領(lǐng)域沒有成熟的解決方案,對于Web項(xiàng)目支持的尚可,有優(yōu)秀的Yesod框架作為代表。

總的來說,Haskell值的學(xué)習(xí)但不會在大型的生產(chǎn)環(huán)境中使用。

5.2 Scala

??Scala語言的出現(xiàn)目的很明確,感覺就是為了替代Java而存在,在Java語言越來越力不從心的今天,能夠有一門語言既繼承了它廣大的生態(tài)系統(tǒng),又能夠在表達(dá)能力和開發(fā)效率大大改進(jìn)的情況,可以說是很有希望的。

Scala從一開始就是一門設(shè)計(jì)良好的語言,幾乎完美的集合了函數(shù)式的特性和面向?qū)ο蟮奶匦裕m然他的函數(shù)式不是純函數(shù)式。其面向?qū)ο蟮母杏X更像Ruby而不是Java,所有的東西都是對象,包括簡單類型例如Int,以及函數(shù)本身都是一種對象,這樣在這個(gè)層面實(shí)現(xiàn)了面向?qū)ο蠛秃瘮?shù)式的統(tǒng)一。

</>復(fù)制代碼

  1. Scala運(yùn)行于JVM之上,能夠無縫的使用所有的原來Java語言所開發(fā)的各種庫,語言上作為Java的超集,遷移過來只會更強(qiáng)大而不會打折。

Java8的出現(xiàn)雖然增加了針對集合的stream api以及Lambda表達(dá)式這種函數(shù)式特性的支持,但只會讓人們覺得Java與Scala更像了,即使Java在以后的發(fā)展過程中擁有了所有的Scala的能力.

</>復(fù)制代碼

  1. 打個(gè)比方一塊歪歪扭扭的經(jīng)過各種后期焊接所建造起來的機(jī)器和一個(gè)一開始就有目的的設(shè)計(jì)出來的結(jié)構(gòu)精密、風(fēng)格統(tǒng)一、表達(dá)高效的機(jī)器比較,后者更像前者的重構(gòu),而前者雖然如日中天但已經(jīng)是暮年的四不像,不停的往身上增加各種各樣的功能.

也許Java9會有進(jìn)步,但現(xiàn)在我看到Java8后反而更傾向于Scala。

Scala的元編程能力可以讓他修改自己的語言定義,不只是實(shí)現(xiàn)某些業(yè)務(wù)邏輯,這樣從符號層面上,scala可以做到自洽,除了核心的一些規(guī)則,其他的都可以被自己根據(jù)狀態(tài)調(diào)整所修改,這種能力可以極大的擴(kuò)展語言自身的能力,當(dāng)然也帶來了一些負(fù)面效果,每學(xué)習(xí)一種新的包不只是了解他的API,而是學(xué)習(xí)了一種新的語言,風(fēng)格可能跟scala大不相同。

強(qiáng)有力的證明,大數(shù)據(jù)生態(tài)系統(tǒng)代表-Spark&Kafka,一個(gè)是分布式計(jì)算一個(gè)是分布式大規(guī)模數(shù)據(jù)吞吐,都證明了Scala的開發(fā)能力和效率。

</>復(fù)制代碼

  1. Scala的問題其實(shí)也有跟Java類似的地方,首先這個(gè)語言雖然是重新設(shè)計(jì)的,但是使用起來復(fù)雜度依然很高,對于范型的繼承,+-等范型標(biāo)注不好理解,

5.3 Go

??Go語言目前呈現(xiàn)了很火爆的趨勢,由于其簡單,整個(gè)語言的specification也不過十幾頁,最多半天就能夠完全了解并上手寫一些小工具。GO語言最初是希望替代C和C++成為新的系統(tǒng)語言,自帶GC垃圾回收,不過最終更多的是替代了python來開發(fā)一些服務(wù)或者工具,并沒有成為系統(tǒng)級別的語言。
??Go語言有很多的優(yōu)點(diǎn),編譯速度快,有協(xié)程和Channel做并發(fā)支持和通信,有很多官方的網(wǎng)絡(luò)協(xié)議的庫,非常適合于寫一些網(wǎng)絡(luò)服務(wù),啟動一個(gè)http的接口服務(wù)只需要幾行代碼。目前github上也有大量的第三方項(xiàng)目使用go語言來開發(fā)應(yīng)用或者擴(kuò)展go的功能,在使用的時(shí)候直接import即可。Go的多返回機(jī)制也還不錯(cuò),節(jié)省了大量的無意義數(shù)據(jù)結(jié)構(gòu)和不可讀的Map的使用,總的來說Go在其擅長的領(lǐng)域生產(chǎn)力很高,寫起來比較流暢,靜態(tài)類型也足夠的安全。目前Docker生態(tài)系統(tǒng)里邊的各種工具都是Go來寫的。最新發(fā)布的1.5版本使得交叉編譯更加容易,靜態(tài)鏈接庫的方式使生成的可執(zhí)行文件在相同CPU架構(gòu)的操作系統(tǒng)都能運(yùn)行,減少了額外查找依賴的問題,對我們現(xiàn)在基本同構(gòu)的Linux服務(wù)器而言,也打到了一次編譯處處運(yùn)行的目的。同時(shí)Go語言在運(yùn)行時(shí)消耗的資源也比Java要小,啟動速度更快,確實(shí)是輕量級服務(wù)的優(yōu)選。
??

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/65859.html

相關(guān)文章

  • JavaScript語言特性以及重要版本

    摘要:通常一個(gè)完成的不僅僅包含了還包括了以及相關(guān)版本該版本在中使用。基于原型函數(shù)先行的語言使用基于原型的的繼承機(jī)制,函數(shù)是的第一等公民其他相關(guān)的語言特性編譯型語言把做好的源程序全部編譯成二進(jìn)制代碼的可運(yùn)行程序。 轉(zhuǎn)載請注明出處,創(chuàng)作不易,更多文章請戳 https://github.com/ZhengMaste... 前言:JavaScript誕生于1995年,它是一門腳本語言,起初的目...

    Yangder 評論0 收藏0
  • 第3章:抽象數(shù)據(jù)類型(ADT)和面向對象編程(OOP) 3.1數(shù)據(jù)類型類型檢查

    摘要:所有變量的類型在編譯時(shí)已知在程序運(yùn)行之前,因此編譯器也可以推導(dǎo)出所有表達(dá)式的類型。像變量的類型一樣,這些聲明是重要的文檔,對代碼讀者很有用,并由編譯器進(jìn)行靜態(tài)檢查。對象類型的值對象類型的值是由其類型標(biāo)記的圓。 大綱 1.編程語言中的數(shù)據(jù)類型2.靜態(tài)與動態(tài)數(shù)據(jù)類型3.類型檢查4.易變性和不變性5.快照圖6.復(fù)雜的數(shù)據(jù)類型:數(shù)組和集合7.有用的不可變類型8.空引用9.總結(jié) 編程語言中的數(shù)據(jù)...

    zhangqh 評論0 收藏0
  • JVM 平臺上各種語言開發(fā)指南[z]

    摘要:我們的目標(biāo)是建立對每一種語言的認(rèn)識,它們是如何進(jìn)化的,未來將走向何方。有點(diǎn)的味道是堅(jiān)持使用動態(tài)類型,但唯一還收到合理擁泵的編程語言,然而一些在企業(yè)的大型團(tuán)隊(duì)中工作的開發(fā)者擇認(rèn)為這會是的一個(gè)缺陷。 為什么我們需要如此多的JVM語言? 在2013年你可以有50中JVM語言的選擇來用于你的下一個(gè)項(xiàng)目。盡管你可以說出一大打的名字,你會準(zhǔn)備為你的下一個(gè)項(xiàng)目選擇一種新的JVM語言么? 如今借助來自...

    phodal 評論0 收藏0
  • Javagroovy混編 —— 一種兼顧接口清晰和實(shí)現(xiàn)敏捷開發(fā)方

    摘要:原文鏈接有大量平均水平左右的工人可被選擇參與進(jìn)來這意味著好招人有成熟的大量的程序庫可供選擇這意味著大多數(shù)項(xiàng)目都是既有程序庫的拼裝,標(biāo)準(zhǔn)化程度高而定制化場景少開發(fā)工具測試工具問題排查工具完善,成熟基本上沒有團(tuán)隊(duì)愿意在時(shí)間緊任務(wù)重的項(xiàng)目情況 原文鏈接:http://pfmiles.github.io/blog/java-groovy-mixed/ 有大量平均水平左右的工人可被選擇、參與...

    LittleLiByte 評論0 收藏0
  • SegmentFault 技術(shù)周刊 Vol.32 - 七夕將至,你對象”還好嗎?

    摘要:很多情況下,通常一個(gè)人類,即創(chuàng)建了一個(gè)具體的對象。對象就是數(shù)據(jù),對象本身不包含方法。類是相似對象的描述,稱為類的定義,是該類對象的藍(lán)圖或原型。在中,對象通過對類的實(shí)體化形成的對象。一類的對象抽取出來。注意中,對象一定是通過類的實(shí)例化來的。 showImg(https://segmentfault.com/img/bVTJ3H?w=900&h=385); 馬上就要到七夕了,離年底老媽老爸...

    李昌杰 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<