導航:首頁 > 編程語言 > java非同步代碼

java非同步代碼

發布時間:2022-06-25 09:14:21

java 非同步編程

用非同步輸入輸出流編寫Socket進程通信程序
在Merlin中加入了用於實現非同步輸入輸出機制的應用程序介麵包:java.nio(新的輸入輸出包,定義了很多基本類型緩沖(Buffer)),java.nio.channels(通道及選擇器等,用於非同步輸入輸出),java.nio.charset(字元的編碼解碼)。通道(Channel)首先在選擇器(Selector)中注冊自己感興趣的事件,當相應的事件發生時,選擇器便通過選擇鍵(SelectionKey)通知已注冊的通道。然後通道將需要處理的信息,通過緩沖(Buffer)打包,編碼/解碼,完成輸入輸出控制。

通道介紹:
這里主要介紹ServerSocketChannel和 SocketChannel.它們都是可選擇的(selectable)通道,分別可以工作在同步和非同步兩種方式下(注意,這里的可選擇不是指可以選擇兩種工作方式,而是指可以有選擇的注冊自己感興趣的事件)。可以用channel.configureBlocking(Boolean )來設置其工作方式。與以前版本的API相比較,ServerSocketChannel就相當於ServerSocket(ServerSocketChannel封裝了ServerSocket),而SocketChannel就相當於Socket(SocketChannel封裝了Socket)。當通道工作在同步方式時,編程方法與以前的基本相似,這里主要介紹非同步工作方式。

所謂非同步輸入輸出機制,是指在進行輸入輸出處理時,不必等到輸入輸出處理完畢才返回。所以非同步的同義語是非阻塞(None Blocking)。在伺服器端,ServerSocketChannel通過靜態函數open()返回一個實例serverChl。然後該通道調用serverChl.socket().bind()綁定到伺服器某埠,並調用register(Selector sel, SelectionKey.OP_ACCEPT)注冊OP_ACCEPT事件到一個選擇器中(ServerSocketChannel只可以注冊OP_ACCEPT事件)。當有客戶請求連接時,選擇器就會通知該通道有客戶連接請求,就可以進行相應的輸入輸出控制了;在客戶端,clientChl實例注冊自己感興趣的事件後(可以是OP_CONNECT,OP_READ,OP_WRITE的組合),調用clientChl.connect(InetSocketAddress )連接伺服器然後進行相應處理。注意,這里的連接是非同步的,即會立即返回而繼續執行後面的代碼。

選擇器和選擇鍵介紹:
選擇器(Selector)的作用是:將通道感興趣的事件放入隊列中,而不是馬上提交給應用程序,等已注冊的通道自己來請求處理這些事件。換句話說,就是選擇器將會隨時報告已經准備好了的通道,而且是按照先進先出的順序。那麼,選擇器是通過什麼來報告的呢?選擇鍵(SelectionKey)。選擇鍵的作用就是表明哪個通道已經做好了准備,准備干什麼。你也許馬上會想到,那一定是已注冊的通道感興趣的事件。不錯,例如對於伺服器端serverChl來說,可以調用key.isAcceptable()來通知serverChl有客戶端連接請求。相應的函數還有:SelectionKey.isReadable(),SelectionKey.isWritable()。一般的,在一個循環中輪詢感興趣的事件(具體可參照下面的代碼)。如果選擇器中尚無通道已注冊事件發生,調用Selector.select()將阻塞,直到有事件發生為止。另外,可以調用selectNow()或者select(long timeout)。前者立即返回,沒有事件時返回0值;後者等待timeout時間後返回。一個選擇器最多可以同時被63個通道一起注冊使用。
應用實例:
下面是用非同步輸入輸出機制實現的客戶/伺服器實常式序――程序清單1(限於篇幅,只給出了伺服器端實現,讀者可以參照著實現客戶端代碼):

程序類圖

