成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

漫談編程語(yǔ)言的數(shù)據(jù)親和力

開發(fā) 前端
語(yǔ)言的數(shù)據(jù)親和力(Data Affinity)指的是語(yǔ)言與某種數(shù)據(jù)格式之間的相容程度,它主要取決于語(yǔ)言的數(shù)據(jù)模型,類型系統(tǒng),以及庫(kù)的支持等。語(yǔ)言對(duì)某種數(shù)據(jù)格式親和力越強(qiáng),則操作某類數(shù)據(jù)越容易。

目前,程序設(shè)計(jì)語(yǔ)言似乎進(jìn)入了一個(gè)蓬勃發(fā)展的時(shí)期,JavaScript、Perl、Python、Ruby、Groovy等一批較新的語(yǔ)言正越來(lái)越多地被熟悉和使用,而C++、C#、Java等主流語(yǔ)言也在不斷地融入函數(shù)式和動(dòng)態(tài)性特征。程序員的百寶箱中可供選擇的寶貝是越來(lái)多了,而社區(qū)中關(guān)于語(yǔ)言間的比較和爭(zhēng)論也更為熱烈,我們常常見到關(guān)于“面向過(guò)程和面向?qū)ο蟮谋容^”、“動(dòng)態(tài)語(yǔ)言和靜態(tài)語(yǔ)言的比較”、“命令式和函數(shù)式范式的比較”等比較。我注意到這類討論的關(guān)注點(diǎn)多集中于設(shè)計(jì)相關(guān)話題,如“動(dòng)態(tài)語(yǔ)言的Duck typing多態(tài)和靜態(tài)語(yǔ)言的繼承多態(tài)的比較”,“Prototype based和Class based的比較”等。但我認(rèn)為還有一個(gè)十分重要的方面值得關(guān)注,這就是數(shù)據(jù)處理。

數(shù)據(jù)處理之所以重要是因?yàn)椴徽撌潜镜匦畔⒋鎯?chǔ)還是系統(tǒng)間信息交換都需要建立在一定的數(shù)據(jù)格式基礎(chǔ)上。另外,不管語(yǔ)言屬于那種范式,設(shè)計(jì)上采用什么模式,在微觀層次上程序很大一部分工作都是在做數(shù)據(jù)處理。所以,從數(shù)據(jù)處理角度比較和理解語(yǔ)言間的差異有重要的現(xiàn)實(shí)意義。雖然數(shù)據(jù)通常是平臺(tái)和語(yǔ)言無(wú)關(guān)的,但不同的語(yǔ)言在處理某種格式的數(shù)據(jù)時(shí)會(huì)表現(xiàn)出不同的難度,甚至某些數(shù)據(jù)格式只能采用特定的語(yǔ)言才能實(shí)現(xiàn),這就是數(shù)據(jù)親和力的不同。

語(yǔ)言的數(shù)據(jù)親和力(Data Affinity)指的是語(yǔ)言與某種數(shù)據(jù)格式之間的相容程度,它主要取決于語(yǔ)言的數(shù)據(jù)模型,類型系統(tǒng),以及庫(kù)的支持等。語(yǔ)言對(duì)某種數(shù)據(jù)格式親和力越強(qiáng),則操作某類數(shù)據(jù)越容易。

二進(jìn)制字節(jié)塊格式

在偏底層的操作系統(tǒng)、嵌入式和通信系統(tǒng)中,二進(jìn)制的字節(jié)塊是最常見的一種數(shù)據(jù)格式。二進(jìn)制數(shù)據(jù)布局緊湊和接近機(jī)器的特點(diǎn)使得它常常作為系統(tǒng)間通信或系統(tǒng)文件的數(shù)據(jù)格式。但一般高級(jí)語(yǔ)言不方便直接和0101打交道,而是基于記錄、結(jié)構(gòu)體和類等結(jié)構(gòu)化表示操作數(shù)據(jù),這就存在著在底層的二進(jìn)制字節(jié)塊和高層的結(jié)構(gòu)化數(shù)據(jù)之間的轉(zhuǎn)換問(wèn)題。

