Java概述:
目前Java主要应用于中间件的开发(middleware)---处理客户机于服务器之间的通信技术,早期的实践证明,Java不适合pc应用程序的开发,其发展逐渐变成在开发手持设备,互联网信息站,及车载计算机的开发.Java于其他语言所不同的是程序运行时提供了平台的独立性,称许可以在windows,solaris,linux其他操作系统上使用完全相同的代码.Java的语法与C++语法类似,C++/C程序员很容易掌握,而且Java是完全的彻底的面向对象的,其中提出了很好的GC(Garbage Collector)垃圾处理机制,防止内存溢出。
Java11个关键特质。
(1)Easy:Java的语法比C++的相对简单,另一个方面就是Java能使软件在很小的机器上运行,基础解释其和类库的支持的大小约为40kb,增加基本的标准库和线程支持的内存需要增加125kb。
(2)分布式:Java带有很强大的TCP/IP协议族的例程库,Java应用程序能够通过URL来穿过网络来访问远程对象,由于servlet机制的出现,使Java编程非常的高效,现在许多的大的web server都支持servlet。
(3)OOP(Object Oriented Programming):面向对象设计是把重点放在对象及对象的接口上的一个编程技术.其面向对象和C++有很多不同,在与多重继承的处理及Java的原类模型。
(4)健壮特质:Java采取了一个安全指针模型,能减小重写内存和数据崩溃的可能型。
(5)安全:Java用来设计网路和分布系统,这带来了新的安全问题,Java可以用来构建防病毒和防攻击的System.事实证明Java在防毒这一方面做的很优秀。
(6)中立体系结构:Java编译其生成体系结构中立的目标文件格式可以在很多处理器上执行,编译器产生的指令字节码(Javabytecode)实现此特性,此字节码可以在任何机器上解释执行。
(7)可移植:Java中对基本数据结构类型的大小和算法都有严格的规定所以可移植很好。
(8)多线程:Java处理多线程的过程很简单,Java把多线程实现交给底下操作系统或线程程序完成.所以多线程是Java作为服务器端开发语言的流行原因之一。
(9)Applet和servlet:能够在网页上执行的程序叫Applet,需要支持Java的浏览器很多,而applet支持动态的网页,这是很多其他语言所不能做到的。
搬砖而来的30个基本概念(粗略的30个):
1.OOP中唯一关心的是对象的接口是什么所有的程序是由一定的属性和行为对象组成的,不同的对象的访问通过函数调用来完成,对象间所有的交流都是通过方法调用,通过对封装对象数据,很大限度上提高复用率。
2.OOP中最重要的思想是类,类是模板从类中构造一个对象,即创建了这个类的一个实例(instance)。
3.封装:就是把数据和行为结合起在一个包中并对对象使用者隐藏数据的实现过程,一个对象中的数据叫他的实例字段(instance field)。
4.继承:通过扩展一个类来获得一个新类叫继承(inheritance),而所有的类都继承Object类。
5.对象的3个主要特点
behavior---说明这个对象能做什么.
state---当对象施加方法时对象的反映.
identity---与其他相似行为对象的区分标志.
每个对象有唯一的indentity 而这3者之间相互影响.
6.类之间的关系:
use-a : 依赖关系
has-a : 聚合关系
is-a : 继承关系(个性存在于共性中)
7.构造对象使用构造器:构造器的提出,构造器是一种特殊的方法,构造对象并对其初始化。
构造器特点: 0或多个参数
与类名相同
一个类可以有多个构造器
没有返回值
总是和new运算符一起使用.
8.重载:方法同名不同参.编译器必须挑选出调用哪个方法。
9.包(package):Java允许把一个或多个类收集在一起成为一组,称作包,以便于组织任务,标准Java库分为许多包.java.lang java.util java,net等,包是分层次的所有的java包都在java和javax包层次内。
10.继承思想:在已经存在的类的基础上继承新的类,新类继承原类的属性和行为,并可以添加新的属性和行为。
11.扩展类:扩展类充分体现了is-a的继承关系. 形式为:class (子类) extends (基类)。
12.多态:java中单继承,多态。
13.动态绑定:调用对象方法的机制。
(1)编译器检查对象声明的类型和方法名。
(2)编译器检查方法调用的参数类型。
(3)静态绑定:若方法类型为priavte static final 编译器会准确知道该调用哪个方法。
(4)当程序运行并且使用动态绑定来调用一个方法时,那么虚拟机必须调用x所指向的对象的实际类型相匹配的方法版本。
(5)动态绑定:是很重要的特性,它能使程序变得可扩展而不需要重编译已存代码。
14.final类:不能被继承。
15.动态调用比静态调用花费的时间要长。
16.抽象类:具有abstract方法的类必须为抽象类。
17.Java中的每一个类都是从Object类扩展而来的。
18.object类中的equal和toString方法。
equal用于测试一个对象是否同另一个对象相等。
toString返回一个代表该对象的字符串,几乎每一个类都会重载该方法,以便返回当前状态的正确表示.
19.通用编程:任何类类型的所有值都可以同object类型的变量来代替(new的对象都可以上升到Object对象)。
20.数组列表:ArrayList动态数组列表,是一个类库,定义在java.uitl包中,可自动调节数组的大小。
21.class类 object类中的getclass方法返回class类型的一个实例,程序启动时包含在main方法的类会被加载,虚拟机要加载他需要的所有类,每一个加载的类都要加载它需要的类。
22.class类为编写可动态操纵java代码的程序提供了强大的功能反射,这项功能为JavaBeans特别有用,使用反射Java能支持VB程序员习惯使用的工具。
能够分析类能力的程序叫反射器,Java中提供此功能的包叫Java.lang.reflect反射机制十分强大.
1.在运行时分析类的能力。
2.在运行时探察类的对象。
3.实现通用数组操纵代码。
4.提供方法对象。
而此机制主要针对是工具者而不是应用及程序。
反射机制中的最重要的部分是允许你检查类的结构.用到的API有:
java.lang.reflect.Field 返回字段.
java.reflect.Method 返回方法.
java.lang.reflect.Constructor 返回参数.
方法指针:java没有方法指针,把一个方法的地址传给另一个方法,可以在后面调用它,而接口是更好的解决方案。
23.接口(Interface)说明类该做什么而不指定如何去做,一个类可以实现一个或多个interface。
24.接口不是一个类,而是对符合接口要求的类的一套规范。
若实现一个接口需要2个步骤:
1.声明类需要实现的指定接口。
2.提供接口中的所有方法的定义。
声明一个类实现一个接口需要使用implements 关键字
25.类可以单继承多实现。Java中的一个重要接口:Cloneable
26.接口和回调.编程一个常用的模式是回调模式,在这种模式中你可以指定当一个特定时间发生时回调对象上的方法。
例:ActionListener 接口监听.
类似的API有:java.swing.JOptionPane
java.swing.Timer
java.awt.Tookit
27.对象clone:clone方法是object一个保护方法,这意味着你的代码不能简单的调用它。
28.内部类:一个内部类的定义是定义在另一个内部的类。
原因是:
1.一个内部类的对象能够访问创建它的对象的实现,包括私有数据。
2.对于同一个包中的其他类来说,内部类能够隐藏起来。
3.匿名内部类可以很方便的定义回调。
4.使用内部类可以非常方便的编写事件驱动程序。
29.代理类(proxy):
1.指定接口要求所有代码
2.object类定义的所有的方法(toString equals)
30.数据类型:Java是强调类型的语言,每个变量都必须先申明它都类型,四类八种--> byte short int long char boolean float double。
31.简述String类中的equals方法与Object类中的equals方法的不同点。
String类 --> 将字符串与指定字符串比较,如果仅当参数不是null,且字符串相同时,才返回true
Object类--> 将对象与指定对象进行比较,引用相同对象时才会返回true
所谓同一个对象指的是内存中的同一块存储空间。
32.简述StringBuilder类与String类的区别。
String类--> 内容不可改变,所以每当进行字符串拼接时,总是会在内存中创建一个新的对象,所以经常改变内容的字符串最好不要用String,因为每次生成对象都会对系统性能产生影响。
StringBuilder--> 又称为可变字符序列,是JDK5.0中新增加的一个类,它是一个类似于String的字符串缓冲区,通过某些方法调用可以改变该序列的长度和内容。即它是一个容器,容器中可以装很多字符串,并且能够对其中的字符串进行各种操作。
--> StringBuilder 的内部拥有一个数组用来存放字符串内容,进行字符串拼接时,直接在数组中加入新内容,StringBuilder会自动维护数组的扩容。
集合概念
33.简述集合框架。
集合按照其存储结构可以分为两大类,分别是单列集合java.util.Collection和双列集合java.util.Map。
Collection:单列集合类的根接口,(元素孤立存在,采取单独存储方式), 用于存储一系列符合某种规则的元素,它有两个重要的子接口,分别是java.util.List和java.util.Set。
List的特点是元素有序、元素可重复 --> 实现类有java.util.ArrayList和java.util.LinkedList,
Set的特点是元素无序,而且不可重复 --> 实现类有java.util.HashSet和java.util.TreeSet。
Map: 双列集合类的根接口, 元素成对存在,每个元素有key和value两部分组成 , 不包含重复的键,但是可以包含重复的值
HashMapM
LinkedHashMap
34.简述迭代器的实现原理
当遍历集合时,首先通过调用集合的iterator()方法获得迭代器对象,然后使用hashNext()方法判断集合中是否存在下一个元素,如果存在,则调用next()方法将元素取出,否则说明已到达了集合末尾,停止遍历元素。
Iterator迭代器对象在遍历集合时,内部采用指针的方式来跟踪集合中的元素,在调用Iterator的next()方法之前,迭代器的索引位于第一个元素之前,不指向任何元素,当第一次调用迭代器的next方法后,迭代器的索引会向后移动一位,指向第一个元素并将该元素返回,当再次调用next方法时,迭代器的索引会指向第二个元素并将该元素返回,依此类推,直到hasNext方法返回false,表示到达了集合的末尾,终止对元素的遍历。
35.简述List接口的特点。
它是一个元素存取有序的集合。例如,存元素的顺序是11、22、33。那么集合中,元素的存储就是按照11、22、33的顺序完成的)。
它是一个带有索引的集合,通过索引就可以精确的操作集合中的元素(与数组的索引是一个道理)。
集合中可以有重复的元素,通过元素的equals方法,来比较是否为重复的元素。
36.HashSet集合特点
1.不能保证元素的排列顺序,顺序有可能发生变化
2.HashSet不是同步的,如果多个线程同时访问一个Set集合,必须通过代码保证其同步
3.集合元素值可以使null
主要依赖hashCode和equals方法进行元素重复判断
哈希表中如何判断元素的唯一性
1.先对比两个对象的哈希值,
如果哈希值不同,肯定不是同一个对象
如果哈希值相同,不一定是同一个对象
2.如果哈希值相同,还会继续调用equals方法进行判断
如果equals相同,是同一个对象
如果equals不同,不是同一个对象
36.请简述HashSet去除重复元素的原理。
调用被添加元素的hashCode(),和HashSet中已有元素的hashCode比较是否相同
如果不相同,直接存储
如果相同,调用equals方法比较是否相同
不相同,直接存储元素
相同,认为是同一元素.不存储
37.简述Comparable和Comparator两个接口的区别。
Comparable:强行对实现它的每个类的对象进行整体排序。这种排序被称为类的自然排序,类的compareTo方法被称为它的自然比较方法。只能在类中实现compareTo()一次,不能经常修改类的代码实现自己想要的排序。实现此接口的对象列表(和数组)可以通过Collections.sort(和Arrays.sort)进行自动排序,对象可以用作有序映射中的键或有序集合中的元素,无需指定比较器。
Comparator: 强行对某个对象进行整体排序。可以将Comparator 传递给sort方法(如Collections.sort或 Arrays.sort),从而允许在排序顺序上实现精确控制。还可以使用Comparator来控制某些数据结构(如有序set或有序映射)的顺序,或者为那些没有自然顺序的对象collection提供排序。
39.请简述Map 的特点。
Map每个元素由键与值两部分组成
Map键不能重复,每个键对应一个值
键和值可以为null
40.说出Entry键值对对象遍历Map集合的原理。
Map中存放的是两种对象,一种称为key(键),一种称为value(值),它们在在Map中是一一对应关系,这一对对象又称做Map 中的一个Entry(项)。Entry将键值对的对应关系封装成了对象。即键值对对象,这样我们在遍历Map集合时,就可以从每一个键值对(Entry)对象中获取对应的键与对应的值。
41final/finally/finalize的区别
fianl:
final修饰类不能被继承,修饰方法不能被重写,修饰变量只能赋值一次
finally是try语句中的一个语句体,不能单独使用,用来释放资源
finalize:
是一个方法,当垃圾回收期不存在对该对象的更多饮用时,垃圾回收期调用此方法
finally-->如果catch里面有return语句,finally会执行,return建立返回路径,处理finally后再返回
42.问题:
请描述异常的继承体系
请描述你对错误(Error)的理解
请描述你对异常(Expection的理解)
请描述你对运行时异常(RuntimeException)的理解
答:
异常继承体系为:异常的根类是 java.lang.Throwable,其下有两个子类:
java.lang.Error 与 java.util.Exception 。而Exception又分为编译时期异常:checked异常,与运行时期异常:runtime异常。
Error:表示不可修复的恶性的错误,只能通过修改代码规避错误的产生,通常是系统级别的,所以很严重。
Exception:表示可修复的良性(相对于错误)的异常,异常产生后程序员可以并且应该通过代码的方式纠正,使程序继续运行,是必须要处理的。
运行时期异常:runtime异常。在运行时期,检查异常.在编译时期,运行异常不会编译器检测(不报错)。
43.throw和throws区别
throw:
用在方法体内,跟的是异常类名
只能抛出一个异常对象名
表示抛出异常,由方法体内的语句处理
程序运行到throw语句时立即停止,他后面的语句都不执行
throws:
用在方法声明后面,跟的是异常类名
可以跟多个异常类名,用逗号隔开
表示抛出多个异常,由该方法的调用者来处理
44.如何使用异常处理
原则
如果该功能内部可以将问题处理,用try,如果处理不了,交由调用者处理,用throws
区别
后续程序需要继续运行就try
后续程序不需要继续运行就throws
45.问题:
1. 异常处理方式有几种,分别是什么?
2. 详细阐述每种方式对异常是如何处理的
答:
1. 异常的处理方式有两种,分别是使用throws和try...catch...finally
2. throws用在方法的声明上后接异常类名,是把异常抛给调用者进行处理
3. try...catch...finally是捕获异常,自己处理,处理完毕后面的程序可以继续运行
a) try代码块中是可能出现异常的代码
b) catch代码块,是遇到异常,对异常进行处理的代码
c) finally代码块是无论是否发生异常,都必须执行的代码,用于释放资源.
46.问题:请简单描述什么是并行,什么是并发?
答:
并行:指两个或多个事件在同一时刻发生(同时发生)。
并发:指两个或多个事件在同一个时间段内发生。
47.进程&线程定义和区别
进程 ==> 定义: 正在运行的应用程序(程序的执行过程 --> 系统运行程序的基本单位)
-->系统运行一个程序即是一个进程创建/运行/消亡的过程
特点: 独立的内存空间 --> 该内存空间内有多个线程
--> 一个应用程序可以同时运行多个进程(至少包含一条线程)
--> 有独立的内存空间,进程中的数据存放空间(Heap & Stack),是独立的,至少有一个线程
线程==> 定义: 进程内部的一个独立执行单元,一个线程对应一个任务
特点:
--> 一个进程可以同时并发的运行多个线程
--> 线程是由CPU调度执行的,同一个时间点,CPU只能去调度执行一个线程(CPU在多个线程之间频繁快速切换因为速度很快,所以可以看成同时)
--> 一个进程相当于单CPU操作系统,线程便是这个系统中运行的多个任务
--> 堆空间是共享的,栈空间是独立的,线程消耗的资源比进程小的多
45.java程序运行原理:
--> java命令会启动jvm.等于启动了一个应用程序,即进程,该进程自动启动一个主线程,主线程就会调用某个类的main方法
46.java中进程及线程运行
1.进程中多个线程并发运行--> 有先后顺序,取决于CPU的调度,程序员无法干涉,造成多线程的随机性
2.Java程序的进程里至少包含2个线程,主进程main方法线程 + 垃圾回收机制线程
3.单线程程序只能同时执行一个任务,如果有多个任务,只能执行完成其中一个后再执行另外一个任务
--> 可以使用多线程
4.由于创建一个线程的开销比创建一个进程的开销小很多,通常考虑多线程
47.&和&&的区别
&运算符有两种:1.按位与;2逻辑与.&&运算符是短路与运算,逻辑与跟短路与的差别是非常巨大的,虽然二者都要求运算符左右的布尔值都是true整个表达式的值才是true.&&之所以称为短路运算是因为,如果&&左边的表达式的值是false,右边的表达式会被直接短路掉,不会进行运算.很多时候我们可能都需要用&&而不是&,例如在验证用户登录时判定用户名不是null而且不是空字符串,应当写为: username != null && !username.equals(),二者的顺序不能交换,更不能用&运算符,因为第一个条件如果不成立,根本不能进行字符串的equals比较,否则会产生NullPointerException异常.注意:逻辑或和短路运算符的差别也是如此
48.值传递和引用传递
值传递是对基本型变量而言的,传递的是该对象地址的一个副本,改变副本不影响原变量.引用传递一般是对于对象型变量而言的,传递的是该对象地址的一个副本,并不是原对象本身.一般认为,java内的传递都是值传递,java中实例对象的传递时引用传递
49.是否可以在static环境中访问非static变量?
static变量在java中是属于类的,它在所有的实例中的值是一样的.当类被java虚拟机载入的时候,会对static变量进行初始化.如果你的代码尝试不用实例来访问static的变量,编译器会报错,因为这些变量还没有被创建出来,还没有跟任何实例关联上.
50.集合框架中的泛型有什么优点?
java1.5引入了泛型,所有的集合接口和实现都大量地使用它.泛型允许我们为集合提供一个可以容纳的对象类型,因此,如果你添加其他类型的任何元素,他会在编译时报错,这避免了在运行时出现ClassCastException,因为你将会在编译时得到报错信息.泛型也使得代码整洁,我们不需要使用显示转换和instanceOf操作符.它也给运行时带来好处,因为不会产生类型检查的字节码指令.
51.为何Map接口不继承Collection接口?
尽管Map接口和他的实现也是集合框架的一部分,但Map不是集合,集合也不是Map.因此,Map继承Collection毫无意义,反之亦然.如果Map继承Collection接口,那么元素取哪?map包含key-value对,它提供抽取key或value列表集合的方法,但是它不适合一组对象规范.
52.快速失败和安全失败的区别是什么?
快速失败:当你在迭代一个集合的时候,如果有另一个线程正在修改你正在访问的哪个集合时,就会抛出一个ConcurentModification异常.
在java.util包下的都是快速失败
安全失败: 在迭代的时候会去底层集合做一个拷贝,所以你在修改上层集合的识货是不会受到影响的,不会抛出异常.
在java.util.conturent包下的全是安全失败的.
52.Thread类中的start()和run()方法的区别
线程对象调用run方法不开启线程,仅是对对象调用方法.
线程对象调用start方法开启线程,并让jvm调用run方法在开启的线程中执行
53.实现Runnable接口的优势
1.适合多个相同的程序到吗的线程去共享同一个资源
2.可以避免java中的单继承的局限性
3.增加程序的健壮性,实现解耦操作,代码可以被多个线程共享,代码和数据独立
4.线程池只能放入实现Runnable或acllable类线程,不能直接放入继承Thread的类
54.线程状态
new Runnable waiting() timed-waiting blocked teminated
7/14/18
55.Java中的方法覆盖Overriding和方法重载Overloading是什么意思?
Java中的方法重载发生在同一个类里面两个或多个方法的方法名相同,但是参数不同的情况.
方法覆盖是说子类重新定义了父类的方法.,方法覆盖必须有相同的方法名/参数列表/返回类型,覆盖着不能限制它所覆盖的方法的访问.
56.Java中,什么是构造方法?构造方法重载?复制构造方法?
当新对象被创建的时候,构造方法会被调用.每一个类都有构造方法.且Java编译器会为这个类创建一个默认的构造方法.
Java中构造方法重载和方法重载很相似.可以为一个类创建多个构造方法.每个构造方法必须有它自己唯一的参数列表
Java不支持赋值构造方法,如果不写构造方法,Java不会创建默认的复制构造方法
57.Java支持多继承么?
Java中类不支持多继承,只支持单继承,但是接口支持多继承
接口用来扩展对象的功能,子接口可以扩展多个功能
58.解释内存中的stack/heap/method area的用法
stack: 一个基本数据类型/对象的引用/函数调用的现场
heap: new关键字和构造器创建的对象 --> 堆是垃圾回收器的主要管理区域,由于现在的垃圾收集器都采用分代收集算法,所以heap还可以分为新生代和老生代
方法区和堆都是各各线程共享的内存区域,用于存储已经被JVM加载的类信息,常量.静态变量.jit编译后的代码等数据
程序中的字面量 --> 放在常量池中 常量池是方法区的一部分
(栈小堆大,通常大量的存放在堆中,栈和堆的大小都可以通过JVM启动参数来进行调整)
栈异常 --> StackOverflowError
堆和常量池 --> OutOfMemoryError
59.接口和抽象类的区别?
从设计层面来说,抽象是对类的抽象,是一种模板设计,接口是行为的抽象,是一种行为的规范。
Java提供和支持创建抽象类和接口。它们的实现有共同点,不同点在于:
接口中所有的方法隐含的都是抽象的。而抽象类则可以同时包含抽象和非抽象的方法。
类可以实现很多个接口,但是只能继承一个抽象类
类可以不实现抽象类和接口声明的所有方法,当然,在这种情况下,类也必须得声明成是抽象的。
抽象类可以在不提供接口方法实现的情况下实现接口。
Java接口中声明的变量默认都是final的。抽象类可以包含非final的变量。
Java接口中的成员函数默认是public的。抽象类的成员函数可以是private,protected或者是public。
接口是绝对抽象的,不可以被实例化。抽象类也不可以被实例化,但是,如果它包含main方法的话是可以被调用的。
60.常量池在不同版本的jdk中的内存位置
7/16/18
61.flush和close的区别
flush: 刷新缓存,刷新后仍然可以继续写入
close: 关闭流,关闭后不能继续写入
62.字节流为什么返回值使用int接受
因为,字节输入流可以操作任意类型的文件,若每次都返回byte,有可能在读到中间的时候遇到11111111,即 -1 -->所以int接受,在前面补上24个0满足4字节,那么结束标记的-1就为int型
63.字符流使用场景
字符流可以拷贝文件,但不推荐使用
--> read时将字节转换为字符,.write时将字符转换为字节
--> 程序需要读取一段文本,或者写出一段文本的时候可以使用字符流
--> 读取的时候是按照字符的大小读取的,不会出现半个中文
--> 写出的时候可以直接将字符串写出,不用转换为字节数组
拷贝非文本文件???
--> 因为在读的时候会将字节转换为字符,可能找不到对应的字符,就会用?代替,写出的时候会将字符转换成字节写出去
--> 如果是?直接写出,这样,文件就乱了