一些小Tip

导语

个人感悟,持续更新中。。。

正文

  1. 无论NIO还是AIO,都没有在数据传输过程(tcp/udp)作革命性的创新。他们在传输过程的效率和传统BIO是一样的,还是会产生阻塞(网络延迟,Socket缓冲区满了或空了),他们通过在OS层对Socket进行统一管理,进行事件管理。避免了进程级的线程开销和线程阻塞(线程是JVM资源,这些都会阻塞线程栈,产生内存消耗和CPU时间片和上下文切换时间),JVM进程只需要一个线程来进行事件处理(不会阻塞)。也就是说,BIO,NIO,AIO的本质(Socket)其实是一样的,只不过把矛盾转移到了OS层(select,poll,epoll)。
  2. 调用一个对象的方法可以理解为在给这个对象发送一个通知。
  3. HTTP是一种文本协议。所谓的文本协议是指,传输的数据可以通过文本表达出可读的内容。HTTP传输的数据可以用ASCII字符集解析成可读的文本,如请求行,请求头。文件上传时文件分隔符可以解析成文本,文件的的内容可能是二进制的,但是它不是协议的内容(协议不会定义数据具体内容,它只定义了一个容器,用来传递数据,无论是二进制数据还是文本数据)。与此相关的,Google ProtoBuf是一种二进制协议。
  4. 线程的阻塞状态和IO阻塞状态不是一回事。线程的阻塞是线程栈中的代码正在等待临获取临界区的锁。而IO的阻塞状态是包含在线程的Runnable状态的。详细
  5. CPU能认识的就仅仅是中断线和中断处理程序这些概念。所谓线程,进程,软中断等概念,是软件发明出来的,CPU是不认识的。所谓线程,本质上是保存CPU运行状态的一种形式,CPU的运行状态,就是CPU的所有寄存器的内容的集合(包括用来控制中断的寄存器),线程的作用就是可以把这些寄存器都保存下来(其实还有软件本身的堆栈等其他信息,但我们这里不关心软件,先忽略),然后用另一个保存的状态刷新CPU的状态,让CPU感觉自己在运行到另一个上下文上。OS对CPU不断进行状态的切换,保存上一个状态,加载下一个线程的状态,就实现线程切换了。至于进程,本质上可以认为是线程切换的同时也会切换地址空间。这里我们混用这两个概念。详细
  6. 中断和上下文切换: 通知操作系统发生了外部事件的机制是中断当前运行线程并将控制转移到中断处理程序。在中断处理程序可以运行之前,必须保存足够的硬件状态以保证在中断处理完成后系统能恢复线程的上下文。新调用的中断处理程序将经历在硬件层次结构中上移带来的所有延迟(除了页面故障)。如果该中断处理程序最近没有运行过(或者中间程序很节约时间),那么它的任何代码或数据不太可能保留在 TLB 或高速缓存中。当再次调度已中断的线程时,它的执行上下文(如寄存器内容)逻辑上将得到恢复,以便它可以正确运行。然而,TLB 和高速缓存的内容必须根据程序的后继请求重新构造。因此,作为中断的结果,中断处理程序和被中断的线程都可能遇到大量的高速缓存未命中和 TLB 未命中延迟。
  7. 系统调用,陷入内核。详细
  8. 比较int大小时,如果简单的使用 a - b > 0来判断会很不安全。因为如果差值可能是int范围的两倍。如最大正数减最小负数。差值会溢出,截取低位。从而产生难以预见的错误。
  9. 字节流和它的包装流,只能被读取一次。读完一次后在读会读不到数据。两种方式解决:重置流和将流读出来缓存后重复使用。
  10. java类中硬编码的字符串长度最大为2个字节表达的长度,即65536。因为类的常量池中字符串类型常量的长度标志位为两个字节。否则无法通过编译检查。但是在运行时在内存中动态生成的字符串不受此限制。
posted @ 2018-04-06 11:40  Yungyu  阅读(188)  评论(0编辑  收藏  举报