【Java面试】---Java基础知识
来源:互联网 发布:中国高铁网络 编辑:程序博客网 时间:2024/06/09 14:18
语言特性和区别
编译型和解释型语言
编译型语言
编译型语言和解释性语言:编译型语言在程序执行之前,先会通过编译器对程序执行一个编译的过程,把程序转变成机器语言。运行时就不需要翻译,而直接执行就可以了。最典型的例子就是C(C/C++)语言。
解释型语言
解释型语言就没有这个编译的过程,而是在程序运行的时候,通过解释器对程序逐行作出解释,然后直接运行,最典型的例子是Ruby(Java、JavaScript、Perl、Python、Ruby、MATLAB),而其中(Shell,JavaScript又是脚本语言,脚本语言通常属于解释型语言)但是,随着Java等基于虚拟机的语言的兴起,我们又不能把语言纯粹地分成解释型和编译型这两种,用Java来举例,Java首先是通过编译器编译成字节码文件,然后在运行时通过解释器给解释成机器文件。所以我们说Java是一种先编译后解释的语言。
先解释后编译语言
先编译后解释语言
但是,随着Java等基于虚拟机的语言的兴起,我们又不能把语言纯粹地分成解释型和编译型这两种,用Java来举例,Java首先是通过编译器编译成字节码文件,然后在运行时通过解释器给解释成机器文件。所以我们说Java是一种先编译后解释的语言。
动态语言和非动态语言
动态语言的定义:动态编程语言 是 高级程序设计语言 的一个类别,在计算机科学领域已被广泛应用。它是一类 在 运行时可以改变其结构的语言 :例如新的函数、对象、甚至代码可以被引进,已有的函数可以被删除或是其他结构上的变化。动态语言目前非常具有活力。众所周知的 ECMAScript ( JavaScript )便是一个动态语言,除此之外如 PHP 、Ruby 、Python 等也都属于动态语言,而 C 、 C++ java, ObjectC等语言则不属于动态语言。
可以这么考虑,就是纯解释型语言基本都是动态语言
java和c++的区别
java是c++基础上的优化,他们的区别主要有以下几种
java是解释型语言,C++是编译型语言,java的执行速度慢于c++,但跨平台性优于c++
java是纯面向对象语言(JAVA或C#都是),所有代码都必须在类中出现,不存在所谓的全局变量或全局函数,但是c++是半面向对象半面向过程,可以定义全局变量和全局函数
java中没有指针,避免了操作指针引起的安全问题
java单继承,C++多继承,java可以通过实现多个接口来模拟多继承
java不需要管理内存分配,有垃圾回收机制,C++需要开发人员管理内存
基础核心部分
Object常用方法
基本的六个操作
protected Object clone()创建并返回此对象的一个副本。只有实现了Cloneable接口才可以调用该方法,否则抛出CloneNotSupportedException异常。
boolean equals(Object obj)指示某个其他对象是否与此对象“相等”。
protected void finalize()当垃圾回收器确定不存在对该对象的更多引用时,由对象的垃圾回收器调用此方法。
Class<? extends Object>
getClass() 返回一个对象的运行时类。int hashCode()返回该对象哈希码值。一般必须满obj1.equals(obj2)==true。可以推出obj1.hashCode()==obj2.hashCode(),但是hashCode相等不一定就满足equals。不过为了提高效率,应该尽量使上面两个条件接近等价。
String toString()返回该对象的字符串表示。
线程相关的五个操作
void notify()唤醒在此对象监视器上等待的单个线程(非指定)。
void notifyAll()唤醒在此对象监视器上等待的所有线程。
void wait()导致当前的线程等待,直到其他线程调用此对象的 notify() 方法或 notifyAll() 方法。
void wait(long timeout)导致当前的线程等待,直到其他线程调用此对象的 notify() 方法或 notifyAll() 方法,或者超过指定的时间量。
void wait(long timeout, int nanos)导致当前的线程等待,直到其他线程调用此对象的 notify() 方法或 notifyAll() 方法,或者其他某个线程中断当前线程,或者已超过某个实际时间量。
关于clone方法的使用
为什么使用
在实际编程过程中,我们常常要遇到这种情况:有一个对象A,在某一时刻A中已经包含了一些有效值,**此时可能会需要一个和A完全相同新对象B,并且此后对B任何改动都不会影响到A中的值**A与B是两个独立的对象。
要说明的有两点:
一是拷贝对象返回的是一个新对象,而不是一个引用。
二是拷贝对象与用 new操作符返回的新对象的区别就是这个拷贝已经包含了一些原来对象的信息,而不是对象的初始信息。
深复制与浅复制的区别
浅复制:直接将源对象中的name的引用值拷贝给新对象的name字段
深复制:根据原Person对象中的name指向的字符串对象创建一个新的相同的字符串对象,将这个新字符串对象的引用赋给新拷贝的Person对象的name字段。
实现过程
package test;import java.util.Date;/** * @author 田茂林 * @data 2017年9月6日 下午9:46:42 */public class Person implements Cloneable { // 实现Cloneable接口,接口没有任何实现方法 private int age; private Date date = new Date(); public Date getDate() { return date; } @SuppressWarnings("deprecation") public void changeDate(){ this.date.setMonth(5); } public void setDate(Date date) { this.date = date; } @Override protected Object clone() { // 重写clone方法,注意是被保护方法 Person p = null; try { p = (Person) super.clone(); // 实现浅复制 } catch (CloneNotSupportedException e) { e.printStackTrace(); //这里要有异常捕获 } p.date = (Date) this.getDate().clone();// 实现深复制 return p; } public static void main(String[] args) { Person p = new Person(); Person p1 = (Person) p.clone(); p1.changeDate(); System.out.println("p="+p.age); System.out.println("p1="+p1.age); System.out.println("p="+p.getDate()); System.out.println("p1="+p1.getDate()); }}
运行结果
p=0p1=0p=Thu Sep 07 11:52:09 CST 2017p1=Wed Jun 07 11:52:09 CST 2017
可以看到改变里边日期的值,对原来的没影响
构造方法
定义
与类同名且没有返回值(返回值也不能为void),用来初始化对象的函数。
几条原则
构造方法可以被重载,一个构造方法可以通过this关键字调用另一个构造方法,this语句必须位于构造方法的第一行;
当一个类中没有定义任何构造方法,Java将自动提供一个缺省构造方法;只有在不显示声明构造方法时,系统才提供默认无参构造方法,也就是说系统不会总是提供,要看你提供没有。
子类通过super关键字调用父类的一个构造方法,也必须位于构造方法第一行,所以super和this不能共存 ;由于this函数指向的构造函数默认有super()方法,所以规定this()和super()不能同时出现在一个构造函数中。
当子类的某个构造方法没有通过super关键字调用父类的构造方法,通过这个构造方法创建子类对象时,会自动先调用父类的缺省构造方法如果子类既没有用super调用父类的构造方法,而父类中又没有无参的构造函数,则编译出错。父类有有参,必须用super调用,如果是多个有参,则子类构造方法任意选一个即可,如果只有一个那就选那个,父类如果无参,也可以用super,或者不用,则默认调用
使用与运行
构造函数在定义类对象(类实例化对象)时自动执行用来初始化对象,也就是new 的时候
修饰符的使用规定
构造方法不能被static、final、synchronized、abstract、native修饰,但可以被public、private(单例模式)、protected修饰 也可以不加任何修饰符表示相当于被default修饰;
构造方法不能被子类继承,所以用final修饰没有意义。
构造方法用于创建一个新的对象,不能作为类的静态方法,所以用static修饰没有意义。
对于synchronized关键字,构造函数每次都是new一个新对象,不存在多线程共享同一变量的问题,所以不需要同步。
native是方法修饰符,native方法是由另外一种语言(如C/C++,汇编等)实现的本地方法,因为在外部实现了方法,所以在 java代码中,就不需要声明了
构造函数是用来初始化对象的,声明为抽象函数没有意义。
使用范围与原则
构造方法不是类的成员方法;
构造方法不能被继承,只能被调用。
构造方法必须跟类名相同,普通的类方法能与类同名的,但是要返回一个值(或者有void)。
构造函数可以是内联函数
public class Justfuck { /* public Justfuck(int a) { // TODO Auto-generated constructor stub } public Justfuck(int a,int b) { // TODO Auto-generated constructor stub }*/}class A extends Justfuck{ A(){ } A(int b){ }}
类加载顺序(不包含子类)
public class B{ public static B t1 = new B(); public static B t2 = new B(); { System.out.println("构造块"); } static { System.out.println("静态块"); } public static void main(String[] args) { B t = new B(); }}构造块 构造块 静态块 构造块
1.程序入口main方法要执行首先要加载类B
2.静态域:分为静态变量,静态块。当执行到静态域时,按照静态域的顺序加载。并且静态域只在类的第一次加载时执行
3.每次new对象时,会执行一次构造块和构造方法,构造块总是在构造方法前执行(当然,第一次new时,会先执行静态域,静态域〉构造块〉构造方法) 注意:加载类时并不会调用构造块和构造方法,只有静态域会执行
4.根据前三点,首先加载类B,执行静态域的第一个静态变量,static b1=new B,输出构造块和构造方法(空)。ps:这里为什么不加载静态方法呢?因为执行了静态变量的初始化,意味着已经加载了B的静态域的一部分,这时候不能再加载另一个静态域了,否则属于重复加载 了(静态域必须当成一个整体来看待。否则加载会错乱) 于是,依次static b2 =new B,输出构造块,再执行静态块,完成对整个静态域的加载,再执行main方法,new b,输出构造块。
类加载顺序(包含子类)
(1) 父类静态代码块(包括静态初始化块,静态属性,按照出现顺序)
(2) 子类静态代码块(包括静态初始化块,静态属性,按照出现顺序 )
(3) 父类非静态代码块( 包括非静态初始化块(比非静态属性稍晚),非静态属性 )
(4) 父类构造函数
(5) 子类非静态代码块 ( 包括非静态初始化块(比非静态属性稍晚),非静态属性 )
(6) 子类构造函数
其中:类中静态块按照声明顺序执行,并且(1)和(2)不需要调用new类实例的时候就执行了(意思就是在类加载到方法区的时候执行的)
其次,需要理解子类覆盖父类方法的问题,也就是方法重写实现多态问题。
Base b = new Sub();它为多态的一种表现形式,声明是Base,实现是Sub类, 理解为 b 编译时表现为Base类特性,运行时表现为Sub类特性。
当子类覆盖了父类的方法后,意思是父类的方法已经被重写,题中 父类初始化调用的方法为子类实现的方法,子类实现的方法中调用的baseName为子类中的私有属性。
其它常识
包的创建和导入
package关键字
1, package语句必须作为源文件的第一条非注释性语句
2,一个源文件只能指定一个包,只能包含一条package语句
import关键字
import java.util.* ; 该语句能访问java/util目录下的所有类,不能访问java/util子目录下的所有类,记住:我的附庸的附庸不是我的附庸。
辅助理解:导入java.util.*不能读取其子目录的类,因为如果java.util里面有个a类,java.util.regex里面也有个a类,我们若是要调用a类的方法或属性时,应该使用哪个a类呢。
文件个数
(1) public权限类只能有一个(也可以一个都没有,但最多只有一个);
(2)这个.java文件名只能是public 权限的类的类名;
(3)倘若这个文件中没有public 类,则它的.java文件的名字是随便的一个类名;
(4)当用javac命令生成编译这个.java 文件的时候,则会针对每一个类(接口)生成一个.class文件(字节码文件);
java的编译和运行
后缀名
1 .class 编译后的Java文件
2 .java是未编译的程序
3 .jsp是页面程序
4 .xml配置程序
5 .jar是.calss的集合
6 .exe是可执行文件
编译
- javac 是编译命令,后跟 你的 Java 程序名字加后缀,也就是 YourClassName.java ,然后生成一份后缀为.class的字节码文件。当用javac命令生成编译这个.java 文件的时候,则会针对每一个类生成一个.class文件;
一个源程序文件中可以有多个类,如果没有public类,则源程序文件可以与任意类名相同,如果有public类则文件名必须与此类名相同,因为一个文件中只能有一个public类。如果文件中只有一个类,则文件名必须与类名相同
在Java中,环境变量可在编译source code时指定 , 在编译程序时,所能指定的环境变量包括classpath
javac一次可同时编译数个Java源文件 用javac *.java. 即可编译当前目录下的所有java文件
javac.exe能指定编译结果要置于哪个目录(directory)
运行
运行命令是 java + 你的 Java 程序的名字但是不加后缀, 也就是不加 .class这个后缀。java YourClassName
其它命令
1,javadoc用来生成api文档 。
2,jar用来生成jar包
可执行程序程序
javac.exe是编译.java文件
java.exe是执行编译好的.class文件
javadoc.exe是生成Java说明文档
jdb.exe是Java调试器
javaprof.exe是剖析工具
枚举类
可以把 enum 看成是一个普通的 class,它们都可以定义一些属性和方法,不同之处是:enum 不能使用 extends 关键字继承其他类,因为 enum 已经继承了java.lang.Enum(java是单一继承) 。枚举类中的每一个枚举值都会 调用一次构造函数
以下执行结果是什么:
enum AccountType{ SAVING, FIXED, CURRENT; private AccountType() { System.out.println(“It is a account type”); }}class EnumOne{ public static void main(String[]args) { System.out.println(AccountType.FIXED); }}
解析:类在后台实现时,实际上是转化为一个继承了java.lang.Enum类的实体类,原先的枚举类型变成对应的实体类型,上例中AccountType变成了个class AccountType,并且会生成一个新的构造函数,若原来有构造函数,则在此基础上添加两个参数,生成新的构造函数,如上例子中:
private AccountType(){System.out.println(“It is a account type”);}
变成
private AccountType(String s,inti){ super(s,i); System.out.println(“It is a account type”); }
而在这个类中,会添加若干字段来代表具体的枚举类型:
public static final AccountType SAVING;public static final AccountType FIXED;public static final AccountType CURRENT;
而且还会添加一段static代码段:
static{ SAVING =new AccountType("SAVING",0); FIXED =new AccountType("FIXED",0); CURRENT =new AccountType("CURRENT",0); $VALUES =newAccountType[]{ SAVING, FIXED, CURRENT } }
以此来初始化枚举中的每个具体类型。(并将所有具体类型放到一个$VALUE数组中,以便用序号访问具体类型)在初始化过程中new AccountType构造函数被调用了三次,所以Enum中定义的构造函数中的打印代码被执行了3遍。
J2EE常用名词
web容器:给处于其中的应用程序组件( JSP , SERVLET )提供一个环境,使 JSP,SERVLET 直接更容器中的环境变量接 ** 互,不必关注其它系统问 题。主要有 WEB 服务器来实现。例如: TOMCAT,WEBLOGIC,WEBSPHERE 等。该容器提供的接口严格遵守 J2EE 规范中的 WEB APPLICATION 标准。我们 把遵守以上标准的 WEB 服务器就叫做 J2EE 中的 WEB 容器。
EJB容器: Enterprise java bean 容器。更具有行业领域特色。他提供给运行在其中的组件 EJB 各种管理功能。只要满足 J2EE 规范的 EJB 放入该容 器,马上就会被容器进行高效率的管理。并且可以通过现成的接口来获得系统级别的服务。例如邮件服务、事务管理。
JNDI:( Java Naming & Directory Interface ) JAVA 命名目录服务。主要提供的功能是:提供一个目录系 ,让其它各地的应用程序在其上面留下自己的索引,从而满足快速查找和定位分布式应用程序的功能。
JMS:( Java Message Service ) JAVA 消息服务。主要实现各个应用程序之间的通讯。包括点对点和广播。
JTA:( Java Transaction API ) JAVA 事务服务。提供各种分布式事务服务。应用程序只需调用其提供的接口即可。
JAF:( Java Action FrameWork ) JAVA 安全认证框架。提供一些安全控制方面的框架。让开发者通过各种部署和自定义实现自己的个性安全控制 策略。
RMI/IIOP:( Remote Method Invocation /internet 对象请求中介协议)他们主要用于通过远程调用服务。例如,远程有一台计算机上运行一个 程序,它提供股票分析服务,我们可以在本地计算机上实现对其直接调用。当然这是要通过一定的规范才能在异构的系统之间进行通信。 RMI 是 JAVA 特有的。
Java程序的种类
Application–Java应用程序”是可以独立运行的Java程序。 由Java解释器控制执行。
Applet –Java小程序”不能独立运行(嵌入到Web页中)。 由Java兼容浏览器控制执行。
Serverlets –Java技术对CGI 编程的解决方案。 是运行于Web server上的、作为来自于Webbrowser 或其他HTTP client端的请求和在server上的数据库及其他应用程序之间的中间层程序。Serverlets的工作是:
1,读入用户发来的数据(通常在web页的form中,)
2,找出隐含在HTTP请求中的其他请求信息(如浏览器功能细节、请求端主机名等)
3, 产生结果(调用其他程序、访问数据库、直接计算)
4,格式化结果(网页) 设置HTTP response参数(如告诉浏览器返回文档格式) 将文档返回给客户端。
java的关键字与保留字
1,true ,false , null在java中不是关键字,也不是保留字,它们只是显式常量值,但是你在程序中不能使用它们作为标识符。
2,java中const和goto是java的保留字也是关键字。java中所有的关键字都是小写的,还有要注意true,false,null,friendly,sizeof不是java的关键字,但是你不能把它们作为java标识符用。
java关键字列表
Java 关键字列表 (依字母排序 共50组):
abstract, assert, boolean, break, byte, case, catch, char, class, const(保留关键字), continue, default, do, double, else,
enum, extends, final, finally, float, for, goto(保留关键字), if, implements, import, instanceof, int, interface, long, native, new, package, private, protected, public,return, short, static, strictfp, super, switch, synchronized, this, throw, throws, transient, try, void, volatile, while
java保留字列表
java保留字列表 (依字母排序共14组),Java保留字是指现有Java版本尚未使用,但以后版本可能会作为关键字使用:
byValue, cast, false, future, generic, inner,operator, outer, rest, true, var, goto(保留关键字) , const(保留关键字) , null
System.out.println();
System是java.lang中的一个类,out是System内的一个成员变量,这个变量是一个java.io.PrintStream类的对象,println呢就是一个方法了。
java常用包
1 java.lang:java的语言包,是一个核心包,系统自动将这个包引入到用户程序,该包中主要的类,object类,它是所有类的父类,其中定义的方法其它类都可以使用。数据类型包装类,数学类,字符串类,系统和运行时类,操作类,线程类,错误和异常处理类,过程类。System提供一个独立于具体计算机资源的编程界面,Runtime类可用于直接访问运行时资源。
2 java.util: java的实用包, 实用包提供了各种实用功能的类,主要包括日期类、数据结构类和随机数类等。
3 Java的java.awt提供了绘图和图像类,主要用于编写GUI程序,包括按钮、标签等常用组件以及相应的事件类。
4 java.io: 包含提供多种输出输入功能的类
5 java.net: 包含执行与网络有关的类,如URL,SCOKET,SEVERSOCKET
6 java.applet: 包含java小应用程序的类
Java提供的事件处理模型
Java提供的事件处理模型是一种人机交互模型。它有三个基本要素:
1) 事件源(Event Source):即事件发生的场所,就是指各个组件,如按钮等,点击按钮其实就是组件上发生的一个事件;
2)事件(Event):事件封装了组件上发生的事情,比如按钮单击、按钮松开等等;
3) 事件监听器(Event Listener):负责监听事件源上发生的特定类型的事件,当事件到来时还必须负责处理相应的事件;
- 【Java面试】---Java基础知识
- java面试基础知识
- java面试基础知识
- java基础知识(面试)
- java笔试面试基础知识
- JAVA面试基础知识
- JAVA程序员面试基础知识
- java程序员面试基础知识
- 【面试】-Java基础知识
- java面试基础知识
- Java面试基础知识提纲
- 【Java面试】基础知识篇
- java面试基础知识#多线程
- java基础知识面试要点
- java工程师基础知识面试
- java面试基础知识
- java面试资料-基础知识
- 面试-java基础知识
- 用C语言编写简易计算器
- 向ElasticSearch批量导入数据
- Android 美团批量打包新方案
- Build设计模式
- 如何对网站关键词进行合理布局?
- 【Java面试】---Java基础知识
- 使用Fiddler做抓包分析
- 18、DuplicateFileException: Duplicate files copied in APK META-INF/INDEX.LIST
- 前端碰到的问题
- syslog-ng 通过pipe写数据到mysql
- Java SE、Java EE、Java ME三者的区别
- C++ 类型转换函数 与 explicit
- 图片加载失败或默认图片
- 微信小程序从注册到上线系列