基础面试题

来源:互联网 发布:简单java加密解密 编辑:程序博客网 时间:2024/04/28 09:30
1,我们先说一说数组。
数组是用来存储数据的容器,数组中有角标,可以方便的操作数据。
数组中元素排序的操作
public static void bubbleSort(int[] arr)//冒泡排序
{
for (int x=1; x<arr.length; x++ )
{
for (int y=0; y<arr.length-x; y++)
{
if (arr[y]>arr[y+1])
{
int temp = arr[y];
arr[y] = arr[y+1];
arr[y+1] = temp;
}
}
}
}
2,面向对象的三大特性。


第一个是继承。继承提高了代码的复用性。
成员变量在继承中的特点是:当子类中有和父类同名的成员变量,子类如果要调用父类中的同名变量要加super
子类如果要调用本类中的同名变量要加this。
成员函数在继承中的特点是:当子类中有和父类一模一样的成员函数时,子类对象在调用在这方法时用的是子类中的方法
面父类中的方法就相当于覆盖了。这是函数的一个特性,重写。重写要注意的是子类的权限不能小于父类。
静态只能覆盖静态。
构造函数在继承中的特点是:当子类对象进行初始化时,会先运行父类中无参的构造函数,如果父类中没有无参的构造函数
要手动调用。要注意的是super语句或this语句要写在构造函数的第一行。


第二个是多态。多态的好处是提高了代码的扩展性。
多态的体现是:父类引用指向了自己的子类对象,父类引用接收了自己的子类对象。
多态的前提是,类与类之间有关系,往往还有一个前提就是存在重写。
成员变量在多态中的特点是:无论编译还是运行都看左边。
成员函数在多态中的特点是:编译看左边,运行看右边。
静态成员变量在多态中的特点是:无论编译还是运行都看左边。


第三个是封装。封装就是隐藏类中的成员。
封装的关键字是private。封装的作用是不让用户直接操作数据而是通过方法来操作数据。
我们可以在方法中加入逻辑判断来增强代码的健壮性。


3,什么是面向对象。
java把我们生活中一个个的事物都映射成了对象。比如:张三是一个对象。李四也是一个对象。
对象中的属性如性别姓名就是成员变量。对象的行为如吃饭睡觉就是成员方法。
把对象中的共性抽取出来就形成了类。
我们用java编程其实就是一个找对象,用对象,建立对象的过程。


4,接口。
接口就是一个特殊的抽象类,里面有常量和抽象方法。接口中的成员都是有固定的修饰符。常量:public static final方法:public abstract
接口不可以创建对象。接口需要子类实现。子类要覆盖接口中全部的方法才能创建对象,否则子类就是一个抽象类。
接口可以被类多实现。


5,内部类。
内部类就是定义在类里面的类。可以是成员位置也可以是局部位置。
内部类可以直接访问外部类中的成员包括私有。格式是:外部类名.this
外部类想访问内部类必须建立对象。
当内部类定义在成员位置上时,可以被成员修饰符修饰,比如private 。
当内部类定义在局部位置上时,不可以被成员修饰符修饰,不可以访问非final的局部变量。可以访问外部类中的成员。
静态内部类。当内部类中的方法是静态时,内部类也要是静态的。


5,final 和finally
final是一个修饰符。它可以修饰类,变量,方法
被final修饰的类不能被继承。
被final修饰的变量是一个常量。常量的书写规则是所有字母大写。如果由多个单词组成,中间用下划线分开。
被final修饰的方法不能被复写。


6,this  static
this代表本类对象。可以用于区分成员变量和局部变量同名的情况。
还可以用于构造函数之间互相的调用。要注意的是:this语句只能放在构造函数的第一行。
static是一个静态修饰符。随着类的加载而加载。随着类的消失而消失。
优先于对象存在。可以直接被类名调用。被所有对象共享。




7,重载和重写
重载是一个类中有多个相当方法名的方法。这些方法的参数不一样,可以是个数不一样也可以是类型不一样。
java不能通过返回值来判断一个方法是否重载。
重写是指子类的方法和父类中的方法名称和参数一致,当子类对象在调用方法时,运行的子类中的方法,
相当于把父类中的方覆盖了一样。重写要注意的是子类的权限不能小于父类的权限。子类只能抛出比父类更少的异常。
父类中的方法是private时,不是重写,而是产生了一个全新的方法。


