java新知识系列 一

内联函数:
所谓内联函数就是指函数在被调用的地方直接展开,编译器在调用时不用像一般函数那样,参数压栈,返回时参数出栈以及资源释放等,这样提高了程序执行速度。 对应Java语言中也有一个关键字final来指明那个函数是内联的。 内联不一定好,当被指定为内联的方法体很大时,展开的开销可能就已经超过了普通函数调用调用的时间,引入了内联反而降低了性能,因为在选择这个关键字应该慎重些,不过,在以后高版本的JVM中,在处理内联时做出了优化,它会根据方法的规模来确定是否展开调用。”
 
 
String类StringBuffer,以及StringBudder类的注意点:
String类可以直接赋值,但是StringBuffer,以及StringBudder类并不可以;只能通过创建新的对象或者痛殴哦个append方法;
字符串相加的底层实现,实际是通过StringBuffer类来进行append然后再调用toStirng方法;
 
 
Map接口和Collection接口的注意点:
Map接口和Collection接口是同一等级的
Collection
    -----List   //有序可重复
               -----LinkedList      非同步
                ----ArrayList       非同步,实现了可变大小的元素数组
                ----Vector          同步
                         ------Stack
    -----Set   //无序列不可重复
 
 
Map
    -----HashTable        同步,实现一个key--value映射的哈希表
    -----HashMap          非同步,
    -----WeakHashMap      改进的HashMap,实现了“弱引用”,如果一个key不被引用,则被GC回收
 
https://zhidao.baidu.com/question/563120272.html?qbl=relate_question_0
服务器端:ServerSocket提供的实例 ServerSocket server = new ServerSocket(端口号)
客户端:Socket提供的实例 Socket client = new Socket(IP地址,端口号)
 
 
//创建Socket 客户端对象
Socket s = new Socket("127.0.0.1",6666);
 
//创建ServerSocket 服务器端对象。。
ServerSocket ss = new ServerSocket(6666);
//监听服务器连接
s = ss.accept();
识别合法的构造方法:
  1:构造方法可以被重载,一个构造方法可以通过this关键字调用另一个构造方法,this语句必须位于构造方法的第一行;
    重载:方法的重载(overload):重载构成的条件:方法的名称相同,但参数类型或参数个数不同,才能构成方法的重载。  
 
  2 当一个类中没有定义任何构造方法,Java将自动提供一个缺省构造方法;
  3 子类通过super关键字调用父类的一个构造方法;
  4 当子类的某个构造方法没有通过super关键字调用父类的构造方法,通过这个构造方法创建子类对象时,会自动先调用父类的缺省构造方法
  5 构造方法不能被static、final、synchronized、abstract、native修饰,但可以被public、private、protected修饰;
  6 构造方法不是类的成员方法;
  7 构造方法不能被继承。
  8 java构造方法中的this关键字: 构造器的this指向同一个类中,用于调用同一个类中不同参数列表的另外一个构造器,必须放在第一行,否则会引起编译错误!
  9 java构造方法中的super关键字:构造方法的super关键字用于调用其父类的构造方法,子类默认调用父类的构造方法,也就是说super()是默认调用的,显示调用必须放在构造方法第一行!
 
 
关于return语句:
结论一:
 
return语句并不是函数的最终出口,如果有finally语句,这在return之后还会执行finally(return的值会暂存在栈里面,等待finally执行后再返回)
结论二:
 
 
finally里面不建议放return语句,根据需要,return语句可以放在try和catch里面和函数的最后。可行的做法有四:
(1)return语句只在函数最后出现一次。
(2)return语句仅在try和catch里面都出现。
(3)return语句仅在try和函数的最后都出现。
(4)return语句仅在catch和函数的最后都出现。
 
注意,除此之外的其他做法都是不可行的,编译器会报错
 
对象的初始化方式:
1.new时初始化 ;
2.静态工厂 newInstance;
3.反射Class.forName();
4.clone方式;
5.反序列化;
顺序:
 
 
析构函数(destructor) :析构函数与  构造函数 相反,当对象结束其 生命周期时(例如对象所在的函数已调用完毕),系统自动执行析构函数。析构函数往往用来做“清理善后” 的工作(例如在建立对象时用new开辟了一片内存空间,应在退出前在析构函数中用delete释放),java中的finalize()方法其实就是析构函数的代替者。Java中虽然有析构器,但是我们一般不需要程序员主动去调用,因为JVM的垃圾回收机制会自动完成垃圾回收,对象销毁工作,
 
 
Java多线程之内存可见性和原子性:Synchronized和Volatile的比较
 
内存模型:线程-工作内存,主内存;
2.什么是原子性
一个操作是不可中断的,要么全部执行成功要么全部执行失败,比如银行转账
 
3.什么是可见性
当多个线程访问同一变量时,一个线程修改了这个变量的值,其他线程就能够立即看到修改的值
 
4.什么是有序性
涉及指令重排序;
volatile只保证多线程操作的可见性,和禁止了指令重排序,不保证原子性。
synchronized才保证了原子性和可见性。
 