public class NBlockingServer {
int port = 8000;
int BUFFERSIZE = 1024;
Selector selector = null;
ServerSocketChannel serverChannel = null;
HashMap clientChannelMap = null;//用來存放每一個客戶連接對應的套接字和通道

public NBlockingServer( int port ) {
this.clientChannelMap = new HashMap();
this.port = port;
}

public void initialize() throws IOException {
//初始化,分別實例化一個選擇器,一個伺服器端可選擇通道
this.selector = Selector.open();
this.serverChannel = ServerSocketChannel.open();
this.serverChannel.configureBlocking(false);
InetAddress localhost = InetAddress.getLocalHost();
InetSocketAddress isa = new InetSocketAddress(localhost, this.port );
this.serverChannel.socket().bind(isa);//將該套接字綁定到伺服器某一可用埠
}
//結束時釋放資源
public void finalize() throws IOException {
this.serverChannel.close();
this.selector.close();
}
//將讀入位元組緩沖的信息解碼
public String decode( ByteBuffer byteBuffer ) throws
CharacterCodingException {
Charset charset = Charset.forName( "ISO-8859-1" );
CharsetDecoder decoder = charset.newDecoder();
CharBuffer charBuffer = decoder.decode( byteBuffer );
String result = charBuffer.toString();
return result;
}
//監聽埠,當通道准備好時進行相應操作
public void portListening() throws IOException, InterruptedException {
//伺服器端通道注冊OP_ACCEPT事件
SelectionKey acceptKey =this.serverChannel.register( this.selector,
SelectionKey.OP_ACCEPT );
//當有已注冊的事件發生時,select()返回值將大於0
while (acceptKey.selector().select() > 0 ) {
System.out.println("event happened");
//取得所有已經准備好的所有選擇鍵
Set readyKeys = this.selector.selectedKeys();
//使用迭代器對選擇鍵進行輪詢
Iterator i = readyKeys.iterator();
while (i
else if ( key.isReadable() ) {//如果是通道讀准備好事件
System.out.println("Readable");
//取得選擇鍵對應的通道和套接字
SelectableChannel nextReady =
(SelectableChannel) key.channel();
Socket socket = (Socket) key.attachment();
//處理該事件,處理方法已封裝在類ClientChInstance中
this.readFromChannel( socket.getChannel(),
(ClientChInstance)
this.clientChannelMap.get( socket ) );
}
else if ( key.isWritable() ) {//如果是通道寫准備好事件
System.out.println("writeable");
//取得套接字後處理,方法同上
Socket socket = (Socket) key.attachment();
SocketChannel channel = (SocketChannel)
socket.getChannel();
this.writeToChannel( channel,"This is from server!");
}
}
}
}
//對通道的寫操作
public void writeToChannel( SocketChannel channel, String message )
throws IOException {
ByteBuffer buf = ByteBuffer.wrap( message.getBytes() );
int nbytes = channel.write( buf );
}
//對通道的讀操作
public void readFromChannel( SocketChannel channel, ClientChInstance clientInstance )
throws IOException, InterruptedException {
ByteBuffer byteBuffer = ByteBuffer.allocate( BUFFERSIZE );
int nbytes = channel.read( byteBuffer );
byteBuffer.flip();
String result = this.decode( byteBuffer );
//當客戶端發出」@exit」退出命令時,關閉其通道
if ( result.indexOf( "@exit" ) >= 0 ) {
channel.close();
}
else {
clientInstance.append( result.toString() );
//讀入一行完畢,執行相應操作
if ( result.indexOf( "\n" ) >= 0 ){
System.out.println("client input"+result);
clientInstance.execute();
}
}
}
//該類封裝了怎樣對客戶端的通道進行操作,具體實現可以通過重載execute()方法
public class ClientChInstance {
SocketChannel channel;
StringBuffer buffer=new StringBuffer();
public ClientChInstance( SocketChannel channel ) {
this.channel = channel;
}
public void execute() throws IOException {
String message = "This is response after reading from channel!";
writeToChannel( this.channel, message );
buffer = new StringBuffer();
}
//當一行沒有結束時,將當前字竄置於緩沖尾
public void append( String values ) {
buffer.append( values );
}
}

//主程序
public static void main( String[] args ) {
NBlockingServer nbServer = new NBlockingServer(8000);
try {
nbServer.initialize();
} catch ( Exception e ) {
e.printStackTrace();
System.exit( -1 );
}
try {
nbServer.portListening();
}
catch ( Exception e ) {
e.printStackTrace();
}
}
}

程序清單1

小結:
從以上程序段可以看出,伺服器端沒有引入多餘線程就完成了多客戶的客戶/伺服器模式。該程序中使用了回調模式(CALLBACK)。需要注意的是,請不要將原來的輸入輸出包與新加入的輸入輸出包混用,因為出於一些原因的考慮,這兩個包並不兼容。即使用通道時請使用緩沖完成輸入輸出控制。該程序在Windows2000,J2SE1.4下,用telnet測試成功。

❷ 如何用JAVA實現非同步信息處理