8,单例设计模式
有两种一种是懒汉式:
private 构造函数。private static final 对象。通过一个静态方法返回对象。
一种是饿汉式:
private 构造函数。private static final 引用。通过一个静态方法返回对象。
class Single  
{  
    private static Single s = null;  
    private Single(){}  
    public static Single getInstance()  
    {  
        if(s==null)  
        {  
            synchronized(Single.class)  
            {                 
                if(s==null)  
                    s = new Single();  
            }  
        }  
        return s;  
    }  
}
9,异常
异常的父类是throwable。下面有两个子类,一个exception 一个是error
处理异常的方式有两种,一种是throws。一种是try catch finally
throws和throw的区别
throws使用在函数上。
throw使用在函数内。


throws后面跟的异常类。可以跟多个。用逗号隔开。
throw后跟的是异常对象。


10,多线程,主要是应用




11,集合
connection下面有两个子类一个是list一个是set
list集合的特点是每一个元素都对应一个角标,我们可以操作角标从而操作元素。它里面的数据可以重复,是有序的。
list集合下面有两个子类一个是arraylist,它的底层数据结构是数组。查找很快,添加稍慢。
而且它有一个特有的迭代器可以在迭代时添加数据
另一个是linklist,它的底层用的是链表。它的特点就是添加很快查找很慢。
set集合的特点是元素是唯一的。
set集合下面有两个子类,一个是hashset,它底层用的是哈希表。它保证数据唯一性用的是比较哈希值,和equals方法。
另一个是treeset,它的底层用的是二叉树。它保证数据唯一性用的是comparator比较器,或对象本身实现了comparable接口。


12,map集合
map集合存储是的键值对,要一对一对往里面存,而且要保证键的唯一性。
它取出数据有两种方式,
一种是keyset,它是把map集合中所有的键存入set集合,然后通过迭代set集合,得到对应的值。
还有一种是entryset,它是把map集合中键值的映射对关系存入set集合。这种关系的类型是map.entry。
然后通过迭代set集合,得到映射关系,从而得到对应的键和值。


13,io和File,properties,主要是应用。
限制程序运行次数。
删除文件夹。
复制mp3


14,编码
编码就是把字符串转换成字节数组。用的方法是String.getBytes(编码表)
解码就是把字节数组转换成字符串。用的方法是new String(char[] ,编码表);
要注意是如果是用utf-8解码出问题了,那数据就会发生变化。因为utf-8。。。
如果用gbk解码错了,再用gbk编码就能还原数据。




15,tcp udp url,也是应用。
从客户端传输图片到服务端。
然后服务端保存文件后返回客户端一句话。
其中要注意是的有一个shutdown不要忘记了。


16,正则表达示
在包util.regex里面,有两个类,一个是pattern,一个是matcher
作用:专门操作字符串的。
特点:有很多规则可以对字符串进行复杂操作。
具体的功能有:匹配,切割,替换,查找。


17,枚举
枚举就是让某个类型的变量的取值,只能是固定的那么几种中的一个。
否则编译器会报错,比如星期日用什么值来表示?0还是7?
枚举就是专门解决这类问题的。而普通变量无法实现这一点。
枚举是一种特殊的类,其中的每个元素都是该类的一个实例对象


18,反射,
反射就是把Java类中的各种成分映射成相应的java类。
java类中的成员变量,成员函数,构造函数都有相应的实例对象。
它们就是field,method,constrctor...
如何得到一个类的字节码有三种方式。


19,动态代理,
java虚拟机可以在运行时动态的生成类的字节码。这些动态生成的类往往被用在代理。这就是动态代理类。
动态生成的类必须实现一个或多个接口。所以目标类只有实现接口我们才能代理。
用Proxy.newInstance方法直接一步就创建出代理对象。
或者先得到Proxy的构造函数,用构造函数创建出实例对象。再传入InvocationHandler的实例对象。


20,类加载器
每一个类都是由类加载器加载进内存的。java系统默认有三个类加载器。
加载类的过程是当前线程的类加载器会委托bootstrap类加载器进行加载。如果加载不了
它会一层一层的委托下去,最后会返回给发起的类加载器。如果它也加载不了就会产生异常。
同时我们还可以自己写类加载器。用loadcalss方法把指定的类加载进内存。