C語(yǔ)言作為最主要的系統(tǒng)語(yǔ)言具有很高的字節(jié)塊數(shù)據(jù)親和力。這不僅因?yàn)镃語(yǔ)言具有指針可以直接訪問(wèn)內(nèi)存以外,還因?yàn)镃的結(jié)構(gòu)體(struct)可以和字節(jié)塊建立起直接的映射關(guān)系。例如,在基于Socket連接的分布式系統(tǒng)中服務(wù)器端和客戶端通過(guò)二進(jìn)制的字節(jié)數(shù)據(jù)進(jìn)行通信,通信雙方只要事先定義共用的結(jié)構(gòu)體,發(fā)送方先創(chuàng)建相應(yīng)的結(jié)構(gòu)體變量并填充字段,然后把變量對(duì)應(yīng)的內(nèi)存塊copy到Socket,接收方從Socket讀取字節(jié)塊,然后把字節(jié)塊強(qiáng)制類型轉(zhuǎn)換為相應(yīng)的結(jié)構(gòu)體指針即可讀取個(gè)字段信息。整個(gè)過(guò)程中通信的雙方都沒(méi)有復(fù)雜的信息編碼和解碼的過(guò)程。示例代碼如下:

  1. struct t_data {  
  2.     int version;  
  3.     char type[10];  
  4.     float value;  
  5. }; 
  1. //發(fā)送方  
  2. struct t_data data;  
  3. data.version = 1;  
  4. strcpy(data.type, “degree”);  
  5. data.value = 189.0;  
  6. send(socket,  (char*)&data, sizeof(data)); 
  1. //接收方  
  2. struct t_data data;  
  3. read(socket,  (char*)&data, sizeof(data));  
  4. printf(“%d, %s, %f”, data.version, data.type, data.value); 

上面的方法在實(shí)際應(yīng)用中還需要注意內(nèi)存對(duì)齊問(wèn)題和大小端問(wèn)題。內(nèi)存對(duì)齊問(wèn)題可以通過(guò)編譯器預(yù)處理命令來(lái)進(jìn)行控制,保證內(nèi)存中struct結(jié)構(gòu)與傳輸?shù)淖止?jié)塊具有相同的對(duì)齊方式;大小端問(wèn)題需要通信的雙方采用同樣的大小端方式,否則就需要進(jìn)行轉(zhuǎn)換。

C++可以完全兼容C的結(jié)構(gòu)體,但C++的類(包括class和struct)中如果定義了虛函數(shù),則會(huì)喪失結(jié)構(gòu)的字節(jié)塊數(shù)據(jù)親和力,這是C++編程時(shí)需要權(quán)衡的一個(gè)因素。而除了C/C++,其他語(yǔ)言中則難以見到字節(jié)塊數(shù)據(jù)親和力,其原因在于C/C++允許控制結(jié)構(gòu)體/對(duì)象的內(nèi)存布局,并允許對(duì)指針進(jìn)行非類型安全的強(qiáng)制類型轉(zhuǎn)換,這都是在Java,C#等語(yǔ)言中不允許的。所以,在Java、C#中進(jìn)行字節(jié)塊的編碼解碼就只能按照協(xié)議一個(gè)字段一個(gè)字段地按偏移量和長(zhǎng)度進(jìn)行解析。C/C++的指針以及結(jié)構(gòu)體和內(nèi)存的直接映射帶來(lái)了對(duì)字節(jié)塊數(shù)據(jù)的親和力,但同時(shí)也留下了內(nèi)存訪問(wèn)和類型安全的隱患;而Java、C#在擁有引用安全和類型安全的同時(shí)也失去了對(duì)字節(jié)塊數(shù)據(jù)的親和力。

文本格式

文本格式是另一種十分常見的數(shù)據(jù)格式。《Unix編程藝術(shù)》是這樣評(píng)價(jià)文本格式的:"Text streams are a valuable universal format because they're easy for human beings to read, write, and edit without specialized tools ”。基于文本流的管道處理是一種備受贊譽(yù)的Unix風(fēng)格。Shell可以通過(guò)管道把各種功能單一的命令串聯(lián)起來(lái),讓文本流在管道上流動(dòng),因而Shell語(yǔ)言具有很好的文本數(shù)據(jù)親和力。許多文本數(shù)據(jù)處理任務(wù)Bash都可以一行搞定,這就是Hacker們酷愛(ài)的One Liner風(fēng)格。