一個進程專門循環這個list處理這個消息。是進程還是線程?進程間共享數據,你的list不是直接就能訪問的,所以估計LZ說的是線程

如果LZ想省點工作,可以用BlockingQueue來代替你的list,這樣線程等待和喚醒不用你自己寫代碼實現了,如果非要用list,那麼就自己做好同步

list的小例子,LZ自己參考發揮吧

class MessageConsumer extends Thead {
private List<YourMessageType> list;
private boolean running = true;
public MessageConsumer(List<YourMessageType> list) {this.list = list;}

public void run() {
while (running) {
YourMessageType msg = null;
try {
synchronized(list) {
while (list.size() == 0) {
list.wait();
}
msg = list.remove(0);
list.notiryAll();
}
} catch (Exception e) {
e.printStackTrace();
}

if (msg == null) continue;

//System.out.println(msg); //print message
}
}
}

//調用sample
class ShareMole {
List<YourMessageType> list = new ArrayList<YourMessageType>();
...
}

public class Main {
public static void main(String[] args) {
ShareMule sm; //so on

...

Thread t = new MessageConsumer(sm.list);
t.start();

...
}
}

❸ java 總結幾種線程非同步轉同步的方法

以Java語言為例:
用synchronized關鍵字修飾同步方法。
同步有幾種實現方法分別是synchronized,wait與notify
wait():使一個線程處於等待狀態,並且釋放所持有的對象的lock。
sleep():使一個正在運行的線程處於睡眠狀態,是一個靜態方法,調用此方法要捕捉InterruptedException異常。
notify():喚醒一個處於等待狀態的線程,注意的是在調用此方法的時候,並不能確切的喚醒某一個等待狀態的線程,而是由JVM確定喚醒哪個線程,而且不是按優先順序。
Allnotity():喚醒所有處入等待狀態的線程,注意並不是給所有喚醒線程一個對象的鎖,而是讓它們競爭。
同步是多線程中的重要概念。同步的使用可以保證在多線程運行的環境中,程序不會產生設計之外的錯誤結果。同步的實現方式有兩種,同步方法和同步塊,這兩種方式都要用到synchronized關鍵字。
給一個方法增加synchronized修飾符之後就可以使它成為同步方法,這個方法可以是靜態方法和非靜態方法,但是不能是抽象類的抽象方法,也不能是介面中的介面方法。下面代碼是一個同步方法的示例:
public synchronized void aMethod() {
// do something
}
public static synchronized void anotherMethod() {
// do something
}

線程在執行同步方法時是具有排它性的。當任意一個線程進入到一個對象的任意一個同步方法時,這個對象的所有同步方法都被鎖定了,在此期間,其他任何線程都不能訪問這個對象的任意一個同步方法,直到這個線程執行完它所調用的同步方法並從中退出,從而導致它釋放了該對象的同步鎖之後。在一個對象被某個線程鎖定之後,其他線程是可以訪問這個對象的所有非同步方法的。
同步塊是通過鎖定一個指定的對象,來對同步塊中包含的代碼進行同步;而同步方法是對這個方法塊里的代碼進行同步,而這種情況下鎖定的對象就是同步方法所屬的主體對象自身。如果這個方法是靜態同步方法呢?那麼線程鎖定的就不是這個類的對象了,也不是這個類自身,而是這個類對應的java.lang.Class類型的對象。同步方法和同步塊之間的相互制約只限於同一個對象之間,所以靜態同步方法只受它所屬類的其它靜態同步方法的制約,而跟這個類的實例(對象)沒有關系。

❹ java同步和非同步的區別

java同步和非同步的區別如下:

一、根據情況需要專門的線程方式

如果數據將在線程間共享.例如正在寫的數據以後可能被另一個線程讀到,或者正在讀的數據可能已經被另一個線程寫過了,那麼這些數據就是共享數據,必須進行同步存取.

當應用程序在對象上調用了一個需要花費很長時間來執行的方法,並且不希望讓程序等待方法的返回時,就應該使用非同步編程,在很多情況下採用非同步途徑往往更有效率.

二、應用不同:

(說明:以下有些例子為了突出重點,省略了不必要的代碼.非凡是省掉了一些成員變數,就是需要同步的對象.)

1. 多線程中對共享、可變的數據進行同步.

對於函數中的局部變數沒必要進行同步.

對於不可變數據,也沒必要進行同步.

多線程中訪問共享可變數據才有必要.

