华为java笔试.docx
《华为java笔试.docx》由会员分享,可在线阅读,更多相关《华为java笔试.docx(27页珍藏版)》请在冰豆网上搜索。
华为java笔试
1.在main(String[]args)方法内是否可以调用一个非静态方法?
答案:
不能.静态成员不能访问非静态成员.
对一个类而言,包含三种最常见的成员:
构造器、属性、方法。
类内各成员的定义顺序没有影响,各成员之间可以相互调用,但是,static修饰的成员不能修饰没有static修饰的成员。
还记得我说的,如果类A中有一个普通方法f(),那么编译器会隐式地把它转化为f(Athis)吗?
那你也还记得我说,static方法就是没有这个this的方法吗?
如果A中有两个普通方法f()和g(),那么编译器会隐式地把它们变成f(Athis)和g(Athis)。
这样,在f方法里面调用g方法的时候,编译器就可以隐式地把f方法参数中的this传递给g方法。
然而,如果f方法是static的,而g方法是非static的,那么,f方法本身就没有this参数,所以它无法隐式地提供给g方法一个this参数,因此,f方法就不能直接调用g方法了。
我们有一个解决的办法,就是在f方法中手动产生一个A的对象obj,然后把这个对象当作this参数传递给g方法(obj.g()),这样就可以调用g方法了,明白了吗?
其实还可以跟你说简单一点。
普通方法是对象的方法,也就是说,普通方法的调用都是跟某一个具体的对象相关联的(this),我们要用一个对象来调用它,它也可以改变这个对象属性;而静态方法是用作工具的方法,也就是说,它不跟任何对象相关联,它可以不通过对象来调用,它做的事情也不能改变任何对象的属性。
明白了吗?
使用方法如下:
静态成员一般通过类名调用,也可以通过对象来调用,或者在所在类的其他方法(可以是静态,也可以是非静态)里直接使用(不管如何调用,只要记住一点:
同类所有对象共用同一个静态成员)。
但是在静态方法里,只能直接访问静态成员,不能直接访问非静态成员。
(要想在静态方法里访问非静态成员,可以实例该类的一个对象,然后在通过对象调用非静态成员。
)非静态成员只能通过实例调用,别无他法。
只要记住一点:
把static成员和非静态成员彻底分隔开,他们各自作用不同,用法不同,之间没有任何联系
这个跟编译器的内存处理有关系,静态成员变量需要在一开始就分配内存进行初始化,而一般的类成员只是在类实例化的时候才会为止分配内存初始化,从方面来说,假如允许非静态类中有静态成员变量,如下面所示:
classA{
publicclassB{
staticstringvar_a;
}
}
那么在程序一开始就需要给A.B.var_a分配内存并初始化,假如这个成立了,那么A.B也应该会有相应的内存,但是由于B只是A的一个非静态成员变量,在类A还没有实例化的时候就以及有了相应的内存(也就是非静态成员变量只有在类的实例中才会有相应的内存位置),这样跟原来的标准有冲突,假如JAVA编译器(或者JAVA虚拟机)支持这种做法(其实也是可以实现的),这有的后果会导致编译器混乱无序的,大大增加了编译器的难度和复杂性,每一种语言都有预先制定好的语言标准,相对应的编译器都是基于这种标准来实现的,假如随意突破这种标准,那只会导致灾难性的后果而已
我的理解,因为静态的东西是在编译的时候就要有内存空间的,但是不是静态的东西只有当实例化的时候才会分配空间,如果你在非静态方法里面包含了静态的东西,这个方法还没有去分配空间,怎么又能为里面的变量去分配空间呢,个人理解
JVM启动的时候要先把static的东西初始化但此时外部类可能还没有被实例化所以会引起混乱
java的主函数写public和static的原因?
public使得该函数可以被外部(Java虚拟机)调用;
static使得该函数不需要任何对象便可直接被调用。
JavaisnotaC。
下面一点是不同的。
static不能在方法中修饰变量,只能在类中申明使用!
把staticintm=0;放在main()方法的上面
static是静态的,它所修饰的东西属于类,在程序加载的时候就分配内存,而方法在被调用的时候才分配内存,所以你把一个静态变量放到一个方法中是错误的
我们运行java程序使用的是java虚拟机。
虚拟机启动之后,会在.class文件里面去找一个名为main的函数,然后运行它,我们的程序便运行了。
那么你想一想,这个main函数是在它所属的类的实例产生之前就被调用的,所以它只能是static的。
另外,这个main函数是虚拟机来调用的,即是外部代码来调用的,所以它只能是public的。
然后,你也可以把这个函数声明为int返回值。
但是虚拟机并不需要返回状态,所以它只会找返回值为void的main,如果你定义为int,则不会当作主函数被调用。
最后,函数参数是String类型的一个数组,这个数组也就是运行时的参数。
args是型参名,可以随意。
2.同一个文件里是否可以有两个public类?
答案:
不能.同个源文件有多个公共类,编译器就找不到应该执行的main方法了
3.方法名是否可以与构造器的名字相同?
答案:
可以。
publicclassTest//定义类,把类当成一种自定义数据类型,即,所有类是引用数据类型。
(引用数据类型即是对一个对象的引用,即为指针。
对象包括实例和数组。
引用类型包括类、接口、数组和特殊的null类型)。
类包含三种常见成员:
构造器、属性、方法。
{
publicStringname;//属性用于定义该类或该类的实例所包含的数据。
publicintage;
publicTest(Stringiceboy) { System.out.println(iceboy); }//构造器用于构造该类的实例。
Java通过new关键字来调用构造器,从而返回该类的实例。
构造器是一个类创建对象的根本途径,如果一个类没有构造器,这个类通常将无法创建实例。
Java中,如果程序员没有为一个类编写构造器,则系统会为该类提供一个默认的构造器。
系统提供的构造器总是没有参数的。
构造器名必须与类名相同。
构造器不能定义返回值类型声明,也不能使用void定义构造器没有返回值,因为构造器的返回值为实例(new调用构造器时,生成实例),因此构造器的返回值类型总是当前类,因此无须定义。
故,不能在构造器里显式使用return返回当前类对象,因为构造器的返回值是隐式的。
publicvoidTest(Stringiceboy){System.out.println(iceboy); }//Test方法;方法用于定义该类或该类的实例的行为特征或功能实现。
若无返回值必须void声明。
如果声明了方法返回值类型,则方法体内必须有一个有效的return语句。
方法体内多条可执行语句之间有严格的执行顺序,排在前面的总是先执行。
publicstaticvoidmain(String[]args)//static修饰的成员表明它是属于这个类共有的,而不是属于该类的单个实例。
因此,通常把static修饰的属性和方法称为类属性、类方法(即是翻译过来的静态属性静态方法)。
不使用static修饰的普通方法属性则只是属于该类的单个实例,通常称为实例属性、实例方法(即是翻译过来的对应的非静态属性非静态方法)。
——静态成员不能访问非静态成员。
{
Testa=newTest("abc");//输出“abc”//创建对象的根本途径是构造器,too那个过new关键字来调用某个类的构造器即可创建这个类的实例。
a.Test("iceboy");//输出“iceboy” } }
4.初始化了一个没有run()方法的线程类,是否会出错?
答案:
不会。
第一种方法:
直接继承Thread类。
publicclassTest
{
publicstaticvoidmain(String[]args)
{
ThreadClasst=newThreadClass();
t.start();
System.out.println("end");//输出“end”
}
}
classThreadClassextendsThread//Thread类已经实现了空的run()方法。
{
}
第二种方法:
实现Runnable接口
publicclassTest
{
publicstaticvoidmain(String[]args)
{
ThreadClasst=newThreadClass();
Threadthread=newThread(t);
thread.start();
System.out.println("end");
}
}
classThreadClassimplementsRunnable
{
publicvoidrun()//必须有此方法否则编译报错。
它是Runnable接口中的抽象方法。
{
System.out.println("Threads");
}
}
4.局部内部类是否可以访问非final变量?
答案:
不能访问局部的,可以访问成员变量(全局的)。
classOut
{
privateStringname="out.name";
voidprint()
{
finalStringwork="out.local.work";//若不是final的则不能被Animal使用.
intage=10;
classAnimal
//定义一个局部内部类.只能在print()方法中使用.
//局部类中不能使用外部的非final的局部变量.全局的可以.
{
publicvoideat()
{
System.out.println(work);//ok
//age=20;errornotfinal
System.out.println(name);//ok.
}
}
Animallocal=newAnimal();
local.eat();
}
}
5.选择语句case中,允许使用的值有哪些?
答案:
int,short,char,byte(都在int范围之内,且是整数)
6.Math,String是不可继承的。
(final类)
Instanceof后面跟的应该是OBJECT。
构造器可以是私有的。
(private)
=与==意义是完全不同的。
一个是赋值,一个是等于。
全局变量可以不进行初始化,如果使用一个局部变量,则这个局部变量要被初始化。
7.在try-catch-final块中的退出语句。
publicclassTest
{
publicstaticvoidmain(String[]args)
{
inta=1;
try
{
a=a/0;
}catch(Exceptione)
{
System.out.println("catch");
return;//当return时,finally中的语句会执行。
//System.exit(0);//若用上这句,finally中的语句不会执行。
直接返回,退出程序。
}
finally//当没有System.exit(0);时,无论是否发生异常它都会执行。
{
System.out.println("finally"); } } }
注:
try-catch-final块的顺序不能调换。
8.下面都是正确的main方法签名。
publicstaticvoidmain(String[]args)
publicstaticfinalvoidmain(String[]args)
staticpublicvoidmain(String[]args)
staticpublicsynchronizedvoidmain(String[]args)
staticpublicabstractvoidmain(String[]args)//错误
9.if(-0.0==0.0)是相等还是不等?
答案:
相等。
10.一个抽象类是否可以没有抽象方法?
答案:
可以。
11.RandomAccessFile类继承Object,并且实现了DataInput和DataOutput接口。
答案正确
12.Collection与Collections的区别?
答案:
Collection是一个接口,但Collections却是一个辅助类,里面有很多静态的工具方法。
而且很有用的。
如:
reverse(Listlist);sort(Listlist,Comparatorc)等。
Collections没有实现任何接口。
它直接继承了Object。
13.classChildextendsParents{} classParents{} 是否可以这样声明类,在一个文件中?
答案:
可以。
无所谓的。
14.数组,无论是当前的,还是类等级的,都会被初始化。
String是被初始化为null,不是空字符。
null,““,”“,都是不同的。
“continue”只能在一个循环里(如for,do,while),它不能在case语句中出现。
Primitive(int,char,long等)数组是不能互相赋值的,即使它们本身可以。
一个Constructor可以抛出任何异常。
初始化块是按照声明的顺序执行的。
所有关于NaN(NotaNumber)和non-NaN的比较,都返回false.这条很重要。
==会产生编译错误,如果两边类型不匹配的话。
equals()返回false如果对象类型不同,但不产生编译错误。
15.Java成员变量默认初始化的值。
成员变量类型取值 byte-0short-0int-0long-0L
char-'u0000'float-0.0Fdouble-0.0Dboolean-false 所有引用类型null
16.integer和long操作/和%的话,可能会抛出ArithmeticException,比如除0。
但是float与double不会,即使是除以0。
doublea=0;a=a/0;则a等于NaN。
17.普通内部类不可以拥有静态变量,但静态内部类可以。
File类没有任何处理文件内容的方法。
InputStream和OutputStream是抽象类,DataInput和DataOutput是接口。
DataInputStream实现了DataInput接口。
18.面向对象的特征有哪些方面?
答案:
最基本特征:
封装,继承,多态。
其他特征:
抽象关联,聚合,组合,内聚,耦合
19.String是最基本的数据类型吗?
String和StringBuffer的区别?
答案:
String不是一最基本的数据类型。
STRING的长度是不可变的,STRINGBUFFER的长度是可变的。
如果你对字符串中的内容经常 进行操作,特别是内容要修改时,那么使用StringBuffer,如果最后需要String,那么使用StringBuffer的toString()方法
20.int和Integer有什么区别
答案:
int是基本类型。
Integer是引用类型。
Integer可以把String转换成int。
21.运行时异常与一般异常有何异同?
答案:
异常表示程序运行过程中可能出现的非正常状态,运行时异常表示虚拟机的通常操作中可能遇到的异常,是一种常见运行错误。
java编译器要求方法必须声明抛出可能发生的非运行时异常,但是并不要求必须声明抛出未被捕获的运行时异常。
22.说出一些常用的类,包,接口,请各举5个?
答案:
常用类-System,ArrayList,FileInputStream,Thread,Socket.
常用的包-java.io,java.util,java.sql,java.javax.naming,
常用接口-Collection,Connection,Cloneable,Comparable,Serializable
23.说出ArrayList,Vector,LinkedList的存储性能和特性.
答案:
ArrayList和Vector都是使用数组方式存储数据,此数组元素数大于实际存储的数据以便增加和插入元素,它们都允许直接按序号索引元素,但是插入元素要涉及数组元素移动等内存操作,所以索引数据快而插入数据慢,Vector由于使用了synchronized方法(线程安全),通常性能上较ArrayList差,而LinkedList使用双向链表实现存储,按序号索引数据需要进行前向或后向遍历,但是插入数据时只需要记录本项的前后项即可,所以插入速度较快。
24.设计4个线程,其中两个线程每次对j增加1,另外两个线程对j每次减少1。
写出程序。
注:
因为这4个线程共享J,所以线程类要写到内部类中。
加线程:
每次对j加一。
减线程:
每次对j减一。
publicclassTestThreads
{
privateintj=1;
//加线程
privateclassIncimplementsRunnable
{
publicvoidrun()
{
for(inti=0;i<10;i++)
{ inc(); } } }
//减线程
privateclassDecimplementsRunnable
{
publicvoidrun()
{
for(inti=0;i<10;i++)
{ dec(); } } }
//加1
privatesynchronizedvoidinc()
{
j++;
System.out.println(Thread.currentThread().getName()+"-inc:
"+j);
} //减1
privatesynchronizedvoiddec()
{
j--;
System.out.println(Thread.currentThread().getName()+"-dec:
"+j); }
//测试程序
publicstaticvoidmain(String[]args)
{
TestThreadstest=newTestThreads();
//创建两个线程类
Threadthread=null;
Incinc=test.newInc();
Decdec=test.newDec();
//启动4个线程
for(inti=0;i<2;i++)
{
thread=newThread(inc);
thread.start();
thread=newThread(dec);
thread.start(); } } }
25.数组转换问题。
Object[]object=newPerson[2];
Person[]person=newPerson[3];
person=(Person[])object;//可以转换
int[]i=newint[2];
long[]l=newint[3];
i=(long[])l;//不可以转换
26.用socket通讯写出客户端和服务器端的通讯,要求客户发送数据后能够回显相同的数据。
Server.java:
源代码
import.*; importjava.io.*;
classServer
{
publicServer()
{
BufferedReaderbr=null;
PrintWriterpw=null;
try
{
ServerSocketserver=newServerSocket(8888);//建立服务器端
Socketsocket=server.accept();//监听客户端
//得到该连接的输入流
br=newBufferedReader(newInputStreamReader(socket.getInputStream()));
//得到该连接的输出流
pw=newPrintWriter(socket.getOutputStream(),true);
//先读后写
Stringdata=br.readLine();
System.out.println(data);//输出到控制台
pw.println(data);//转发给客户端
}catch(Exceptione) { e.printStackTrace(); }
finally
{
try
{ //关闭读写流 br.close(); pw.close(); }catch(Exceptione) {}
} }
publicstaticvoidmain(String[]args)
{ Serverserver=newServer(); } }
Client.java:
源代码
import.*; importjava.io.*;
classClient
{
publicClient()
{ BufferedReaderbr=null; PrintWriterpw=null;
try
{
Socketsocket=newSocket("localhost",8888);//与服务器建立连接,服务器要先启
//得到Socket的输入与输出流
br=newBufferedReader(newInputStreamReader(socket.getInputStream()));
pw=newPrintWriter(socket.getOutputStream(),true);
//先写后读
pw.pri