JAVA基础学习总结(不按期更新)

1、java语法基础java

一、finalc++

关于final的问题我曾经被问到两次,因此首先说一下这个东西。编程

应用于变量,表示该变量一旦被赋值则不能够改变,可是有一个特殊的:StringBuffer,看下面一个例子设计模式

final StringBuffer sb=new StringBuffer("123");数组

这样写 sb=new StringBuffer("");会报错,可是sb.append("111");不会报错。安全

final是指引用变量不能变,但变量的内容是不能够改变的。StringBuffer 只是有这样一个方法能够改变它的内容而已。数据结构

应用于方法,表示该方法不能够被重写覆盖。多线程

应用与类,表示该类不能够被继承。app

二、关于private,public,protected,friendly异步

能够用一个表格说明他们的权限和访问范围,当修饰元素没有修饰符时默认是friendly

- 表示不支持 √ 表示支持

修饰符 当前类 同一包 子孙类 其余包
public
protected -
friendly - -
private - - -

三、基本数据类型

byte、int、short、double、float、long、double、boolean

级别从低到高为byte,char,short(这三个平级)-->int-->float-->long-->double

由低级到高级系统会自动转换,由高级到低级须要强制转换。

四、运算符

a++ 和++a区别

二者都表示a+1可是前者表示先进行运算,而后给a+1,后者表示先a+1,再参加运算,例如:a=2;b=a++;能够理解为b=a,a=a+1;b=++a;能够理解为a=a+1,b=a;一样a--和--a相似

& 和 &&(| 和||)区别

首先二者都表示与运算符,两边条件均为true时结果才为true,其余状况均为false;

&&有短路功能,例如a&&b,当a为false时,就不会执行b;可是a&b无论a为true或者false,b都会执行。

& 还能够看成位运算符,两边表达式不是boolean类型时,表示按位与操做。

有一个关于位运算的题:请编程实现计算1234变成二进制之后包含多少1。

通常思路就是先经过Integer.toBinaryString(int i)方法转换成二进制,而后遍历里面1的个数。

这里说一下不一样进制之间的转换方法:

十进制转成十六进制:
Integer.toHexString(int i)
十进制转成八进制
Integer.toOctalString(int i)
十进制转成二进制
Integer.toBinaryString(int i)
十六进制转成十进制
Integer.valueOf("FFFF",16).toString()
八进制转成十进制
Integer.valueOf("876",8).toString()
二进制转十进制
Integer.valueOf("0101",2).toString()

其实经过位运算能够实现更快的方法。

public static void main(String[] args) {
  int c=0;
  int t=1234;
  while (t>0) {
   t=t&(t-1);
   c++; 
  }
  System.out.print(c);
 }

说明一下,t&(t-1)实际上是 t 的二进制进行移位运算,0&1=0,1&0=0,1&1=1。

说道移位运算还有一个:请用最有效率的方法计算出2乘以8的结果。

2<<3   一个数左移几位就至关于这个数乘以2的几回方,2*八、等价于2左移3位

五、Override和Overload的区别(重写和重载区别)。

重载是指同一个类中能够存在多个命名相同的方法,可是各个方法的参数个数或类型必须不一样,而且不能够经过改变方法的返回值来表示两个方法的不通。

重写是指子类能够与父类的方法名称参数相同,等于彻底把父类的方法覆盖了。可是对于异常,子类的方法必须比父类抛出更少的异常或者是父类异常的子异常。

六、java内存

java内存大概分为5块:寄存器,本地方法区,方法区,堆,栈。

栈:主要用来存储局部变量,当运算完成所在趋于结束,内存将被释放。

堆:存储数组和对象。

七、成员变量和局部变量区别

成员变量在类里面定义,只在类里面有效;局部变量存在方法中定义,只在方法所在的大括号有效。

成员变量存在于堆内存中;局部变量存在与栈内存中

八、this 和 super

this 一般用来表示对象自己,super访问父类被子类隐藏的变量或覆盖的方法。

若是一个类继承自父类,那么子类的super()方法即对父类的初始化。当类中有两个同名变量,一个属于类(类的成员变量),而另外一个属于某个特定的方法(方法中的局部变量),使用this区分红员变量和局部变量。