2. 單個線程中可以使用synchronized,而且可以嵌套,但無意義.

class Test {

public static void main(String[] args) {

Test t = new Test();

synchronized(t) {

synchronized(t) {

System.out.println("ok!");

}

}

}

}

3. 對象實例的鎖

class Test{

public synchronized void f1(){

//do something here

}

public void f2(){

synchronized(this){

//do something here

}

}

}

上面的f1()和f2()效果一致, synchronized取得的鎖都是Test某個實列(this)的鎖.

比如: Test t = new Test();

線程A調用t.f2()時, 線程B無法進入t.f1(),直到t.f2()結束.

作用: 多線程中訪問Test的同一個實例的同步方法時會進行同步.

4. class的鎖

class Test{

final static Object o= new Object();

public static synchronized void f1(){

//do something here

}

public static void f2(){

synchronized(Test.class){

//do something here

}

}

public static void f3(){

try {

synchronized (Class.forName("Test")) {

//do something here

}

}

catch (ClassNotFoundException ex) {

}

}

public static void g(){

synchronized(o){

//do something here

}

}

}

上面f1(),f2(),f3(),g()效果一致

f1(),f2(),f3()中synchronized取得的鎖都是Test.class的鎖.

g()是自己產生一個對象o,利用o的鎖做同步

作用: 多線程中訪問此類或此類任一個實例的同步方法時都會同步. singleton模式lazily initializing屬於此類.

5. static method

class Test{

private static int v = 0;

public static void f1(){

//do something, 但函數中沒用用到v

}

public synchronized static void f2(){

//do something, 函數中對v進行了讀/寫.

}

}

多線程中使用Test的某個實列時,

(1) f1()是線程安全的,不需要同步

(2) f2()這個靜態方法中使用了函數外靜態變數,所以需要同步.

❺ java怎麼寫非同步代碼

非同步不在後端 在前端 一般用ajax 非同步請求

❻ 求 JAVA 非同步觀察者模式 的源代碼(完整的),不要同步的,好的給加分

package TestObserver;

import java.util.Iterator;
import java.util.Vector;

/**
*
* @author Seastar
*/
interface Observed {

public void addObserver(Observer o);

public void removeObserver(Observer o);

public void update();
}

interface Observer {

public void takeAction();
}

class Invoker {

private Observer o;
Handler handler;

public Invoker(Observer o) {
new Handler();
this.o = o;
}

private class Handler extends Thread {

public Handler() {
handler = this;
}

@Override
public void run() {
o.takeAction();
}
}

public boolean TestSameObserver(Observer o) {
return o == this.o;
}

public void invoke() {
handler.start();
}
}

class ObservedObject implements Observed {

private Vector<Invoker> observerList = new Vector<Invoker>();

public void addObserver(Observer o) {
observerList.add(new Invoker(o));
}

public void removeObserver(Observer o) {
Iterator<Invoker> it = observerList.iterator();
while (it.hasNext()) {
Invoker i = it.next();
if (i.TestSameObserver(o)) {
observerList.remove(i);
break;
}
}
}

public void update() {
for (Invoker i : observerList) {
i.invoke();
}
}
}

class ObserverA implements Observer {

public void takeAction() {
System.out.println("I am Observer A ,state changed ,so i have to do something");
}
}

class ObserverB implements Observer {

public void takeAction() {
System.out.println("I am Observer B ,i was told to do something");
}
}

class ObserverC implements Observer {

public void takeAction() {
System.out.println("I am Observer C ,I just look ,and do nothing");
}
}

public class Main {

/**
* @param args the command line arguments
*/
public static void main(String[] args) {
ObserverA a = new ObserverA();
ObserverB b = new ObserverB();
ObserverC c = new ObserverC();
ObservedObject oo = new ObservedObject();
oo.addObserver(a);
oo.addObserver(b);
oo.addObserver(c);
for (int i = 0; i < 5; ++i) {
oo.addObserver(new Observer() {

public void takeAction() {
System.out.println("我是山寨觀察者"+",誰敢攔我");
}
});
}
//sometime oo changed ,so it calls update and informs all observer
oo.update();
}
}

觀察者模式的精髓在於注冊一個觀察者觀測可能隨時變化的對象,對象變化時就會自動通知觀察者,
這樣在被觀測對象影響范圍廣,可能引起多個類的行為改變時很好用,因為無需修改被觀測對象的代碼就可以增加被觀測對象影響的類,這樣的設計模式使得代碼易於管理和維護,並且減少了出錯幾率

