一些基本概念
-
内存溢出 out of memory,是指程序在申请内存时,没有足够的内存空间供其使用,出现out of memory;比如申请了一个integer,但给它存了long才能存下的数,那就是内存溢出。
内存泄露 memory leak,是指程序在申请内存后,无法释放已申请的内存空间,一次内存泄露危害可以忽略,但内存泄露堆积后果很严重,无论多少内存,迟早会被占光。
memory leak会最终会导致out of memory!
栈满时再做进栈必定产生空间溢出,叫上溢,栈空时再做退栈也产生空间溢出,称为下溢。就是分配的内存不足以放下数据项序列,称为内存溢出. -
ServerSocket(int port) 是服务端绑定port端口,调accept()监听等待客户端连接,它返回一个连接队列中的一个socket。
Socket(InetAddress address , int port)是创建客户端连接主机的socket流,其中InetAddress是用来记录主机的类,port指定端口。
socket和servletSocket的交互如下图所示:
Paste_Image.png - A: 垃圾回收在jvm中优先级相当相当低。
B:垃圾收集器(GC)程序开发者只能推荐JVM进行回收,但何时回收,回收哪些,程序员不能控制。
C:垃圾回收机制只是回收不再使用的JVM内存,如果程序有严重BUG,照样内存溢出。
D:进入DEAD的线程,它还可以恢复,GC不会回收 -
Java把内存分成两种,一种叫做栈内存,一种叫做堆内存。
在函数中定义的一些基本类型的变量和对象的引用变量都是在函数的栈内存中分配。当在一段代码块中定义一个变量时,java就在栈中为这个变量分配内存空间,当超过变量的作用域后,java会自动释放掉为该变量分配的内存空间,该内存空间可以立刻被另作他用。
堆内存用于存放由new创建的对象和数组。在堆中分配的内存,由java虚拟机自动垃圾回收器来管理。在堆中产生了一个数组或者对象后,还可以在栈中定义一个特殊的变量,这个变量的取值等于数组或者对象在堆内存中的首地址,在栈中的这个特殊的变量就变成了数组或者对象的引用变量,以后就可以在程序中使用栈内存中的引用变量来访问堆中的数组或者对象,引用变量相当于为数组或者对象起的一个别名,或者代号。
引用变量是普通变量,定义时在栈中分配内存,引用变量在程序运行到作用域外释放。而数组&对象本身在堆中分配,即使程序运行到使用new产生数组和对象的语句所在地代码块之外,数组和对象本身占用的堆内存也不会被释放,数组和对象在没有引用变量指向它的时候(比如先前的引用变量x=null时),才变成垃圾,不能再被使用,但是仍然占着内存,在随后的一个不确定的时间被垃圾回收器释放掉。这个也是java比较占内存的主要原因。
以上段落来自于某一本Java程序设计的书中,实际上,栈中的变量指向堆内存中的变量,这就是Java中的指针。
总结起来就是对象存储在堆内存,引用变量存储在栈内存。栈内存指向堆内存。 - 数据类型的转换,分为自动转换和强制转换。自动转换是程序在执行过程中 “ 悄然 ” 进行的转换,不需要用户提前声明,一般是从位数低的类型向位数高的类型转换;强制类型转换则必须在代码中声明,转换顺序不受限制。
自动数据类型转换
自动转换按从低到高的顺序转换。不同类型数据间的优先关系如下:
低 ---------------------------------------------> 高
byte,short,char-> int -> long -> float -> double
运算中,不同类型的数据先转化为同一类型,然后进行运算,转换规则如下:
操作数 1 类型 | 操作数 2 类型 | 转换后的类型 |
---|---|---|
byte 、 short 、 char | int | int |
byte 、 short 、 char 、 int | long | long |
byte 、 short 、 char 、 int 、 long | float | float |
byte 、 short 、 char 、 int 、 long 、 float | double | double |
强制数据类型转换
强制转换的格式是在需要转型的数据前加上 “( )” ,然后在括号内加入需要转化的数据类型。有的数据经过转型运算后,精度会丢失,而有的会更加精确
面向对象语法特点
- 方法的重写(override)两同两小一大原则:
方法名相同,参数类型相同(参数顺序也相同,总之参数相同,返回值类型可以不同)
子类返回类型小于等于父类方法返回类型,
子类抛出异常小于等于父类方法抛出异常,
子类访问权限大于等于父类方法访问权限。 - throws用于在方法上声明该方法不需要处理的异常类型,用在方法上后面跟异常类名 可以是多个异常类
throw用于抛出具体异常类的对象,用在方法内 后面跟异常对象只能是一个异常类型实体.
try块必须和catch块或和finally同在,不能单独存在,二者必须出现一个.
finally块总会执行,不论是否有错误出现.但是若try语句块或会执行的catch语句块使用了JVM系统退出语句,finally块就不会被执行了. 一般我们把关闭资源的代码放在finally里面 保证资源总是能关闭。finally在throw和return之前执行 - 链接:https://www.nowcoder.com/questionTerminal/27a89bce14c242d1a4161fbeca2b6b7e来源:牛客网
1.父类静态代码块 ( java虚拟机加载类时,就会执行该块代码,故只执行一次)
2 .子类静态代码块 ( java虚拟机加载类时,就会执行该块代码,故只执行一次)
3. 父类属性对象初始化
4.父类普通代码块(每次new,每次执行 )
5. 父类构造函数(每次new,每次执行)
6.子 类 属性对象初始化
7.子类普通代码块(每次new,每次执行 )
8.子 类构造函数(每次new,每次执行) - Java 提供的事件处理模型是一种人机交互模型。它有三个基本要素:
- 事件源(Event Source):即事件发生的场所,就是指各个组件,如按钮等,点击按钮其实就是组件上发生的一个事件;
- 事件(Event):事件封装了组件上发生的事情,比如按钮单击、按钮松开等等;
- 事件监听器(Event Listener):负责监听事件源上发生的特定类型的事件,当事件到来时还必须负责处理相应的事件;
Java自带API解读
- String、StringBuilder、StringBuffer的区别:
String是不可变对象,不适合用来做大量修改自身操作的地方,因为每次修改都是新建一个String,会造成对内存的浪费。StringBuilder是非线程同步的,StringBuffer是线程同步的。单线程情况下推荐使用StringBuilder,因为不用考虑同步,速度自然要快一些。 - 单线程和多线程容器有(左边是非线程同步的,右边是线程同步的):
- HashMap和HashTable
- StringBuilder和StringBuffer
- ArrayList和Vector
- HashMap和HashTable的区别:
- HashMap是非synchronized,而Hashtable是synchronized,这意味着Hashtable是线程安全的,多个线程可以共享一个Hashtable;而如果没有正确的同步的话,多个线程是不能共享HashMap的。Java 5提供了ConcurrentHashMap,它是HashTable的替代,比HashTable的扩展性更好。
- HashMap可以使用null做key或者value,HashTable则不行。
sychronized意味着在一次仅有一个线程能够更改Hashtable。就是说任何线程要更新Hashtable时要首先获得同步锁,其它线程要等到同步锁被释放之后才能再次获得同步锁更新Hashtable。
我们能否让HashMap同步?
HashMap可以通过下面的语句进行同步:
Map m = Collections.synchronizeMap(hashMap);
Java多线程
- join()的作用是:“等待该线程终止”,这里需要理解的就是该线程是指的主线程等待子线程的终止。也就是在子线程调用了join()方法后面的代码,只有等到子线程结束了才能执行。
网友评论