21,7k面试题
交通灯管理系统。
拿到这个题目,首先就应该用面向对象的思想进行分析和设计。
但是在这之间,我们还要搞清楚这个灯是怎么变化的。这就要在图上画清楚了。
搞清楚这个以后,我们还要把分析出要创建哪几个类。这些类之间有什么关系。
因为这个灯有12个,固定这么多。我们可以用枚举的方式来创建这个灯的类。
灯要有属性,灯还要有方法,是亮的吗?变亮和变暗,这些都可以通过更改属性来完成。
灯搞定之后,还要有一个控制器来让它不停的变化。有了控制之后还要有路。
路要能产生车。同时还要有问灯的方法,如果灯是亮的,就让最前面的车通过。
最后在主线程里面创建12条路。再打开控制器。这个程序就完成了。


这个程序里面用到了executor创建线程池的方法。还用到了arraylist中的remove方法。
还用到了枚举中的valueof方法。


22,银行业务调度系统。
拿到这个题目,首先就应该用面向对象的思想进行分析和设计。
先想一下,我们去银行取钱是个什么流程。中间有哪几个对象。
通过分析,我们了解到,有一个取号器,有多个窗口。
现在我们就可以进行代码的编写了,我们先写这个取号器。
因为取号器只有一个,所以我们就用单例来设计。取号器有什么属性呢?
有三种客户,有什么方法。得到最前面的一个客户。还要能不断的创建新客户。
然后我们再定义窗口。窗口是一个抽象类。子类有普通窗口。vip窗口。快速窗口。
窗口有什么属性呢?有窗口名字。有服务时间。有什么方法呢。取得最前面的一个客户。
最后,在主线程中创建三个普通窗口,一个vip一个快速窗口。再创建取号器的对象。
这样一个银行业务调度系统就完成模拟了。




下面这些是java面试宝典中的题目:


23,说说&和&&的区别。
&和&&都可以用作逻辑与的运算符,表示逻辑与(and),
当运算符两边的表达式的结果都为true时,整个运算结果才为true,
否则,只要有一方为false,则结果为false。
&&还具有短路的功能,
即如果第一个表达式为false,则不再计算第二个表达式,
例如,对于if(str != null&& !str.equals(“”))表达式,
当str为null时,后面的表达式不会执行,所以不会出现NullPointerException如果将&&改为&,
则会抛出NullPointerException异常。If(x==33 &++y>0) y会增长,If(x==33 && ++y>0)不会增长
&还可以用作位运算符,当&操作符两边的表达式不是boolean类型时,
&表示按位与操作,我们通常使用0x0f来与一个整数进行&运算
,来获取该整数的最低4个bit位,例如,0x31 & 0x0f的结果为0x01。
备注:这道题先说两者的共同点,再说出&&和&的特殊之处,
并列举一些经典的例子来表明自己理解透彻深入、实际经验丰富


24,在JAVA中如何跳出当前的多重嵌套循环?
在Java中,要想跳出多重循环,可以在外面的循环语句前定义一个标号,
然后在里层循环体的代码中使用带有标号的break语句,即可跳出外层循环。例如,
ok:
for(int i=0;i<10;i++)     {
        for(int j=0;j<10;j++)            {
               System.out.println(“i=” + i + “,j=” + j);
               if(j == 5) break ok;
        }
}
另外,我个人通常并不使用标号这种方式,
而是让外层的循环条件表达式的结果可以受到里层循环体代码的控制,
例如,要在二维数组中查找到某个数字。
int arr[][] ={{1,2,3},{4,5,6,7},{9}};
boolean found = false;
for(int i=0;i<arr.length&& !found;i++)       {
        for(int j=0;j<arr[i].length;j++){
               System.out.println(“i=” + i + “,j=” + j);
               if(arr[i][j]  ==5) {
                      found = true;
                      break;
               }
        }
}


25,switch语句能否作用在byte上,能否作用在long上,能否作用在String上?
在switch(expr1)中,expr1只能是一个整数表达式或者枚举常量(更大字体),
整数表达式可以是int基本类型或Integer包装类型,
由于,byte,short,char都可以隐含转换为int,
所以,这些类型以及这些类型的包装类型也是可以的。
显然,long和String类型都不符合switch的语法规定,
并且不能被隐式转换成int类型,
所以,它们不能作用于swtich语句中。


26,short s1 = 1; s1 = s1 + 1;有什么错? short s1 = 1; s1 += 1;有什么错?
对于short s1 = 1; s1 = s1 + 1;
由于s1+1运算时会自动提升表达式的类型,
所以结果是int型,再赋值给short类型s1时,编译器将报告需要强制转换类型的错误。
对于short s1 = 1; s1 += 1;由于 +=是java语言规定的运算符,
java编译器会对它进行特殊处理,因此可以正确编译。