至於非同步機制實際是個噱頭,可以有觀測對象來實現非同步,也可以有觀察者自身實現,這個程序實際是觀測對象實現了非同步機制,方法是在觀察者類外包裝了一層invoker類

❼ 如何用Java回調和線程實現非同步調用

軟體模塊之間的調用關系可以分為兩大類:即同步調用和非同步調用。在同步調用中,一段代碼(主調方)調用另一段代碼(被調方),主調方必須等待這段代碼執行完成返回結果後,才能繼續往下執行,所以,同步調用是一種阻塞式調用,主調方代碼一直阻塞等待直到被調方返回為止。同步調用相對比較直觀,也是大部分編程語言直接支持的一種調用方式。但是,同步調用在處理比較耗時的情況下會嚴重影響程序性能,影響人機交互的瞬時反應。例如,某個程序需要訪問資料庫獲取大量數據,然後根據這些數據進行一系列處理,將處理結果顯示在程序主窗口。由於資料庫訪問和大量數據的處理都是耗時的工作,在這個工作完成之前,處理結果遲遲不能顯示,用戶點擊滑鼠也不會立即得到響應,讓用戶感到整個程序顯得很沉重。面對這樣一些需要比較長時間才能完成的應用場景,我們需要採用一種非阻塞式調用方式,即非同步調用方式

❽ java 非同步調用方法

asynchronous call(非同步調用)
一個可以無需等待被調用函數的返回值就讓操作繼續進行的方法
中文名
非同步調用
外文名
asynchronous call
領域
函數
傑作
線程


快速
導航
實戰用法非同步調用使用方法
舉例
非同步調用就是你 喊 你朋友吃飯 ,你朋友說知道了 ,待會忙完去找你 ,你就去做別的了。
同步調用就是你 喊 你朋友吃飯 ,你朋友在忙 ,你就一直在那等,等你朋友忙完了 ,你們一起去。
實戰用法
操作系統發展到今天已經十分精巧,線程就是其中一個傑作。操作系統把 CPU 處理時間劃分成許多短暫時間片,在時間 T1 執行一個線程的指令,到時間 T2又執行下一線程的指令,各線程輪流執行,結果好象是所有線程在並肩前進。這樣,編程時可以創建多個線程,在同一期間執行,各線程可以「並行」完成不同的任務。
在單線程方式下,計算機是一台嚴格意義上的馮·諾依曼式機器,一段代碼調用另一段代碼時,只能採用同步調用,必須等待這段代碼執行完返回結果後,調用方才能繼續往下執行。有了多線程的支持,可以採用非同步調用,調用方和被調方可以屬於兩個不同的線程,調用方啟動被調方線程後,不等對方返回結果就繼續執行後續代碼。被調方執行完畢後,通過某種手段通知調用方:結果已經出來,請酌情處理。

❾ java隊列實現非同步執行

在整個思路上要調整一下

1、會有很多線程給一個隊列上添加任務

2、有一個或者多個線程逐個執行隊列的任務


考慮一下幾點:

1、沒有任務時,隊列執行線程處於等待狀態

2、添加任務時,激活隊列執行線程,全部run起來,首先搶到任務的執行,其他全部wait


給個小例子吧

packageorg;
importjava.util.LinkedList;
importjava.util.List;
publicclassQueues{
publicstaticList<Task>queue=newLinkedList<Task>();
/**
*假如參數o為任務
*@paramo
*/
publicstaticvoidadd(Taskt){
synchronized(Queues.queue){
Queues.queue.add(t);//添加任務
Queues.queue.notifyAll();//激活該隊列對應的執行線程,全部Run起來
}
}
staticclassTask{
publicvoidtest(){
System.out.println("我被執行了");
}
}
}
packageorg;
importjava.util.List;
{
@Override
publicvoidrun(){
while(true){
synchronized(Queues.queue){
while(Queues.queue.isEmpty()){//
try{
Queues.queue.wait();//隊列為空時,使線程處於等待狀態
}catch(InterruptedExceptione){
e.printStackTrace();
}
System.out.println("wait...");
}
Queues.Taskt=Queues.queue.remove(0);//得到第一個
t.test();//執行該任務
System.out.println("end");
}
}
}
publicstaticvoidmain(String[]args){
Exece=newExec();
for(inti=0;i<2;i++){
newThread(e).start();//開始執行時,隊列為空,處於等待狀態
}
//上面開啟兩個線程執行隊列中的任務,那就是先到先得了
//添加一個任務測試
Queues.Taskt=newQueues.Task();
Queues.add(t);//執行該方法,激活所有對應隊列,那兩個線程就會開始執行啦
}

}