调用super()必须写在子类构造方法的第一行,不然编译不经过。每一个子类构造方法的第一条语句,都是隐含地调用super(),若是父类没有这种形式的构造函数,那么在编译的时候就会报错。

super()和this()相似,区别是super从子类中调用父类的构造方法this()在同一类内调用其它方法。

super的本质是java的一个关键字,this的本质是一个指向本对象的指针。

九、单例模式

保证一个类在内存中的对象中惟一性。

步骤:一、私有化构造函数。二、建立一个静态的私有的本类对象。三、提供一个对外调用的方法

单例模式的建立有两种:懒汉式,饿汉式

首先来看下懒汉式:

public class Single {
  public static Single single;  
  private Single(){
  }
  public static Single getInstance(){
 if (single==null) {
  single=new Single();
   }     
 return single;   
 }
}

能够看出当须要Single的时候,随时用随时new,这样之后就不用实例了,再看下饿汉式:

 public class Single {
  public static Single singleInstance=new Single(); 
  private Single(){
  } 
  public static Single getInstance(){    
    return single;   
  }
}

比较推荐饿汉式,由于他不用考虑线程安全问题,懒汉模式下若是有两个线程同时访问,第一个线程走到if后尚未执行new,第二个线程也会判断为Null,从新建立一个实例,这样就建立了两个。固然有一种方法能够解决这个问题那就是synchronized,看一下代码:

 public class Single {
  public static Single single;  
  private Single(){
  }
  public  synchronized static Single getInstance(){
  if (single==null) {
  single=new Single();
   }     
return single;   
}
}

固然这样是能够的,实现了同步锁,可是其实还能够进行优化,这样每次调用getInstance()都会受同步锁的影响,效率会下降。其实只要保证new的时候同步就能够了,这种方法叫双重锁定(Double-Check Locking)有兴趣的能够查一下,先看代码:

 public class Single {
  public static Single single;  
  private Single(){
  }
  public static Single getInstance(){
  if(sing==null){
  synchronized (Single.class){
  if (single==null) {
  single=new Single();
   }    
   } 
   }
return single;   
}
}

10abstract 

抽象类的特色:

1:抽象方法只能定义在抽象类中,抽象类和抽象方法必须由abstract关键字修饰(能够描述类和方法,不能够描述变量)。

2:抽象方法只定义方法声明,并不定义方法实现。

3:抽象类不能够被建立对象(实例化)。

4:只有经过子类继承抽象类并覆盖了抽象类中的全部抽象方法后,该子类才能够实例化。不然,该子类仍是一个抽象类。

十一、String、StringBuffer、StringBuilder区别

因为String类是final修饰的,因此string对象是不可变的,当前它也就是线程安全的。

StringBuffer和StringBuilder都是继承AbstractStringBuilder类,他们都是可变的。

因为StringBuffer对方法或者调用的方法加了同步锁,StringBuilder没有加,因此StringBuilder是非线程安全的,StringBuffer是线程安全的。

在不kao虑多线程的状况下,StringBuilder效率要高于StringBuffer。

十二、==和equals区别

==表示两个对象在内存中存储的值相等,而equals是两个对象的内容相等。

好比:String a=new String("123");String =new String("123");

若是用a==b的话返回false,而a.equals(b)返回true,a和b的内容是相等的,可是a、b是不通的两个对象,他们的首地址是不同的,因此a==b返回false。

1三、JAVA集合类

有时候会有这样的题:请说出几个JAVA经常使用的集合类,他们都有什么区别?

集合你们并不陌生,经常使用的什么ArrayList、map等,下面来介绍一下JAVA的集合类。

总的来讲总共分为两大部分一个是Collection接口,一个是Map接口。

Collection
├List
│├LinkedList
│├ArrayList
│└Vector
│ └Stack
└Set

│├AbstractSet

│├HashSet

│└TreeSet

Map
├Hashtable
├HashMap
└WeakHashMap

 先说下Collection,由Collection又派生出两个接口:List和set,二者最大的区别就是list容许有重复元素,set不容许有重复元素;List是有序的,而set除了TreeSet之外,都是无序的。