27,char型变量中能不能存贮一个中文汉字?为什么?
char型变量是用来存储Unicode编码的字符的,
unicode编码字符集中包含了汉字,
所以,char型变量中当然可以存储汉字啦。
不过,如果某个特殊的汉字没有被包含在unicode编码字符集中,
那么,这个char型变量中就不能存储这个特殊汉字。
补充说明:unicode编码占用两个字节,所以,char类型的变量也是占用两个字节。
备注:后面一部分回答虽然不是在正面回答题目,
但是,为了展现自己的学识和表现自己对问题理解的透彻深入,
可以回答一些相关的知识,做到知无不言,言无不尽。


28,使用final关键字修饰一个变量时,是引用不能变,还是引用的对象不能变?
使用final关键字修饰一个变量时,是指引用变量不能变,引用变量所指向的对象中的内容还是可以改变的。例如,对于如下语句:
 final StringBuffer a=new StringBuffer("immutable");
执行如下语句将报告编译期错误:
a=new StringBuffer("");
但是,执行如下语句则可以通过编译:
a.append(" broken!");  
有人在定义方法的参数时,可能想采用如下形式来阻止方法内部修改传进来的参数对象:
public void method(final  StringBuffer param){}
实际上,这是办不到的,在该方法内部仍然可以增加如下代码来修改参数对象:
param.append("a");


29,"=="和equals方法究竟有什么区别?
(单独把一个东西说清楚,然后再说清楚另一个,这样,它们的区别自然就出来了,混在一起说,则很难说清楚)
==操作符专门用来比较两个变量的值是否相等,也就是用于比较变量所对应的内存中所存储的数值是否相同,
要比较两个基本类型的数据或两个引用变量是否相等,只能用==操作符。
如果一个变量指向的数据是对象类型的,那么,这时候涉及了两块内存,对象本身占用一块内存(堆内存),
变量也占用一块内存,例如Objet obj = newObject();变量obj是一个内存,new Object()是另一个内存,
此时,变量obj所对应的内存中存储的数值就是对象占用的那块内存的首地址。对于指向对象类型的变量,
如果要比较两个变量是否指向同一个对象,即要看这两个变量所对应的内存中的数值是否相等,这时候就需要用==操作符进行比较。
equals方法是用于比较两个独立对象的内容是否相同,就好比去比较两个人的长相是否相同,
它比较的两个对象是独立的。例如,对于下面的代码:
String a=new String("foo");
String b=new String("foo");
两条new语句创建了两个对象,然后用a/b这两个变量分别指向了其中一个对象,
这是两个不同的对象,它们的首地址是不同的,即a和b中存储的数值是不相同的,
所以,表达式a==b将返回false,而这两个对象中的内容是相同的,所以,表达式a.equals(b)将返回true。
在实际开发中,我们经常要比较传递进行来的字符串内容是否等,
例如,String input = …;input.equals(“quit”),许多人稍不注意就使用==进行比较了,这是错误的,
随便从网上找几个项目实战的教学视频看看,里面就有大量这样的错误。
记住,字符串的比较基本上都是使用equals方法。
如果一个类没有自己定义equals方法,那么它将继承Object类的equals方法,
Object类的equals方法的实现代码如下:
boolean equals(Object o){
return this==o;
}
这说明,如果一个类没有自己定义equals方法,它默认的equals方法(从Object类继承的)就是使用==操作符,
也是在比较两个变量指向的对象是否是同一对象,这时候使用equals和使用==会得到同样的结果,
如果比较的是两个独立的对象则总返回false。如果你编写的类希望能够比较该类创建的两个实例对象的内容是否相同,
那么你必须覆盖equals方法,由你自己写代码来决定在什么情况即可认为两个对象的内容是相同的。


30,静态变量和实例变量的区别?
在语法定义上的区别:静态变量前要加static关键字,而实例变量前则不加。
在程序运行时的区别:实例变量属于某个对象的属性,必须创建了实例对象,
其中的实例变量才会被分配空间,才能使用这个实例变量。静态变量不属于某个实例对象,
而是属于类,所以也称为类变量,只要程序加载了类的字节码,不用创建任何实例对象,
静态变量就会被分配空间,静态变量就可以被使用了。总之,实例变量必须创建对象后才可以通过这个对象来使用,
静态变量则可以直接使用类名来引用。
例如,对于下面的程序,无论创建多少个实例对象,永远都只分配了一个staticVar变量,
并且每创建一个实例对象,这个staticVar就会加1;但是,每创建一个实例对象,
就会分配一个instanceVar,即可能分配多个instanceVar,并且每个instanceVar的值都只自加了1次。
public class VariantTest{
        public static int staticVar = 0;
        public int instanceVar = 0;
        public VariantTest(){
               staticVar++;
               instanceVar++;
               System.out.println(“staticVar=” + staticVar + ”,instanceVar=”+ instanceVar);
        }
}
备注:这个解答除了说清楚两者的区别外,最后还用一个具体的应用例子来说明两者的差异,
体现了自己有很好的解说问题和设计案例的能力,思维敏捷,超过一般程序员,有写作能力!