上面的就是很簡單的例子了

❿ java後端怎麼接收前端的非同步請求

前端提交

POST /api/test HTTP/1.1

Host: 192.168.135.69:81

Connection: keep-alive

Content-Length: 18

Origin: http://192.168.135.69:81

User-Agent: Mozilla/5.0 (iPhone; CPU iPhone OS 11_0 like Mac OS X) AppleWebKit/604.1.38 (KHTML, like Gecko) Version/11.0 Mobile/15A372 Safari/604.1

Content-Type: application/x-www-form-urlencoded

Accept: */*

Referer: http://192.168.135.69:81/

Accept-Encoding: gzip, deflate

Accept-Language: zh-CN,zh;q=0.9

數據類型

{"phone":"222222"}

後台代碼

@At

@Ok("json")

@Filters

@POST

@AdaptBy(type= JsonAdaptor.class)

public Object test(@Param("..") NutMap nutMap, HttpServletRequest req) {undefined

System.out.println("nutMap::" + nutMap);

System.out.println("longin ::" + req);

return Result.success("system.success");

}

報錯信息

2019-01-05 20:02:20,560 org.nutz.ioc.loader.combo.ComboIocLoader.printFoundIocBean(ComboIocLoader.java:226) DEBUG - Found IocObject(portalGlobalsNavService) in AnnotationIocLoader(packages=[com.yunqi])

2019-01-05 20:02:20,560 org.nutz.ioc.impl.NutIoc.get(NutIoc.java:223) DEBUG - >> Make...'portalGlobalsNavService'

2019-01-05 20:02:20,560 org.nutz.ioc.impl.ScopeContext.save(ScopeContext.java:65) DEBUG - Save object 'portalGlobalsNavService' to [app]

2019-01-05 20:02:20,560 org.nutz.ioc.impl.NutIoc.get(NutIoc.java:166) DEBUG - Get ''<>

2019-01-05 20:02:20,560 org.nutz.ioc.aop.impl.DefaultMirrorFactory.getMirror(DefaultMirrorFactory.java:76) DEBUG - Load class com.yunqi.moles.service.portal.PortalGlobalsNavService without AOP

2019-01-05 20:02:20,560 org.nutz.ioc.impl.NutIoc.get(NutIoc.java:166) DEBUG - Get ''<>

2019-01-05 20:02:20,561 org.nutz.service.EntityService.(EntityService.java:41) DEBUG - Get TypeParams for self : com.yunqi.moles.models.portal.Portal_Globals_navnutMap::null

longin ::org.apache.shiro.web.servlet.ShiroHttpServletRequest@334e3d74

2019-01-05 20:02:20,572 com.yunqi.common.processor.LogTimeProcessor.process(LogTimeProcessor.java:24) DEBUG - [POST]URI=/app/test 60ms

————————————————

版權聲明:本文為CSDN博主「weixin_39657249」的原創文章,遵循CC 4.0 BY-SA版權協議,轉載請附上原文出處鏈接及本聲明。

原文鏈接:https://blog.csdn.net/weixin_39657249/article/details/114925997

閱讀全文

與java非同步代碼相關的資料

熱點內容
怎麼查看u盤加密區 瀏覽:181
台電加密是什麼格式 瀏覽:155
php論壇版塊在哪個文件夾 瀏覽:442
暗黑的伺服器為什麼維護 瀏覽:623
android內存溢出的原因 瀏覽:17
標志307的壓縮比是多少 瀏覽:636
伺服器啟動為什麼叫三聲 瀏覽:997
追風箏的人英文pdf 瀏覽:939
解壓小熊手機殼 瀏覽:346
成都市區建成面積演算法 瀏覽:660
智能家居單片機 瀏覽:97
買男裝用什麼app好 瀏覽:855
文件夾合並了怎麼拆開 瀏覽:260
波段副圖源碼無未來函數 瀏覽:89
livecn伺服器地址 瀏覽:259
程序員這個工作真的很吃香嗎 瀏覽:847
程序員和數學分析師待遇 瀏覽:681
壓縮氣彈簧怎麼拆 瀏覽:325
華為公有雲伺服器添加虛擬ip 瀏覽:211
程序員和運營哪個累 瀏覽:27