java工程师最新面试题(java语言基础)
Java语言基础主要涉及一下几个方面
Java的基本语言元素
原始数据类型
变量声明
变量的初始化
Java源文件的结构
Main方法
面试(1)掌握java标示符
请标记出下面代码中的错误。
public class x {
private int m-48abc;
private int m_abc;
private int number=60;
private static String $hk;
private double !@#;
private static String 我是变量="我是一个兵";
private String my@email="helloworld";
private String String;
private String sizeof;
private String null;
private String default;
private Stirng throws;
public static void main(String[] args) {
System.out.println(我是变量);
System.out.println($hk);
/*//*/
}
}
标识符是一个语言的基本元素,在java开发语言中,标示符可以用来标示类、方法、变量和标签。标识符是由一系列字符组成,每个字符可以是字母、数字、链接符号_或者是货币符号。
求职者注意第一个字母不能为数字,JAVA语言是区分大小写的。
(2)掌握java关键字
JAVA语言中的关键字是开发语言中预定于的保留标识符,不能在程序代码中标示类、变量、方法等成员。Java关键字有如下特征
A java的关键字都是小写
B then和sizeof都不是java关键字。熟悉c或者c++,写惯asp的程序员一定要注意。
C大写的NULL不是JAVA语言关键字。String是java语言的一个封装类的类名,也不是关键字。
关键字 |
含义 |
abstract |
表明类或者成员方法具有抽象属性 |
assert |
用来进行程序调试 |
boolean |
基本数据类型之一,布尔类型 |
break |
提前跳出一个块 |
byte |
基本数据类型之一,字节类型 |
case |
用在switch语句之中,表示其中的一个分支 |
catch |
用在异常处理中,用来捕捉异常 |
char |
基本数据类型之一,字符类型 |
class |
类 |
const |
保留关键字,没有具体含义 |
continue |
回到一个块的开始处 |
default |
默认,例如,用在switch语句中,表明一个默认的分支 |
do |
用在do-while循环结构中 |
double |
基本数据类型之一,双精度浮点数类型 |
else |
用在条件语句中,表明当条件不成立时的分支 |
enum |
枚举 |
extends |
表明一个类型是另一个类型的子类型,这里常见的类型有类和接口 |
final |
用来说明最终属性,表明一个类不能派生出子类,或者成员方法不能被覆盖,或者成员域的值不能被改变 |
finally |
用于处理异常情况,用来声明一个基本肯定会被执行到的语句块 |
float |
基本数据类型之一,单精度浮点数类型 |
for |
一种循环结构的引导词 |
goto |
保留关键字,没有具体含义 |
if |
条件语句的引导词 |
implements |
表明一个类实现了给定的接口 |
import |
表明要访问指定的类或包 |
instanceof |
用来测试一个对象是否是指定类型的实例对象 |
int |
基本数据类型之一,整数类型 |
interface |
接口 |
long |
基本数据类型之一,长整数类型 |
native |
用来声明一个方法是由与计算机相关的语言(如C/C++/FORTRAN语言)实现的 |
new |
用来创建新实例对象 |
package |
包 |
private |
一种访问控制方式:私用模式 |
protected |
一种访问控制方式:保护模式 |
public |
一种访问控制方式:共用模式 |
return |
从成员方法中返回数据 |
short |
基本数据类型之一,短整数类型 |
static |
表明具有静态属性 |
strictfp |
用来声明FP_strict(单精度或双精度浮点数)表达式遵循IEEE 754算术规范 |
super |
表明当前对象的父类型的引用或者父类型的构造方法 |
switch |
分支语句结构的引导词 |
synchronized |
表明一段代码需要同步执行 |
this |
指向当前实例对象的引用 |
throw |
抛出一个异常 |
throws |
声明在当前定义的成员方法中所有需要抛出的异常 |
transient |
声明不用序列化的成员域 |
try |
尝试一个可能抛出异常的程序块 |
void |
声明当前成员方法没有返回值 |
volatile |
表明两个或者多个变量必须同步地发生变化 |
while |
用在循环结构中 |
Java语言中的保留字:null、ture和false
Java语言中保留但是未使用的关键字:const和goto
(3)找出java关键字
A if B then C goto D while E then F sizeof
参考上面那道题
答案acde;
(4)挑选java关键字
A default B NULL C String D throw E long F true
(5)选择完整合理的java注解
请问这是一个完整且合理的java注解吗
/*//*/
Java语言提供了3种用于程序的注解
单行注解://***到行尾
多行注解 /*…*/
归档javadoc 注解://**..*/
- 文件头注解
/**
* 该类主要演示了如何使用微博 OpenAPI 来获取以下内容:
* <li>获取某条微博的评论列表
* <li>...
*
* @author SINA
* @since 2013-11-24
*/
需要注明该类文件创建时间、文件名、命名空间信息
- 类、接口注释电放费
/**
* @see {@link AdapterView.OnItemClickListener#onItemClick}
*/
类和接口采用/** */,描述部分用来书写该类的作用或者相关信息。
- 构造函数注解
/**
* HTTP 同步请求。
*
* @param url 请求的地址
* @param params 请求的参数
* @param httpMethod 请求方法
*
* @return 同步请求后,服务器返回的字符串。
- */
使用/** */描述构造函数的作用
- 域注解
- 方法注解
(6)int 和Integer的区别是什么
java提供引用类型和原始类型(或者内置类型)两种不同的类型。另外,java还以每个原始类型提供封装类(Wrapper)。
原始类型 引用类型
=================
boolean Boolean
char Character
byte Byte
short Short
int Integer
long Long
float Float
double Double
引用类型和原始类型的行为完全不一样,并且分别具有不同的语义。
1 int i=5; //原始类型
Integer j=new Integer(10);//对象引用
这两个变量都存储在局部变量表中,并且都是在java操作数堆栈中被操作的。原始类型和对象引用各占堆栈的32位。Integer类型对象对应的堆栈项并不是对象本身,而是一个对象引用,对象引用是指向对象所在堆中的某个区域指针。Java中的所有对象都要通过对象引用访问。而当声明了一个原始类型,就为类型本身声明了存储。
(1)哪些不属于java原始类型
A “abc”
B ‘ x’
C 100.09F
D ”hello”
E false
答案
Ad除外其他都是原始类型(八个不包含string),而ad是字符串,都是string对象类型
(2)String 和StringBuffer的区别
Java提供了两个字符串类:String 和StringBUffer。字符串String类提供了数值不可以改变的字符串,而StringBuffer类提供的字符串对象可以进行更改。
(3)指出java的原始数据类型并说出其分类
Java编程语言为8个原始基本类型:
boolean,char,byte,short,int,long,double,flout
逻辑类:boolean
boolean truth = true;
注意:在整数类型和boolean之间无转换计算.有些语言(特别强调的是C和C++)允许将数字值,转换成逻辑值,这在Java编程语言中是不允许的;boolean类型只允许使用boolean值.
if(a==2)条件表达式返回的是boolean.
文本类:char和String
char代表一个16-bit的Unicode字符.
必须包含用单引号(')引用的文字.
'\t' 一个制表符;
'\u????' 一个特殊的Unicode字符,????应严格使用四个16进制数进行替换.
String-不是原始类型,而是一个类,它被用来表示字符序列.(与C和C++不同String不能用\0作为结束);
-具有双引号引用的文字.
注意:String s = "Good, morning
\n";
//"\n"表示一个换行
System.out.println(s); //这里打印后会换2行
整数类:byte,short,int,long(注意java中整数类型都是带符号的)
1,采用3种进制十,八,十六进制
2 表示十进制的2
017 首位的0,表示这是一个八进制数
0x1A 前2位的0x,表示这是一个16进制数
2,具有缺省int(整数类文字属int类型,除非在后面直接跟一个字母"L")."L"表示一个long值
浮点(float和double):
浮点变量可用float或double来声明.如果一个数字包括小数点或指数部分,或者在数字后面带有字母F或f,D或d,则该
文字为浮点.
-缺省为double
-浮点文字包括小数点或下列各项之一
-E或e 增加指数值
-F或f(float) 32bits
-D或d(double) 64bits
System.out.println(123.4E+306D);//=1.234E308???
类型自动转换
...................char
........↓
byte→short→int→long
..... ... ↘
.......float → double
另外long int 和float double有可能损失精度
System.out.println((12.0==12));
12.0浮点型double 12数值型int
int→double自动转换 所以结果为真 返还布尔值TRUE
System.out.println(('a'==97.0));
"a"字符char 97.0为浮点值double
char→int→double自动转换
a的进制表示就是97
97==97.0所以结果为真 返还布尔值TRUE
(4)理解和掌握变量初始化
写Java代码的时候很少去关注成员变量的声明和初始化顺序,今天借此机会抛出一些问题:语言的设计者们为什么会这样设计?比如说很常见的一个问题:abstract(抽象)类不能用final进行修饰。这个问题比较好理解:因为一个类一旦被修饰成了final,那么意味着这个类是不能被继承的,而abstract(抽象)类又不能被实例化。如果一个抽象类可以是final类型的,那么这个类又不能被继承也不能被实例化,就没有存在的意义。从语言的角度来讲一个类既然是抽象类,那么它就是为了继承,所以给它标识为final是没有意义的。语言的设计者们当然不可能让这么大的一个bug产生。对于开发者而言抽象类不能修饰final可能就是一种约定俗成的规定,并没有特殊意义。我们完全可以往前想一点:为什么这么设计?
下面我所展示的一些代码实例也同样会采用我上面的一些思考方法。有一些是一些”契约“,并没有特别的缘由,可能用别的方法也是合理的。下面的代码会讲到初始化的一些策略,从实际的执行结果中得出一些结论。
- public class Test1 {
- {
- a = 1;
- //System.out.println(a);//这里会抛错。
- }
- private int a=2;//这里初始化一次,上面的动态块中也对a进行了赋值,这个时候a=?,为什么可以对a进行赋值,而不可以对a进行输出
- public static void main(String[] args){
- Test1 test1 = new Test1();
- System.out.println(test1.a);
- 10. }
11. }
看看上面的代码一,第一个问题就是这段代码能否编译通过。结果是能编译通过。这里说明一个问题就是变量的声明和赋值是两步操作?(这句话我先保留一半,在上面
的代码中有一行代码我注释掉了,这里会抛错,对于这个问题我也没有想明白为什么。)
第一个问题解决了。那下一个问题很显然最后输出的结果是什么?答案是“2”,这里可能会有些诧异。从直观上来讲就是说明在赋值的过程中是完全按照代码的前后顺序进
行。
- public class Test2 {
- {
- a = 4;
- }
- private final int a;//这里我并没有对a做初始化。
- public static void main(String[] args){
- 10. Test2 test2 = new Test2();
- 11. System.out.println(test2.a);
- 12. }
13. }
代码二”只是在“代码一”的基础上对成员变量a多修饰了一个final,另外我并没有立即初始化。第一个问题就是这段代码能不能编译通过,答案是能。在这里展示这段代码是为了后面做铺垫,因为这段代码仍然符合上面的“契约”。
- public class Test3 {
- {
- a = 4;
- }
- private static int a;
- public static void main(String[] args){
- 10. Test3 test3 = new Test3();//注意:这里开始new了一个对象
- 11. System.out.println(test3.a);
- 12. }
13. }
代码三在代码一的的基础上对于成员变量a多修饰了一个static。这里同样可以编译通过,最后输出的结果也皆大欢喜为4。这里要注意的是我是new了一个对象,而不是直接访问静态变量。
- public class Test3 {
- {
- a = 4;
- System.out.println(a);//这里不会报错,但是这条语句并不会执行
- }
- private static int a;
- public static void main(String[] args){
- System.out.println(a);
- 10. }
11. }
代码四在代码三的基础上把new 对象给去掉了,直接输出静态变量a。这时候就会出现非常诧异的结果0。对,你没有看错,结果是0。如果有兴趣的可以在a=4后面打印一条,会很清晰的发现并没有执行a=4那一条语句。这里先不解释,只看一下现象。
- public class Test3 {
- static{
- a = 4;
- //System.out.println(a);//这里会抛错。
- }
- private static int a;
- public static void main(String[] args){
- System.out.println(a);
- }
10. }
代码五和代码四和不同在于采用了静态初始化,最后的结论很简单,结果为4。这里有一个问题就是如果在a=4之后紧接着使用a就会报错。也就是说定义在声明之前的静态化块只能对声明变量进行赋值,并不能使用该变量。对于这一条规则我也不是特别理解,因为按照常理在赋值之后进行使用是一种再正常不过的事情,在这里只有记住这样一条规则。
- public class Test6 {
- {
- a = 4;
- }
- private static final int a;
- public static void main(String[] args){
- 10. System.out.println(a);
- 11. }
12. }
代码六是在代码一的基础上增加static final的修饰符。回到我们上面三段代码所问的问题,这次的答案是“否”,也就是说在这里是不能编译通过。在这里我估计有一部分人和我有同样的疑惑:为什么对于成员变量修饰单独修饰final或者static可以进行单独的初始化,而把两个修饰符合起来的时候就不行了呢?我们把这个问题要反过来问:如果可以这样进行初始化会产生什么问题,那么就可以知道为什么需要这样设计?
我们看代码三、代码四、代码五和代码六,这里估计会有点绕。上面也说了在代码三中的初始化块是执行了的,而代码四的初始化块没有执行,代码五的静态初始化块也执行了。所以问题归根结底就一条:静态初始化块和普通的初始化块在什么时候执行。结论就是在初始化阶段编译器会收集类中的类变量(区别实例变量)的赋值动作和静态语句块中的语句,而静态的调用并不会触发实例变量的初始化。
这里回到代码六,根据上面所得出的结论。变量a被修鉓成了static final,那么意味着有且仅有一次赋值。我们在访问a的同时,域中的a=4并未执行(根据代码四所得出的结论),这样就违背了final类型有且仅有一次赋值的这样一个约定。所以{a=4;}不管是放在声明的代码前还是声明的代码后都无法编译通过。