java ByteBuffer clear()问题,下面这段代码为什么会死循环

public static void main(String[] args) throws IOException,
ClassNotFoundException, InstantiationException, IllegalAccessException {
File f=new File("D:/1.txt");
FileChannel chanel=new RandomAccessFile(f,"rw").getChannel();
MappedByteBuffer map=chanel.map(FileChannel.MapMode.READ_ONLY,0,f.length() );
java.nio.ByteBuffer buffer=java.nio.ByteBuffer.allocate(256);
Charset charset=Charset.forName("utf-8");
CharsetDecoder decorder=charset.newDecoder();

    while((chanel.read(buffer))!=-1){

        buffer.flip();
        CharBuffer cb=charset.decode(buffer);
        System.out.println(cb);
        //buffer.clear();

    }

}

1个回答

可以看一看这个文档
https://my.oschina.net/talenttan/blog/889887
希望对你有帮助

Csdn user default icon
上传中...
上传图片
插入图片
抄袭、复制答案,以达到刷声望分或其他目的的行为,在CSDN问答是严格禁止的,一经发现立刻封号。是时候展现真正的技术了!
其他相关推荐
关于ByteBuffer的position和limit的问题
@Test public void test() throws Exception{ FileInputStream fis = new FileInputStream("D:\\1.jpg"); FileOutputStream fos = new FileOutputStream("D:\\2.jpg"); //获取通道 FileChannel inChannel = fis.getChannel(); FileChannel outChannel = fos.getChannel(); //分配指定大小缓存区 ByteBuffer buff = ByteBuffer.allocate(1024); System.out.println("-----ByteBuffer.allocate(1024)-----"); System.out.println("position"+buff.position()); System.out.println("limit"+buff.limit()); } 这个test在run下输出为 -----ByteBuffer.allocate(1024)----- position0 limit1024 将断点打在System.out.println("position"+buff.position());这个代码前面,debug下输出为 -----ByteBuffer.allocate(1024)----- position1024 limit1024 如果将 FileInputStream fis = new FileInputStream("D:\\1.jpg"); FileOutputStream fos = new FileOutputStream("D:\\2.jpg"); //获取通道 FileChannel inChannel = fis.getChannel(); FileChannel outChannel = fos.getChannel(); 注释掉,run和debug输出是一样的 -----ByteBuffer.allocate(1024)----- position1024 limit1024 获取通道FileChannel对ByteBuffer有什么影响? 求解答
java nio的select和linux的epoll有什么区别?
#### 最近在看关于epoll和select相关问题,但是并没有发现java的select和linux的epoll有什么区别 #### java的nio select代码如下 ``` import java.io.IOException; import java.net.InetSocketAddress; import java.net.ServerSocket; import java.nio.ByteBuffer; import java.nio.channels.SelectionKey; import java.nio.channels.Selector; import java.nio.channels.ServerSocketChannel; import java.nio.channels.SocketChannel; import java.nio.charset.Charset; import java.util.HashMap; import java.util.Map; import java.util.Set; import java.util.UUID; public class NioServer { private static Map<String, SocketChannel> clientMap = new HashMap<>(); public static void main(String[] args) throws IOException { ServerSocketChannel serverSocketChannel = ServerSocketChannel.open(); serverSocketChannel.configureBlocking(false); ServerSocket serverSocket = serverSocketChannel.socket(); serverSocket.bind(new InetSocketAddress(8899)); Selector selector = Selector.open(); serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT); while (true) { try { /** * 程序会卡在select()函数,当客户端有动作了,比如连接上了,或者是发送消息过来了,服务端才会继续走 * 当第一个客户端连接上并且是selectionKey.isAcceptable(),代码就又重新卡到了select()函数上 * 等待客户端的再次操作(无论是哪个客户端) */ selector.select(); /** * selector.selectedKeys()这段代码可以从中知道是哪个客户端,执行了什么操作 * */ Set<SelectionKey> selectionKeys = selector.selectedKeys(); selectionKeys.forEach((selectionKey) -> { final SocketChannel client; try { if (selectionKey.isAcceptable()) { ServerSocketChannel server = (ServerSocketChannel) selectionKey.channel(); /** * 这代代码获取了真正的客户端socket句柄 */ client = server.accept(); client.configureBlocking(false); /** * 这句话如果不写,就相当于没有注册当消息可读时的回调函数,当客户端发送消息过来的时候 * 服务端的selector.selectedKeys()就永远不会受到这类消息 */ client.register(selector, SelectionKey.OP_READ); String key = "[" + UUID.randomUUID().toString() + "]"; clientMap.put(key, client); } else if (selectionKey.isReadable()) { client = (SocketChannel) selectionKey.channel(); ByteBuffer readBuffer = ByteBuffer.allocate(1024); int count = client.read(readBuffer); if (count > 0) { readBuffer.flip(); Charset charset = Charset.forName("utf-8"); String recvMsg = String.valueOf(charset.decode(readBuffer).array()); System.out.println(client + ":" + recvMsg); String sendKey = null; for (Map.Entry<String, SocketChannel> stringSocketChannelEntry : clientMap.entrySet()) { if (stringSocketChannelEntry.getValue() == client) { sendKey = stringSocketChannelEntry.getKey(); break; } } for (Map.Entry<String, SocketChannel> stringSocketChannelEntry : clientMap.entrySet()) { SocketChannel socketChannel = stringSocketChannelEntry.getValue(); ByteBuffer writeBuffer = ByteBuffer.allocate(1024); writeBuffer.put((sendKey + ": " + recvMsg).getBytes()); writeBuffer.flip(); socketChannel.write(writeBuffer); } } } } catch (Exception ex) { ex.printStackTrace(); } }); selectionKeys.clear(); } catch (Exception e) { e.printStackTrace(); } } } } ``` #### linux的epoll的c代码如下 ``` #include <iostream> #include <sys/socket.h> #include <sys/epoll.h> #include <netinet/in.h> #include <arpa/inet.h> #include <fcntl.h> #include <unistd.h> #include <stdio.h> #include <errno.h> #include <cstring> using namespace std; #define MAXLINE 5 #define OPEN_MAX 100 #define LISTENQ 20 #define SERV_PORT 5000 #define INFTIM 1000 void setnonblocking(int sock) { int opts; opts=fcntl(sock,F_GETFL); if(opts<0) { perror("fcntl(sock,GETFL)"); exit(1); } opts = opts|O_NONBLOCK; if(fcntl(sock,F_SETFL,opts)<0) { perror("fcntl(sock,SETFL,opts)"); exit(1); } } int main(int argc, char* argv[]) { int i, maxi, listenfd, connfd, sockfd,epfd,nfds, portnumber; ssize_t n; char line[MAXLINE]; socklen_t clilen; if ( 2 == argc ) { if( (portnumber = atoi(argv[1])) < 0 ) { fprintf(stderr,"Usage:%s portnumber/a/n",argv[0]); return 1; } } else { fprintf(stderr,"Usage:%s portnumber/a/n",argv[0]); return 1; } //声明epoll_event结构体的变量,ev用于注册事件,数组用于回传要处理的事件 struct epoll_event ev,events[20]; //生成用于处理accept的epoll专用的文件描述符 //创建一个epoll文件描述符 epfd=epoll_create(256); struct sockaddr_in clientaddr; struct sockaddr_in serveraddr; listenfd = socket(AF_INET, SOCK_STREAM, 0); //把socket设置为非阻塞方式 //setnonblocking(listenfd); //设置与要处理的事件相关的文件描述符 ev.data.fd=listenfd; //设置要处理的事件类型 ev.events=EPOLLIN|EPOLLET; //ev.events=EPOLLIN; //注册epoll事件,将socket文件描述符listenfd的ev事件注册到epoll上 epoll_ctl(epfd,EPOLL_CTL_ADD,listenfd,&ev); memset(&serveraddr, sizeof(serveraddr) ,0); serveraddr.sin_family = AF_INET; char *local_addr="127.0.0.1"; inet_aton(local_addr,&(serveraddr.sin_addr));//htons(portnumber); serveraddr.sin_port=htons(portnumber); //先bind再监听 bind(listenfd,(sockaddr *)&serveraddr, sizeof(serveraddr)); listen(listenfd, LISTENQ); maxi = 0; for ( ; ; ) { //等待epoll事件的发生 //param epfd表示将监听epfd的事件 //param events表示容器,一旦有事件发生,events数组会被填充 nfds=epoll_wait(epfd,events,20,500); //处理所发生的所有事件 for(i=0;i<nfds;++i) { if(events[i].data.fd==listenfd)//如果新监测到一个SOCKET用户连接到了绑定的SOCKET端口,建立新的连接。 { connfd = accept(listenfd,(sockaddr *)&clientaddr, &clilen); if(connfd<0){ perror("connfd<0"); exit(1); } //setnonblocking(connfd); char *str = inet_ntoa(clientaddr.sin_addr); cout << "accapt a connection from " << str << endl; //设置用于读操作的文件描述符 ev.data.fd=connfd; //设置用于注测的读操作事件 ev.events=EPOLLIN|EPOLLET; //ev.events=EPOLLIN; //注册ev epoll_ctl(epfd,EPOLL_CTL_ADD,connfd,&ev); } else if(events[i].events&EPOLLIN)//如果是已经连接的用户,并且收到数据,那么进行读入。 { cout << "EPOLLIN" << endl; if ( (sockfd = events[i].data.fd) < 0) continue; if ( (n = read(sockfd, line, MAXLINE)) < 0) { if (errno == ECONNRESET) { close(sockfd); events[i].data.fd = -1; } else std::cout<<"readline error"<<std::endl; } else if (n == 0) { close(sockfd); events[i].data.fd = -1; } line[n] = '/0'; cout << "read " << line << endl; //设置用于写操作的文件描述符 ev.data.fd=sockfd; //设置用于注测的写操作事件 ev.events=EPOLLOUT|EPOLLET; //修改sockfd上要处理的事件为EPOLLOUT //epoll_ctl(epfd,EPOLL_CTL_MOD,sockfd,&ev); } else if(events[i].events&EPOLLOUT) // 如果有数据发送 { sockfd = events[i].data.fd; write(sockfd, line, n); //设置用于读操作的文件描述符 ev.data.fd=sockfd; //设置用于注测的读操作事件 ev.events=EPOLLIN|EPOLLET; //修改sockfd上要处理的事件为EPOLIN epoll_ctl(epfd,EPOLL_CTL_MOD,sockfd,&ev); } } } return 0; } ``` #### 从上面两段代码看好像基本思想都是一样的,并没有传说中的select不知道发生的事件,只能通过循环去判断的情况。 #### 但是后来我又在网上找了一段linux的select实现的网络io代码 ``` #include<stdio.h> #include<sys/types.h> #include<sys/socket.h> #include<unistd.h> #include<stdlib.h> #include<errno.h> #include<arpa/inet.h> #include<netinet/in.h> #include<string.h> #include<signal.h> #define MAXLINE 1024 #define LISTENLEN 10 #define SERV_PORT 6666 int main(int argc, char **argv) { int i, maxi, maxfd, listenfd, connfd, sockfd; int nready, client[FD_SETSIZE]; ssize_t n; fd_set rset, allset; char buf[MAXLINE]; socklen_t clilen; struct sockaddr_in cliaddr, servaddr; listenfd = socket(AF_INET, SOCK_STREAM, 0); bzero(&servaddr, sizeof(servaddr)); servaddr.sin_family = AF_INET; servaddr.sin_addr.s_addr = htonl(INADDR_ANY); servaddr.sin_port = htons(SERV_PORT); bind(listenfd, (struct sockaddr*) &servaddr, sizeof(servaddr)); listen(listenfd, LISTENLEN); maxfd = listenfd; /* initialize */ maxi = -1; /* index into client[] array */ for (i = 0; i < FD_SETSIZE; i++) client[i] = -1; /* -1 indicates available entry */ FD_ZERO(&allset); FD_SET(listenfd, &allset); for ( ; ; ) { rset = allset; /* structure assignment */ nready = select(maxfd+1, &rset, NULL, NULL, NULL); if (FD_ISSET(listenfd, &rset)) /* new client connection */ { clilen = sizeof(cliaddr); connfd = accept(listenfd, (struct sockaddr*) &cliaddr, &clilen); #ifdef NOTDEF printf("new client: %s, port %d\n", inet_ntop(AF_INET, &cliaddr.sin_addr, 4, NULL), ntohs(cliaddr.sin_port)); #endif for (i = 0; i < FD_SETSIZE; i++) if (client[i] < 0) { client[i] = connfd; /* save descriptor */ break; } if (i == FD_SETSIZE) { printf("too many clients"); exit(0); } FD_SET(connfd, &allset); /* add new descriptor to set */ if (connfd > maxfd) maxfd = connfd; /* for select */ if (i > maxi) maxi = i; /* max index in client[] array */ if (--nready <= 0) continue; /* no more readable descriptors */ } for (i = 0; i <= maxi; i++) /* check all clients for data */ { if ( (sockfd = client[i]) < 0) continue; if (FD_ISSET(sockfd, &rset)) { if ( (n = read(sockfd, buf, MAXLINE)) == 0)/* connection closed by client */ { close(sockfd); FD_CLR(sockfd, &allset); client[i] = -1; } else write(sockfd, buf, n); if (--nready <= 0) break; /* no more readable descriptors */ } } } } ``` #### 从这段代码里面确实是可以看出是通过循环判断的,我的问题是java的select是不是就是linux的epoll的思想?
bytebuffer 的 position问题
public class BytebufferTest{ public static void main(String[] args)throws IOException{ ByteBuffer bbuffer = ByteBuffer.allocate(10); byte[] b1 = new byte[]{'a','b'}; bbuffer.put(b1); System.out.println(bbuffer.position()); char[] c1 = new char[]{'c','d'}; bbuffer.asCharBuffer().put(c1); System.out.println(bbuffer.position()); buffer.rewind(); while(bbuffer.hasRemaining()){ System.out.println((char)bbuffer.get()); } } } 请问为什么“System.out.println(bbuffer.position());”输出的position值一样,之后的“'c','d'”不是已经成功存入byterbuffer了吗,为什么position值不相应增加? 谢谢大侠! [b]问题补充:[/b] TO:RednaxelaFX 请问大侠这段JavaDoc您是在哪里找到的?我也想拜读下。
java 遍历问题为什么会抛异常
public class GetData { private static final int BSIZE = 1024; public static void main(String[] args) { ByteBuffer bb = ByteBuffer.allocate(BSIZE); int i = 0; while(i++ < bb.limit()){ System.out.println(i); if(bb.get() != 0){ System.out.println("nonzero"); }else{ if(i == 512){ System.out.println(bb.get()); } } } } } 结果Exception in thread "main" java.nio.BufferUnderflowException at java.nio.Buffer.nextGetIndex(Buffer.java:492) at java.nio.HeapByteBuffer.get(HeapByteBuffer.java:135) at java_nio.GetData.main(GetData.java:13)
AIO问题请帮忙解答一下,为什么会阻塞掉
问题描述: 1. 先启动服务端进入等待 2. 启动客户端进行数据发送,然后服务端与客户端线程都会被阻塞 这里是服务端代码: ``` package org.morningdew.javaaio.main; import java.io.IOException; import java.net.InetSocketAddress; import java.nio.ByteBuffer; import java.nio.channels.AsynchronousServerSocketChannel; import java.nio.channels.AsynchronousSocketChannel; import java.util.concurrent.ExecutionException; import java.util.concurrent.Future; public class Server { public static void main(String[] args) { AsynchronousServerSocketChannel assc = null; try { assc = AsynchronousServerSocketChannel.open(); assc.bind(new InetSocketAddress(9090)); System.out.println("server start at 9090 !"); while(true) { System.out.println("Server waiting connect !"); Future<AsynchronousSocketChannel> f = assc.accept(); AsynchronousSocketChannel asc = f.get(); System.out.println(Thread.currentThread().getName()); ByteBuffer byteBuffer = ByteBuffer.allocate(1024); byteBuffer.clear(); StringBuilder stringBuilder = new StringBuilder(); while(asc.read(byteBuffer).get() > 0) { byteBuffer.flip(); byte[] b = new byte[byteBuffer.remaining()]; byteBuffer.get(b); byteBuffer.clear(); stringBuilder.append(new String(b, "utf-8")); } System.out.println(stringBuilder.toString()); ByteBuffer byteBufferWrite = ByteBuffer.allocate(1024); byteBufferWrite.clear(); byteBufferWrite.put("我服务点".getBytes("utf-8")); byteBufferWrite.flip(); while(byteBufferWrite.hasRemaining()) { System.out.println("写出成功"); asc.write(byteBufferWrite).get(); } } } catch (IOException e) { e.printStackTrace(); } catch (InterruptedException e) { e.printStackTrace(); } catch (ExecutionException e) { e.printStackTrace(); }finally { try { if(assc != null && assc.isOpen()) { assc.close(); } } catch (IOException e) { e.printStackTrace(); } } } } 下是客户端代码: package org.morningdew.javaaio.main; import java.io.IOException; import java.net.InetSocketAddress; import java.nio.ByteBuffer; import java.nio.channels.AsynchronousSocketChannel; import java.util.concurrent.ExecutionException; public class Client { public static void main(String[] args) { AsynchronousSocketChannel asc = null; try { asc = AsynchronousSocketChannel.open(); asc.connect(new InetSocketAddress(9090)).get(); ByteBuffer byteBuffer = ByteBuffer.allocate(1024); byteBuffer.clear(); byteBuffer.put("我是客户端".getBytes("utf-8")); byteBuffer.flip(); while(byteBuffer.hasRemaining()) { asc.write(byteBuffer).get(); } ByteBuffer byteBufferRead = ByteBuffer.allocate(1024); byteBufferRead.clear(); StringBuilder stringBuilder = new StringBuilder(); System.out.println("等到接受服务端数据"); while(asc.read(byteBufferRead).get() > 0) { byteBufferRead.flip(); byte[] b = new byte[byteBufferRead.remaining()]; byteBufferRead.get(b); byteBufferRead.clear(); stringBuilder.append(new String(b, "utf-8")); } System.out.println(stringBuilder.toString()); System.out.println("zhixing wanbu "); } catch (IOException e) { e.printStackTrace(); } catch (InterruptedException e) { e.printStackTrace(); } catch (ExecutionException e) { e.printStackTrace(); }finally { try { if(asc != null && asc.isOpen()) { asc.close(); } } catch (IOException e) { e.printStackTrace(); } } } } ```
Java Nio中Charset的decode()方法问题
try { ByteBuffer byteBuffer = ByteBuffer.allocate(20); System.out.println("capacity = " + byteBuffer.capacity() + ", limit = " + byteBuffer.limit() + ", position = " + byteBuffer.position()); FileChannel channel = new FileInputStream(PATH).getChannel(); channel.read(byteBuffer); System.out.println("capacity = " + byteBuffer.capacity() + ", limit = " + byteBuffer.limit() + ", position = " + byteBuffer.position()); byteBuffer.clear(); System.out.println("capacity = " + byteBuffer.capacity() + ", limit = " + byteBuffer.limit() + ", position = " + byteBuffer.position()); CharBuffer buffer = Charset.defaultCharset().decode(byteBuffer); System.out.println("capacity = " + buffer.capacity() + ", limit = " + buffer.limit() + ", position = " + buffer.position()); } catch (Exception e) { e.printStackTrace(); } 代码如上,假设有一个文件是系统默认GBK编码,文件内容只有一个数字1,那么上述代码在decode之后得到的CharBuffer的容量为什么是21,比原ByteBuffer都大?而且CharBuffer的容量与极限为什么不同?
mina自定义解码器报错?
自定义的mina解码器时不时就会报错,找了很久没找到原因?希望各位大佬给我排查一下,帮我理一下怎么定位这个问题一, 下是自己写的解码器 ``` protected boolean doDecode(IoSession session, IoBuffer in, ProtocolDecoderOutput out) throws Exception { if (in.position() == in.limit()) return false; //前4字节校验代码 if (in.remaining() < 4) { //由于未消费字节,无需reset return false; } if (isPolicy(session, in)) return false; in.mark(); // 接受key if (in.limit() == 8) { for (int i = 0; i < 4; i++) { in.get(); } byte[] keys = new byte[4]; keys[0] = in.get(); keys[1] = in.get(); keys[2] = in.get(); keys[3] = in.get(); session.setAttribute("randomKey", keys); return false; } // 获得密匙 byte[] keys = (byte[]) session.getAttribute("randomKey"); if (keys == null) { in.reset(); return false; } int dataLength = readLength1(in, keys); if (dataLength == -1) { in.reset(); return false; } // 数据长度 int len = in.remaining(); // 判断长度 if (dataLength > MNTcpConnect.MAX_DATA_LENGTH) { // 测试代码 String data = ""; { byte[] cc = new byte[len]; in.get(cc); ByteBuffer byteBuffer = new ByteBuffer(cc); data = (byteBuffer.readUnsignedShort() + " " + byteBuffer.readShort() + " " + byteBuffer.readInt()); } in.clear(); throw new IllegalArgumentException("over max data length! length: " + dataLength + ", data:" + data); } if (dataLength > len) { in.reset(); return false; } byte[] bb = new byte[dataLength]; in.get(bb); // 解密数据 ByteKit.xorBytes4(bb, keys); out.write(bb); return true; ``` //报错信息如下--希望大佬们帮我排查一下 ``` 2019-08-21 04:51:57,928 [pool-3-thread-21256] ERRORcore.mina.MNTcpIOHandler - Error...:core.mina.MNTcpIOHandler@67a64777 org.apache.mina.filter.codec.ProtocolDecoderException: java.lang.IllegalArgumentException: over max data length! length: 1968796530, data:57386 0 1124073472 (Hexdump: 03 00 00 2F 2A E0 00 00 00 00 00 43 6F 6F 6B 69 65 3A 20 6D 73 74 73 68 61 73 68 3D 41 64 6D 69 6E 69 73 74 72 0D 0A 01 00 08 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ......) at org.apache.mina.filter.codec.ProtocolCodecFilter.messageReceived(ProtocolCodecFilter.java:262) at org.apache.mina.core.filterchain.DefaultIoFilterChain.callNextMessageReceived(DefaultIoFilterChain.java:650) at org.apache.mina.core.filterchain.DefaultIoFilterChain.access$1300(DefaultIoFilterChain.java:49) at org.apache.mina.core.filterchain.DefaultIoFilterChain$EntryImpl$1.messageReceived(DefaultIoFilterChain.java:1141) at core.back.MNBlacklistFilter.messageReceived(MNBlacklistFilter.java:34) at org.apache.mina.core.filterchain.DefaultIoFilterChain.callNextMessageReceived(DefaultIoFilterChain.java:650) at org.apache.mina.core.filterchain.DefaultIoFilterChain.access$1300(DefaultIoFilterChain.java:49) at org.apache.mina.core.filterchain.DefaultIoFilterChain$EntryImpl$1.messageReceived(DefaultIoFilterChain.java:1141) at org.apache.mina.core.filterchain.IoFilterAdapter.messageReceived(IoFilterAdapter.java:122) at org.apache.mina.core.filterchain.DefaultIoFilterChain.callNextMessageReceived(DefaultIoFilterChain.java:650) at org.apache.mina.core.filterchain.DefaultIoFilterChain.fireMessageReceived(DefaultIoFilterChain.java:643) at org.apache.mina.core.polling.AbstractPollingIoProcessor.read(AbstractPollingIoProcessor.java:539) at org.apache.mina.core.polling.AbstractPollingIoProcessor.access$1200(AbstractPollingIoProcessor.java:68) at org.apache.mina.core.polling.AbstractPollingIoProcessor$Processor.process(AbstractPollingIoProcessor.java:1242) at org.apache.mina.core.polling.AbstractPollingIoProcessor$Processor.process(AbstractPollingIoProcessor.java:1231) at org.apache.mina.core.polling.AbstractPollingIoProcessor$Processor.run(AbstractPollingIoProcessor.java:683) at org.apache.mina.util.NamePreservingRunnable.run(NamePreservingRunnable.java:64) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) at java.lang.Thread.run(Thread.java:748) Caused by: java.lang.IllegalArgumentException: over max data length! length: 1968796530, data:57386 0 1124073472 at core.mina.MNProtocolDecoder.doDecode(MNProtocolDecoder.java:74) at org.apache.mina.filter.codec.CumulativeProtocolDecoder.decode(CumulativeProtocolDecoder.java:180) at org.apache.mina.filter.codec.ProtocolCodecFilter.messageReceived(ProtocolCodecFilter.java:253) ... 19 more ```
ByteBuffer.allocateDirect()分配的内存是在用户空间还是内核空间
1、ByteBuffer.allocateDirect()到底是在用户空间还是内核空间分配内存 2、如果它是从用户空间分配内存,那么为什么后面说交互都在内核空间中发生,不需要数据的拷贝?如果它是从内核空间分配内存,为什么与c语言的malloc不一致呢? java能直接分配、读写内核空间吗?
java 关于NIO实现UDP数据传输问题 ,急谢谢,C币不足请不要介意
各位大侠好,小弟想问一下问题,搞了一两天没有搞明白的。因为要实现一个UDP传输服务端,于是在网上找了很多资料然后就写了一个。但是写好之后发现有两个很严重的问题,希望各位大哥给点意见或者思路去解决。 问题一:启动服务端,同时也启动客户端,客户端传输数据服务器正常接收,但是断开客户端后,再启动客户端,服务器就收不到任何客户端发送的消息,好像是服务器关闭了UDP一样,但是重启服务器后(重新打开UDP)客户端既可以发送信息过来。 问题二:多个客户端。第一个客户端连接上后,第二个客户端怎么也链接不上了。即使关闭了第一个客户端也一样。 如下是代码: package com.gateway.socket; import java.io.IOException; import java.net.InetSocketAddress; import java.net.SocketAddress; import java.net.UnknownHostException; import java.nio.ByteBuffer; import java.nio.channels.DatagramChannel; import java.nio.channels.SelectionKey; import java.nio.channels.Selector; import java.util.Iterator; import java.util.Set; import org.apache.log4j.Logger; public class UDPEchoServerSelector extends Thread { private static final Logger log = Logger.getLogger(ServerSocket.class); // private InetSocketAddress inetSocketAddress; // socket处理类 private UDPSocketHandler handler = new UDPSocketHandler(); // 注册的接受服务 private SocketReceiver receiver = null; /** * 初始化socket * * @param receiver * @param hostname * @param port * @throws IOException * @throws UnknownHostException */ public UDPEchoServerSelector(SocketReceiver receiver, String hostname, int port) { if (hostname.isEmpty()) { inetSocketAddress = new InetSocketAddress(port); } else { inetSocketAddress = new InetSocketAddress(hostname, port); } this.receiver = receiver; } @Override public void run() { try { Selector selector = Selector.open(); // 创建选择器,可以处理多路通道。 DatagramChannel serverSocketChannel = DatagramChannel.open(); // 打开通道 serverSocketChannel.configureBlocking(false); // 非阻塞 serverSocketChannel.socket().bind(inetSocketAddress); /* * 将通道管理器和该通道绑定,并为该通道注册SelectionKey.OP_READ事件,注册该事件后, * 当该事件到达时,selector.select()会返回,如果该事件没到达selector.select()会一直阻塞。 */ serverSocketChannel.register(selector, SelectionKey.OP_READ, new ClientData()); log.info("Server: socket server started."); /* * 采用轮询的方式监听selector上是否有需要处理的事件,如果有,则进行处理 */ while (true) { // 轮询 // 当注册的事件到达时,方法返回;否则,该方法会一直阻塞 int nKeys = selector.select(); if (nKeys == 0) { continue; } // 得到选择键列表 Set Keys = selector.selectedKeys(); Iterator it = Keys.iterator(); while (it.hasNext()) { SelectionKey key = null; key = (SelectionKey) it.next(); // 键为位掩码 it.remove(); // 客户端请求连接事件 if (key.isValid() && key.isWritable()) { log.info("Server: SelectionKey is acceptable."); handler.handleWrite(key); } if (key.isReadable()) {// 获得了可读的事件 log.info("Server: SelectionKey is readable."); handler.receiveMsg(key, receiver); } } Keys.clear(); } } catch (IOException e) { e.printStackTrace(); } } public static class ClientData { public SocketAddress clientAddress; public ByteBuffer buffer = ByteBuffer.allocate(255); } } package com.gateway.socket; import java.io.IOException; import java.net.InetSocketAddress; import java.nio.ByteBuffer; import java.nio.channels.DatagramChannel; import java.nio.channels.SelectionKey; import org.apache.log4j.Logger; import com.gateway.common.DeviceDataTools; import com.gateway.common.data.HexUtils; import com.gateway.socket.UDPEchoServerSelector.ClientData; /** * * 处理socket类 * * @author Andy * */ public class UDPSocketHandler { private static Logger log = Logger.getLogger(UDPSocketHandler.class); /** * 链接请求 * * @throws IOException */ public void handleWrite(SelectionKey key) { try { DatagramChannel channel = (DatagramChannel) key.channel(); ClientData clntDat = (ClientData) key.attachment(); clntDat.buffer.flip(); // 从起始位置开始发送 int bytesSent; bytesSent = channel.send(clntDat.buffer, clntDat.clientAddress); if (bytesSent != 0) { key.interestOps(SelectionKey.OP_READ); // 关注客户端发送数据 } } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } /** * 读请求 * * @throws IOException */ public void receiveMsg(SelectionKey key, SocketReceiver receiver) { ByteBuffer byteBuffer = ByteBuffer.allocate(1024); byteBuffer.clear(); DatagramChannel socketChannel = (DatagramChannel) key.channel(); //非阻塞 try { socketChannel.configureBlocking(false); } catch (IOException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } System.out.println("channel code:" + socketChannel.hashCode()); try { while (true) { InetSocketAddress client = (InetSocketAddress) socketChannel .receive(byteBuffer); byteBuffer.flip(); // byteBuffer中传过来的是10进制的bytep[] byte[] dst = new byte[byteBuffer.limit()]; byteBuffer.get(dst); // 将10进制的byte[]转化成16进制字符串 String data = HexUtils.converBytesToHex(dst); System.out.println(data); log.info("Server: data1 = " + data); byteBuffer.clear(); receiver.udpreceive(socketChannel, data, client); break; } } catch (java.io.IOException e) { //e.printStackTrace(); //this.closeChannel(key, socketChannel); } catch (Exception e) { //e.printStackTrace(); //this.closeChannel(key, socketChannel); } } /** * * @param socketChannel */ private void closeChannel(SelectionKey key, DatagramChannel socketChannel) { try { while (socketChannel.isOpen()) { key.cancel(); socketChannel.close(); } } catch (IOException e1) { e1.printStackTrace(); } } /** * 根据socketKey从内存中获取channel,通过channel向client端发送消息 * * @param socketKey * 内存在channel对应的key * @param data * 发送的数据 * @return * @throws IOException */ public static boolean send(String socketKey, String data) throws IOException { DatagramChannel socketChannel = SocketChannelMapper .getUDPChannel(socketKey); if (socketChannel == null || !socketChannel.isOpen()) { return false; } InetSocketAddress client = SocketChannelMapper .getUDPInetSocketAddress(socketKey + "address"); boolean f = socketChannel.isConnected(); ByteBuffer byteBuffer = ByteBuffer.wrap(DeviceDataTools.hex2Byte(data)); if (f) { socketChannel.write(byteBuffer); } else { socketChannel.connect(new InetSocketAddress(client.getAddress(), client.getPort())); socketChannel.send(byteBuffer, client); } return true; } /** * 根据socketKey从内存中获取channel,通过channel向client端发送消息 * * @param socketKey * 内存在channel对应的key * @param data * 发送的数据 * @return * @throws IOException */ public static boolean send(DatagramChannel socketChannel, String data, InetSocketAddress client) throws IOException { if (socketChannel == null) { return false; } System.out.println("#########################ADDRESS" + client.getAddress()); System.out.println("#########################PORT" + client.getPort()); boolean f = socketChannel.isConnected(); ByteBuffer byteBuffer = ByteBuffer.wrap(DeviceDataTools.hexStr2ByteArray(data)); if (f) { socketChannel.write(byteBuffer); } else { socketChannel.connect(new InetSocketAddress(client.getAddress(), client.getPort())); socketChannel.send(byteBuffer, client); } return true; } }
Android Socket使用NIO的基础性问题
在尝试向SocketChannel写入数据时出问题了,每次写入后返回的Size都是0,问题代码如下: ``` SocketChannel socketChannel = null; ByteBuffer sendBuffer = null; ``` 下面这是发送数据的函数中一部分 ``` sendBuffer = ByteBuffer.wrap("hello".getBytes("UTF8")); sendBuffer.flip(); int bufferLength = sendBuffer.array().length; int sendsize = 0; while(sendBuffer.hasRemaining()) { sendsize += socketChannel.write(sendBuffer); } sendBuffer.clear(); ``` 问题1:查看了ByteBuffer.flip() 和 ByteBuffer.clear()的代码发现都是改变它的位置指针,flip是把position 和 limit 都置0,而remaining的值是limit - position,这样一来flip之后remaining不总是等于0吗?我的循环就始终没有执行,但是又在几篇帖子里看到说write之前需要先flip,于是很困惑。 问题2:如果不加while语句,不判断remaining而直接write,发现返回的size还是0,就是说没有数据被写到socketChannel里。 还请大侠指点迷津!
Android OpenGL es 下面这段代码在模拟器2.2上可以正常 在真机上都是黑屏
测试环境:平板Android 2.3.1 和 mtk6592 cpu Android4.2.2 mtk6592 cpu Android4.2.2 还报错 09-20 15:00:30.264: E/linker(13810): load_library(linker.cpp:761): library "libmaliinstr.so" not found 09-20 15:00:30.265: E/(13810): appName=cn.it.opengl, acAppName=com.android.cts.openglperf 09-20 15:00:30.265: E/(13810): 009-20 15:00:30.266: E/(13810): appName=cn.it.opengl, acAppName=com.android.browser09-20 15:00:30.266: E/(13810): 0 public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); view = new MyGLSurfaceView(this); this.setContentView(view); //渲染模式:持续渲染(默认)|命令渲染 view.setRenderer(new MyRendererCirclePoint()); //设置脏渲染(命令渲染) view.setRenderMode(GLSurfaceView.RENDERMODE_CONTINUOUSLY); //请求渲染,renderer.onDrawFrame(); // view.requestRender(); } class MyGLSurfaceView extends GLSurfaceView{ public MyGLSurfaceView(Context context) { super(context); } } public class MyRendererCirclePoint implements Renderer { private float ratio; /** * 表层创建时调用该方法 */ public void onSurfaceCreated(GL10 gl, EGLConfig config) { //清屏色(黑色) gl.glClearColor(0, 0, 0, 1); //颜色缓冲和顶点缓冲区 gl.glEnableClientState(GL10.GL_VERTEX_ARRAY); gl.glEnableClientState(GL10.GL_COLOR_ARRAY); } /** * 表层大小改变时调用该方法 */ public void onSurfaceChanged(GL10 gl, int width, int height) { gl.glViewport(0, 0, width, height); ratio = (float)width / height; //投影矩阵 gl.glMatrixMode(GL10.GL_PROJECTION); gl.glLoadIdentity();//重置矩阵 gl.glFrustumf(-ratio, ratio, -1, 1, 3, 100);//设置平截头体 } /** * 绘图 */ public void onDrawFrame(GL10 gl) { //清除颜色缓冲去 gl.glClear(GL10.GL_COLOR_BUFFER_BIT); gl.glMatrixMode(GL10.GL_MODELVIEW);//设置模型视图矩阵 gl.glLoadIdentity(); GLU.gluLookAt(gl, 0, 0, 5, 0, 0, 0, 0, 1, 0);//架设相机位置 /** * vertextList,顶点集合 */ float r = 0.6f ;//半径 List<Float> vertextList = new ArrayList<Float>(); float x = 0 , y = 0 , z = 0.8f ; for(float angle = 0 ; angle <= Math.PI * 6 ; angle = (float) (angle + (Math.PI / 20))){ x = (float) (r * Math.cos(angle)); y = (float) (r * Math.sin(angle)); z = z - 0.01f ; vertextList.add(x); vertextList.add(y); vertextList.add(z); } ByteBuffer vbb = ByteBuffer.allocateDirect(vertextList.size() * 4); vbb.order(ByteOrder.nativeOrder()); FloatBuffer fbb = FloatBuffer.allocate(vertextList.size()); for(Float f : vertextList){ fbb.put(f); } fbb.position(0); vbb.position(0); //设置蓝色 gl.glColor4f(0, 0, 1, 1); gl.glPointSize(5f); gl.glRotatef(-90, 1, 0, 0); gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vbb); gl.glDrawArrays(GL10.GL_POINTS, 0, vertextList.size() / 3); } }
java nio selector.select不阻塞
# java nio selector.select不阻塞 java nio 构建的服务端在与客户端(用ubuntu虚拟机的netcat)连接上后, netcat直接ctrl + d(什么内容都不输入)的话,服务端的selector.select()方法的结果就一直是0 也不阻塞了。请问这是为什么。 代码如下: ```java package chapter4; import org.junit.Test; import java.io.IOException; import java.net.InetSocketAddress; import java.nio.ByteBuffer; import java.nio.channels.SelectionKey; import java.nio.channels.Selector; import java.nio.channels.ServerSocketChannel; import java.nio.channels.SocketChannel; import java.util.Iterator; import java.util.Set; public class List4_2 { @Test public void test1(){ PlainNIOServer server = new PlainNIOServer(); try { server.serve(12345); } catch (IOException e) { e.printStackTrace(); } } private static class PlainNIOServer { public void serve(int port) throws IOException {//在对方连接上以后直接ctrl+d会陷入readable的死循环 ServerSocketChannel serverChannel = ServerSocketChannel.open(); serverChannel.configureBlocking(false); serverChannel.bind(new InetSocketAddress(port)); Selector selector = Selector.open(); serverChannel.register(selector, SelectionKey.OP_ACCEPT); while(true){ if (selector.select() == 0){ try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } // continue; } Set<SelectionKey> keys = selector.selectedKeys(); Iterator<SelectionKey> it = keys.iterator(); while (it.hasNext()){ SelectionKey key = it.next(); it.remove(); System.out.println("acc : " + key.isAcceptable() + ", w : " + key.isWritable() + ", r : " + key.isReadable() + ", conn : " + key.isConnectable() + ", v : " + key.isValid()); try { if (key.isAcceptable()) { ServerSocketChannel server = (ServerSocketChannel) key.channel(); SocketChannel client = server.accept(); if (client != null) { client.configureBlocking(false); client.register(selector, SelectionKey.OP_READ); System.out.println("Accept Connection from " + client); } } if (key.isReadable()) { SocketChannel client = (SocketChannel) key.channel(); ByteBuffer byteBuffer = ByteBuffer.allocate(5); System.out.println("readable !!!"); int count = 0; while (( count = client.read(byteBuffer)) > 0 ) { byteBuffer.flip(); byte[] bytes = new byte[1024]; while (byteBuffer.hasRemaining()) { byteBuffer.get(bytes, 0, Math.min(byteBuffer.remaining(), bytes.length)); String sentence; System.out.println(sentence = new String(bytes, 0, count)); byteBuffer.compact(); byteBuffer.put(sentence.getBytes()); byteBuffer.flip(); client.write(byteBuffer); } byteBuffer.compact(); } } } catch (Exception e){ e.printStackTrace(); key.channel().close(); } } } } } } ``` 运行如上代码以后,在虚拟机里运行netcat , 截图如下 ![图片说明](https://img-ask.csdn.net/upload/201806/23/1529747149_870890.png) 此时在netcat中按下ctrl + d (EOF)则服务端的selector.select方法调用之后返回结果一直为0且不再阻塞,所有连上的客户端也没办法发消息了。 服务端效果如下: ![图片说明](https://img-ask.csdn.net/upload/201806/23/1529747418_255698.png)
关于直接/非直接字节缓冲区的相关问题
对于ByteBuffer 可以通过allocateDirect()来创建缓冲区。那MappedByteBuffer 他应该也是直接字节缓冲区吧。 问题: 1. 他们两个的区别 2.ByteBuffer .allocateDirect(); 是不是也创建了映射文件。 3.他们在使用的时候创建的是什么内存(物理还是什么),这个内存会不会被GC回收或者被jvm去控制。() ``` static void reserveMemory(long size) { synchronized (Bits.class) { if (!memoryLimitSet && VM.isBooted()) { maxMemory = VM.maxDirectMemory(); memoryLimitSet = true; } if (size <= maxMemory - reservedMemory) {//如果创建直接缓冲区后的内存占用不超过最大内存限制 reservedMemory += size;//更新已分配的内存大小 return; } }    //如果超过最大内存限制,执行垃圾回收 System.gc(); try { Thread.sleep(100);//等待垃圾回收完成 } catch (InterruptedException x) { // Restore interrupt status Thread.currentThread().interrupt(); } synchronized (Bits.class) { if (reservedMemory + size > maxMemory)//如果依然超过最大内存限制,则抛出内存溢出异常 throw new OutOfMemoryError("Direct buffer memory"); reservedMemory += size; } ``` 这个是allocateDirect里调用的方法 他确实是对于内存不够是进行了GC。那MappedByteBuffer呢。 **我说的比较乱 因为我的理解也不是很好见谅**
Java AIO AsynchronousServerSocketChannel阻塞问题
我在win7 下用aio做了AIO线程测试,大致步骤如下: 1. 使用AsynchronousServerSocketChannel监听6025端口 2. 为第一步设置的channel设定一个大小为4的AsynchronousChannelGroup 3. 为CompletionHandler实现了一个匿名内部类,并且在completed方法中强制当前线程sleep20秒。 4. 然后我开了两个command line窗口,各尝试了一次telnet 6025端口:'telnet localhost 6025' 在我预想中,这两个telnet应该会直接返回,并且在后台打印出相关内容,两次telnet调用应该不会阻塞。 但事实情况是第二次调用会等到第一次调用20s sleep时间过去之后再处理第二条。这是console log,注意一下两次打印的时间差了20s: ``` the main thread is 1 Listening on localhost:6025 Channel Provider : sun.nio.ch.WindowsAsynchronousChannelProvider@17f17060 waiting.... current thread is 10 sleep the thread 10,current time is Fri Aug 04 08:48:21 CST 2017 thread 10 has wake up!!! waiting.... current thread is 11 sleep the thread 11,current time is Fri Aug 04 08:48:41 CST 2017 thread 11 has wake up!!! ``` 这难道就是传说中的阻塞?虽然我知道在completed方法中要是有长时间未响应的处理,很容易hang掉系统,尤其是fixthreadpool,但前提是线程池撑爆了!但我的线程池有4个,而且并未用满,为什么还会阻塞呢? 下面是我的代码: ``` public class AIOEchoServer { private AsynchronousServerSocketChannel server; public static void main(String[] args) throws Exception { System.out.println("the main thread is "+Thread.currentThread().getId()); AIOEchoServer aioServer = new AIOEchoServer(); aioServer.init("localhost", 6025); } private void init(String host, int port) throws IOException, Exception { AsynchronousChannelGroup group = AsynchronousChannelGroup.withThreadPool(Executors.newFixedThreadPool(4)); server = AsynchronousServerSocketChannel.open(group); server.setOption(StandardSocketOptions.SO_REUSEADDR, true); server.setOption(StandardSocketOptions.SO_RCVBUF, 16 * 1024); server.bind(new InetSocketAddress(host, port)); System.out.println("Listening on " + host + ":" + port); System.out.println("Channel Provider : " + server.provider()); server.accept(null, new CompletionHandler<AsynchronousSocketChannel, Object>() { final ByteBuffer buffer = ByteBuffer.allocate(1024); @Override public void completed(AsynchronousSocketChannel result, Object attachment) { System.out.println("waiting...."); buffer.clear(); System.out.println("current thread is "+Thread.currentThread().getId()); try { System.out.println("sleep the thread "+Thread.currentThread().getId()+",current time is "+new Date()); Thread.currentThread().sleep(20000l); System.out.println("thread "+Thread.currentThread().getId()+" has wake up!!!"); } catch (InterruptedException e) { e.printStackTrace(); } finally { try { result.close(); server.accept(null, this); } catch (IOException e) { e.printStackTrace(); } } } @Override public void failed(Throwable exc, Object attachment) { System.out.print("Server failed...." + exc.getCause()); } }); group.awaitTermination(Long.MAX_VALUE, TimeUnit.SECONDS); } } ```
java nio selector怎么达到与Linux select一样的效果
前几天做了一个linux下的socket实验使用了select,可以让程序在不使用多线程的情况下,实现io的异步,也就是可以收数据,也可以发数据,但不阻塞。 于是我就想能不能移植到Java下来实现。结果我发现Java也有select类似的功能,但是我发现Java nio的Chanel无法对标准输入进行处理,要发数据的时候就会阻塞。 可能是我技术不够,我想问问大家Java nio到底能不能实现与linux select一样的效果? package server; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.IOException; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.net.InetAddress; import java.net.InetSocketAddress; import java.net.ServerSocket; import java.net.Socket; import java.nio.channels.SocketChannel; import java.util.Iterator; import java.util.Scanner; import java.nio.ByteBuffer; import java.nio.channels.Channel; import java.nio.channels.SelectionKey; import java.nio.channels.Selector; import java.nio.channels.ServerSocketChannel; public class ServerSock { public ServerSock() { // TODO Auto-generated constructor stub try { ServerSocketChannel server= ServerSocketChannel.open(); server.bind(new InetSocketAddress(InetAddress.getLocalHost(), 8899), 5); System.out.println("服务器启动...."); Selector selector = Selector.open(); server.configureBlocking(false); server.register(selector, SelectionKey.OP_ACCEPT); ByteBuffer buf = ByteBuffer.allocate(48); SocketChannel channel = null; while(true){ int a=selector.select(); Iterator<SelectionKey> keyIter = selector.selectedKeys().iterator(); while(keyIter.hasNext()){ SelectionKey key = keyIter.next(); if (key.isAcceptable()) { channel = server.accept(); System.out.println("接受: "); channel.configureBlocking(false); channel.register(selector, SelectionKey.OP_READ | SelectionKey.OP_WRITE); }else if (key.isReadable()) { System.out.println("读取:"); int bytesRead = channel.read(buf); buf.flip(); String aString = new String(buf.array()).trim(); System.out.println(aString); buf.clear(); }else if (key.isWritable()) { System.out.println("写入:"); Scanner scanner = new Scanner(System.in); String b = scanner.nextLine(); buf.put(b.getBytes()); buf.flip(); channel.write(buf); buf.clear(); } keyIter.remove(); } } } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } public static void main(String[] args) { new ServerSock(); } } ``` ```
java这个简单的服务器我要如何读取客户端的输入信息?
import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.io.PrintWriter; import java.net.InetSocketAddress; import java.net.ServerSocket; import java.nio.ByteBuffer; import java.nio.CharBuffer; import java.nio.channels.SelectionKey; import java.nio.channels.Selector; import java.nio.channels.ServerSocketChannel; import java.nio.channels.SocketChannel; import java.nio.charset.Charset; import java.nio.charset.CharsetDecoder; import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.Date; import java.util.Iterator; import java.util.Set; public class EchoServer { public static int DEFAULT_PORT = 7; public static String text=""; public static ServerSocketChannel server; public static SocketChannel client ; public static ByteBuffer output ; public static void main(String[] args){ int port; try{ port = Integer.parseInt(args[0]); }catch(RuntimeException ex){ port = DEFAULT_PORT; } System.out.println("Listening for connertions on port "+port); ServerSocketChannel serverChannel; Selector selector; try{ serverChannel = ServerSocketChannel.open(); ServerSocket ss = serverChannel.socket(); InetSocketAddress address = new InetSocketAddress(port); ss.bind(address); serverChannel.configureBlocking(false); selector =Selector.open(); serverChannel.register(selector, SelectionKey.OP_ACCEPT); }catch(IOException ex){ ex.printStackTrace(); return; } while(true){ try{ selector.select(); }catch(IOException ex){ ex.printStackTrace(); break; } Set<SelectionKey> readyKeys = selector.selectedKeys(); Iterator<SelectionKey> iterator = readyKeys.iterator(); while(iterator.hasNext()){ SelectionKey key = iterator.next(); iterator.remove(); try{ if(key.isAcceptable()){ ServerSocketChannel server = (ServerSocketChannel) key.channel(); SocketChannel client = server.accept(); System.out.println("Accepted connection from "+client); client.configureBlocking(false); SelectionKey clientKey = client.register(selector, SelectionKey.OP_WRITE|SelectionKey.OP_READ); ByteBuffer buffer = ByteBuffer.allocate(100); clientKey.attach(buffer); } if(key.isReadable()){ client =(SocketChannel)key.channel(); output = (ByteBuffer)key.attachment(); client.read(output); output.flip(); Charset charset = Charset.forName("UTF-8"); CharsetDecoder decoder = charset.newDecoder(); CharBuffer charBuffer = null; charBuffer = decoder.decode(output); text=charBuffer.toString(); //if(text.equals("time")) //{ //System.out.println("2"); Date date=new Date(); DateFormat format=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); String time=format.format(date); byte b[] = time.getBytes(); //将十六进制字符串转换成十进制整数 //int i=Integer.decode(time); //创建一个大小为1的字节缓冲区因为只放一个byte值 ByteBuffer bb=ByteBuffer.allocate(1); //将十进制整数转换成二进制byte值然后存进ByteBuffer //bb.put(b); //打印ByteBuffer中的byte值 //byte []b1=bb.array(); client.write(output); // output.compact(); //} // text=output.toString(); //System.out.println(text); //output.compact(); } if(key.isWritable()){ client = (SocketChannel) key.channel(); output = (ByteBuffer)key.attachment(); //output.flip(); client.write(output); //output.compact(); } }catch(IOException ex){ key.cancel(); try{ key.channel().close(); }catch(IOException cex){} } } } } } 这是我写的,中间有点乱,因为客户在cmd访问我的服务器如果他输入time,我要给他返回时间。。。大神求助!!
请问下面这个程序,在不改变功能的前提下,可以改装成多线程运行吗?*请贴上代码,谢谢*
import java.net.*; // for Socket, ServerSocket, and InetAddress import java.io.*; // for IOException and Input/OutputStream public class Server { private static final int BUFSIZE = 32; // Size of receive buffer public static void main(String[] args) throws IOException { if (args.length != 1) // Test for correct # of args throw new IllegalArgumentException("Parameter(s): <Port>"); int servPort = Integer.parseInt(args[0]); // Create a server socket to accept client connection requests ServerSocket servSock = new ServerSocket(servPort); int recvMsgSize; // Size of received message byte[] byteBuffer = new byte[BUFSIZE]; // Receive buffer for (;;) { // Run forever, accepting and servicing connections Socket clntSock = servSock.accept(); // Get client connection System.out.println("Handling client at " + clntSock.getInetAddress().getHostAddress() + " on port " + clntSock.getPort()); InputStream in = clntSock.getInputStream(); OutputStream out = clntSock.getOutputStream(); // Receive until client closes connection, indicated by -1 return while ((recvMsgSize = in.read(byteBuffer)) != -1) { byte[] changeOrder = changeOrder(byteBuffer, recvMsgSize); out.write(changeOrder, 0, recvMsgSize); } clntSock.close(); // Close the socket. We are done with this client! } /* NOT REACHED */ } /* change order, for example input <code>abc</code> then output <code>cba</code> */ private static byte[] changeOrder(byte[] byteBuffer, int recvMsgSize) { byte[] result = new byte[recvMsgSize]; for (int i = 0; i < recvMsgSize; i++) { result[i] = byteBuffer[recvMsgSize - 1 - i]; } return result; } }
java nio通信问题如何解决
大佬们帮我看看这句代码,我有点理解不了:![图片说明](https://img-ask.csdn.net/upload/201706/02/1496365514_646261.png) 这句代码的前面是获取欲与服务器端建立联系的selectionkey的作用,但是server.accept()这句代码并没有和相应的selectionkey对应,jdk只是说这句代码的作用只是获取此刻与服务器channel建立连接的socketchannel而不是此刻正在被检查的selectionkey的对应的socketchannel,那前面的那句sk.isAccpetable()不就起不到作用了吗?请知道的大侠告诉下。代码如下: public class NServer { //用于检测所有Channel状态的Selector private Selector selector=null; static final int PORT=3334; //定义实现编码、解码的字符集对象 private Charset charset=Charset.forName("UTF-8"); public void init() { try { selector=Selector.open(); //通过open方法来打开一个未绑定的ServerSocketChannel实例 ServerSocketChannel server=ServerSocketChannel.open(); InetSocketAddress isa=new InetSocketAddress("127.0.0.1",PORT); //将该ServerSocketChannel绑定到指定IP地址 server.bind(isa); //设置ServerSocket以非阻塞方式工作 server.configureBlocking(false); //将server注册到指定的Selector对象 server.register(selector,SelectionKey.OP_ACCEPT); while(true) //说明有需要处理的IO对象 { if(selector.select()==0)continue; //依次处理selector上的每个选择的SelectionKey for(SelectionKey sk :selector.selectedKeys()) { //从selector上的已选择Key集中删除正在处理的SelectionKey selector.selectedKeys().remove(sk); //如果sk对应的Channel包含客户端的连接请求 if(sk.isAcceptable()) { //调用accept方法接受连接,产生服务端的SocketChannel SocketChannel sc=server.accept(); //设置采用非阻塞模式 if (sc == null) { continue; } sc.configureBlocking(false); //将该SocketChannel也注册到selector //后面的read表示我们可以向通道那里读入数据了 // System.out.println("@@@@@@@@@@@@"); sc.register(selector, SelectionKey.OP_READ); //将sk对应的Channel设置成准备接收其他请求 //sk.interestOps(SelectionKey.OP_ACCEPT); } //如果sk对应的Channel有数据需要读取 if(sk.isReadable()) { //System.out.println("@@@@@@@@@@@@"); //获取该SelectionKey对应的Channel,该Channel中有可读的数据 SocketChannel sc=(SocketChannel) sk.channel(); //定义准备执行读取数据的ByteBuffer ByteBuffer buff=ByteBuffer.allocate(1024); String content=""; //开始读取数据 try { while(sc.read(buff)>0) { buff.flip(); content+=charset.decode(buff); } //打印从该sk对应的Channel里读取到的数据 while(sc.write(buff)>0) { buff.clear(); content+=charset.decode(buff); } //将sk对应的Channel设置成准备下一次读取 sk.interestOps(SelectionKey.OP_READ); System.out.println("Server收到信息了: "+content); if(content.length()<5) { sc.write(charset.encode("你发过来的长度小于5")); } else if(content.length()<9) { sc.write(charset.encode("你发过来的长度小于9")); } }catch(IOException ex) { //从Selector中删除指定的SelectionKey sk.cancel(); if(sk.channel()!=null) { sk.channel().close(); } } //sc.write(charset.encode(line)); } } } } catch (IOException e) { // TODO 自动生成的 catch 块 //System.out.println("出错了"); e.printStackTrace(); } } class Thread3 extends Thread { public void run() { init(); System.out.println("结束了"); } } public static void main(String[]args) { new NServer().new Thread3().start(); } }
java nio scoket的连接问题
下面是一个测试例子,主要是连接地址不同,请在注释的地方切换分别测试.希望能详细讲解一下这两个过程,特别是连127.0.0.1这个 1) InetSocketAddress addr = new InetSocketAddress("www.baidu.com", 80); 2) //InetSocketAddress addr = new InetSocketAddress("127.0.0.1", 80); /** * NIO_baidu.java * * Version 1.0 * * 2014-1-16 * * Copyright www.wangjiu.com */ package com._0116; import java.net.InetSocketAddress; import java.nio.ByteBuffer; import java.nio.channels.SocketChannel; /** * TODO (描述类的功能) * * @author d * 2014-1-16 * */ public class NIO_baidu { /** * TODO (描述方法的作用) * * @param args * @throws Exception */ public static void main(String[] args) throws Exception { // 用下面两个连接地址分别测试 InetSocketAddress addr = new InetSocketAddress("www.baidu.com", 80); //InetSocketAddress addr = new InetSocketAddress("127.0.0.1", 80); SocketChannel channel = SocketChannel.open(addr); System.out.println(); byte[] header = "GET / HTTP/1.1\r\nHost: www.baidu.com\r\n\r\n".getBytes(); ByteBuffer buf = ByteBuffer.allocate(header.length); buf.put(header); buf.flip(); channel.write(buf); buf = ByteBuffer.allocate(1024); int count = channel.read(buf); while(count != -1) { buf.flip(); while(buf.hasRemaining()){ System.out.print((char)buf.get()); } buf.clear(); count = channel.read(buf); System.out.print(count); } channel.close(); } } 第一个的返回结果是: 就是百度首页的html代码,太长了贴不下. ============= 第二个返回结果是: HTTP/1.1 200 OK Date: Fri, 17 Jan 2014 02:39:29 GMT Server: Apache/2.2.25 (Win32) Last-Modified: Sat, 20 Nov 2004 07:16:24 GMT ETag: "80c5b3c60-2c-3e94b66a46200" Accept-Ranges: bytes Content-Length: 44 Content-Type: text/html <html><body><h1>It works!</h1></body></html>
爬虫福利二 之 妹子图网MM批量下载
爬虫福利一:27报网MM批量下载    点击 看了本文,相信大家对爬虫一定会产生强烈的兴趣,激励自己去学习爬虫,在这里提前祝:大家学有所成! 目标网站:妹子图网 环境:Python3.x 相关第三方模块:requests、beautifulsoup4 Re:各位在测试时只需要将代码里的变量 path 指定为你当前系统要保存的路径,使用 python xxx.py 或IDE运行即可。
Java学习的正确打开方式
在博主认为,对于入门级学习java的最佳学习方法莫过于视频+博客+书籍+总结,前三者博主将淋漓尽致地挥毫于这篇博客文章中,至于总结在于个人,实际上越到后面你会发现学习的最好方式就是阅读参考官方文档其次就是国内的书籍,博客次之,这又是一个层次了,这里暂时不提后面再谈。博主将为各位入门java保驾护航,各位只管冲鸭!!!上天是公平的,只要不辜负时间,时间自然不会辜负你。 何谓学习?博主所理解的学习,它
程序员必须掌握的核心算法有哪些?
由于我之前一直强调数据结构以及算法学习的重要性,所以就有一些读者经常问我,数据结构与算法应该要学习到哪个程度呢?,说实话,这个问题我不知道要怎么回答你,主要取决于你想学习到哪些程度,不过针对这个问题,我稍微总结一下我学过的算法知识点,以及我觉得值得学习的算法。这些算法与数据结构的学习大多数是零散的,并没有一本把他们全部覆盖的书籍。下面是我觉得值得学习的一些算法以及数据结构,当然,我也会整理一些看过
大学四年自学走来,这些私藏的实用工具/学习网站我贡献出来了
大学四年,看课本是不可能一直看课本的了,对于学习,特别是自学,善于搜索网上的一些资源来辅助,还是非常有必要的,下面我就把这几年私藏的各种资源,网站贡献出来给你们。主要有:电子书搜索、实用工具、在线视频学习网站、非视频学习网站、软件下载、面试/求职必备网站。 注意:文中提到的所有资源,文末我都给你整理好了,你们只管拿去,如果觉得不错,转发、分享就是最大的支持了。 一、PDF搜索网站推荐 对于大部
linux系列之常用运维命令整理笔录
本博客记录工作中需要的linux运维命令,大学时候开始接触linux,会一些基本操作,可是都没有整理起来,加上是做开发,不做运维,有些命令忘记了,所以现在整理成博客,当然vi,文件操作等就不介绍了,慢慢积累一些其它拓展的命令,博客不定时更新 顺便拉下票,我在参加csdn博客之星竞选,欢迎投票支持,每个QQ或者微信每天都可以投5票,扫二维码即可,http://m234140.nofollow.ax.
比特币原理详解
一、什么是比特币 比特币是一种电子货币,是一种基于密码学的货币,在2008年11月1日由中本聪发表比特币白皮书,文中提出了一种去中心化的电子记账系统,我们平时的电子现金是银行来记账,因为银行的背后是国家信用。去中心化电子记账系统是参与者共同记账。比特币可以防止主权危机、信用风险。其好处不多做赘述,这一层面介绍的文章很多,本文主要从更深层的技术原理角度进行介绍。 二、问题引入  假设现有4个人
程序员接私活怎样防止做完了不给钱?
首先跟大家说明一点,我们做 IT 类的外包开发,是非标品开发,所以很有可能在开发过程中会有这样那样的需求修改,而这种需求修改很容易造成扯皮,进而影响到费用支付,甚至出现做完了项目收不到钱的情况。 那么,怎么保证自己的薪酬安全呢? 我们在开工前,一定要做好一些证据方面的准备(也就是“讨薪”的理论依据),这其中最重要的就是需求文档和验收标准。一定要让需求方提供这两个文档资料作为开发的基础。之后开发
网页实现一个简单的音乐播放器(大佬别看。(⊙﹏⊙))
今天闲着无事,就想写点东西。然后听了下歌,就打算写个播放器。 于是乎用h5 audio的加上js简单的播放器完工了。 欢迎 改进 留言。 演示地点跳到演示地点 html代码如下`&lt;!DOCTYPE html&gt; &lt;html&gt; &lt;head&gt; &lt;title&gt;music&lt;/title&gt; &lt;meta charset="utf-8"&gt
Python十大装B语法
Python 是一种代表简单思想的语言,其语法相对简单,很容易上手。不过,如果就此小视 Python 语法的精妙和深邃,那就大错特错了。本文精心筛选了最能展现 Python 语法之精妙的十个知识点,并附上详细的实例代码。如能在实战中融会贯通、灵活使用,必将使代码更为精炼、高效,同时也会极大提升代码B格,使之看上去更老练,读起来更优雅。 1. for - else 什么?不是 if 和 else 才
数据库优化 - SQL优化
前面一篇文章从实例的角度进行数据库优化,通过配置一些参数让数据库性能达到最优。但是一些“不好”的SQL也会导致数据库查询变慢,影响业务流程。本文从SQL角度进行数据库优化,提升SQL运行效率。 判断问题SQL 判断SQL是否有问题时可以通过两个表象进行判断: 系统级别表象 CPU消耗严重 IO等待严重 页面响应时间过长
2019年11月中国大陆编程语言排行榜
2019年11月2日,我统计了某招聘网站,获得有效程序员招聘数据9万条。针对招聘信息,提取编程语言关键字,并统计如下: 编程语言比例 rank pl_ percentage 1 java 33.62% 2 c/c++ 16.42% 3 c_sharp 12.82% 4 javascript 12.31% 5 python 7.93% 6 go 7.25% 7
通俗易懂地给女朋友讲:线程池的内部原理
餐厅的约会 餐盘在灯光的照耀下格外晶莹洁白,女朋友拿起红酒杯轻轻地抿了一小口,对我说:“经常听你说线程池,到底线程池到底是个什么原理?”我楞了一下,心里想女朋友今天是怎么了,怎么突然问出这么专业的问题,但做为一个专业人士在女朋友面前也不能露怯啊,想了一下便说:“我先给你讲讲我前同事老王的故事吧!” 大龄程序员老王 老王是一个已经北漂十多年的程序员,岁数大了,加班加不动了,升迁也无望,于是拿着手里
经典算法(5)杨辉三角
写在前面: 我是 扬帆向海,这个昵称来源于我的名字以及女朋友的名字。我热爱技术、热爱开源、热爱编程。技术是开源的、知识是共享的。 这博客是对自己学习的一点点总结及记录,如果您对 Java、算法 感兴趣,可以关注我的动态,我们一起学习。 用知识改变命运,让我们的家人过上更好的生活。 目录一、杨辉三角的介绍二、杨辉三角的算法思想三、代码实现1.第一种写法2.第二种写法 一、杨辉三角的介绍 百度
腾讯算法面试题:64匹马8个跑道需要多少轮才能选出最快的四匹?
昨天,有网友私信我,说去阿里面试,彻底的被打击到了。问了为什么网上大量使用ThreadLocal的源码都会加上private static?他被难住了,因为他从来都没有考虑过这个问题。无独有偶,今天笔者又发现有网友吐槽了一道腾讯的面试题,我们一起来看看。 腾讯算法面试题:64匹马8个跑道需要多少轮才能选出最快的四匹? 在互联网职场论坛,一名程序员发帖求助到。二面腾讯,其中一个算法题:64匹
面试官:你连RESTful都不知道我怎么敢要你?
面试官:了解RESTful吗? 我:听说过。 面试官:那什么是RESTful? 我:就是用起来很规范,挺好的 面试官:是RESTful挺好的,还是自我感觉挺好的 我:都挺好的。 面试官:… 把门关上。 我:… 要干嘛?先关上再说。 面试官:我说出去把门关上。 我:what ?,夺门而去 文章目录01 前言02 RESTful的来源03 RESTful6大原则1. C-S架构2. 无状态3.统一的接
为啥国人偏爱Mybatis,而老外喜欢Hibernate/JPA呢?
关于SQL和ORM的争论,永远都不会终止,我也一直在思考这个问题。昨天又跟群里的小伙伴进行了一番讨论,感触还是有一些,于是就有了今天这篇文。 声明:本文不会下关于Mybatis和JPA两个持久层框架哪个更好这样的结论。只是摆事实,讲道理,所以,请各位看官勿喷。 一、事件起因 关于Mybatis和JPA孰优孰劣的问题,争论已经很多年了。一直也没有结论,毕竟每个人的喜好和习惯是大不相同的。我也看
SQL-小白最佳入门sql查询一
一 说明 如果是初学者,建议去网上寻找安装Mysql的文章安装,以及使用navicat连接数据库,以后的示例基本是使用mysql数据库管理系统; 二 准备前提 需要建立一张学生表,列分别是id,名称,年龄,学生信息;本示例中文章篇幅原因SQL注释略; 建表语句: CREATE TABLE `student` ( `id` int(11) NOT NULL AUTO_INCREMENT, `
项目中的if else太多了,该怎么重构?
介绍 最近跟着公司的大佬开发了一款IM系统,类似QQ和微信哈,就是聊天软件。我们有一部分业务逻辑是这样的 if (msgType = "文本") { // dosomething } else if(msgType = "图片") { // doshomething } else if(msgType = "视频") { // doshomething } else { // dosho
【图解经典算法题】如何用一行代码解决约瑟夫环问题
约瑟夫环问题算是很经典的题了,估计大家都听说过,然后我就在一次笔试中遇到了,下面我就用 3 种方法来详细讲解一下这道题,最后一种方法学了之后保证让你可以让你装逼。 问题描述:编号为 1-N 的 N 个士兵围坐在一起形成一个圆圈,从编号为 1 的士兵开始依次报数(1,2,3…这样依次报),数到 m 的 士兵会被杀死出列,之后的士兵再从 1 开始报数。直到最后剩下一士兵,求这个士兵的编号。 1、方
致 Python 初学者
文章目录1. 前言2. 明确学习目标,不急于求成,不好高骛远3. 在开始学习 Python 之前,你需要做一些准备2.1 Python 的各种发行版2.2 安装 Python2.3 选择一款趁手的开发工具3. 习惯使用IDLE,这是学习python最好的方式4. 严格遵从编码规范5. 代码的运行、调试5. 模块管理5.1 同时安装了py2/py35.2 使用Anaconda,或者通过IDE来安装模
“狗屁不通文章生成器”登顶GitHub热榜,分分钟写出万字形式主义大作
一、垃圾文字生成器介绍 最近在浏览GitHub的时候,发现了这样一个骨骼清奇的雷人项目,而且热度还特别高。 项目中文名:狗屁不通文章生成器 项目英文名:BullshitGenerator 根据作者的介绍,他是偶尔需要一些中文文字用于GUI开发时测试文本渲染,因此开发了这个废话生成器。但由于生成的废话实在是太过富于哲理,所以最近已经被小伙伴们给玩坏了。 他的文风可能是这样的: 你发现,
程序员:我终于知道post和get的区别
IT界知名的程序员曾说:对于那些月薪三万以下,自称IT工程师的码农们,其实我们从来没有把他们归为我们IT工程师的队伍。他们虽然总是以IT工程师自居,但只是他们一厢情愿罢了。 此话一出,不知激起了多少(码农)程序员的愤怒,却又无可奈何,于是码农问程序员。 码农:你知道get和post请求到底有什么区别? 程序员:你看这篇就知道了。 码农:你月薪三万了? 程序员:嗯。 码农:你是怎么做到的? 程序员:
《程序人生》系列-这个程序员只用了20行代码就拿了冠军
你知道的越多,你不知道的越多 点赞再看,养成习惯GitHub上已经开源https://github.com/JavaFamily,有一线大厂面试点脑图,欢迎Star和完善 前言 这一期不算《吊打面试官》系列的,所有没前言我直接开始。 絮叨 本来应该是没有这期的,看过我上期的小伙伴应该是知道的嘛,双十一比较忙嘛,要值班又要去帮忙拍摄年会的视频素材,还得搞个程序员一天的Vlog,还要写BU
加快推动区块链技术和产业创新发展,2019可信区块链峰会在京召开
      11月8日,由中国信息通信研究院、中国通信标准化协会、中国互联网协会、可信区块链推进计划联合主办,科技行者协办的2019可信区块链峰会将在北京悠唐皇冠假日酒店开幕。   区块链技术被认为是继蒸汽机、电力、互联网之后,下一代颠覆性的核心技术。如果说蒸汽机释放了人类的生产力,电力解决了人类基本的生活需求,互联网彻底改变了信息传递的方式,区块链作为构造信任的技术有重要的价值。   1
程序员把地府后台管理系统做出来了,还有3.0版本!12月7号最新消息:已在开发中有github地址
第一幕:缘起 听说阎王爷要做个生死簿后台管理系统,我们派去了一个程序员…… 996程序员做的梦: 第一场:团队招募 为了应对地府管理危机,阎王打算找“人”开发一套地府后台管理系统,于是就在地府总经办群中发了项目需求。 话说还是中国电信的信号好,地府都是满格,哈哈!!! 经常会有外行朋友问:看某网站做的不错,功能也简单,你帮忙做一下? 而这次,面对这样的需求,这个程序员
网易云6亿用户音乐推荐算法
网易云音乐是音乐爱好者的集聚地,云音乐推荐系统致力于通过 AI 算法的落地,实现用户千人千面的个性化推荐,为用户带来不一样的听歌体验。 本次分享重点介绍 AI 算法在音乐推荐中的应用实践,以及在算法落地过程中遇到的挑战和解决方案。 将从如下两个部分展开: AI 算法在音乐推荐中的应用 音乐场景下的 AI 思考 从 2013 年 4 月正式上线至今,网易云音乐平台持续提供着:乐屏社区、UGC
【技巧总结】位运算装逼指南
位算法的效率有多快我就不说,不信你可以去用 10 亿个数据模拟一下,今天给大家讲一讲位运算的一些经典例子。不过,最重要的不是看懂了这些例子就好,而是要在以后多去运用位运算这些技巧,当然,采用位运算,也是可以装逼的,不信,你往下看。我会从最简单的讲起,一道比一道难度递增,不过居然是讲技巧,那么也不会太难,相信你分分钟看懂。 判断奇偶数 判断一个数是基于还是偶数,相信很多人都做过,一般的做法的代码如下
日均350000亿接入量,腾讯TubeMQ性能超过Kafka
整理 | 夕颜出品 | AI科技大本营(ID:rgznai100) 【导读】近日,腾讯开源动作不断,相继开源了分布式消息中间件TubeMQ,基于最主流的 OpenJDK8开发的
8年经验面试官详解 Java 面试秘诀
    作者 | 胡书敏 责编 | 刘静 出品 | CSDN(ID:CSDNnews) 本人目前在一家知名外企担任架构师,而且最近八年来,在多家外企和互联网公司担任Java技术面试官,前后累计面试了有两三百位候选人。在本文里,就将结合本人的面试经验,针对Java初学者、Java初级开发和Java开发,给出若干准备简历和准备面试的建议。   Java程序员准备和投递简历的实
面试官如何考察你的思维方式?
1.两种思维方式在求职面试中,经常会考察这种问题:北京有多少量特斯拉汽车? 某胡同口的煎饼摊一年能卖出多少个煎饼? 深圳有多少个产品经理? 一辆公交车里能装下多少个乒乓球? 一
相关热词 c# 图片上传 c# gdi 占用内存 c#中遍历字典 c#控制台模拟dos c# 斜率 最小二乘法 c#进程延迟 c# mysql完整项目 c# grid 总行数 c# web浏览器插件 c# xml 生成xsd
立即提问