瘋狂的java
          好的藝術(shù)家復(fù)制,偉大的藝術(shù)家偷竊!
          posts - 3,  comments - 4,  trackbacks - 0
          本文轉(zhuǎn)載自Tyr Chen的博客在文中作者總結(jié)了他認(rèn)為高效能程序員應(yīng)該具備的七個(gè)習(xí)慣,原文內(nèi)容如下。 

          昨天收到一個(gè)讀者留言,問(wèn)作為程序員,有什么學(xué)習(xí)和工作上的好習(xí)慣可以借鑒?想了想,干脆附庸風(fēng)雅一下,總結(jié)個(gè)『高效能程序員的七個(gè)習(xí)慣』吧。Disclaimer:一家之言,可不信,但也可以部分信。 

          1.  擁抱unix哲學(xué) 

          每個(gè)程序員入門(mén)的第一堂和第二堂課應(yīng)該是和unix哲學(xué)相關(guān)的內(nèi)容,簡(jiǎn)言之就是:做一件事,做好它。具體點(diǎn):

          • 小即是美。
          • 讓程序只做好一件事。
          • 盡可能早地創(chuàng)建原型。
          • 可移植性比效率更重要。
          • 數(shù)據(jù)應(yīng)該保存為文本文件。
          • 盡可能地榨取軟件的全部?jī)r(jià)值。
          • 使用shell腳本來(lái)提高效率和可移植性。
          • 避免使用可定制性低下的用戶(hù)界面。
          • 所有程序都是數(shù)據(jù)的過(guò)濾器。

          2.  選一個(gè)樣板,follow之 

          每個(gè)NBA新秀都有自己的樣板,我們也總習(xí)慣稱(chēng)某足球新星為『小羅』,『小小羅』。樣板為你提供了可模仿可追趕的對(duì)象,同時(shí)也讓你審視自己究竟想成為什么樣的程序員。我的樣板是Greg Pass和Werner Vogels,雖然我這輩子可能也達(dá)不到他們的高度,可這并不妨礙向著我心目中的明星一步步靠近。 

          3.  寫(xiě)代碼,而不是調(diào)代碼 

          寫(xiě)軟件最糟糕的體驗(yàn)恐怕是邊寫(xiě)邊調(diào),寫(xiě)一點(diǎn),運(yùn)行一下,再寫(xiě)一點(diǎn)。是很多程序員都會(huì)這么干。原因有二:1. 不熟悉相關(guān)的代碼(類(lèi)庫(kù)),需要邊寫(xiě)邊運(yùn)行保證代碼的正確。2. 現(xiàn)代編程語(yǔ)言的REPL(Read-Evaluate-Print-Loop,就是語(yǔ)言的shell)能力助長(zhǎng)了這一行為。 

          寫(xiě)系統(tǒng)軟件的人很少這么做。他們手頭糟糕的工具讓邊寫(xiě)邊調(diào)的行為成為效率殺手 —— 如果稍稍改動(dòng),編譯就要花去幾分鐘,甚至更長(zhǎng)的時(shí)間,你還會(huì)這么干么?所以他們往往是寫(xiě)完一個(gè)模塊,再編譯調(diào)試。(由此看來(lái),高效的工具有時(shí)候是把雙刃劍啊) 

          我覺(jué)得寫(xiě)代碼就跟寫(xiě)文章一樣,構(gòu)思好,有了大綱,就應(yīng)該行云流水一樣寫(xiě)下去,一氣呵成,然后回過(guò)頭來(lái)再調(diào)整語(yǔ)句,修改錯(cuò)別字。如果寫(xiě)完一段,就要回溯檢查之前寫(xiě)的內(nèi)容,效率很低,思維也會(huì)被打散。 

          靠邊寫(xiě)邊調(diào)做出來(lái)的代碼還往往質(zhì)量不高。雖然局部經(jīng)過(guò)了雕琢,但整體上不那么協(xié)調(diào),看著總是別扭。這就好比雕刻,拿著一塊石頭,你先是精修了鼻子,然后再一點(diǎn)一點(diǎn)刻畫(huà)面部。等修到耳朵的時(shí)候,鼻子可能過(guò)大或過(guò)小,即便再精美,它也得不到贊賞。 

          4.  聰明地調(diào)試 

          軟件總會(huì)出問(wèn)題。遇到問(wèn)題,很多程序員就會(huì)用IDE在各種可能的地方加斷點(diǎn)調(diào)試,如果沒(méi)有IDE,那么各種print/log手段一齊拋出,有棗沒(méi)棗打一桿子再說(shuō)。 

          優(yōu)秀的程序員會(huì)在撰寫(xiě)代碼的時(shí)候就考慮到調(diào)試問(wèn)題,在系統(tǒng)關(guān)鍵的節(jié)點(diǎn)上注入各種等級(jí)的調(diào)試信息,然后在需要的時(shí)候打開(kāi)相應(yīng)的調(diào)試級(jí)別,順藤摸瓜,避免了不靠譜的臆測(cè)。這是調(diào)試之『道』。 

          很多問(wèn)題打開(kāi)調(diào)試開(kāi)關(guān)后就原形畢露,但有時(shí)候靠調(diào)試信息找到了初步原因,進(jìn)一步定位問(wèn)題還需要具體的工具,也就是調(diào)試之『術(shù)』,如上文所述之?dāng)帱c(diǎn)調(diào)試。有些時(shí)候,遇到靠類(lèi)似gdb(如python的pdb)的工具無(wú)法解決的問(wèn)題時(shí)(如性能問(wèn)題),你還需要更多的調(diào)試工具做runtime profiling,如systemtap。 

          5.  使用標(biāo)記語(yǔ)言來(lái)寫(xiě)文檔,而非word/power point 

          不要使用只能使用特定軟件才能打開(kāi)的工具寫(xiě)文檔,如word/page或者power point/keynote。要使用『放之四海而皆可用』的工具。 

          java的市場(chǎng)口號(hào)是:『一次編寫(xiě),到處運(yùn)行』,對(duì)于文檔,你也需要這樣的工具。Markdown(md) / Restructured Text(rst)(以及任何編輯語(yǔ)言,甚至是jade)就是這樣的工具。通過(guò)使用一種特定的文本格式,你的文檔可以被編譯成幾乎任意格式(html,rtf,latex,pdf,epub,...),真正達(dá)到了『一次編寫(xiě),到處運(yùn)行』。最重要的是,由于邏輯層(文章本身)和表現(xiàn)層(各種格式,字體,行距等)分離,同樣的文檔,換個(gè)模板,就有完全不一樣的形象。 

          除非必須,我現(xiàn)在所有的文檔都是md或者rst格式。 

          6.  一切皆項(xiàng)目 

          程序員的所有產(chǎn)出應(yīng)該項(xiàng)目制。軟件自不必說(shuō),文檔和各種碎片思想也要根據(jù)相關(guān)性組織成項(xiàng)目。舉一些我自己的例子: 

          • 我的博客是一個(gè)名叫jobs的github項(xiàng)目
          • 我的微信文章全部放在craftsman這個(gè)項(xiàng)目中
          • 我學(xué)習(xí)某種知識(shí)的過(guò)程(比如說(shuō)golang)會(huì)放在一個(gè)或若干個(gè)項(xiàng)目中
          • 我工作上每個(gè)項(xiàng)目的各種產(chǎn)出(包括會(huì)議紀(jì)要)會(huì)按照項(xiàng)目對(duì)應(yīng)生成git repo

          項(xiàng)目制的好處是具備可回溯性。每個(gè)項(xiàng)目我可以用git來(lái)管理,這樣,幾乎在任何一臺(tái)設(shè)備上我都可以看到我之前的工作。想想你三年前寫(xiě)的某個(gè)文檔,你還能找到它么?你還能找回你的修改歷史么? 

          項(xiàng)目制的另一大好處是可以在其之上使能工具。比如說(shuō)你看到的這些微信文章,我隨時(shí)可以“make publish YEAR=2014”來(lái)生成包含了2014年我所寫(xiě)文章的pdf。 

          7.  心態(tài)開(kāi)放,勇于嘗試 

          在程序員社區(qū)里,語(yǔ)言之爭(zhēng),系統(tǒng)之爭(zhēng),軟件思想之爭(zhēng)幾乎是常態(tài)。python vs ruby,go vs java vs erlang vs rust,scala vs cljure,OOP vs FP,iOS vs Android。其實(shí)不管黑貓白貓,抓到老鼠的就是好貓,facebook還用php呢。程序員應(yīng)該用開(kāi)放的心態(tài)去包容新的技術(shù),新的思想,勇于嘗試,而不是立即否定。這個(gè)世界最悲哀的是,手里有把錘子,看什么都是釘子(或者說(shuō),眼里就只能看見(jiàn)釘子)。 

          我接觸mac時(shí)間不過(guò)三年。可這三年時(shí)間,我從對(duì)mac不屑,到深深熱愛(ài),最終成為mac的一個(gè)重度用戶(hù)。很多東西用過(guò)才知道,不嘗試不接觸我可能永遠(yuǎn)活在自己下意識(shí)構(gòu)筑的無(wú)形之墻的另一邊。
          posted @ 2014-04-13 10:17 永志歌德 閱讀(334) | 評(píng)論 (0)編輯 收藏

          common-logging

          common-logging是apache提供的一個(gè)通用的日志接口。用戶(hù)可以自由選擇第三方的日志組件作為具體實(shí)現(xiàn),像log4j,或者jdk自帶的logging, common-logging會(huì)通過(guò)動(dòng)態(tài)查找的機(jī)制,在程序運(yùn)行時(shí)自動(dòng)找出真正使用的日志庫(kù)。當(dāng)然,common-logging內(nèi)部有一個(gè)Simple logger的簡(jiǎn)單實(shí)現(xiàn),但是功能很弱。所以使用common-logging,通常都是配合著log4j來(lái)使用。使用它的好處就是,代碼依賴(lài)是common-logging而非log4j, 避免了和具體的日志方案直接耦合,在有必要時(shí),可以更改日志實(shí)現(xiàn)的第三方庫(kù)。

          使用common-logging的常見(jiàn)代碼:
          1. import org.apache.commons.logging.Log;  
          2. import org.apache.commons.logging.LogFactory;  
          3.   
          4. public class A {  
          5.     private static Log logger = LogFactory.getLog(this.getClass());  
          6. }  
          動(dòng)態(tài)查找原理:Log 是一個(gè)接口聲明。LogFactory 的內(nèi)部會(huì)去裝載具體的日志系統(tǒng),并獲得實(shí)現(xiàn)該Log 接口的實(shí)現(xiàn)類(lèi)。LogFactory 內(nèi)部裝載日志系統(tǒng)的流程如下:
          1. 首先,尋找org.apache.commons.logging.LogFactory 屬性配置。
          2. 否則,利用JDK1.3 開(kāi)始提供的service 發(fā)現(xiàn)機(jī)制,會(huì)掃描classpah 下的META-INF/services/org.apache.commons.logging.LogFactory文件,若找到則裝載里面的配置,使用里面的配置。
          3. 否則,從Classpath 里尋找commons-logging.properties ,找到則根據(jù)里面的配置加載。
          4. 否則,使用默認(rèn)的配置:如果能找到Log4j 則默認(rèn)使用log4j 實(shí)現(xiàn),如果沒(méi)有則使用JDK14Logger 實(shí)現(xiàn),再?zèng)]有則使用commons-logging 內(nèi)部提供的SimpleLog 實(shí)現(xiàn)。
          從上述加載流程來(lái)看,只要引入了log4j 并在classpath 配置了log4j.xml ,則commons-logging 就會(huì)使log4j 使用正常,而代碼里不需要依賴(lài)任何log4j 的代碼。

          slf4j

          slf4j全稱(chēng)為Simple Logging Facade for JAVA,java簡(jiǎn)單日志門(mén)面。類(lèi)似于A(yíng)pache Common-Logging,是對(duì)不同日志框架提供的一個(gè)門(mén)面封裝,可以在部署的時(shí)候不修改任何配置即可接入一種日志實(shí)現(xiàn)方案。但是,他在編譯時(shí)靜態(tài)綁定真正的Log庫(kù)。使用SLF4J時(shí),如果你需要使用某一種日志實(shí)現(xiàn),那么你必須選擇正確的SLF4J的jar包的集合(各種橋接包)。

          使用slf4j的常見(jiàn)代碼:

          1. import org.slf4j.Logger;  
          2. import org.slf4j.LoggerFactory;  
          3.   
          4. public class A {  
          5.     private static Log logger = LogFactory.getLog(this.getClass());  
          6. }  

          slf4j靜態(tài)綁定原理:SLF4J 會(huì)在編譯時(shí)會(huì)綁定import org.slf4j.impl.StaticLoggerBinder; 該類(lèi)里面實(shí)現(xiàn)對(duì)具體日志方案的綁定接入。任何一種基于slf4j 的實(shí)現(xiàn)都要有一個(gè)這個(gè)類(lèi)。如:org.slf4j.slf4j-log4j12-1.5.6: 提供對(duì) log4j 的一種適配實(shí)現(xiàn)。注意:如果有任意兩個(gè)實(shí)現(xiàn)slf4j 的包同時(shí)出現(xiàn),那么就可能出現(xiàn)問(wèn)題。

          slf4j 與 common-logging 比較

          common-logging通過(guò)動(dòng)態(tài)查找的機(jī)制,在程序運(yùn)行時(shí)自動(dòng)找出真正使用的日志庫(kù)。由于它使用了ClassLoader尋找和載入底層的日志庫(kù), 導(dǎo)致了象OSGI這樣的框架無(wú)法正常工作,因?yàn)镺SGI的不同的插件使用自己的ClassLoader。 OSGI的這種機(jī)制保證了插件互相獨(dú)立,然而卻使Apache Common-Logging無(wú)法工作。

          slf4j編譯時(shí)靜態(tài)綁定真正的Log庫(kù),因此可以再OSGI中使用。另外,SLF4J 支持參數(shù)化的log字符串,避免了之前為了減少字符串拼接的性能損耗而不得不寫(xiě)的if(logger.isDebugEnable()),現(xiàn)在你可以直接寫(xiě):logger.debug(“current user is: {}”, user)。拼裝消息被推遲到了它能夠確定是不是要顯示這條消息的時(shí)候,但是獲取參數(shù)的代價(jià)并沒(méi)有幸免。

          Log4j

          Apache的一個(gè)開(kāi)放源代碼項(xiàng)目,通過(guò)使用Log4j,我們可以控制日志信息輸送的目的地是控制臺(tái)、文件、GUI組件、甚至是套接口服務(wù) 器、NT的事件記錄器、UNIX Syslog守護(hù)進(jìn)程等;用戶(hù)也可以控制每一條日志的輸出格式;通過(guò)定義每一條日志信息的級(jí)別,用戶(hù)能夠更加細(xì)致地控制日志的生成過(guò)程。這些可以通過(guò)一個(gè) 配置文件來(lái)靈活地進(jìn)行配置,而不需要修改程序代碼。

          LogBack

          Logback是由log4j創(chuàng)始人設(shè)計(jì)的又一個(gè)開(kāi)源日記組件。logback當(dāng)前分成三個(gè)模塊:logback-core,logback- classic和logback-access。logback-core是其它兩個(gè)模塊的基礎(chǔ)模塊。logback-classic是log4j的一個(gè) 改良版本。此外logback-classic完整實(shí)現(xiàn)SLF4J API使你可以很方便地更換成其它日記系統(tǒng)如log4j或JDK14 Logging。logback-access訪(fǎng)問(wèn)模塊與Servlet容器集成提供通過(guò)Http來(lái)訪(fǎng)問(wèn)日記的功能。 

          Log4j 與 LogBack 比較

          LogBack作為一個(gè)通用可靠、快速靈活的日志框架,將作為L(zhǎng)og4j的替代和SLF4J組成新的日志系統(tǒng)的完整實(shí)現(xiàn)。LOGBack聲稱(chēng)具有極佳的性能,“ 某些關(guān)鍵操作,比如判定是否記錄一條日志語(yǔ)句的操作,其性能得到了顯著的提高。這個(gè)操作在LogBack中需要3納秒,而在Log4J中則需要30納秒。 LogBack創(chuàng)建記錄器(logger)的速度也更快:13微秒,而在Log4J中需要23微秒。更重要的是,它獲取已存在的記錄器只需94納秒,而 Log4J需要2234納秒,時(shí)間減少到了1/23。跟JUL相比的性能提高也是顯著的”。 另外,LOGBack的所有文檔是全面免費(fèi)提供的,不象Log4J那樣只提供部分免費(fèi)文檔而需要用戶(hù)去購(gòu)買(mǎi)付費(fèi)文檔。 

          slf4j與其他各種日志組件的橋接

          應(yīng)用代碼中使用slf4j接口,接入具體實(shí)現(xiàn)的方法

          應(yīng)用代碼中使用別的日志接口,轉(zhuǎn)成slf4j的方法


          日志組件相關(guān)歷史

          Java 界里有許多實(shí)現(xiàn)日志功能的工具,最早得到廣泛使用的是 log4j,許多應(yīng)用程序的日志部分都交給了 log4j,不過(guò)作為組件開(kāi)發(fā)者,他們希望自己的組件不要緊緊依賴(lài)某一個(gè)工具,畢竟在同一個(gè)時(shí)候還有很多其他很多日志工具,假如一個(gè)應(yīng)用程序用到了兩個(gè)組件,恰好兩個(gè)組件使用不同的日志工具,那么應(yīng)用程序就會(huì)有兩份日志輸出了。

          為了解決這個(gè)問(wèn)題,Apache Commons Logging (之前叫 Jakarta Commons Logging,JCL)粉墨登場(chǎng),JCL 只提供 log 接口,具體的實(shí)現(xiàn)則在運(yùn)行時(shí)動(dòng)態(tài)尋找。這樣一來(lái)組件開(kāi)發(fā)者只需要針對(duì) JCL 接口開(kāi)發(fā),而調(diào)用組件的應(yīng)用程序則可以在運(yùn)行時(shí)搭配自己喜好的日志實(shí)踐工具。

          所以即使到現(xiàn)在你仍會(huì)看到很多程序應(yīng)用 JCL + log4j 這種搭配,不過(guò)當(dāng)程序規(guī)模越來(lái)越龐大時(shí),JCL的動(dòng)態(tài)綁定并不是總能成功,具體原因大家可以 Google 一下,這里就不再贅述了。解決方法之一就是在程序部署時(shí)靜態(tài)綁定指定的日志工具,這就是 SLF4J 產(chǎn)生的原因。

          跟 JCL 一樣,SLF4J 也是只提供 log 接口,具體的實(shí)現(xiàn)是在打包應(yīng)用程序時(shí)所放入的綁定器(名字為 slf4j-XXX-version.jar)來(lái)決定,XXX 可以是 log4j12, jdk14, jcl, nop 等,他們實(shí)現(xiàn)了跟具體日志工具(比如 log4j)的綁定及代理工作。舉個(gè)例子:如果一個(gè)程序希望用 log4j 日志工具,那么程序只需針對(duì) slf4j-api 接口編程,然后在打包時(shí)再放入 slf4j-log4j12-version.jar 和 log4j.jar 就可以了。

          現(xiàn)在還有一個(gè)問(wèn)題,假如你正在開(kāi)發(fā)應(yīng)用程序所調(diào)用的組件當(dāng)中已經(jīng)使用了 JCL 的,還有一些組建可能直接調(diào)用了 java.util.logging,這時(shí)你需要一個(gè)橋接器(名字為 XXX-over-slf4j.jar)把他們的日志輸出重定向到 SLF4J,所謂的橋接器就是一個(gè)假的日志實(shí)現(xiàn)工具,比如當(dāng)你把 jcl-over-slf4j.jar 放到 CLASS_PATH 時(shí),即使某個(gè)組件原本是通過(guò) JCL 輸出日志的,現(xiàn)在卻會(huì)被 jcl-over-slf4j “騙到”SLF4J 里,然后 SLF4J 又會(huì)根據(jù)綁定器把日志交給具體的日志實(shí)現(xiàn)工具。過(guò)程如下

          Component
          |
          | log to Apache Commons Logging
          V
          jcl-over-slf4j.jar --- (redirect) ---> SLF4j ---> slf4j-log4j12-version.jar ---> log4j.jar ---> 輸出日志

          看到上面的流程圖可能會(huì)發(fā)現(xiàn)一個(gè)有趣的問(wèn)題,假如在 CLASS_PATH 里同時(shí)放置 log4j-over-slf4j.jar 和 slf4j-log4j12-version.jar 會(huì)發(fā)生什么情況呢?沒(méi)錯(cuò),日志會(huì)被踢來(lái)踢去,最終進(jìn)入死循環(huán)。

          所以使用 SLF4J 的比較典型搭配就是把 slf4j-api、JCL 橋接器、java.util.logging(JUL)橋接器、log4j 綁定器、log4j 這5個(gè) jar 放置在 CLASS_PATH 里。

          不過(guò)并不是所有APP容器都是使用 log4j 的,比如 Google AppEngine 它使用的是 java.util.logging(JUL),這時(shí)應(yīng)用 SLF4J 的搭配就變成 slf4j-api、JCL橋接器、logj4橋接器、JUL綁定器這4個(gè) jar 放置在 WEB-INF/lib 里。
          posted @ 2014-04-13 09:49 永志歌德 閱讀(14916) | 評(píng)論 (4)編輯 收藏

          幾乎在每個(gè)jar包里都可以看到log4j的身影,在多個(gè)子工程構(gòu)成項(xiàng)目中,slf4j相關(guān)的沖突時(shí)不時(shí)就跳出來(lái)讓你不爽,那么slf4j-api、slf4j-log4j12還有l(wèi)og4j他們是什么關(guān)系?我把自己了解的和大家簡(jiǎn)單分享一下:

              slf4j:Simple Logging Facade for Java,為java提供的簡(jiǎn)單日志Facade。Facade:門(mén)面,更底層一點(diǎn)說(shuō)就是接口。他允許用戶(hù)以自己的喜好,在工程中通過(guò)slf4j接入不同的日志系統(tǒng)。更直觀(guān)一點(diǎn),slf4j是個(gè)數(shù)據(jù)線(xiàn),一端嵌入程序,另一端鏈接日志系統(tǒng),從而實(shí)現(xiàn)將程序中的信息導(dǎo)入到日志系統(tǒng)并記錄。 

             因此,slf4j入口就是眾多接口的集合,他不負(fù)責(zé)具體的日志實(shí)現(xiàn),只在編譯時(shí)負(fù)責(zé)尋找合適的日志系統(tǒng)進(jìn)行綁定。具體有哪些接口,全部都定義在slf4j-api中。查看slf4j-api源碼就可以發(fā)現(xiàn),里面除了public final class LoggerFactory類(lèi)之外,都是接口定義。因此,slf4j-api本質(zhì)就是一個(gè)接口定義。

                

          下圖比較清晰的描述了他們之間的關(guān)系:


             

               


            當(dāng)系統(tǒng)采用log4j作為日志框架實(shí)現(xiàn)的調(diào)用關(guān)系:

              

              首先系統(tǒng)包含slf4j-api作為日志接入的接口;

              

              at compile時(shí)slf4j-api中public final class LoggerFactor類(lèi)中

              private final static void bind() 方法會(huì)尋找具體的日志實(shí)現(xiàn)類(lèi)綁定,主要通過(guò)
              
          StaticLoggerBinder.getSingleton();語(yǔ)句調(diào)用

              

            

             slf4j-log4j12:鏈接slf4j-api和log4j中間的適配器。它實(shí)現(xiàn)了slf4j-apiz中StaticLoggerBinder接口,從而使得在編譯時(shí)綁定的是slf4j-log4j12的getSingleton()方法

          log4j:這個(gè)是具體的日志系統(tǒng)。通過(guò)slf4j-log4j12初始化Log4j,達(dá)到最終日志的輸出。

          posted @ 2014-04-13 09:17 永志歌德 閱讀(632) | 評(píng)論 (0)編輯 收藏
          僅列出標(biāo)題  

          <2025年6月>
          25262728293031
          1234567
          891011121314
          15161718192021
          22232425262728
          293012345

          常用鏈接

          留言簿

          隨筆分類(lèi)

          隨筆檔案

          文章檔案

          收藏夾

          我的博客

          牛人博客

          搜索

          •  

          最新評(píng)論

          閱讀排行榜

          評(píng)論排行榜

          主站蜘蛛池模板: 金堂县| 耿马| 井研县| 札达县| 吉隆县| 加查县| 滁州市| 昭通市| 紫云| 阿拉善左旗| 乌拉特前旗| 阳东县| 堆龙德庆县| 西峡县| 渑池县| 平果县| 巩义市| 建宁县| 垣曲县| 山阳县| 吴川市| 奉贤区| 城固县| 怀远县| 淳化县| 平顶山市| 临武县| 延庆县| 蒙阴县| 鄂温| 桐城市| 永顺县| 吉木乃县| 高安市| 衡南县| 凤庆县| 大关县| 津南区| 二连浩特市| 济源市| 汝阳县|