给定一个字符串(长度不会超过500,必定会有重复的字符),编程返回字符串内第一个重复的字符。例如:“tyuioqiwyss”,返回值:i  。

public static char getFirstRepeat(String str){
  HashSet<Object> hs=new HashSet<>(); //定义一个hashset
  char[] m=str.toCharArray();//将字符串放进一个char数组
  for (int i = 0; i < m.length; i++) {
   boolean b=hs.add(m[i]);//遍历数组元素放进hashset
   if (!b) {             //因为hashset不容许有重复元素,因此当有重复元素被添加的时候就会返回false
    return m[i];         
   }
  }
  return 0;
 }

List下面又有ArrayList、LinkedList、Vector和stack,先说下ArrayList、LinkedList的区别:一、ArrayList是基于动态数组的数据结构,对于查找访问操做效率较高;LinkedList是基于链表的数据结构,对于元素的增长删除效率较高。二者都是非同步的。Vector和stack固然就是同步的了,stack继承自Vector,实现了一个后进先出的堆栈。

Set接口是不容许插入重复元素的。

Map的元素是用key,value的形式存储的,能够存入相同的value可是key要保证惟一。

1四、Math

关于math有几个经常使用的方法。

Math.ceil():向上取整   Math.ceil(11.5)=12   Math.ceil(-11.5)=-11

Math.floor():向下取整  Math.floor(11.5)=11  Math.floor(-11.5)=-12

Math.round():四舍五入  Math.round(11.5)=12  Math.round(-11.5)=-11  Math.round(-11.6)=-12

1五、关于异或运算

给定两个Int参数,编程返回两个参数二进制数有多少位不一样。

异或运算是这样的:两位相同则为0,不一样则为1。0000^0011=0011 1001^1100=0101

因此先把给定的两个参数作异或运算,获得的值在判断他的二进制里面有多少1即有多少个不一样的位。

 public static int Sample(int m,int n) {
  int s=m^n; //异或运算
 int count=0;//统计1的个数
  while (s>0) {
   s=s&(s-1);//进行与运算,相似移位运算 0&0=0 0&1=0 1&1=1 1&0=0
   count++;
  }
  return count;
  
 }

 

1六、面向对象的特色,说说对他们的理解。

封装:可使程序实现“高内聚,低耦合”,对象是封装的最基本单位。

继承:提升软件的可重用性和可扩展性

抽象:把某些具备相同特征的事物抽象成一个具体的类,只关心咱们须要的地方

多态:增长软件的灵活性和可扩展性

1七、列举常见的异常及可能产生缘由,异常解决方法?

NullPointerException 空指针异常 简单地说就是调用了未经初始化的对象或者是不存在的对象,好比调用了未初始化对象的方法

ArrayIndexOutOfBoundsException 数组越界 调用的数组长度与实际数组长度不一致,好比一个数组有3个元素,获取第四个元素时就会出现这个异常,因此最好先查看一下数组长度。

NumberFormatException 数字强转异常 常见于把一个字符串转为Int 类型是,Intenger.parseInt("123#")就会抛出异常。

ClassCastException 数据类型转换异常 如用户在输入日期的时候只输入月、日信息,而没有年份的信息。此时应用程序在进行数据类型转换的时候,就会出现异常。

IllegalArgumentException 方法的参数错误 好比g.setColor(int red,int green,int blue)这个方法中的三个值,若是有超过255的也会出现这个异常,所以一旦发现这个异常,咱们要作的,就是赶忙去检查一下方法调用中的参数传递是否是出现了错误。

异常的处理一般咱们使用try catch来处理可能出现的异常,固然咱们应该是捕获这个异常来处理。下面是有关异常处理的几个关键字:

throws 捕获并向外抛出异常

throw 抛出异常

try catch 内部捕获异常并作自定义处理

finally 不管是否有异常都会被处理的语句

1八、线程相关

1)实现一个线程

两种方法:继承thread和实现Runnable接口

2)sleep() wait()区别