1.volatile修饰的变量是读可见性的,什么意思呢,就是所有线程读取该变量的值都是正确的,变量写入这一动作,会被编译成机器指令,并且,是先写入到当前线程的工作内存而不是主内存(不懂的看看java 内存模型去),但是volatile修饰的变量的修改写入动作会被直接写入主内存,写入的同时会通过总线发出信号宣告其他线程的内存区该变量的值无效(即过时的),当其他线程去读该变量的值的时候,会发现工作内存的值过时了,就会到主内存去读该变量的值,所以是读可见性的。
2. 为什么不是线程安全的呢?这是因为原子性问题,什么是原子性?大家知道cpu工作是以时间片的方式分配cpu资源,当一个线程正在执行的时候,如果此时失去时间片,那么它所有的工作都要暂停,原子性就是:一个完整不再能分割的操作。即使是时间片结束,也要完成当前的原子操作,否则不允许切换。 Synchronized:保证可见性和原子性, 在Java内存模型中,synchronized规定,线程在加锁时 ,先清空工作内存→在主内存中拷贝最新变量的副本到工作内存→执行完代码→将更改后的共享变量的值刷新到主内存中→释放互斥锁 。
 
 
 
 
 
 
 
public class StringDemo{
  private static final String MESSAGE="taobao";
  public static void main(String [] args) {
    String a ="tao"+"bao";
    String b="tao";   
    String c="bao";
    System.out.println(a==MESSAGE);  //true
    System.out.println((b+c)==MESSAGE);    //false
  }
}
intern() 方法会先检查 String 池 ( 或者说成栈内存 ) 中是否存在相同的字符串常量,如果有就返回。
//1,字符串在java中存储在字符串常量区中
2,==判断的是对象引用是否是同一个引用,判断字符串相等要用equals方法
首先判断a==MESSAGE 同一份字符串常量在内存中只有一份,因此是同一地址,返回true
再次比较(b+c)==MESSAGE 这相当于 new String(b+c)==MESSAGE 这里new了一个String对象,所以返回false
 
 
 
什么是ResultSet?
结果集(ResultSet)是数据中查询结果返回的一种对象,可以说结果集是一个存储查询结果的对象,但是结果集并不仅仅具有存储的功能,他同时还具有操纵数据的功能,可能完成对数据的更新
ResultSet结果集读取数据的方法主要是getXXX() ,他的参数可以使整型表示第几列(是从1开始的),还可以是列名。
 
 
 
关于jsp生命周期:
init()和destroy()方法分别在创建和销毁时执行一次(仅此一次)
service()方法是接收请求,返回响应的方法。每次请求都执行一次,该方法被HttpServlet封装为doGet和doPost方法
 
关于抽象类的注意点:抽象类不能够被实例化,可以用来初始化;
抽象类有构造函数的;
抽象类的构造函数用来初始化抽象类的一些字段,而这一切都在抽象类的派生类实例化之前发生。不仅如此,抽线类的构造函数还有一种巧妙应用:就是在其内部实现子类必须执行的代码。
 
 
 
java类之间的关系有哪些:
use-a 是依赖关系
has-a   一般是组合关系
is-a   一般是继承关系  
 
 
引用传递和值传递;
引用数据类型是引用传递(call by reference),基本数据类型是值传递(call by value)
值传递不可以改变原变量的内容和地址---》原因是java方法的形参传递都是传递原变量的副本,在方法中改变的是副本的值,而不适合原变量的
引用传递不可以改变原变量的地址,但可以改变原变量的内容---》原因是当副本的引用改变时,原变量 的引用并没有发生变化,当副本改变内容时,由于副本引用指向的是原变量的地址空间,所以,原变量的内容发生变化。
 
结论:1.值传递不可以改变原变量的内容和地址;
           2.引用传递不可以改变原变量的地址,但可以改变原变量的内容;
 
 
 
什么是内存泄漏,内存泄漏的原因:
内存泄露(Memory Leak)是指一个不再被使用的对象或者变量还在内存中占有存储空间。在C/C++语言中,内存泄露出现在开发人员忘记释放已分配的内存就会造成内存泄露。在java语言中引入垃圾回收机制,有GC负责进行回收不再使用的对象,释放内存。但是还是会存在内存泄露的问题。
内存泄露主要有两种情况:1.在堆中申请的空间没有释放。2.对象已不再被使用(注意:这里的不在被使用是指对程序来说没有用处,如数据库连接使用后没有关。但是还是存在着引用),但是仍然在内存中保留着。GC机制的引入只能解决第一种情况,对于第2种情况无法保证不再使用的对象会被释放。java语言中的内存泄露主要指第2种情况。
内存泄露的原因:1.静态集合类。如HashMap和Vector。这些容器是静态的,生命周期和程序的生命周期一致,那么在容器中对象的生命周期也和其一样,对象在程序结束之前将不能被释放,从而会造成内存泄露。2.各种连接,如数据库连接,网络连接,IO连接,不再使用时如果连接不释放容易造成内存泄露。3.监听器,释放对象时往往没有相应的删除监听器,可能会导致内存泄露。
内存溢出(OOM)是指程序在申请内存时没有足够的内存供使用,进而导致程序崩溃这是结果描述。内存泄露(Memory Leak)最终会导致内存溢出。
 
 
 
 
 
 
 
 
 
 
 
 

原文地址:https://www.cnblogs.com/liguo-wang/p/9734437.html