下面我們來(lái)看兩個(gè)用Bash進(jìn)行文本處理的例子:

1. 統(tǒng)計(jì)當(dāng)前目錄下的gz文件數(shù)目:

ls –l *.gz | wc –l

2. 在Web服務(wù)器日志service.log中統(tǒng)計(jì)2011年6月26和27兩天中每天各頁(yè)面的PV

cat service.log | grep ^2011-06-2[6-7] | cut –d ‘ ‘ –f 1, 3 | sort | uniq –c

service.log:

2011-06-25 13:00:55 /music/c.htm Safari

2011-06-26 08:01:23 /main.htm IE

2011-06-26 08:03:01 /sports/b.htm Chrome

2011-06-27 11:41:06 /main.htm IE

2011-06-27 11:52:41 /news/a.htm Firefox

輸出:

210 2011-06-26 /main.htm

231 2011-06-26 /news/a.htm

155 2011-06-26 /sports/b.htm

288 2011-06-27 /main.htm

292 2011-06-27 /news/a.htm

161 2011-06-27 /sports/b.htm

上面的兩個(gè)簡(jiǎn)單文本數(shù)據(jù)處理任務(wù)如果是在C或C++下實(shí)現(xiàn)則要麻煩得多,代碼量至少是十幾行或者數(shù)十行,加上編譯調(diào)試,整個(gè)開發(fā)效率可能比Shell低一個(gè)數(shù)量級(jí)。除了Shell外,Perl也是以強(qiáng)大的文本數(shù)據(jù)處理而聞名的。我們來(lái)看一個(gè)Perl正則表達(dá)式的例子:

  1. while (<STDIN>) {  
  2.     if (/hello\s(\w+)/i) {  
  3.         print “say hello to $1“  
  4.     }  
  5.     else if (/goodbye\s(\w+)/i) {  
  6.         print “say goodbye to $1”  
  7.     }  

輸入:

HeLLo world

Goodbye bug

輸出:

say hello to world

say goodbye to bug

上面的例子中我們看到Perl直接進(jìn)行字符串匹配并進(jìn)行數(shù)據(jù)提取的強(qiáng)大威力。Perl基于正則表達(dá)式的字符串處理不僅比C/C++等系統(tǒng)語(yǔ)言更強(qiáng)大,甚至比Python這樣的動(dòng)態(tài)語(yǔ)言也更強(qiáng)大和更方便,這是因?yàn)檎齽t表達(dá)式是Perl語(yǔ)言的“一等公民”,這就使得Perl比其他以庫(kù)的方式支持正則表達(dá)式功能的語(yǔ)言具有更好的文本數(shù)據(jù)親和力。后來(lái)的Ruby也學(xué)習(xí)Perl直接在語(yǔ)言上支持正則表達(dá)式。

結(jié)構(gòu)化文本格式