sleep()是thread类的一个方法,他须要指定一个时间告诉线程暂停指定时间,时间到了继续执行,暂停期间依然占用CPU;wait()是Object类的一个方法,不须要指定时间,想恢复执行的话须要调用notify或者notifyAll方法,暂停期间不会占用CPU资源。

3)同步和异步

若是数据须要在线程间共享,一个线程在读取数据,另外一个线程在插入数据,这个时候就须要保证同步读取。若是一个线程须要调用的方法须要执行很长时间,但其余线程又不须要该线程的数据返回时应该用异步。

4)启动一个线程是调用start()方法,run()方法是线程进入执行状态所执行的方法。

1九、输入输出流

JAVA的输入输出流有两种 字节流和字符流。字节流继承InputOutStream、OutputStream,字符流继承自InputOutStreamReader、OutputStreamReader。字节流主要操做对象是byte,字符流主要操做对象是字符或者字符串。

字节流在操做的时候自己是不会用到缓冲区(内存)的,是与文件自己直接操做的,而字符流在操做的时候是使用到缓冲区的

字节流在操做文件时,即便不关闭资源(close方法),文件也能输出,可是若是字符流不使用close方法的话,则不会输出任何内容,说明字符流用的是缓冲区,而且可使用flush方法强制进行刷新缓冲区,这时才能在不close的状况下输出内容。

20、内存溢出和内存泄漏(主要针对Android中的状况进行分析)

内存溢出:应用使用的内存大于机器的最大内存。
内存泄漏:cursor使用完了没有关闭;Bitmap没有回收;构造Adapter时,没有使用 convertView

2一、抽象类和接口的区别

一、抽象类能够有成员变量,接口里通常没有。若是有的话默认必须是static final类型的。

二、一个类能够实现多个接口但只能继承一个抽象类

三、抽象类里面能够有非抽象的方法,接口里面的方法都是抽象的,也就是实现他的类里面必须实现他的方法。

四、抽象类中的抽象方法的访问类型能够是public、protected或者包访问类型。而接口中的抽象方法只能是public abstract类型,接口的方法前面能够不加修饰符,默认就是public abstract类型。

2二、java中静态属性、静态代码块、非静态属性、非静态代码块、构造函数在new的时候执行顺序是怎样的?

对于没有继承其余类的执行顺序是这样的:

静态属性--静态代码块--非静态属性--非静态代码块--构造函数

若是继承了其余类:

父类的公共静态属性和静态代码块--自身的静态属性和静态代码块--父类的非静态属性和非静态代码块--父类的构造函数--自身的非静态属性和非静态代码块--自身的构造函数

2三、什么是编译型语言,什么是解释型语言?JAVA属于哪种?

编译型语言是指程序在执行前须要有一个单独的编译过程,将程序翻译成机器语言,之后执行这个程序的时候,就不用再进行翻译了。

解释型语言是指是每次在运行的时候将程序翻译成机器语言,因此运行速度相对于编译型语言要慢。

C/C++ 等都是编译型语言,而Java,C#,脚本语言等都是解释型语言。

虽然Java程序在运行以前也有一个编译过程,可是并非将程序编译成机器语言,而是将它编译成字节码(能够理解为一个中间语言)。
在运行的时候,由JVM将字节码再翻译成机器语言。

2四、经常使用的设计模式有哪些?

单例模式、工厂模式、观察者设计模式、适配器模式等。

2五、synchronized修饰静态方法和非静态方法的区别

synchronized在静态方法上表示调用前要得到类的锁,而在非静态方法上表示调用此方法前要得到对象的锁。

public class StaticSynDemo {

private static String a="test";

//等同于方法print2
public synchronized void print1(String b){ //调用前要取得StaticSynDemo实例化后对象的锁
   System.out.println(b+a);
}
public void print2(String b){
   synchronized (this) {//取得StaticSynDemo实例化后对象的锁
    System.out.println(b+a);
   }
}
//等同于方法print4
public synchronized static void print3(String b){//调用前要取得StaticSynDemo.class类的锁
   System.out.println(b+a);
}
public static void print4(String b){
   synchronized (StaticSynDemo.class) { //取得StaticSynDemo.class类的锁
    System.out.println(b+a);
   }
}
}

 

相关文章
相关标签/搜索