java nio reactor疑惑

1:最近学习Java nio的线程模型 参考了很多资料 都提到了reactor模式
有个疑问 这里的reactor模式(包括单线程reactor模式多线程reactor模式主从reactor模式)
这个是由java nio实现的 还是需要开发的时候自己封装成reactor模式的nio框架?
2:reactor模式我的理解是把网络IO放在了内核中执行 轮询selector会有注册的感兴趣的
OP_ACCEPT OP_Read等的selectionKey。真正提高的是以非阻塞的方式读取IO,完成后会
触发事件通知selector,之后的业务处理还是可以另起线程池来处理。所以才说selector模式
降低的是网络IO的开销。不知道这样理解对不对 希望大神不吝赐教

2个回答

nio只是提供了非阻塞模式,并不是包装成事件模型了,事件模型还是要自己实现的,还是要开线程while轮询。

非阻塞模式最大的好处是不至于写一个socket.accept()就停在那里,后面的代码都执行不了,导致一出现这个语句就要开一线程。

Givemefive555
Givemefive555 selector只是提供了一个java 级别的多路复用器 这样可以处理多个消息。给分!
4 年多之前 回复
Givemefive555
Givemefive555 哈~兄台此言甚和我意。最近花了时间看了netty的源码 发现也是基于NIO实现的。只是运用了比较好的线程模型罢了,
4 年多之前 回复
Givemefive555
Givemefive555 这个类似的文章我看过了 也许是我没完全理解 才有上面的俩个问题 。可不可以谈下你自己的看法呢
4 年多之前 回复
Csdn user default icon
上传中...
上传图片
插入图片
抄袭、复制答案,以达到刷声望分或其他目的的行为,在CSDN问答是严格禁止的,一经发现立刻封号。是时候展现真正的技术了!
其他相关推荐
java nio 如何实现 阻塞读 不阻塞写
java nio 如何实现 阻塞读 不阻塞写 java nio 如何实现 阻塞读 不阻塞写
java nio解惑 求大神解惑
对于java nio 的channel 可以做同时读写。如果在read的时候做了同时write多条命令。下发一条命令 thread睡眠5秒。客户端接收到之后马上返回。这种情况,服务端还阻塞的情况下能收到吗
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)
java NIO写入和读取的数据不一样 丢失了很多数据 怎么解决
java NIO写入和读取的数据不一样 丢失了很多数据 怎么解决 我把图片对象存入Bytebuffer, 发到服务器读取后,很多图片都是不完整的
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 NIO的一点疑惑
大家都说NIO在传统阻塞IO的基础上面,提高了效率,增大了服务器并发处理能力,我对此有一点点疑惑; 传统型的IO,处理过程如下 (1)服务器准备就绪---->(2)接受连接(accept阻塞)------>(3)读取服务器请求(阻塞)------>(4)改请求业务逻辑处理(如数据库)----->(5)发送响应至服务器----------(2)重新开始 如果在(2)accept的时候,接受到A请求,服务器会read A请求的请求数据,如果在此时A数据读取阻塞,那么接下来的B请求,将得不到响应; 为此。我们通常的处理方式是在 |--------------线程1 (2)接受连接(accept阻塞)---|--------------线程2 |--------------线程3 ........ 进行线程分发; 在使用了NIO以后,利用一种selector.select同样是的需要阻塞才能得到,这一点我认为跟accept没有本质区别,不同的是select能够得到多个channel的处理状态,迭代进行顺序处理: for (;;) { try { selector.select(); Iterator<SelectionKey> it = selector.selectedKeys().iterator(); while (it.hasNext()) { SelectionKey key = (SelectionKey)it.next(); if (key.isAcceptable()) { handleAccept(key); } else if (key.isReadable()) { handleRead(key); } else if (key.isWritable()) { handleWrite(key); } else if (key.isConnectable()) { handleConnect(key); } if(!key.isValid()){ key.cancel(); } it.remove(); } } catch (IOException e) { continue; } } 处理方法如下: public void handleAccept(SelectionKey key) { } public void handleRead(SelectionKey key) { } public void handleWrite(SelectionKey key) { } 对于一些数据库操作,每次在处理handleRead的时候,我们还是必须的使用多线程对请求进行处理,比如查询数据库等等耗时操作,(别拿那张helloworld回显的例子做比喻)我一直在疑惑,好比有1000个用户进行请求,阻塞IO是开1000个线程进行相应处理,而NIO一样也必须开1000个线程处理;而假如我把一次请求处理周期看成三段: --------------------|------------------------|------------------ 读取请求信息 业务处理(数据库访问) 写信息回客户端 阻塞IO是 [img]http://dl.iteye.com/upload/attachment/230022/116b63b5-b54f-340b-a250-154b24badc41.bmp[/img] 而NIO就是 [img]http://dl.iteye.com/upload/attachment/230020/3d8da6d3-44fc-3ff0-8520-1a831f9db789.bmp[/img] 性能提高的就是不需要在读取请求信息和写信息回客户端的时候,也需要线程分发处理,而可以采取主线程中顺序处理即可(因为不需要担心阻塞)? 衷心希望有这方面的高手能解答心中疑惑,万分感谢!
JAVA NIO双向通信问题
我想要是使用JAVA NIO做一个客户端、服务器**双向通讯**的东东,但是我遇到的问题是: 服务器无法想客户端发送消息,类似这样的方式并不是我想要的: while(it.hasNext()) { SelectionKey key = it.next(); if(key.isAcceptable()) { log.info("Server: SelectionKey is acceptable."); handler.handleAccept(key); } else if(key.isReadable()) { log.info("Server: SelectionKey is readable."); handler.handleRead(key); } else if(key.isWritable()) { log.info("Server: SelectionKey is writable."); handler.handleWrite(key); } it.remove(); 我的数据是从前台产生的,**数据产生的时间比较随机**,因此并不能像上述一下作为反馈信息发送回去,那么这种情况该怎么解决呢? *我真的没有C币啊,求懂的人帮下忙啦~~~~*
使用java nio 将超过2G文件映射到内存中,报异常
代码如下: MappedByteBuffer buffer = FileChannel.map(FileChannel.MapMode.READ_ONLY, 0, Integer.MAX_VALUE);//int java.lang.Integer.MAX_VALUE = 2147483647 [0x7fffffff] 环境:jdk7 64位 操作系统系统win7 64位 异常信息 Exception in thread "main" java.io.IOException: Map failed at sun.nio.ch.FileChannelImpl.map(FileChannelImpl.java:888) at com.bigfile.read.MappedBiggerFileReader.<init>(MappedBiggerFileReader.java:36) at com.bigfile.read.MappedBiggerFileReader.main(MappedBiggerFileReader.java:83) Caused by: java.lang.OutOfMemoryError: Map failed at sun.nio.ch.FileChannelImpl.map0(Native Method) at sun.nio.ch.FileChannelImpl.map(FileChannelImpl.java:885) ... 2 more
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的思想?
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>
java的nio可以做客户端吗
我我看到的demo源码,都是用java nio做服务器的 但是我现在需要开发客户端程序,连接数以千计的服务器 由服务器给我推送数据 这个情形使用多线程模式肯定是不可以的 需要用nio机制 但是我看到的nio的demo都是服务器用nio处理客户端连接的 有没有用客户端nio处理大量服务器推送数据的呢? 还是说根本不能这么做?谢谢。
java nio SelectionKey isWritable为什么一直是true
服务器 [code="java"] package test.nio; import java.io.IOException; import java.net.InetSocketAddress; 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.util.Iterator; import java.util.Set; public class NonBlockEchoServer { private ServerSocketChannel serverSocketChannel; private int port = 8992; private Selector selector; private Charset charset; public NonBlockEchoServer() throws IOException { charset = Charset.forName("UTF-8"); selector = Selector.open(); serverSocketChannel = ServerSocketChannel.open(); //可以绑定到同一个端口 serverSocketChannel.socket().setReuseAddress(true); //设置为非阻塞模式 serverSocketChannel.configureBlocking(false); serverSocketChannel.socket().bind(new InetSocketAddress(port)); } public void service() throws IOException { serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT); while(selector.select() > 0) { Set<SelectionKey> keys = selector.selectedKeys(); Iterator<SelectionKey> it = keys.iterator(); while(it.hasNext()) { SelectionKey key = null; try { key = it.next(); it.remove(); if(key.isAcceptable()) { ServerSocketChannel serverSocketChannel = (ServerSocketChannel) key.channel(); SocketChannel socketChannel = serverSocketChannel.accept(); socketChannel.configureBlocking(false); ByteBuffer byteBuffer = ByteBuffer.allocate(0); socketChannel.register(selector, SelectionKey.OP_READ|SelectionKey.OP_WRITE, byteBuffer); } if(key.isReadable()) { read(key); } if(key.isWritable()) { write(key); } }catch (IOException e) { if(key != null) { try { key.cancel(); key.channel().close(); } catch (IOException e1) { e1.printStackTrace(); } } e.printStackTrace(); } } } } private void write(SelectionKey key) throws IOException { SocketChannel socketChannel = (SocketChannel) key.channel(); ByteBuffer byteBuffer = (ByteBuffer) key.attachment(); byteBuffer.flip(); String data = decode(byteBuffer); if(data.indexOf("\r\n") == -1) { return; } String outputData = data.substring(0, data.indexOf("\n")+1); System.out.println("--->" + outputData); ByteBuffer outputBuffer = encode("echo:" + outputData); while(outputBuffer.hasRemaining()) { socketChannel.write(outputBuffer); } ByteBuffer temp = encode(outputData); byteBuffer.position(temp.limit()); byteBuffer.compact(); if(outputData.equals("bye\r\n")) { key.cancel(); socketChannel.close(); System.out.println("链接已经关闭"); } } private void read(SelectionKey key) throws IOException { System.out.println("server read"); SocketChannel socketChannel = (SocketChannel) key.channel(); socketChannel.configureBlocking(false); ByteBuffer byteBuffer = (ByteBuffer) key.attachment(); ByteBuffer readBuff = ByteBuffer.allocate(32); socketChannel.read(readBuff); byteBuffer.limit(byteBuffer.capacity()); readBuff.flip(); byteBuffer.put(readBuff); } /** * 解码 * @param byteBuffer * @return */ private String decode(ByteBuffer byteBuffer) { CharBuffer charBuffer = charset.decode(byteBuffer); return charBuffer.toString(); } /** * 编码 * @param str * @return */ private ByteBuffer encode(String str) { return charset.encode(str); } public static void main(String[] args) throws IOException { NonBlockEchoServer nonServer = new NonBlockEchoServer(); nonServer.service(); } } [/code] 客户端 [code="java"] package test.nio; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.net.InetSocketAddress; import java.nio.ByteBuffer; import java.nio.channels.SelectionKey; import java.nio.channels.Selector; import java.nio.channels.SocketChannel; import java.nio.charset.Charset; import java.util.Iterator; import java.util.Set; public class NonBlockEchoClient { private SocketChannel socketChannel; private ByteBuffer sendBuffer = ByteBuffer.allocate(1024); private ByteBuffer receiveBuffer = ByteBuffer.allocate(1024); Charset charset = Charset.forName("utf-8"); private Selector selector; private int port = 8992; public NonBlockEchoClient() throws IOException { socketChannel = SocketChannel.open(); socketChannel.connect(new InetSocketAddress(port)); socketChannel.configureBlocking(false); System.out.println("与服务器链接成功"); selector = Selector.open(); } public static void main(String[] args) throws IOException { final NonBlockEchoClient non = new NonBlockEchoClient(); Thread client = new Thread(new Runnable() { @Override public void run() { non.receiveFromUser(); } }); client.start(); non.talk(); } private void talk() throws IOException { socketChannel.register(selector, SelectionKey.OP_READ|SelectionKey.OP_WRITE); while(selector.select() > 0) { Set<SelectionKey> keys = selector.selectedKeys(); Iterator<SelectionKey> it = keys.iterator(); while(it.hasNext()) { SelectionKey key = it.next(); it.remove(); if(key.isReadable()) { receive(key); } if(key.isWritable()) { send(key); } } } } public void receiveFromUser() { try { BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in)); String msg = null; while((msg = bufferedReader.readLine()) != null) { System.out.println(msg); synchronized (sendBuffer) { sendBuffer.put(encode(msg+"\r\n")); } if("bye".equals(msg)) { break; } } } catch(IOException e) { e.printStackTrace(); } } private void send(SelectionKey key) throws IOException { SocketChannel socketChannel = (SocketChannel) key.channel(); synchronized (sendBuffer) { sendBuffer.flip(); socketChannel.write(sendBuffer); sendBuffer.compact(); } } private void receive(SelectionKey key) throws IOException { System.out.println("client RECEIVE"); SocketChannel socketChannel = (SocketChannel) key.channel(); socketChannel.read(receiveBuffer); receiveBuffer.flip(); String receiveData = decode(receiveBuffer); if(receiveData.indexOf("\n") == -1) return; String outputData = receiveData.substring(0, receiveData.indexOf("\n") + 1); System.out.println("--->" + outputData); if(outputData.equals("echo:bye\r\n")) { key.cancel(); socketChannel.close(); selector.close(); System.exit(0); } ByteBuffer temp = encode(outputData); receiveBuffer.position(temp.limit()); receiveBuffer.compact(); } private String decode(ByteBuffer byteBuffer) { return charset.decode(byteBuffer).toString(); } private ByteBuffer encode(String str) { return charset.encode(str); } } [/code] 各位大侠,最近小弟在学习nio编程,遇到一个问题:客户端在连接服务器端成功后,没有进行任何操作,服务器端并没有触发 写事件 为什么key.isWritable()一直为true ??
JAVA NIO channel中同时执行两个写操作
NIO中设置 channel.register(this.selector,SelectionKey.OP_WRITE); 在相应的方法中,同时执行两个写操作 if (selectionKey.isWritable()){ write(selectionKey); writequotation(selectionKey); }
java NIO服务器并发编程
各位CSDN的编程大神们!求帮忙,求解决方案!跪求! 最近开发一个基于nio的服务器端程序(也包括客户端),实现一个多人(很多人)并发进行即时通讯的东东。。。发觉这个NIO太难搞了,不过总算还是能够建立一个连接发发“hello world”之类的东西,但是问题来了。由于NIO是针对缓冲区进行操作的,所有数据只能够写入到缓冲区中(我用的是byteBuffer),完了我自定义了一个数据包的格式,如下:|包头一个字节|包长度四个字节|包内容长度可变|包尾一个字节|, 然后在客户端或者服务器端根据这个包长度的数据域去数据进行组包(很多原因啦,比如说为了处理粘包问题啊,还有限定每次传递的数据包大小啊之类的)。缓冲区固然好,但就是这个粘包的问题不好搞。我想到一个办法:每次首先读取包头,根据包头中给出的包长度再去读取包数据,但是我在想要是出现包头到了,但是包的内容信息还没有发送过来,那我得要重新把包头放回缓冲区,等待下一次再读取么?如何放回去呢? 如果不放回去的话,由于服务器端是多用户并发的,下一次(readable)事件到来的时候,我就不知道这个是上一次只读取了包头的那个通道呢还是一个新的通道,那处理起来就更加复杂了。。。说了好多废话,不知道有没有把问题说清楚,总之一句话,神啊!求带走啊!
java.nio.BufferOverflowException.
[2014-12-16 12:12:31 - Dex Loader] Unable to execute dex: java.nio.BufferOverflowException. Check the Eclipse log for stack trace. [2014-12-16 12:12:31 - com.TestReferencePoints.MainActivity] Conversion to Dalvik format failed: Unable to execute dex: java.nio.BufferOverflowException. Check the Eclipse log for stack trace.
java NIO通信 客户端为什么收不到数据
客户端程序 public class NioSelectorClient { public static void main(String[] args) throws IOException{ SocketChannel channel = SocketChannel.open(); channel.configureBlocking(false); Selector selector = Selector.open(); channel.connect(new InetSocketAddress("127.0.0.1", 7777)); channel.register(selector,SelectionKey.OP_CONNECT|SelectionKey.OP_READ); System.out.println("============读===AAAA======"); while(true) { int n = selector.select(); if(n==0) continue; Iterator<SelectionKey> iter = selector.selectedKeys().iterator(); while(iter.hasNext()){ SelectionKey key = iter.next(); if(key.isConnectable()) { System.out.println("================连接成功了==============="); } if( key.isReadable()) { System.out.println("=========数据来了============"); SocketChannel client = (SocketChannel)key.channel(); ByteBuffer buf = ByteBuffer.allocate(1024); int a= client.read(buf); buf.flip(); byte[] b = new byte[a]; System.arraycopy(buf.array(), 0, b, 0, a); String s = new String(b); System.out.println("============读描述符有数据了======服务器发来的数据:"+s); } iter.remove(); } } } } 服务端程序 public class NioSelectorServer { public static void main(String[] args) throws IOException { // 创建一个selector选择器 Selector selector = Selector.open(); SocketChannel clientchannel = null; // 打开一个通道 ServerSocketChannel serverchannel = ServerSocketChannel.open(); // 使设定non-blocking的方式。 serverchannel.configureBlocking(false); serverchannel.socket().bind(new InetSocketAddress(7777)); // 向Selector注册Channel及我们有兴趣的事件 serverchannel.register(selector, SelectionKey.OP_ACCEPT); while(true) { int n = selector.select(); if (n != 0) { Iterator<SelectionKey> it = selector.selectedKeys().iterator(); while (it.hasNext()) { SelectionKey key = (SelectionKey) (it.next()); if (key.isAcceptable()) { System.out.println("=====服务端========连接了======="); ServerSocketChannel Serverchannel = (ServerSocketChannel) key.channel(); clientchannel = Serverchannel.accept(); clientchannel.configureBlocking(false); clientchannel.register(selector, SelectionKey.OP_WRITE); } if(key.isWritable()) { System.out.println("=============服务端===========可写========="); SocketChannel client = (SocketChannel) key.channel(); String ss = "客户端 你好"; client.write(ByteBuffer.wrap(ss.getBytes())); } it.remove(); } } } } } 在本地运行 为什么客户端一直收不到服务端发来的数据了,到底程序错在哪了 ,请大家帮忙指点,最好将我的错误代码改正过来,万分感谢!!!
java nio channel注册select疑问
final SelectionKey key = channel.register(_selector, 0, attachment); 有人知道register方法的第二个参数为0是什么意思吗
java nio 创建buffer的疑问
以bytebuffer为例 allocate方法的源码 ``` public static ByteBuffer allocate(int capacity) { if (capacity < 0) throw new IllegalArgumentException(); return new HeapByteBuffer(capacity, capacity); } ``` heapbytebuffer的源码 。只不过调用的bytebuffer的构造器 ``` HeapByteBuffer(int cap, int lim) { // package-private super(-1, 0, lim, cap, new byte[cap], 0); /* hb = new byte[cap]; offset = 0; */ } ``` 为什么不直接调用bytebuffer的构造器,而是要通过heapbytebuffer调用bytebuffer构造器
相见恨晚的超实用网站
搞学习 知乎:www.zhihu.com 简答题:http://www.jiandati.com/ 网易公开课:https://open.163.com/ted/ 网易云课堂:https://study.163.com/ 中国大学MOOC:www.icourse163.org 网易云课堂:study.163.com 哔哩哔哩弹幕网:www.bilibili.com 我要自学网:www.51zxw
花了20分钟,给女朋友们写了一个web版群聊程序
参考博客 [1]https://www.byteslounge.com/tutorials/java-ee-html5-websocket-example
爬虫福利二 之 妹子图网MM批量下载
爬虫福利一:27报网MM批量下载    点击 看了本文,相信大家对爬虫一定会产生强烈的兴趣,激励自己去学习爬虫,在这里提前祝:大家学有所成! 目标网站:妹子图网 环境:Python3.x 相关第三方模块:requests、beautifulsoup4 Re:各位在测试时只需要将代码里的变量 path 指定为你当前系统要保存的路径,使用 python xxx.py 或IDE运行即可。
字节跳动视频编解码面经
引言 本文主要是记录一下面试字节跳动的经历。 三四月份投了字节跳动的实习(图形图像岗位),然后hr打电话过来问了一下会不会opengl,c++,shador,当时只会一点c++,其他两个都不会,也就直接被拒了。 七月初内推了字节跳动的提前批,因为内推没有具体的岗位,hr又打电话问要不要考虑一下图形图像岗,我说实习投过这个岗位不合适,不会opengl和shador,然后hr就说秋招更看重基础。我当时
Java学习的正确打开方式
在博主认为,对于入门级学习java的最佳学习方法莫过于视频+博客+书籍+总结,前三者博主将淋漓尽致地挥毫于这篇博客文章中,至于总结在于个人,实际上越到后面你会发现学习的最好方式就是阅读参考官方文档其次就是国内的书籍,博客次之,这又是一个层次了,这里暂时不提后面再谈。博主将为各位入门java保驾护航,各位只管冲鸭!!!上天是公平的,只要不辜负时间,时间自然不会辜负你。 何谓学习?博主所理解的学习,它
程序员必须掌握的核心算法有哪些?
由于我之前一直强调数据结构以及算法学习的重要性,所以就有一些读者经常问我,数据结构与算法应该要学习到哪个程度呢?,说实话,这个问题我不知道要怎么回答你,主要取决于你想学习到哪些程度,不过针对这个问题,我稍微总结一下我学过的算法知识点,以及我觉得值得学习的算法。这些算法与数据结构的学习大多数是零散的,并没有一本把他们全部覆盖的书籍。下面是我觉得值得学习的一些算法以及数据结构,当然,我也会整理一些看过
大学四年自学走来,这些私藏的实用工具/学习网站我贡献出来了
大学四年,看课本是不可能一直看课本的了,对于学习,特别是自学,善于搜索网上的一些资源来辅助,还是非常有必要的,下面我就把这几年私藏的各种资源,网站贡献出来给你们。主要有:电子书搜索、实用工具、在线视频学习网站、非视频学习网站、软件下载、面试/求职必备网站。 注意:文中提到的所有资源,文末我都给你整理好了,你们只管拿去,如果觉得不错,转发、分享就是最大的支持了。 一、电子书搜索 对于大部分程序员...
linux系列之常用运维命令整理笔录
本博客记录工作中需要的linux运维命令,大学时候开始接触linux,会一些基本操作,可是都没有整理起来,加上是做开发,不做运维,有些命令忘记了,所以现在整理成博客,当然vi,文件操作等就不介绍了,慢慢积累一些其它拓展的命令,博客不定时更新 顺便拉下票,我在参加csdn博客之星竞选,欢迎投票支持,每个QQ或者微信每天都可以投5票,扫二维码即可,http://m234140.nofollow.ax.
比特币原理详解
一、什么是比特币 比特币是一种电子货币,是一种基于密码学的货币,在2008年11月1日由中本聪发表比特币白皮书,文中提出了一种去中心化的电子记账系统,我们平时的电子现金是银行来记账,因为银行的背后是国家信用。去中心化电子记账系统是参与者共同记账。比特币可以防止主权危机、信用风险。其好处不多做赘述,这一层面介绍的文章很多,本文主要从更深层的技术原理角度进行介绍。 二、问题引入 假设现有4个人...
Python 基础(一):入门必备知识
目录1 标识符2 关键字3 引号4 编码5 输入输出6 缩进7 多行8 注释9 数据类型10 运算符10.1 常用运算符10.2 运算符优先级 1 标识符 标识符是编程时使用的名字,用于给变量、函数、语句块等命名,Python 中标识符由字母、数字、下划线组成,不能以数字开头,区分大小写。 以下划线开头的标识符有特殊含义,单下划线开头的标识符,如:_xxx ,表示不能直接访问的类属性,需通过类提供
这30个CSS选择器,你必须熟记(上)
关注前端达人,与你共同进步CSS的魅力就是让我们前端工程师像设计师一样进行网页的设计,我们能轻而易举的改变颜色、布局、制作出漂亮的影音效果等等,我们只需要改几行代码,不需...
国产开源API网关项目进入Apache孵化器:APISIX
点击蓝色“程序猿DD”关注我回复“资源”获取独家整理的学习资料!近日,又有一个开源项目加入了这个Java开源界大名鼎鼎的Apache基金会,开始进行孵化器。项目名称:AP...
程序员接私活怎样防止做完了不给钱?
首先跟大家说明一点,我们做 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)杨辉三角
杨辉三角 是经典算法,这篇博客对它的算法思想进行了讲解,并有完整的代码实现。
编写Spring MVC控制器的14个技巧
本期目录 1.使用@Controller构造型 2.实现控制器接口 3.扩展AbstractController类 4.为处理程序方法指定URL映射 5.为处理程序方法指定HTTP请求方法 6.将请求参数映射到处理程序方法 7.返回模型和视图 8.将对象放入模型 9.处理程序方法中的重定向 10.处理表格提交和表格验证 11.处理文件上传 12.在控制器中自动装配业务类 ...
腾讯算法面试题:64匹马8个跑道需要多少轮才能选出最快的四匹?
昨天,有网友私信我,说去阿里面试,彻底的被打击到了。问了为什么网上大量使用ThreadLocal的源码都会加上private static?他被难住了,因为他从来都没有考虑过这个问题。无独有偶,今天笔者又发现有网友吐槽了一道腾讯的面试题,我们一起来看看。 腾讯算法面试题:64匹马8个跑道需要多少轮才能选出最快的四匹? 在互联网职场论坛,一名程序员发帖求助到。二面腾讯,其中一个算法题:64匹
面试官:你连RESTful都不知道我怎么敢要你?
面试官:了解RESTful吗? 我:听说过。 面试官:那什么是RESTful? 我:就是用起来很规范,挺好的 面试官:是RESTful挺好的,还是自我感觉挺好的 我:都挺好的。 面试官:… 把门关上。 我:… 要干嘛?先关上再说。 面试官:我说出去把门关上。 我:what ?,夺门而去 文章目录01 前言02 RESTful的来源03 RESTful6大原则1. C-S架构2. 无状态3.统一的接
求小姐姐抠图竟遭白眼?痛定思痛,我决定用 Python 自力更生!
点击蓝色“Python空间”关注我丫加个“星标”,每天一起快乐的学习大家好,我是 Rocky0429,一个刚恰完午饭,正在用刷网页浪费生命的蒟蒻...一堆堆无聊八卦信息的网页内容慢慢使我的双眼模糊,一个哈欠打出了三斤老泪,就在此时我看到了一张图片:是谁!是谁把我女朋友的照片放出来的!awsl!太好看了叭...等等,那个背景上的一堆鬼画符是什么鬼?!真是看不下去!叔叔婶婶能忍,隔壁老王的三姨妈的四表...
为啥国人偏爱Mybatis,而老外喜欢Hibernate/JPA呢?
关于SQL和ORM的争论,永远都不会终止,我也一直在思考这个问题。昨天又跟群里的小伙伴进行了一番讨论,感触还是有一些,于是就有了今天这篇文。 声明:本文不会下关于Mybatis和JPA两个持久层框架哪个更好这样的结论。只是摆事实,讲道理,所以,请各位看官勿喷。 一、事件起因 关于Mybatis和JPA孰优孰劣的问题,争论已经很多年了。一直也没有结论,毕竟每个人的喜好和习惯是大不相同的。我也看
SQL-小白最佳入门sql查询一
不要偷偷的查询我的个人资料,即使你再喜欢我,也不要这样,真的不好;
项目中的if else太多了,该怎么重构?
介绍 最近跟着公司的大佬开发了一款IM系统,类似QQ和微信哈,就是聊天软件。我们有一部分业务逻辑是这样的 if (msgType = "文本") { // dosomething } else if(msgType = "图片") { // doshomething } else if(msgType = "视频") { // doshomething } else { // doshom...
致 Python 初学者
欢迎来到“Python进阶”专栏!来到这里的每一位同学,应该大致上学习了很多 Python 的基础知识,正在努力成长的过程中。在此期间,一定遇到了很多的困惑,对未来的学习方向感到迷茫。我非常理解你们所面临的处境。我从2007年开始接触 python 这门编程语言,从2009年开始单一使用 python 应对所有的开发工作,直至今天。回顾自己的学习过程,也曾经遇到过无数的困难,也曾经迷茫过、困惑过。开办这个专栏,正是为了帮助像我当年一样困惑的 Python 初学者走出困境、快速成长。希望我的经验能真正帮到你
“狗屁不通文章生成器”登顶GitHub热榜,分分钟写出万字形式主义大作
一、垃圾文字生成器介绍 最近在浏览GitHub的时候,发现了这样一个骨骼清奇的雷人项目,而且热度还特别高。 项目中文名:狗屁不通文章生成器 项目英文名:BullshitGenerator 根据作者的介绍,他是偶尔需要一些中文文字用于GUI开发时测试文本渲染,因此开发了这个废话生成器。但由于生成的废话实在是太过富于哲理,所以最近已经被小伙伴们给玩坏了。 他的文风可能是这样的: 你发现,...
程序员:我终于知道post和get的区别
是一个老生常谈的话题,然而随着不断的学习,对于以前的认识有很多误区,所以还是需要不断地总结的,学而时习之,不亦说乎
《程序人生》系列-这个程序员只用了20行代码就拿了冠军
你知道的越多,你不知道的越多 点赞再看,养成习惯GitHub上已经开源https://github.com/JavaFamily,有一线大厂面试点脑图,欢迎Star和完善 前言 这一期不算《吊打面试官》系列的,所有没前言我直接开始。 絮叨 本来应该是没有这期的,看过我上期的小伙伴应该是知道的嘛,双十一比较忙嘛,要值班又要去帮忙拍摄年会的视频素材,还得搞个程序员一天的Vlog,还要写BU...
相关热词 c# 输入ip c# 乱码 报表 c#选择结构应用基本算法 c# 收到udp包后回包 c#oracle 头文件 c# 序列化对象 自定义 c# tcp 心跳 c# ice连接服务端 c# md5 解密 c# 文字导航控件
立即提问