欧美一区二区三区老妇人-欧美做爰猛烈大尺度电-99久久夜色精品国产亚洲a-亚洲福利视频一区二区

java源代碼分析 Java程序分析

JXTA Platform JAVA參考實現(xiàn)源代碼分析(2)

引言 管道的概念源于Unix 是不同線程之間直接傳輸數據的基本手段 JDK中java io包中就有管道類 同時 管道在JXTA中是最基本的概念 是對等點之間的數據傳輸的主要方式 對等管道協(xié)議(PBP)明確規(guī)范了對等管道的綁定 解析 響應 本文依次剖析集中式(JDK)和對等環(huán)境下(JXTA)管道的實現(xiàn)方式 對比分析其異同 然后嘗試在JXTA中建立一個虛擬的全雙工的管道 本文的目標是通過對不同環(huán)境下管道的實現(xiàn)方式對比分析 來理解為什么JXTA采用管道作為基本的數據傳輸手段 管道的形象化描述 一個生活中的情景 現(xiàn)在有兩個地區(qū)A B A是石油生產區(qū) B是石油消費區(qū) 現(xiàn)在B地區(qū)需要消費A地區(qū)的石油 當然可以通過海運 空運獲得 然而最通常的方式是架設輸油管道 如圖所示   引言 管道的概念源于Unix 是不同線程之間直接傳輸數據的基本手段 JDK中java io包中就有管道類 同時 管道在JXTA中是最基本的概念 是對等點之間的數據傳輸的主要方式 對等管道協(xié)議(PBP)明確規(guī)范了對等管道的綁定 解析 響應 本文依次剖析集中式(JDK)和對等環(huán)境下(JXTA)管道的實現(xiàn)方式 對比分析其異同 然后嘗試在JXTA中建立一個虛擬的全雙工的管道 本文的目標是通過對不同環(huán)境下管道的實現(xiàn)方式對比分析 來理解為什么JXTA采用管道作為基本的數據傳輸手段 管道的形象化描述 一個生活中的情景 現(xiàn)在有兩個地區(qū)A B A是石油生產區(qū) B是石油消費區(qū) 現(xiàn)在B地區(qū)需要消費A地區(qū)的石油 當然可以通過海運 空運獲得 然而最通常的方式是架設輸油管道 如圖所示 java中流的概念和管道的概念都可以通過此案例闡述 A與B之間連接的就是管道 負責將A的石油向B輸出 A向管道輸出數據(output) B從管道輸入數據(input) 可以這樣理解 管道是A的輸出對象 是B的數據源 這里就產生了三個類 輸出流A 輸入流B 管道 輸入流B負責如何獲取數據(read 操作) 輸出流A負責如何消費數據(write操作) 管道負責連接它們(connect 操作) 其實 在實現(xiàn)時 管道類分解為管道口 管道出口 由入口出口負責連接 在復雜的網絡環(huán)境中 這種連接方式可以有專門的網絡協(xié)議負責(例如 JXTA中的PBP 全稱Pipe Bind Protocol) 由以上描述 我們可以清楚知道最原始的管道就是單向的 文章后面介紹的雙向管道 是用兩個單向管道虛擬的 而非真實的連接方式 不難發(fā)現(xiàn)管道最關鍵的問題是如何協(xié)調輸出(A)與輸入(B) 這在不同的網絡環(huán)境會遇到不同的問題 最簡單的是同一JVM下的不同過程(線程或任務)之間用同步方式傳遞數據 而對等環(huán)境下 如何去發(fā)現(xiàn)對方就是一個很現(xiàn)實的問題 這僅僅只是問題的其中之一 下面的章節(jié)會依次分析 集中式環(huán)境下管道的實現(xiàn) 問題的描述 A與B是在同一JVM中 A B有一方能夠發(fā)現(xiàn)另一方的存在 A將數據發(fā)往B方 A發(fā)送數據與B接收數據是相互獨立的 現(xiàn)在回到問題的最初 為什么要使用管道?A只管發(fā)送 B只管接受 那么數據在哪兒呢?經過下面的分析 就會明白管道把管理數據緩沖區(qū)的重任交給了他自己 A B均是圍繞這個緩沖區(qū)來啟停線程的 顯然這才是問題的本質 JDK中 類PipeInputStream(即前面所述的B)與PipeOutputStream(即前面所述的的A)可以很好的解決這一問題 首先給出類圖如下   下面是將類PipeOutputStream的connect方法代碼簡化后給予注釋 public synchronized void connect(PipedInputStream snk) throws IOException { sink = snk; //將PipeInputStream的實例作為PipeOutputStream的一個屬性 以便調用 snk in = ;//緩沖區(qū)的輸入位置 表示緩沖區(qū)為空 snk out = ;//緩沖區(qū)的輸出位置nnected = true;}連接以后 PipeOutputStream的write操作直接調用sink receive(b);這樣 對緩沖區(qū)buffer的維護 就變成了read()和receive()操作之間的線程同步 JDK對緩沖區(qū)的處理非常巧妙 采用了循環(huán)列表 它用緩沖區(qū)的標志位的變化來代替數據的移動 類似于生活中的時鐘把線性的時間規(guī)范為 小時來表示 這不屬于本文的論述范圍 就不繼續(xù)分析了 read操作 正常情況下 從out位置讀取數據 緩沖區(qū)空時進入等待狀態(tài) 以輪詢的方式( 秒間隔)來自我釋放 receive操作 正常情況下 向in位置寫入數據 緩沖區(qū)滿時進入等待狀態(tài) 同樣 以輪詢的方式( 秒間隔)來自我釋放 JXTA對等管道的實現(xiàn) 通過對JDK的分析 我們可以了解到在集中式環(huán)境下 管道的架設方案是比較簡單的 在對等環(huán)境下(分布式環(huán)境下也類似) 出于同樣的目標 遇到的問題卻在急劇的擴大 例如 管道入口和出口之間如何相互發(fā)現(xiàn)?數據如何保證在不同的環(huán)境下傳送?甚至 對管道本身的概念發(fā)生質疑 一定是單入口 單出口嗎?JXTA規(guī)范中 管道是在端點之上的服務或應用之間發(fā)送和接收信息的虛擬連接通道 管道提供在對等端點傳輸之上的網絡抽象 管道有點到點和廣播兩種通信模式 JXTA是通過管道廣告來唯一標示管道的 輸出管道要找到與其廣告相同的輸入管道才能發(fā)送數據 廣告內容如下!DOCTYPE jxta:PipeAdvertisementjxta:PipeAdvertisement xmlns:jxta= ; Idurn:jxta:uuid A E AE ABBE EF CBE /Id Type JxtaUnicast /Type Name PipeExample /Name/jxta:PipeAdvertisement如果您需要對JXTA管道有實例化的概念 請參考Sing Li的使p p能進行交互操作 Jxta命令shell 這篇文章有部分內容專門介紹了如何在通過shell使用管道 本文主要是從編程的視角去看管道是如何實現(xiàn)的 客戶視角Project JXTA : Java Programmer s Guide Chapter 有個例子闡述如何去在對等點之間發(fā)送信息 讀者可以到下載源碼 現(xiàn)在從客戶視角簡要的分析它的傳送原理 要深入的了解可以看下一節(jié)的系統(tǒng)視角分析 該例中 有兩個對等點 并且構建了兩個不同的類 一個負責接收(Pipelistener) 一個負責發(fā)送(PipeExample) 具體的接收次序可以參考時序圖  educity cn/img_ / / / gif 類Pipelistener實現(xiàn)了接口PipeMsgListener 類PipeExample實現(xiàn)了接口OutputPipeListener 由時序圖(這是兩個JVM中的類 所以時序符號是獨立標示的)可以清晰的獲知 各個對等點的前 步是相互獨立的 各自的第 步 采用回調的方式建立輸入和輸出管道 一旦對等系統(tǒng)探測到對方的存在 就分別觸發(fā)各自的事件發(fā)送或接收消息 顯然JXTA中管道是異步的 調試該例程時 注意先建立輸入管道 然后建立輸出管道 因為 輸出管道在一定的時間和次數內探測不到輸入管道的存在 就會主動放棄 否則 容易讓網絡系統(tǒng)在這些無休止的探測中癱瘓 系統(tǒng)視角從上面的例程中 可以了解對等管道的創(chuàng)建方法 以及數據流程 但是不能明確對等系統(tǒng)是如何去實現(xiàn)的 JXTA中管道的實現(xiàn)比在JDK中實現(xiàn)要復雜得多 具體的技術標準可以參考對等管道綁定協(xié)議(PBP) 此協(xié)議規(guī)范了JXTA中管道的概念 但并沒有涉及到如何去實現(xiàn) 這同樣是所有JXTA協(xié)議的特征 它們的目標是闡述what it is 而把how to do it留給開發(fā)者 這樣有利于增強系統(tǒng)的開放性 其中Java參考實現(xiàn) 就是該協(xié)議實現(xiàn)的一個案例 以下將具體分析 首先看管道實現(xiàn)的類圖(以單播為例)  educity cn/img_ / / / gif 關鍵的類  InputPipeImpl 輸入管道的實現(xiàn)類 NonBlockingOutputPipe 輸出管道的實現(xiàn)類 PipeServiceImpl 管道服務的實現(xiàn)類 負責創(chuàng)建輸入輸出管道 PipeResolver 提供管道綁定的解析服務 通過客戶視角的分析 可以得知系統(tǒng)外部是通過PipeServiceImpl來獲取輸入輸出管道 那么消息是如何在對等系統(tǒng)中通過管道過濾和傳遞的? 從程序實現(xiàn)的角度 涉及到太多的技術細節(jié) JXTA的參考實現(xiàn)中有著龐雜的監(jiān)聽系統(tǒng) 本文嘗試用一個案例從兩個層次去解析這個問題 兩個層次分別是消息的具體形式 服務和端點協(xié)議的具體分發(fā)策略 很顯然 這里我們把注意力放在了管道的架構路徑上 而把如何去架構放在了一邊 我想它們是有先后關系的 并且距離并不遙遠 案例描述 現(xiàn)在假設有兩個對等點alas 和sisal 在一個局域網內 按照客戶視角那一節(jié)的例程sisal先建立輸入管道 alas建立輸出管道 由于同一網內可以用廣播的方式發(fā)送查詢信息 可以不設rendevous 并且路由是兩點間的 消息傳遞過程得到了一定的簡化 案例分析 以上案例中 從輸入輸出管道的建立到完成對接并傳輸數據總共有 個步驟 sisal建立輸入管道 alasl建立輸出管道 需要查找輸入管道 通過廣播向網絡發(fā)出管道查詢消息 sisal獲得alas的管道查詢消息 通過單播向sisal發(fā)出響應表示 alas獲得sisal的響應 通過單播向alas發(fā)出數據 sisal獲得數據 lishixinzhi/Article/program/Java/gj/201311/27397

目前成都創(chuàng)新互聯(lián)公司已為成百上千家的企業(yè)提供了網站建設、域名、網站空間網站托管、企業(yè)網站設計、蘭陵網站維護等服務,公司將堅持客戶導向、應用為本的策略,正道將秉承"和諧、參與、激情"的文化,與客戶和合作伙伴齊心協(xié)力一起成長,共同發(fā)展。

Java大神如何學習和分析Java框架的源碼

1、拿到代碼查看項目當中是否有readme這樣的文件,如果沒有查看是否有文檔之類的

2、代碼當中沒有文檔,那么就想你的同事或者其他人要這個框架的介紹或者資料

3、先請教別人這個框架的大體思路

4、自己獨立去按照文檔或者其他人說的思路去看代碼

5、不懂的地方全部記錄下面,一次行去問,有的時候很多問題在你看到后面的東西的時候就自然明白了

6、看懂了代碼之后自己嘗試著寫一個,看自己的理解是否正確就這么多了。

如何讀JAVA源碼

本來不想回答,翻到下面那些答復實在看不過去,就花點功夫整理下吧,希望對有人心能有幫助。

閱讀分析源代碼,一些有效的方法是:

1、閱讀源代碼的說明文檔和API文檔。

2、如果源代碼有用法示例或向導,先閱讀這個。

3、了解整個項目的模塊結構,可以按模塊進行閱讀。

4、隨時使用查找功能(或超鏈接)閱讀關聯(lián)類或關聯(lián)方法。

5、對于有疑問的地方,不妨寫幾行單元測試。

6、由淺入深,由易到難,多閱讀優(yōu)秀的開源項目,代碼閱讀水平會突飛猛進。

java源代碼分析----jvm.dll裝載過程

簡述 眾所周知java exe是java class文件的執(zhí)行程序 但實際上java exe程序只是一個執(zhí)行的外殼 它會裝載jvm dll(windows下 以下皆以windows平臺為例 linux下和solaris下其實類似 為 libjvm so) 這個動態(tài)連接庫才是java虛擬機的實際操作處理所在 本文探究java exe程序是如何查找和裝載jvm dll動態(tài)庫 并調用它進行class文件執(zhí)行處理的 源代碼 本文分析之代碼 《JavaTM SDK Standard Edition v fcsCommunity Source Release》 可從sun官方網站下載 主要分析的源代碼為 j se\src\share\bin\java cj se\src\windows\bin\java_md c java c是什么東西 java程序 源代碼所謂 java程序 包括jdk中的java exe\javac exe\javadoc exe java c源代碼中通過JAVA_ARGS宏來控制生成的代碼 如果該宏沒定義則編譯文件控制生成java exe否則編譯文件控制生成其他的 java程序 比如 j se\make\java\javac\Makefile(這是javac編譯文件)中 $(CD) / /sun/javac ; $(MAKE) $@ RELEASE=$(RELEASE) FULL_VERSION=$(FULL_VERSION)j se\make\sun\javac\javac\Makefile(由上面Makefile文件調用)中 JAVA_ARGS = { \ J ms m\ \ sun tools javac Main\ } 則由同一份java c代碼生成的javac exe程序就會直接調用java類方法 sun tools javac Main 這樣使其執(zhí)行起來就像是直接運行的一個exe文件 而未定義JAVA_ARGS的java exe程序則會調用傳遞過來參數中的類方法 從java c的main入口函數說起 main()函數中前面一段為重新分配參數指針的處理 然后調用函數 CreateExecutionEnvironment 該函數主要查找java運行環(huán)境的目錄 和jvm dll這個虛擬機核心動態(tài)連接庫文件路徑所在 根據操作系統(tǒng)不同 該函數有不同實現(xiàn)版本 但大體處理邏輯相同 我們看看windows平臺該函數的處理(j se\src\windows\bin\java_md c) CreateExecutionEnvironment函數主要分為三步處理 a 查找jre路徑 b 裝載jvm cfg中指定的虛擬機動態(tài)連接庫(jvm dll)參數 c 取jvm dll文件路徑 實現(xiàn) a 查找jre路徑是通過java_md c中函數 GetJREPath實現(xiàn)的 該函數首先調用GetApplicationHome函數 GetApplicationHome函數調用windowsAPI函數GetModuleFileName取java exe程序的絕對路徑 以我的jdk安裝路徑為例 為 D:\java\j sdk _ \bin\java exe 然后去掉文件名取絕對路徑為 D:\java\j sdk _ \bin 之后會在去掉最后一級目錄 現(xiàn)在絕對路徑為 D:\java\j sdk _ 然后GetJREPath函數繼續(xù)判斷剛剛取的路徑+\bin\java dll組合成的這個java dll文件是否存在 如果存在則 D:\java\j sdk _ 為JRE路徑 否則判斷取得的 D:\java\j sdk _ 路徑+\jre\bin\java dll文件是否存在 存在則 D:\java\j sdk _ \jre 為JRE路徑 如果上面兩種情況都不存在 則從注冊表中去查找(參見函數GetPublicJREHome) 函數 GetPublicJREHome先查找 HKEY_LOCAL_MACHINE\Sofare\JavaSoft\Java Runtime Environment\CurrentVersion鍵值 當前JRE版本號 判斷 當前JRE版本號 是否為 做為版本號 如果是則取HKEY_LOCAL_MACHINE\Sofare\JavaSoft\Java Runtime Environment\ 當前JRE版本號 \JavaHome的路徑所在為JRE路徑 我的JDK返回的JRE路徑為 D:\java\j sdk _ \jre b 裝載jvm cfg虛擬機動態(tài)連接庫配置文件是通過java c中函數:ReadKnownVMs實現(xiàn)的 該函數首先組合jvm cfg文件的絕對路徑 JRE路徑+\lib+\ARCH(CPU構架)+\jvm cfgARCH(CPU構架)的判斷是通過java_md c中GetArch函數判斷的 該函數中windows平臺只有兩種情況 WIN 的 ia 其他情況都為 i 我的為i 所以jvm cfg文件絕對路徑為 D:\java\j sdk _ \jre\lib\i \jvm cfg 文件內容如下 ## @(#)jvm cfg  / / # # Copyright Sun Microsystems Inc All rights reserved # SUN PROPRIETARY/CONFIDENTIAL Use is subject to license terms # # ### List of JVMs that can be used as an option to java javac etc # Order is important first in this list is the default JVM # NOTE that this both this file and its format are UNSUPPORTED and# WILL GO AWAY in a future release ## You may also select a JVM in an arbitrary location with the# XXaltjvm=jvm_dir option but that too is unsupported# and may not be available in a future release # client KNOWN server KNOWN hotspot ALIASED_TO client classic WARN native ERROR green ERROR(如果細心的話 我們會發(fā)現(xiàn)在JDK目錄中我的為 D:\java\j sdk _ \jre\bin\client 和 D:\java\j sdk _ \jre\bin\server 兩個目錄下都存在jvm dll文件 而java正是通過jvm cfg配置文件來管理這些不同版本的jvm dll的 )ReadKnownVMs函數會將該文件中的配置內容讀入到一個JVM配置結構的全局變量中 該函數首先跳過注釋(以 # 開始的行) 然后讀取以 開始的行指定的jvm參數 每一行為一個jvm信息 第一部分為jvm虛擬機名稱 第二部分為配置參數 比如行 client KNOWN 則 client 為虛擬機名稱 而 KNOWN 為配置類型參數 KNOWN 表示該虛擬機的jvm dll存在 而 ALIASED_TO 表示為另一個jvm dll的別名 WARN 表示該虛擬機的jvm dll不存在但運行時會用其他存在的jvm dll替代執(zhí)行 而 ERROR 同樣表示該類虛擬機的jvm dll不存在且運行時不會找存在的jvm dll替代而直接拋出錯誤信息 在運行java程序時指定使用那個虛擬機的判斷是由java c中函數 CheckJvmType判斷 該函數會檢查java運行參數中是否有指定jvm的參數 然后從ReadKnownVMs函數讀取的jvm cfg數據結構中去查找 從而指定不同的jvm類型(最終導致裝載不同jvm dll) 有兩種方法可以指定jvm類型 一種按照jvm cfg文件中的jvm名稱指定 第二種方法是直接指定 它們執(zhí)行的方法分別是 java Jjvm cfg中jvm名稱 java XXaltjvm=jvm類型名稱 或 java J XXaltjvm=jvm類型名稱 如果是第一種參數傳遞方式 CheckJvmType函數會取參數 J 后面的jvm名稱 然后從已知的jvm配置參數中查找如果找到同名的則去掉該jvm名稱前的 直接返回該值 而第二種方法 會直接返回 XXaltjvm= 或 J XXaltjvm= 后面的jvm類型名稱 如果在運行java時未指定上面兩種方法中的任一一種參數 CheckJvmType會取配置文件中第一個配置中的jvm名稱 去掉名稱前面的 返回該值 CheckJvmType函數的這個返回值會在下面的函數中匯同jre路徑組合成jvm dll的絕對路徑 比如 如果在運行java程序時使用 java J client test 則ReadKnownVMs會讀取參數 client 然后查找jvm cfg讀入的參數中是否有jvm名稱為 client 的 如果有則去掉jvm名稱前的 直接返回 client 而如果在運行java程序時使用如下參數 java XXaltjvm=D:\java\j sdk _ \jre\bin\client test 則ReadKnownVMs會直接返回 D:\java\j sdk _ \jre\bin\client 如果不帶上面參數執(zhí)行如 java test 因為在jvm cfg配置文件中第一個存在的jvm為 client 所以函數ReadKnownVMs也會去掉jvm名稱前的 返回 client 其實這三中情況都是使用的 D:\java\j sdk _ \jre\bin\client\jvm dll 這個jvm動態(tài)連接庫處理test這個class的 見下面GetJVMPath函數 c 取jvm dll文件路徑是通過java_md c中函數 GetJVMPath實現(xiàn)的 由上面兩步我們已經獲得了JRE路徑和jvm的類型字符串 GetJVMPath函數判斷CheckJvmType返回的jvm類型字符串中是否包含了 \ 或 / 如果包含則以該jvm類型字符串+\jvm dll作為JVM的全路徑 否則以JRE路徑+\bin+\jvm類型字符串+\jvm dll作為JVM的全路徑 看看上面的例子 第一種情況 java J client test jvm dll路徑為 JRE路徑+\bin+\jvm類型字符串+\jvm dll 按照我的JDK路徑則為 D:\java\j sdk _ \jre + \bin + \client + \jvm dll 第二種情況 java XXaltjvm=D:\java\j sdk _ \jre\bin\client test 路徑為 jvm類型字符串+\jvm dll即為 D:\java\j sdk _ \jre\bin\client + \jvm dll 第三種情況 java test 為 D:\java\j sdk _ \jre + \bin + \client + \jvm dll 與情況一相同 所以這三種情況都是調用的jvm動態(tài)連接庫 D:\javaj sdk _ \jre\bin\client\jvm dll 處理test類的 我們來進一步驗證一下 打開cmd控制臺 設置java裝載調試E:\work\java_researchset _JAVA_LAUNCHER_DEBUG= 情況一E:\work\java_researchjava J client test ScanDirectory _JAVA_LAUNCHER_DEBUG lishixinzhi/Article/program/Java/hx/201311/26750

java源代碼分析 實在是不太會,求高手教教我。

package?test2;

import?java.io.BufferedReader;

import?java.io.File;

import?java.io.FileInputStream;

import?java.io.FileOutputStream;

import?java.io.IOException;

import?java.io.InputStream;

import?java.io.InputStreamReader;

import?java.util.HashMap;

import?java.util.Map;

import?java.util.Set;

public?class?JavaCodeAnalyzer?{

public?static?void?analyze(File?file)?throws?IOException{

//FileOutputStream?fos?=?new?FileOutputStream("F;"+File.separator+"result.txt");

if(!(file.getName().endsWith(".txt")||file.getName().endsWith(".java"))){

System.out.println("輸入的分析文件格式不對!");

}

InputStream?is=?new?FileInputStream(file);

BufferedReader?br=?new?BufferedReader(new?InputStreamReader(is));

String?temp;

int?count=0;

int?countSpace=0;

int?countCode=0;

int?countDesc=0;

MapString,?Integer?map?=?getKeyWords();

while((temp=br.readLine())!=null){

countKeys(temp,?map);

count++;

if(temp.trim().equals("")){

countSpace++;

}else?if(temp.trim().startsWith("/*")||temp.trim().startsWith("http://")){

countDesc++;

}else{

countCode++;

}

}

System.out.printf("代碼行數:"+countCode+"占總行數的%4.2f\n",(double)countCode/count);

System.out.printf("空行數:"+countSpace+"占總行數的%4.2f\n",(double)countSpace/count);

System.out.printf("注釋行數:"+countDesc+"占總行數的%4.2f\n",(double)countDesc/count);

System.out.println("總行數:"+count);

System.out.println("出現(xiàn)最多的5個關鍵字是:");

System.out.println("");

System.out.println("");

System.out.println("");

System.out.println("");

System.out.println("");

}

public?static?void?main(String[]?args)?{

getKeyWords();

File?file?=?new?File("F://Test.java");

try?{

analyze(file);

}?catch?(IOException?e)?{

//?TODO?自動生成?catch?塊

e.printStackTrace();

}

}

public?static?MapString,Integer?getKeyWords(){

MapString,Integer?map?=?new?HashMapString,?Integer();

String[]keywords?=?{"abstract","assert","boolean","break","byte","case","catch","char","class","continue","default","do","double","else","enum","extends","final","finally","float","for","if","implements","import","instanceof","int","interface","long","native","new","package","private","protected","public","return","????strictfp","short","static","super","????switch","synchronized","this","throw","throws","transient","try","void","volatile","while","goto","const"};

for(String?s:keywords){

map.put(s,?0);

}

return?map;

}

public?static?void?countKeys(String?s,MapString,Integer?map){

SetString?keys?=?map.keySet();

for(String?ss:keys){

if(s.indexOf(ss)!=-1){

map.put(ss,?map.get(ss)+1);

}

}

}

}

上班沒啥時間了,還有點沒寫完,你在想想。

當前題目:java源代碼分析 Java程序分析
文章位置:http://chinadenli.net/article28/hghdjp.html

成都網站建設公司_創(chuàng)新互聯(lián),為您提供App設計品牌網站建設面包屑導航App開發(fā)外貿網站建設關鍵詞優(yōu)化

廣告

聲明:本網站發(fā)布的內容(圖片、視頻和文字)以用戶投稿、用戶轉載內容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內容未經允許不得轉載,或轉載時需注明來源: 創(chuàng)新互聯(lián)

外貿網站建設