目录
基础语法与算法a++ 与 ++a的区别?&和&&的区别说说jvmGC是什么? 为什么要有GC?数组有没有length()这个方法?String有没有length()这个方法?面向对象什么是多态?Integer封装类可以被继承吗?String可以被继承吗?int 和 Integer有什么区别?extends和implements区别构造器Constructor是否可被override?接口是否可以继承接口?抽象类是否可实现(implements)接口?抽象类是否可继承具体类(concrete class)?抽象类中是否可以有静态的main方法?类的加载机制(类加载机制)据下方代码,写出打印结果:(类加载机制)查看如下代码,写出打印结果:请简述面向对象的一些基本概念java中的常用类,不少于6个?集合List, Set, Map是否继承自Collection接口?HashMap的数据结构 存放数据的机制和扩容问题谈谈HashSet的存储原理list和map的应用场景常用集合的的底层实现?Map怎么实现有序Set和Map的底层hashmap和hashtable的区别?Collections vs CollectionList vs Set集合的工具类有哪些?如何实现集合排序?不使用工具类的话怎么排序?ArrayList vs LinkedListSet vs MapConcurrentHashMap vs HashMap vs LinkedHashMapIO流与异常运行时的异常和一般异常有什么异同?try-catch中return和finally哪个优先执行请说出常见的运行异常有用过NIO吗?NIO的优点在哪里?NIO是什么他跟IO有什么区别?多线程,网络编程线程池有没有用过,怎么用的,在哪里用的?SimpleDataFormat是线程安全的吗?启动一个线程用的是start()还是run()?sleep()和wait()有什么区别?谈谈创建多线程的方式谈谈你对线程安全的理解?如何解决线程的安全问题?Synchronized加在普通方法和静态方法的区别同步代码块和同步方法的区别谈谈线程的生命周期谈谈对线程池的理解?jdk提供了哪几种线程池?他们有什么区别?对多线程的了解?在什么地方使用到过多线程?是否有用过线程池?用的什么线程池?UDP和TCP的区别网络的分层什么是tcp协议Http和Https的区别Http的报文里有什么反射与解析解析XML有几种方式反射你是怎么理解的?编程题请写出下面代码的运行结果给定一个不重复的自然数数组{3,5,9,7,4,13,15,0,2,20},已知其最大值20,请将其按从小到大的方式顺序输出,要求算法复杂度为1对于1-100范围内的整数I(包括100),找出满足I,I+4,I+10(I+10也在100范围)都是素质的整数I,计算这样I的个数cnt和这些整数的和sum用java代码找出A数组中不存在于B数组的项,例如:A[1,2,3],B[4,2]单例具体实现请在如下函数体中补充完成代码,实现根据输入字符串返回该字符串的倒序形式。如输入“ABC”返回“CBA”。下面的程序代码输出的结果是多少?写一个函数,2 个参数,1 个字符串,1 个字节数,返回截取的字符串,要求字符串中的中文不能出现乱码:如(“我ABC”,4)应该截为“我AB”,输入(“我ABC 汉DEF”,6)应该输出为“我ABC”而不是“我ABC+汉的半个”。给定的一个文件“a.txt”,找出所有符合“Japanes”字符串的个数,并修改为“Japanese”智力题
基础语法与算法
a++ 与 ++a的区别?
a++: 后置自增,先计算表达式的值,变量值后+1
++a: 前置自增,变量值先+1,再计算表达式的值
&和&&的区别
&有两个用法:
- 第一个是作为逻辑运算符使用,被当成逻辑运算符时有一个非短路的特性,即当第一个操作数为false,那么第二个操作数仍然执行。
- 第二个是作为位运算符使用。
&&只有一个用法:
- 只能作为逻辑运算符使用,和&的区别在于&&有一个短路的特点,即当第一个操作数为false时(因为这个时候已经可以确定表达式的最终结果已经是false),那么第二个操作数不会执行。
***说说jvm
jvm: java虚拟机,
用法1:可以将字节码解释成不同平台都能识别的指令
用法2:在jvm中的垃圾回收机制,可以自动回收系统中的无用内存
***GC是什么? 为什么要有GC?
GC为垃圾回收器,系统中开辟了大量空间,当这些空间无用时,可通过GC进行释放;提高系统执行性能
数组有没有length()这个方法?String有没有length()这个方法?
数组没有length()方法,只有length属性;
String有length()方法;
面向对象
什么是多态?
概念:多态是面向对象的基本特征之一。在java中一个对象的类型可以分为两种,即编译时类型与运行时类型。当一个对象的编译时类型和运行时类型不相同的时候,就发生了所谓的多态。
理解:换句话说,在Java中用一个父类(父接口)的变量指向之类的对象时,就发生了多态。比如 A a = new B(), 其中A是B的父类或者父接口。为什么会有这样的特性?为什么不是子类的变量指向父类的对象?我们可以换一个生活中的例子来理解。比如现在想要一个动物,先声明一个动物的变量:
Animal a;
但是在实际生活中,根本没有一个具体的物种叫动物,所以其实我们需要创建的一个具体的动物的对象,比如狗(动物是狗的父类):
new Dog();
最后将一条狗给与正需要一个动物的‘你’是一个非常合理的行为:
Animal a = new Dog();
反过来却不成立,同样也不合理,你没办法把随便一个动物给一个正需要狗的人。
作用:多态在面向对象编程中有着非常重要的作用。很多架构搭建,设计模式都使用到了多态的特性。多态的最大作用在于,使用一个父类的变量调用方法时,本质上调用的是子类的重写方法。换而言之,让一个Animal a执行 ‘叫喊’的行为,本质上我们听到的应该是“旺、旺、旺”,因为这个动物其实是Dog。这个特点让多态广泛的运用在架构与程序设计之中,极大的增强了程序的拓展性与维护性。
Integer封装类可以被继承吗?
不能,因为它是final修饰的类。
sun在设计Integer类时添加了final关键字,意为不让其他人随意的拓展和覆盖Integer本来的行为方法。这么设计的作用在于Integer是int类型的包装类,是对基本类型在面向对象的一个补充,很多基础类和第三方的工具类大量引用了这个类型的变量。如果随意覆盖本来的方法会导致这些基础类无法达到预想的结果,从而破坏了底层的实现效果(比如破坏了自动装箱和自动拆箱)。这是sun公司不愿意看到的。如果要对Integer有任何拓展,完全可以通过自定义一个类对Integer进行封装来实现,无需继承。
String可以被继承吗?
不能,同上
int 和 Integer有什么区别?
int为基本类型,Integer为引用类型。
Integer是int类型的包装类,对于int类型在面向对象中的补充。在很多时候没办法直接使用int基本类型,这个时候就需要用到Integer了,比如泛型时,是不能填写基本类型的,必须使用包装类。另外在很多实体类的设计时,通常也是使用包装类,因为包装类可以直接复制为null,而基本类型必须根据不同的基本类型赋予不同的值,操作起来会更加麻烦。
extends和implements区别
implements: 用于实现一个接口
extends: 用于继承一个类
注意:当一个接口需要继承另一个接口时,需要用到extends关键字,而且接口继承多个接口。
构造器Constructor是否可被override?
构造器Constructor不能被继承,因此不能重写,但可以被重载。
接口是否可以继承接口?抽象类是否可实现(implements)接口?抽象类是否可继承具体类(concrete class)?抽象类中是否可以有静态的main方法?
- 接口可以继承接口,而且接口继承多个接口
- 抽象类可以实现接口
- 抽象类可以继承具体类
- 抽象类中可以有静态main方法
类的加载机制
什么是类加载机制? 在一个java程序运行时,虚拟机并不会立刻将这个程序所有的类信息加载到内存中,而是在这个类第一次被使用时进行加载。将一个类加载到虚拟机内存中的过程称为类加载机制。 注意:一个类在一条JVM进程中只会被加载一次。
类加载的步骤 类加载可以大致分成3个步骤,分别是:
-
- 声明静态Field时指定初始值;
- 使用静态初始化块为静态Field指定初始值;
- 验证:验证是连接阶段的第一步,这一阶段的目的是为了确保Class文件的字节流中包含的信息符合当前虚拟机的要求,并且不会危害虚拟机自身的安全。
- 准备:准备阶段是正式为类变量分配内存并设置类变量初始值的阶段,这些变量所使用的内存都将在方法区中进行分配。这时候进行内存分配的仅包括类变量(被static修饰的变量),而不包括实例变量,实例变量将会在对象实例化时随着对象一起分配在堆中。其次,这里所说的初始值“通常情况”下是数据类型的零值
- 解析: 解析阶段是虚拟机将常量池内的符号引用替换为直接引用的过程。解析动作主要针对类或接口、字段、类方法、接口方法、方法类型、方法句柄和调用点限定符7类符号引用进行。 - 通过一个类的全限定名来获取定义此类的二进制字节流(并没有指明一定要从一个Class文件中获取,可以从其他渠道,譬如:网络、动态生成、数据库等,不同的渠道可以使用不同的类加载器); - 将这个字节流所代表的静态存储结构转化为方法区的运行时数据结构; - 在堆内存中生成一个代表这个类的java.lang.Class对象,作为方法区这个类的各种数据的访问入口;
-
加载阶段 在加载阶段需要用到类加载器(ClassLoader类),虚拟机需要完成以下3件事情:
-
连接阶段 连接阶段和加载阶段是交叉进行的,可能加载阶段还没有完成,连接阶段已经开始,但是加载和连接的开始顺序是固定不变的。连接阶段又可以拆分成3个阶段:
-
初始化阶段 在类的初始化阶段,JVM负责对类进行初始化,主要是对静态Field初始化。 对静态Field初始化分两种:
初始化顺序会按照源码的编写顺序执行。 - 创建类的实例。(new关键字、反射、反序列化等等)
- 访问类中的某个静态成员
- 使用反射方式强制创建某个类对应的Class对象。比如:Class.forName(“包名.类名”);
- 加载某个类的子类
- 直接使用java.exe命令运行某个主类,当运行某个主类时,程序会先加载该主类
类的加载的时机
当碰到以下几种情况时会触发一个类被加载进虚拟机内存中:
(类加载机制)据下方代码,写出打印结果:
public class SSClass
{
static
{
System.out.println("SSClass");
}
}
public class SuperClass extends SSClass
{
static
{
System.out.println("SuperClass init!");
}
public static int value = 123;
public SuperClass()
{
System.out.println("init SuperClass");
}
}
public class SubClass extends SuperClass
{
static
{
System.out.println("SubClass init");
}
static int a;
public SubClass()
{
System.out.println("init SubClass");
}
}
public class NotInitialization
{
public static void main(String[] args)
{
System.out.println(SubClass.value);
}
}
结果:
SSClass
SuperClass init!
123
原因:
对于静态字段,只有直接定义这个字段的类才会被初始化,因此通过其子类来引用父类中定义的静态字段,只会触发父类的初始化而不会触发子类的初始化。
(类加载机制)查看如下代码,写出打印结果:
package jvm.classload;
public class StaticTest
{
public static void main(String[] args)
{
staticFunction();
}
static StaticTest st = new StaticTest();
static
{
System.out.println("1");
}
{
System.out.println("2");
}
StaticTest()
{
System.out.println("3");
System.out.println("a="+a+",b="+b);
}
public static void staticFunction(){
System.out.println("4");
}
int a=110;
static int b =112;
}
结果: 2 3 a=110,b=0 1 4
请简述面向对象的一些基本概念
- 封装:将类的属性私有化,使用方法进行封装来获取设置和获取属性值
- 继承:子类继承父类,可使用父类的属性和方法; 另一大特性:重写
- 多态:父类对象指向子类对象,可以调用子类重写方法
- 抽象:如果一个类有相关方法不知具体实现,该方法可设置为抽象方法,所在类就是抽象类; 具体实现交给子类完成;在应用中抽象类可作为模板使用
java中的常用类,不少于6个?
String,StringBuffer,Date,SimpleDateFormat,Random,Math,System,Runtime等
集合
List, Set, Map是否继承自Collection接口?
List,Set是,Map不是
HashMap的数据结构 存放数据的机制和扩容问题
HashMap底层采用的是哈希表这种数据结构。
哈希表的特点在于查询速度快,时间复杂度为O(1)。
谈谈HashSet的存储原理
HashSet的底层就是由HashMap实现的,所以具体存储原理可以参照HashMap的底层实现。
list和map的应用场景
list: 存储有序且允许重复的单个对象
map: 存储无序且唯一的键值对
常用集合的的底层实现?
Map怎么实现有序
通过LinkedHashMap实现有序,具体实现同上
Set和Map的底层
Set底层实现是由Map完成的
hashmap和hashtable的区别?
Hashtable:
线程安全,效率会低于HashMap。而且key和value都不能存放null值。
HashMap:
线程不安全,因此效率会高于Hashtable。key和value都可以为null,但是key只能有一个null。
Collections vs Collection
Collections: 集合的工具类
Collection: 用于存储单个对象的集合接口
List vs Set
List: 存储有序且允许重复的对象,可以使用下标遍历
Set: 存储无序且唯一的对象,不能使用下标遍历
集合的工具类有哪些?如何实现集合排序?不使用工具类的话怎么排序?
集合的工具类: Arrays,Collections
工具类排序: Arrays.sort(),Collections.sort()
如果不使用工具类,对于Map和Set可以分别采用TreeMap和TreeSet实现元素的排序。对于List,则可以手写一个排序算法实现元素的排序,比如快速排序、希尔排序等
ArrayList vs LinkedList
ArrayList: 通过数组扩容的方式存储对象,查找和向后追加元素效率高
LinkedList:通过双向链表的方式存储对象,连续位置添加和删除效率高
Set vs Map
联系: Set的存储是通过Map来实现的
区别: Set存储单个对象无序且唯一, Map存储键值对(key-value),key无序且唯一
ConcurrentHashMap vs HashMap vs LinkedHashMap
IO流与异常
运行时的异常和一般异常有什么异同?
运行时异常: 可以编译通过,运行时报错
一般异常: 编译时报警告,需提供处理异常方式
try-catch中return和finally哪个优先执行
finally会优先执行,在一段代码中,finally是必须执行的
请说出常见的运行异常
空指针,数组溢出,类型转换,算术异常
有用过NIO吗?NIO的优点在哪里?
NIO底层采用的是内存映射实现的,因此效率会比普通的IO效率要高。
NIO是什么他跟IO有什么区别?
- NIO是NO Block IO流,是一种基于通道与缓冲区操作的流,是非阻塞的流,读写效率高
- IO是Block IO流,是一种基于读写操作的流,是阻塞流,读写效率比NIO低
多线程,网络编程
线程池有没有用过,怎么用的,在哪里用的?
在需要创建和销毁大量临时线程时,可以使用线程池
SimpleDataFormat是线程安全的吗?
不是
启动一个线程用的是start()还是run()?
启动线程应该采用start()方法。如果直接调用run()方法,则会像调用普通方法一样执行run方法中的内容。就不会有争抢cpu时间片的过程,达不到线程的效果。
sleep()和wait()有什么区别?
谈谈创建多线程的方式
谈谈你对线程安全的理解?如何解决线程的安全问题?
- 当多个线程互抢资源时,会造成数据混乱;通过线程安全可以确保数据完整性;
- 线程的安全可以通过以下加锁方式解决:
- 同步代码块
- 同步方法
- 互斥对象锁
Synchronized加在普通方法和静态方法的区别
- Synchronized修饰普通方法:要确保调用该方法的对象为同一对象,才能确保线程安全
- Synchronized修饰静态方法:静态方法属于类,可以确保线程安全
同步代码块和同步方法的区别
- 同步代码块锁的范围是代码块区域
- 同步方法锁的范围是当前的方法块区域
谈谈线程的生命周期
- 实例化线程对象
- 启动线程
- 进入就绪状态
- cpu调度后进入运行状态
- 当cpu调度另一线程或当前线程进入阻塞后重新回到3,就绪状态
- 线程的结束
谈谈对线程池的理解?jdk提供了哪几种线程池?他们有什么区别?
- 线程池可以提高线程的创建和销毁的开销
- jdk提供了以下几种线程池:
对多线程的了解?在什么地方使用到过多线程?是否有用过线程池?用的什么线程池?
多线程是程序中的多条执行路径,每个线程在程序中互抢资源;在购票系统,通讯聊天中可以用到多线程
newCachedThreadPool:带缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程
UDP和TCP的区别
- UDP:无连接的传输协议,数据不安全,性能高
- TCP:建立连接的传输协议,数据安全,性能低
网络的分层
OSI七层模型: 应用程,表示层,会话层,传输层,网络层,数据链路层,物理层
TCP四层模型: 应用层,传输层,网络层,网络接口层
什么是tcp协议
是一种可靠安全的传输协议,传输效率低,需建立连接,经过三次握手;
Http和Https的区别
- http: 超文本传输协议,是一种明文的传输协议
- https: 可理解为安全版的超文本传输,进行加密的一种传输协议
Http的报文里有什么
报文里有: 请求行(requestline)、请求头部(header)、空行和请求数据等4个部分组成
反射与解析
解析XML有几种方式
dom解析,sax解析,pull解析
反射你是怎么理解的?
编程题
请写出下面代码的运行结果
String s =”123”;
String temp=s;
temp=”1234”;
System.out.println(s);
System.out.println(temp);
打印结果: 123 1234
给定一个不重复的自然数数组{3,5,9,7,4,13,15,0,2,20},已知其最大值20,请将其按从小到大的方式顺序输出,要求算法复杂度为1
public static void main(String[] args) {
//一个不重复的自然数数组
int[] array = {3,5,9,7,4,13,15,0,2,20};
//最大值为20
int max = 20;
//首先创建一个长度为 最大值+1 的新Integer(消除0的默认值)数据
Integer[] newarray = new Integer[max + 1];
//遍历老数组,将每个元素以此插入到新元素的指定位置(规则:每个元素本身对应的下标位置)
for(int i = 0; i array.length; i++){
newarray[array[i]] = array[i];
}
//遍历新数组,以此打印,遇到null则跳过
for(int i = 0; i newarray.length; i++){
if(newarray[i] != null){
System.out.print(newarray[i] + " ");
}
}
}
对于1-100范围内的整数I(包括100),找出满足I,I+4,I+10(I+10也在100范围)都是素质的整数I,计算这样I的个数cnt和这些整数的和sum
//个数:7;总和:201
public static void main(String[] args) {
int count = 0;
int sum = 0;
for(int i=1;i=100;i++){
int j;
for(j=2;ji;j++){
if(i%j==0||(i+4)%j==0||(i+10)%j==0){
if(i+10100){
System.out.println("个数:"+count+";总和:"+sum);
return;
}
break;
}
}
if(i==j&&i2){
count++;
sum += i;
System.out.println("素数:"+i);
}
}
}
用java代码找出A数组中不存在于B数组的项,例如:A[1,2,3],B[4,2]
public static void main(String[] args) {
int[] a = {1,2,3,9,5,7};
int[] b = {2,4,9};
for(int i=0;ia.length;i++){
int j;
for(j=0;jb.length;j++){
if(a[i]==b[j]){
break;
}
}
if(j==b.length){
System.out.print(a[i]+"t");
}
}
}
单例具体实现
1.构造方法私有化 2.调用静态方法获取对象,且每次获取的对象都相同
请在如下函数体中补充完成代码,实现根据输入字符串返回该字符串的倒序形式。如输入“ABC”返回“CBA”。
Public String getReverseString(String str){
char[] a = str.toCharArray(); //得到字符数组
for(int i=0;ia.length/2;i++){
char t = a[i]; //首尾交换
a[i] = a[a.length-1-i];
a[a.length-1-i] = t;
}
String s = new String(a);
return s;
}
下面的程序代码输出的结果是多少?
public class smallT{
public static void main(String args[]){
smallT t=new smallT();
Int b=t.get();
System.out.println(b);
}
public int get(){
try{
return 1;
}
finally{
return 2;
}
}
}
2 因为finally优先级比return高,哪怕return了,最终也要执行finally中的代码
写一个函数,2 个参数,1 个字符串,1 个字节数,返回截取的字符串,要求字符串中的中文不能出现乱码:如(“我ABC”,4)应该截为“我AB”,输入(“我ABC 汉DEF”,6)应该输出为“我ABC”而不是“我ABC+汉的半个”。
//方式1:
public static void main(String[] args) {
subString("我abc",4);
subString("我abc汉EF",6);
}
private static void subString(String str, int len) {
char[] b = str.toCharArray();
StringBuffer sb = new StringBuffer();
for(int i=0;ilen;i++){
if(b[i]=0&&b[i]=255){
sb.append(b[i]);
}else{
if(i!=len-1){
sb.append(b[i]);
}
len--;
}
}
System.out.println(sb.toString());
}
}
方式2:
utf-8编码,一个汉字占3个字节,gbk编码,一个汉字占2个字节
截取字符串:在gbk编码中,汉字一半的字节都是小于0的
public static String splitFirst(String str, int bytesize) throws UnsupportedEncodingException {
byte[] buf = str.getBytes("GBK");
int num = 0;
boolean bChineseFirstHalf = false;
for (int i = 0; i bytesize; i++) {
if (buf[i] 0 && !bChineseFirstHalf) {
bChineseFirstHalf = true;
} else {
num++;
bChineseFirstHalf = false;
}
}
return str.substring(0, num);
}
给定的一个文件“a.txt”,找出所有符合“Japanes”字符串的个数,并修改为“Japanese”
BufferedReader br = new BufferedReader(new FileReader("a.txt"));
StringBuffer sb = new StringBuffer();
String msg;
while((msg=br.readLine())!=null){
sb.append(msg);
}
msg = sb.toString();
br.close();
int count = 0;
int index = msg.indexOf("Japanese");
while(index=0){
count++;
msg = msg.substring(index+1);
index = msg.indexOf("Japanese");
}
System.out.println("匹配的个数为:"+count);
BufferedWriter bw = new BufferedWriter(new FileWriter("a.txt"));
msg = sb.toString();
msg = msg.replace("Japanese", "Japanese");
bw.write(msg);
bw.close();
智力题