本篇內(nèi)容主要講解“web編程語言的數(shù)據(jù)親和力分析”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學(xué)習(xí)“web編程語言的數(shù)據(jù)親和力分析”吧!
成都創(chuàng)新互聯(lián)公司專業(yè)為企業(yè)提供水磨溝網(wǎng)站建設(shè)、水磨溝做網(wǎng)站、水磨溝網(wǎng)站設(shè)計、水磨溝網(wǎng)站制作等企業(yè)網(wǎng)站建設(shè)、網(wǎng)頁設(shè)計與制作、水磨溝企業(yè)網(wǎng)站模板建站服務(wù),10年水磨溝做網(wǎng)站經(jīng)驗,不只是建網(wǎng)站,更提供有價值的思路和整體網(wǎng)絡(luò)服務(wù)。
目前,程序設(shè)計語言似乎進(jìn)入了一個蓬勃發(fā)展的時期,JavaScript、Perl、Python、Ruby、Groovy等一批較新的語言正越來越多地被熟悉和使用,而C++、C#、Java等主流語言也在不斷地融入函數(shù)式和動態(tài)性特征。程序員的百寶箱中可供選擇的寶貝是越來多了,而社區(qū)中關(guān)于語言間的比較和爭論也更為熱烈,我們常常見到關(guān)于“面向過程和面向?qū)ο蟮谋容^”、“動態(tài)語言和靜態(tài)語言的比較”、“命令式和函數(shù)式范式的比較”等比較。我注意到這類討論的關(guān)注點多集中于設(shè)計相關(guān)話題,如“動態(tài)語言的Duck typing多態(tài)和靜態(tài)語言的繼承多態(tài)的比較”,“Prototype based和Class based的比較”等。但我認(rèn)為還有一個十分重要的方面值得關(guān)注,這就是數(shù)據(jù)處理。
數(shù)據(jù)處理之所以重要是因為不論是本地信息存儲還是系統(tǒng)間信息交換都需要建立在一定的數(shù)據(jù)格式基礎(chǔ)上。另外,不管語言屬于那種范式,設(shè)計上采用什么模式,在微觀層次上程序很大一部分工作都是在做數(shù)據(jù)處理。所以,從數(shù)據(jù)處理角度比較和理解語言間的差異有重要的現(xiàn)實意義。雖然數(shù)據(jù)通常是平臺和語言無關(guān)的,但不同的語言在處理某種格式的數(shù)據(jù)時會表現(xiàn)出不同的難度,甚至某些數(shù)據(jù)格式只能采用特定的語言才能實現(xiàn),這就是數(shù)據(jù)親和力的不同。
語言的數(shù)據(jù)親和力(Data Affinity)指的是語言與某種數(shù)據(jù)格式之間的相容程度,它主要取決于語言的數(shù)據(jù)模型,類型系統(tǒng),以及庫的支持等。語言對某種數(shù)據(jù)格式親和力越強,則操作某類數(shù)據(jù)越容易。
二進(jìn)制字節(jié)塊格式
在偏底層的操作系統(tǒng)、嵌入式和通信系統(tǒng)中,二進(jìn)制的字節(jié)塊是最常見的一種數(shù)據(jù)格式。二進(jìn)制數(shù)據(jù)布局緊湊和接近機(jī)器的特點使得它常常作為系統(tǒng)間通信或系統(tǒng)文件的數(shù)據(jù)格式。但一般高級語言不方便直接和0101打交道,而是基于記錄、結(jié)構(gòu)體和類等結(jié)構(gòu)化表示操作數(shù)據(jù),這就存在著在底層的二進(jìn)制字節(jié)塊和高層的結(jié)構(gòu)化數(shù)據(jù)之間的轉(zhuǎn)換問題。
C語言作為最主要的系統(tǒng)語言具有很高的字節(jié)塊數(shù)據(jù)親和力。這不僅因為C語言具有指針可以直接訪問內(nèi)存以外,還因為C的結(jié)構(gòu)體(struct)可以和字節(jié)塊建立起直接的映射關(guān)系。例如,在基于Socket連接的分布式系統(tǒng)中服務(wù)器端和客戶端通過二進(jìn)制的字節(jié)數(shù)據(jù)進(jìn)行通信,通信雙方只要事先定義共用的結(jié)構(gòu)體,發(fā)送方先創(chuàng)建相應(yīng)的結(jié)構(gòu)體變量并填充字段,然后把變量對應(yīng)的內(nèi)存塊copy到Socket,接收方從Socket讀取字節(jié)塊,然后把字節(jié)塊強制類型轉(zhuǎn)換為相應(yīng)的結(jié)構(gòu)體指針即可讀取個字段信息。整個過程中通信的雙方都沒有復(fù)雜的信息編碼和解碼的過程。示例代碼如下:
struct t_data { int version; char type[10]; float value; };
//發(fā)送方 struct t_data data; data.version = 1; strcpy(data.type, “degree”); data.value = 189.0; send(socket, (char*)&data, sizeof(data));
//接收方 struct t_data data; read(socket, (char*)&data, sizeof(data)); printf(“%d, %s, %f”, data.version, data.type, data.value);
上面的方法在實際應(yīng)用中還需要注意內(nèi)存對齊問題和大小端問題。內(nèi)存對齊問題可以通過編譯器預(yù)處理命令來進(jìn)行控制,保證內(nèi)存中struct結(jié)構(gòu)與傳輸?shù)淖止?jié)塊具有相同的對齊方式;大小端問題需要通信的雙方采用同樣的大小端方式,否則就需要進(jìn)行轉(zhuǎn)換。
C++可以完全兼容C的結(jié)構(gòu)體,但C++的類(包括class和struct)中如果定義了虛函數(shù),則會喪失結(jié)構(gòu)的字節(jié)塊數(shù)據(jù)親和力,這是C++編程時需要權(quán)衡的一個因素。而除了C/C++,其他語言中則難以見到字節(jié)塊數(shù)據(jù)親和力,其原因在于C/C++允許控制結(jié)構(gòu)體/對象的內(nèi)存布局,并允許對指針進(jìn)行非類型安全的強制類型轉(zhuǎn)換,這都是在Java,C#等語言中不允許的。所以,在Java、C#中進(jìn)行字節(jié)塊的編碼解碼就只能按照協(xié)議一個字段一個字段地按偏移量和長度進(jìn)行解析。C/C++的指針以及結(jié)構(gòu)體和內(nèi)存的直接映射帶來了對字節(jié)塊數(shù)據(jù)的親和力,但同時也留下了內(nèi)存訪問和類型安全的隱患;而Java、C#在擁有引用安全和類型安全的同時也失去了對字節(jié)塊數(shù)據(jù)的親和力。
文本格式
文本格式是另一種十分常見的數(shù)據(jù)格式?!禪nix編程藝術(shù)》是這樣評價文本格式的:"Text streams are a valuable universal format because they're easy for human beings to read, write, and edit without specialized tools ”?;谖谋玖鞯墓艿捞幚硎且环N備受贊譽的Unix風(fēng)格。Shell可以通過管道把各種功能單一的命令串聯(lián)起來,讓文本流在管道上流動,因而Shell語言具有很好的文本數(shù)據(jù)親和力。許多文本數(shù)據(jù)處理任務(wù)Bash都可以一行搞定,這就是Hacker們酷愛的One Liner風(fēng)格。
下面我們來看兩個用Bash進(jìn)行文本處理的例子:
1. 統(tǒng)計當(dāng)前目錄下的gz文件數(shù)目:
ls –l *.gz | wc –l
2. 在Web服務(wù)器日志service.log中統(tǒng)計2011年6月26和27兩天中每天各頁面的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
上面的兩個簡單文本數(shù)據(jù)處理任務(wù)如果是在C或C++下實現(xiàn)則要麻煩得多,代碼量至少是十幾行或者數(shù)十行,加上編譯調(diào)試,整個開發(fā)效率可能比Shell低一個數(shù)量級。除了Shell外,Perl也是以強大的文本數(shù)據(jù)處理而聞名的。我們來看一個Perl正則表達(dá)式的例子:
while (<STDIN>) { if (/hello\s(\w+)/i) { print “say hello to $1“ } else if (/goodbye\s(\w+)/i) { print “say goodbye to $1” } }
輸入:
HeLLo world
Goodbye bug
輸出:
say hello to world
say goodbye to bug
上面的例子中我們看到Perl直接進(jìn)行字符串匹配并進(jìn)行數(shù)據(jù)提取的強大威力。Perl基于正則表達(dá)式的字符串處理不僅比C/C++等系統(tǒng)語言更強大,甚至比Python這樣的動態(tài)語言也更強大和更方便,這是因為正則表達(dá)式是Perl語言的“一等公民”,這就使得Perl比其他以庫的方式支持正則表達(dá)式功能的語言具有更好的文本數(shù)據(jù)親和力。后來的Ruby也學(xué)習(xí)Perl直接在語言上支持正則表達(dá)式。
結(jié)構(gòu)化文本格式
XML是最近十幾年來流行起來的一種通用(半)結(jié)構(gòu)化的文本數(shù)據(jù)交換格式。XML除具有一般文本格式的優(yōu)點外,還具有能層次結(jié)構(gòu)表達(dá)力和可擴(kuò)展性的優(yōu)勢,所以它至誕生以來就被大量用于配置文件和各種Web Service中。現(xiàn)代程序設(shè)計基本都少不了和XML打交道,不過在C++、Java和C#幾種靜態(tài)類型語言中處理XML卻并不是一件十分輕松的事情。我們先來看一個Java解析和構(gòu)建下面這個XML的例子:
<langs type="current"> <language>Java</language> <language>Groovy</language> <language>JavaScript</language> </langs>
//Java解析XML DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); try { DocumentBuilder db = dbf.newDocumentBuilder(); Document doc = db.parse("src/languages.xml"); Element langs = doc.getDocumentElement(); System.out.println("type = " + langs.getAttribute("type")); NodeList list = langs.getElementsByTagName("language"); for(int i = 0 ; i < list.getLength();i++) { Element language = (Element) list.item(i); System.out.println(language.getTextContent()); } }catch(Exception e) { e.printStackTrace(); }
//Java創(chuàng)建XML DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); try { DocumentBuilder db = dbf.newDocumentBuilder(); Document doc = db.newDocument(); Element langs = doc.createElement("langs"); langs.setAttribute("type", "current"); doc.appendChild(langs); Element language1 = doc.createElement("language"); Text text1 = doc.createTextNode("Java"); language1.appendChild(text1); langs.appendChild(language1); Element language2 = doc.createElement("language"); Text text2 = doc.createTextNode("Groovy"); language2.appendChild(text2); langs.appendChild(language2); Element language3 = doc.createElement("language"); Text text3 = doc.createTextNode("JavaScript"); language3.appendChild(text3); langs.appendChild(language3); } catch (Exception e) { e.printStackTrace(); }
為了解析和創(chuàng)建小小的一段XML代碼需要編寫如此冗長的Java代碼,而實現(xiàn)同樣的功能動態(tài)語言Groovy則十分簡潔:
//Groovy解析XML def langs = new XmlParser().parse("languages.xml") println "type = ${langs.attribute("type")}" langs.language.each{ println it.text() }
//Groovy創(chuàng)建XML def xml = new groovy.xml.MarkupBuilder() xml.langs(type:"current"){ language("Java") language("Groovy") language("JavaScript") }
上面Groovy操作XML的代碼簡潔而富有表達(dá)力,代碼與XML幾乎是一一對應(yīng)的,如同直接在XML上進(jìn)行操作的DSL一樣,而相應(yīng)的Java代碼則看不到XML的影子。這說明Groovy具有很高的XML數(shù)據(jù)的親和力。為什么Java和Groovy在XML親和力方面有這樣的差異呢?原因在于Java要求所有的方法和屬性都必須先定義再調(diào)用,嚴(yán)格的靜態(tài)類型檢查使得Java只能把XML元素作為“二等公民”來表達(dá);而Groovy則沒有靜態(tài)類型檢查的限制,可以自由地使用方法和屬性來表達(dá)XML結(jié)構(gòu)。上面用Groovy創(chuàng)建XML的例子中,groovy.xml.MarkupBuilder類中實際上并沒有l(wèi)angs, language這些方法,但會在調(diào)用的時候自動創(chuàng)建相應(yīng)的XML結(jié)構(gòu)。
除了XML外,JSON是另一種通用的半結(jié)構(gòu)化的純文本數(shù)據(jù)交換格式,它常被視為輕量級的XML。JSON的本意是Javascript的對象表示(Javascript Object Notation),它屬于Javascript的語法子集,Javascript對JSON有原生的支持。下面就是一個在Javascript中創(chuàng)建JSON對象的例子:
var json = { “l(fā)angs” : { "type” : "current”, "language” : ["Java”, "Groovy”, "Javascript”] } }
許多Javascript程序都會通過AJAX都從服務(wù)器獲取JSON字符串,然后把字符串解析為JSON對象。由于Javascript對JSON的原生支持,所以,在Javascript中解析JSON字符串可以采用通用的eval方式,如:
var json = eval(“(" + jsonStr + “)"); alert(json.langs.type);
甚至可以:
eval(“var json = ” + jsonStr); alert(json.langs.type);
不過eval的通用性帶來了一定的安全隱患,所以一般只建議對受信任的數(shù)據(jù)源采用eval方式解析JSON,對于不受信任的數(shù)據(jù)源可以采用專門的JSON解析庫。無論如何Javascript對JSON的原生支持都使得Javascript具有很高的JSON數(shù)據(jù)親和力。另外,Groovy 1.8也加入了對JSON的原生支持,操作JSON與Javascript一樣方便。
到此,相信大家對“web編程語言的數(shù)據(jù)親和力分析”有了更深的了解,不妨來實際操作一番吧!這里是創(chuàng)新互聯(lián)網(wǎng)站,更多相關(guān)內(nèi)容可以進(jìn)入相關(guān)頻道進(jìn)行查詢,關(guān)注我們,繼續(xù)學(xué)習(xí)!
當(dāng)前題目:web編程語言的數(shù)據(jù)親和力分析
網(wǎng)站地址:http://www.rwnh.cn/article0/pgsjoo.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供搜索引擎優(yōu)化、網(wǎng)站維護(hù)、用戶體驗、關(guān)鍵詞優(yōu)化、定制開發(fā)、微信小程序
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)