31,是否可以从一个static方法内部发出对非static方法的调用?
不可以。因为非static方法是要与对象关联在一起的,
必须创建一个对象后,才可以在该对象上进行方法调用,
而static方法调用时不需要创建对象,可以直接调用。
也就是说,当一个static方法被调用时,可能还没有创建任何实例对象,
如果从一个static方法中发出对非static方法的调用,那个非static方法是关联到哪个对象上的呢?
这个逻辑无法成立,所以,一个static方法内部发出对非static方法的调用。


32,Integer与int的区别
int是java提供的8种原始数据类型之一。Java为每个原始类型提供了封装类,
Integer是java为int提供的封装类。int的默认值为0,而Integer的默认值为null,
即Integer可以区分出未赋值和值为0的区别,int则无法表达出未赋值的情况,
例如,要想表达出没有参加考试和考试成绩为0的区别,则只能使用Integer。
在JSP开发中,Integer的默认为null,所以用el表达式在文本框中显示时,值为空白字符串,
而int默认的默认值为0,所以用el表达式在文本框中显示时,结果为0,所以,int不适合作为web层的表单数据的类型。
在Hibernate中,如果将OID定义为Integer类型,
那么Hibernate就可以根据其值是否为null而判断一个对象是否是临时的,
如果将OID定义为了int类型,还需要在hbm映射文件中设置其unsaved-value属性为0。
另外,Integer提供了多个与整数相关的操作方法,例如,将一个字符串转换成整数,
Integer中还定义了表示整数的最大值和最小值的常量。


33,Math.round(11.5)等於多少? Math.round(-11.5)等於多少?
Math类中提供了三个与取整有关的方法:ceil、floor、round,这些方法的作用与它们的英文名称的含义相对应,
例如,ceil的英文意义是天花板,该方法就表示向上取整,
Math.ceil(11.3)的结果为12,Math.ceil(-11.3)的结果是-11;
floor的英文意义是地板,该方法就表示向下取整,Math.ceil(11.6)的结果为11,Math.ceil(-11.6)的结果是-12;
最难掌握的是round方法,它表示“四舍五入”,算法为Math.floor(x+0.5),
即将原来的数字加上0.5后再向下取整,所以,Math.round(11.5)的结果为12,Math.round(-11.5)的结果为-11。


34,下面的代码有什么不妥之处?
  1. if(username.equals(“zxx”){}
  username可能为NULL,会报空指针错误;改为"zxx".equals(username)
  2.  int  x = 1;
      return x==1?true:false;  这个改成return x==1;就可以!


35,请说出作用域public,private,protected,以及不写时的区别
这四个作用域的可见范围如下表所示。
说明:如果在修饰的元素上面没有写任何访问修饰符,则表示friendly。 
作用域    当前类同一package子孙类其他package
public    √    √         √      √
protected  √    √         √     ×
friendly   √    √         ×     ×
private    √    ×         ×     ×
备注:只要记住了有4种访问权限,4个访问范围,
然后将全选和范围在水平和垂直方向上分别按排从小到大或从大到小的顺序排列,就很容易画出上面的图了。


36,构造器Constructor是否可被override?
构造器Constructor不能被继承,因此不能重写Override,但可以被重载Overload。


37,接口是否可继承接口?抽象类是否可实现(implements)接口?
抽象类是否可继承具体类(concrete class)?抽象类中是否可以有静态的main方法?
接口可以继承接口。抽象类可以实现(implements)接口,
抽象类可以继承具体类。抽象类中可以有静态的main方法。
备注:只要明白了接口和抽象类的本质和作用,这些问题都很好回答,
你想想,如果你是java语言的设计者,你是否会提供这样的支持,如果不提供的话,有什么理由吗?
如果你没有道理不提供,那答案就是肯定的了。
 只有记住抽象类与普通类的唯一区别就是不能创建实例对象和允许有abstract方法。

0 0
原创粉丝点击