XML是最近十幾年來(lái)流行起來(lái)的一種通用(半)結(jié)構(gòu)化的文本數(shù)據(jù)交換格式。XML除具有一般文本格式的優(yōu)點(diǎn)外,還具有能層次結(jié)構(gòu)表達(dá)力和可擴(kuò)展性的優(yōu)勢(shì),所以它至誕生以來(lái)就被大量用于配置文件和各種Web Service中。現(xiàn)代程序設(shè)計(jì)基本都少不了和XML打交道,不過(guò)在C++、Java和C#幾種靜態(tài)類型語(yǔ)言中處理XML卻并不是一件十分輕松的事情。我們先來(lái)看一個(gè)Java解析和構(gòu)建下面這個(gè)XML的例子:

  1. <langs type="current">  
  2.   <language>Java</language>  
  3.   <language>Groovy</language>  
  4.   <language>JavaScript</language>  
  5. </langs> 

  1. //Java解析XML  
  2. DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();  
  3. try {  
  4.     DocumentBuilder db = dbf.newDocumentBuilder();  
  5.     Document doc = db.parse("src/languages.xml");  
  6.     Element langs = doc.getDocumentElement();  
  7.     System.out.println("type = " + langs.getAttribute("type"));  
  8.     NodeList list = langs.getElementsByTagName("language");  
  9.     for(int i = 0 ; i < list.getLength();i++) {  
  10.         Element language = (Element) list.item(i);  
  11.         System.out.println(language.getTextContent());  
  12.     }  
  13. }catch(Exception e) {  
  14.     e.printStackTrace();  
  15. }  
  1. //Java創(chuàng)建XML  
  2. DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();  
  3. try {  
  4.     DocumentBuilder db = dbf.newDocumentBuilder();  
  5.     Document doc = db.newDocument();  
  6.     Element langs = doc.createElement("langs");  
  7.     langs.setAttribute("type""current");  
  8.     doc.appendChild(langs);  
  9.  
  10.     Element language1 = doc.createElement("language");  
  11.     Text text1 = doc.createTextNode("Java");  
  12.     language1.appendChild(text1);  
  13.     langs.appendChild(language1);  
  14.  
  15.     Element language2 = doc.createElement("language");  
  16.     Text text2 = doc.createTextNode("Groovy");  
  17.     language2.appendChild(text2);  
  18.     langs.appendChild(language2);  
  19.     Element language3 = doc.createElement("language");  
  20.     Text text3 = doc.createTextNode("JavaScript");  
  21.     language3.appendChild(text3);  
  22.     langs.appendChild(language3);  
  23. catch (Exception e) {  
  24.     e.printStackTrace();  

為了解析和創(chuàng)建小小的一段XML代碼需要編寫如此冗長(zhǎng)的Java代碼,而實(shí)現(xiàn)同樣的功能動(dòng)態(tài)語(yǔ)言Groovy則十分簡(jiǎn)潔:

  1. //Groovy解析XML             
  2. def langs = new XmlParser().parse("languages.xml")  
  3. println "type = ${langs.attribute("type")}" 
  4. langs.language.each{  
  5.   println it.text()  
  1. //Groovy創(chuàng)建XML  
  2. def xml = new groovy.xml.MarkupBuilder()  
  3. xml.langs(type:"current"){  
  4.   language("Java")  
  5.   language("Groovy")  
  6.   language("JavaScript")  

上面Groovy操作XML的代碼簡(jiǎn)潔而富有表達(dá)力,代碼與XML幾乎是一一對(duì)應(yīng)的,如同直接在XML上進(jìn)行操作的DSL一樣,而相應(yīng)的Java代碼則看不到XML的影子。這說(shuō)明Groovy具有很高的XML數(shù)據(jù)的親和力。為什么Java和Groovy在XML親和力方面有這樣的差異呢?原因在于Java要求所有的方法和屬性都必須先定義再調(diào)用,嚴(yán)格的靜態(tài)類型檢查使得Java只能把XML元素作為“二等公民”來(lái)表達(dá);而Groovy則沒(méi)有靜態(tài)類型檢查的限制,可以自由地使用方法和屬性來(lái)表達(dá)XML結(jié)構(gòu)。上面用Groovy創(chuàng)建XML的例子中,groovy.xml.MarkupBuilder類中實(shí)際上并沒(méi)有l(wèi)angs, language這些方法,但會(huì)在調(diào)用的時(shí)候自動(dòng)創(chuàng)建相應(yīng)的XML結(jié)構(gòu)。

除了XML外,JSON是另一種通用的半結(jié)構(gòu)化的純文本數(shù)據(jù)交換格式,它常被視為輕量級(jí)的XML。JSON的本意是Javascript的對(duì)象表示(Javascript Object Notation),它屬于Javascript的語(yǔ)法子集,Javascript對(duì)JSON有原生的支持。下面就是一個(gè)在Javascript中創(chuàng)建JSON對(duì)象的例子:

  1. var json = { “langs” : {  
  2.         "type” : "current”,  
  3.         "language” : ["Java”, "Groovy”, "Javascript”]  
  4.     }  

許多Javascript程序都會(huì)通過(guò)AJAX都從服務(wù)器獲取JSON字符串,然后把字符串解析為JSON對(duì)象。由于Javascript對(duì)JSON的原生支持,所以,在Javascript中解析JSON字符串可以采用通用的eval方式,如:

  1. var json = eval(“(" + jsonStr + “)");  
  2. alert(json.langs.type); 

甚至可以:

  1. eval(“var json = ” + jsonStr);  
  2. alert(json.langs.type); 

不過(guò)eval的通用性帶來(lái)了一定的安全隱患,所以一般只建議對(duì)受信任的數(shù)據(jù)源采用eval方式解析JSON,對(duì)于不受信任的數(shù)據(jù)源可以采用專門的JSON解析庫(kù)。無(wú)論如何Javascript對(duì)JSON的原生支持都使得Javascript具有很高的JSON數(shù)據(jù)親和力。另外,Groovy 1.8也加入了對(duì)JSON的原生支持,操作JSON與Javascript一樣方便。

總結(jié)

到這里為止本文篇幅已經(jīng)很長(zhǎng)了,只能列舉二進(jìn)制字節(jié)塊格式、文本格式和結(jié)構(gòu)化文本格式3種典型的數(shù)據(jù)格式。實(shí)際上,數(shù)據(jù)親和力的話題還有很多值得探討的,比如C#的Linq。本文的探討算是拋磚引玉,目的在于引起大家注意在比較語(yǔ)言的時(shí)候不要忽略了數(shù)據(jù)親和力這樣一個(gè)重要方面。

原文鏈接:http://www.cnblogs.com/weidagang2046/archive/2011/06/27/2091765.html

【編輯推薦】

  1. 如果你的編程語(yǔ)言是汽車……
  2. 你的編程語(yǔ)言做不到的事情
  3. 在企業(yè)中越來(lái)越流行的8種編程語(yǔ)言
  4. 13種最為荒謬但很獨(dú)特的編程語(yǔ)言
  5. 2011年需要關(guān)注的9大編程語(yǔ)言
責(zé)任編輯:陳貽新 來(lái)源: Todd Wei的博客
相關(guān)推薦

2015-12-17 18:57:06

京東大數(shù)據(jù)

2015-12-22 15:47:32

ZD至頂網(wǎng)軟件頻道

2013-07-19 09:31:09

2022-05-01 17:18:59

區(qū)塊鏈去中心化金融

2016-10-09 20:31:19

2012-06-12 09:15:50

開發(fā)語(yǔ)言

2010-01-11 10:28:51

C++編程

2024-01-03 16:19:04

2010-04-16 09:47:36

Oracle

2009-08-27 17:12:04

Clojure編程語(yǔ)言Java

2010-09-14 11:19:23

DIV+CSS技術(shù)

2012-07-02 14:58:16

HTML5

2010-08-16 13:39:18

DIV+CSS

2011-07-22 13:58:48

java接口

2022-12-05 11:29:14

2019-01-13 16:25:05

PythonJavaC語(yǔ)言

2018-11-11 15:29:13

大數(shù)據(jù)語(yǔ)言Java

2010-01-12 10:50:59

學(xué)習(xí)C++

2010-09-01 10:42:11

DIV+CSS

2018-08-14 11:05:25

點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)

主站蜘蛛池模板: 2018国产大陆天天弄 | 在线第一页 | 国产精品久久 | 在线观看视频亚洲 | 国产亚洲一级 | 国产极品车模吞精高潮呻吟 | 国产精品18久久久 | 自拍视频一区二区三区 | 日日夜夜操天天干 | 在线成人免费视频 | 在线伊人 | 欧美成年黄网站色视频 | 日韩精品久久一区二区三区 | 亚洲高清在线观看 | 亚洲性在线| 正在播放国产精品 | 久久精品久久综合 | 午夜免费观看 | 国产精品久久久久久久久久99 | 天天拍天天操 | 91久久精品一区二区二区 | 美女视频黄色的 | 国产精品99久久久久久宅男 | 久久精品一区二区视频 | 欧美亚洲激情 | 玖玖爱365 | 最新日韩在线 | www亚洲成人| 嫩草视频网 | 香蕉久久a毛片 | 欧美日韩专区 | 九九视频在线观看 | 久久99深爱久久99精品 | 999www视频免费观看 | 亚洲成人av | 中文二区 | 精品久久久久一区二区国产 | 国产999精品久久久影片官网 | 午夜精品一区二区三区免费视频 | 亚洲福利av | 国产蜜臀97一区二区三区 |