面向对象的特征有哪些方面?

原来学的时候说是三种特征,即封装、继承和多态。

现在一般说面向对象有四大特性,即抽象、封装、继承和多态。

1.抽象:将同类对象的共同特征提取出来构造类。

2.封装:将数据隐藏起来,对数据的访问只能通过特定接口。

3.继承:基于基类创建新类。

4.多态:不同子类型对象对相同消息做出不同响应。

访问修饰符public,private,protected以及不写(默认)的区别?

访问权限逐级递减,public>protected>default(不写)>private

public最高可以被其他包访问

protected最高可以被子类访问

default(默认,不写)最高可以被同包访问

private只能在当前类访问

String是基本数据类型吗?

不是。Java只有8个基本数据类型,分别是byte(字节类型)、short(短整型)、int(整型)、long(长整型)、float(浮点型)、double(双精度浮点型)、char(字符型)、boolean(布尔类型);除了基本类型(Primitive Type),剩下的都是引用类型(Reference Type),Java5以后引入的枚举类型也算是一种比较特殊的引用类型。

float f = 3.4;这个表达式是否正确?

不正确。在Java里面,没有小数点的默认是int类型,有小数点的默认是double类型。因此3.4是双精度数,将双精度浮点型(double)赋值给浮点型(float)属于下转型(down-casting,也称为窄化),会造成精度损失,因此需要强制类型转换 float f = (float)3.4 或者写成 float f = 3.4f 。

short s1 = 1; s1 = s1 + 1; 这个表达式有错吗?short s1 = 1; s1 += 1; 这个表达式有错吗?

前面这个表达式,由于1是int类型,因此 s1 + 1 的运算结果也是int类型,再把int类型的结果赋值给short类型的s1是会报错的,需要对结果进行强制类型转换才能通过编译。

后面这个表达式, s1 += 1; 相当于 s1 = (short)(s1 + 1); 表达式,其中会有隐含的强制类型转换,可以正常通过编译。

Java中有没有goto?

goto是Java中的保留字,但是在目前版本的Java中没有使用,即没有goto语句。

int和Integer有什么区别?

Java是一个近乎纯洁的面向对象编程的语言,但是为了编程的方便还是引入了基本数据类型。为了能够将这些基本数据类型当作对象操作,Java为每一个基本数据类型都引入了相应的包装类型(Wrapper Class),int类型的包装类型就是Integer。从Java5开始引入了自动装箱/拆箱机制,使得二者可以相互转换。

Java为每个原始类型(基本数据类型)提供了相应的包装类型:

原始类型:byte,short,int,long,float,double,char,boolean

包装类型:Byte,Short,Integer,Long,Float,Double,Character,Boolean

Integer a = new Integer(3);
Integer b = 3; // 将3自动装箱成Integer类型
int c = 3;
System.out.println(a == b); // false 两个引用没有引用同一对象
System.out.println(a == c); // true a自动拆箱成int类型再和c比较

下面这段代码也和自动装箱/拆箱有关系:

Integer f1 = 100, f2 = 100, f3 = 128, f4 = 128;
System.out.println(f1 == f2); // true
System.out.println(f3 == f4); // false

为什么第一个运算的结果是true,第二个却是false呢?

首先注意,f1、f2、f3和f4都是Integer对象引用,所以下面的==运算比较的不是值而是引用。

装箱的本质是什么呢?是当我们给一个Integer对象赋一个int类型值的时候,会调用Integer类的静态方法valueOf(),看看valueOf()方法的源代码就知道为什么会产生这样的结果。

public static Integer valueOf(int i) {
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
}

IntegerCache是Interger类的内部类,其代码如下:(好好研究)

private static class IntegerCache {
static final int low = -128;
static final int high;
static final Integer cache[]; static {
// high value may be configured by property
int h = 127;
String integerCacheHighPropValue =
sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high");
if (integerCacheHighPropValue != null) {
try {
int i = parseInt(integerCacheHighPropValue);
i = Math.max(i, 127);
// Maximum array size is Integer.MAX_VALUE
h = Math.min(i, Integer.MAX_VALUE - (-low) -1);
} catch( NumberFormatException nfe) {
// If the property cannot be parsed into an int, ignore it.
}
}
high = h; cache = new Integer[(high - low) + 1];
int j = low;
for(int k = 0; k < cache.length; k++)
cache[k] = new Integer(j++); // range [-128, 127] must be interned (JLS7 5.1.7)
assert IntegerCache.high >= 127;
} private IntegerCache() {}
}

简单得说,如果整型字面量的值的范围在-128到127之间,那么就不会new一个新的Integer对象,而是直接引用常量池中的Integer对象。

&和&&的区别?

&运算符有两种用法,一是按位与,二是逻辑与。&&运算符是短路与。

逻辑与跟短语与的差别是非常大的,虽然二者都要求运算符左右两边的布尔值都是true整个表达式的值才是true,但是如果&&运算符左边的表达式是false的话,右边的表达式会直接被短路掉,不会进行运算,这就是&&运算符被称为短路运算的原因。

很多时候我们需要用到的可能都是&&而不是&,例如在验证用户登录的时候,判定用户名不是null而且不是空字符串,应当写为:userName != null && !userName.equals(""),二者的顺序不能交换,更不能使用&运算符,因为第一个条件如果不成立,根本不能进行字符串的equals比较,否则会产生NullPointerException异常。

JavaScript中的短路运算更是强大,因为运算符两边不仅仅能是表达式,还能是值。

解释内存中的栈(Stack)、堆(Heap)和方法区(Method Area)的用法。

通常我们定义一个基本数据类型的变量,一个对象的引用,还有就是函数调用的现场保存都使用JVM中的栈空间;

而通过new关键字和构造器创建的对象则放在堆空间,堆是垃圾收集器管理的主要区域,由于现在的垃圾收集器都采用分代收集算法,所以堆空间还可以细分为新生代和老生代,再具体一点可以分为Eden、Survivor(又可分为From Survivor和To Survivor)、Tenured;

方法区和堆都是各个线程共享的内存区域,用于存储已经被JVM加载的类信息、常量、静态变量、JIT编译器编译后的代码等数据;程序中的字面量(Literal),如直接书写的100、"hello"和常量都是放在常量池中,常量池是方法区的一部分。

栈空间操作起来最快但是栈很小,通常大量的对象都是放在堆空间,栈和堆的大小都可以通过JVM的启动参数来进行调整,栈空间用光了会引发StackOverflowError,而堆和常量池空间不足则会引发OutOfMemoryError。

String str = new String("hello");

上面的语句中,变量str放在栈区,用new关键字创建出来的字符串对象放在堆区,而"hello"这个字面量是放在方法区的。

较新版本的Java(Java6的某个更新开始)中,由于JIT编译器的发展和"逃逸分析"技术的逐渐成熟,栈上分配、标量替换等优化技术使得对象一定分配再堆上这件事情已经变得不那么绝对了。

运行时常量池相当于Class文件,因此常量池具有动态性。即Java语言并不要求常量一定只有编译期间才能产生,运行期间也可以将新的常量放入池中,String类的intern()方法就是这样的。

String s1 = new StringBuilder("go").append("od").toString();
System.out.println(s1.intern() == s1); // true
String s2 = new StringBuilder("ja").append("va").toString();
System.out.println(s2.intern() == s2); // false

为什么会产生这样的结果,要好好思考一下。

Math.round(11.5)等于多少?Math.round(-11.5)等于多少?

Math.round(11.5)的结果是12,Math.round(-11.5)的结果是-11。

四舍五入的原理是在参数上加0.5,然后进行向下取整。

那么Math.round(11.6)和Math.round(-11.6)的结果又是什么呢?

答案是12和-12。

11.6 + 0.5 = 12.1,然后向下取整为12;

-11.6 + 0.5 = -11.1,然后向下取整为-12。

要特别理解向下取整是什么意思。

switch是否能作用在byte上,是否能作用在long上,是否能作用在String上?

在Java5以前,switch(expr)中,expr只能是byte、short、char、int。

从Java5开始,Java中引入了枚举类型,expr也可以是enum类型,从Java7开始,expr还可以是字符串类型(String)。

但是长整型(long)在目前的所有Java版本中都是不可以的。

用最有效率的方法计算2乘以8?

2<<3(左移三位相当于乘以2的三次方,右移三位相当于除以2的三次方)。

我们为编写的类重写hashCode()方法的时候,可能会看到如下所示的代码,其实我们不太理解为什么要使用这样的乘法运算来产生哈希码(散列码),而且为什么这个数是素数,为什么通常选择31这个数?

选择31,是因为可以用移位和减法运算来代替乘法,从而得到更好的性能。说到这里你可能已经想到了:31 * num等价于(num << 5) - num,左移5位相当于乘以2的5次方再减去自身就相当于乘以31,现在的VM都能自动完成这个优化。

public class PhoneNumber {
private int areaCode;
private String prefix;
private String lineNumber; @Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + areaCode;
result = prime * result
+ ((lineNumber == null) ? 0 : lineNumber.hashCode());
result = prime * result + ((prefix == null) ? 0 : prefix.hashCode());
return result;
} @Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
PhoneNumber other = (PhoneNumber) obj;
if (areaCode != other.areaCode)
return false;
if (lineNumber == null) {
if (other.lineNumber != null)
return false;
} else if (!lineNumber.equals(other.lineNumber))
return false;
if (prefix == null) {
if (other.prefix != null)
return false;
} else if (!prefix.equals(other.prefix))
return false;
return true;
} }

数组中有没有length()方法?String有没有length()方法?

数组没有length()方法,但是有length的属性。

String[] stringArr = {"1", "2", "3"};
System.out.println(stringArr.length); //

String有length()方法,没有length属性。

System.out.println("12345".length); //

在JavaScript中,获得字符串的长度是通过length属性得到的,这一点容易和Java混淆。

在Java中,如何跳出当前的多重嵌套循环?

在最外层循环前加一个标记如A,然后用break A;可以跳出多重循环。(Java中支持带标签的break和continue语句,作用有点类似于C和C++中的goto语句,但是就像要避免使用goto一样,应该避免使用带标签的break和continue,因为它不会让你的程序变得更优雅,很多时候甚至有相反的作用,所以这种语法非常不建议使用)。

构造器(Constructor)是否可以被重写(Override)?

构造器不能被继承,因此不能被重写(子类),但是可以被重载(同个类)。

两个对象值相同(x.equals(y) == true)但是却可有不同的hashCode,这句话对不对?

不对。如果两个对象x和y满足equals()结果为true,那么它们的哈希码(hashCode)应当相同。

Java对于equals)(方法和hashCode()方法是这样规定的:

1.如果两个对象相同(equals()方法返回true),那么它们的hashCode值一定要相同;

2.如果两个对象的hashCode相同,它们并不一定相同。

当然,你未必要按照要求去做,但是如果你违背了上述原则,就会发现在使用容器时,相同的对象可以出现在Set集合中,同时增加新元素的效率会大大下降(对于使用哈希存储的系统,如果哈希码频繁地冲突将会造成存取性能急剧下降)。

是否可以继承String类?

String类是final类,不可以被继承。

继承Stirng本身就是一个错误的行为,对String类型最好的重用方式是关联关系(Has-A)和依赖关系(Use-A)而不是继承关系(Is-A)。

"如果你想去远方,就要先想办法离开你现在站的位置。"

java面试题2019的更多相关文章

  1. 2019百度阿里Java面试题(基础+框架+数据库+分布式+JVM+多线程)

    前言 很多朋友对面试不够了解,不知道如何准备,对面试环节的设置以及目的不够了解,因此成功率不高.通常情况下校招生面试的成功率低于1%,而社招的面试成功率也低于5%,所以对于候选人一定要知道设立面试的初 ...

  2. 整理了2019年上千道Java面试题,近500页文档,用了1个月时间!

    spring 面试题 1.一般问题 1.1.不同版本的 spring Framework 有哪些主要功能? 1.2.什么是 spring Framework? 1.3.列举 spring Framew ...

  3. 2019年 Java 面试题解析

    2019年 Java 面试题解析 转载地址:https://www.cnblogs.com/Zz-maker/p/11193930.html 作者: Zz_maker 包含的模块: 本文分为十九个模块 ...

  4. 2019 Java面试题

    马上又是一个金九银十的招聘旺季,小编在这里给大家整理了一套各大互联网公司面试都喜欢问的一些问题或者一些出场率很高的Java面试题,给在校招或者社招路上的你一臂之力. 首先我们需要明白一个事实,招聘的一 ...

  5. 2019年Java面试题基础系列228道,题目汇总,可以先看会多少

    Java面试题(一) 1.面向对象的特征有哪些方面? 2.访问修饰符 public,private,protected,以及不写(默认)时的区别? 3.String 是最基本的数据类型吗? 4.flo ...

  6. 金三银四季来了!Java 面试题大放送,能答对70%就去BATJTMD试试~

    摘要: 2019,相对往年我们会发现今年猎头电话少了,大部分企业年终奖缩水,加薪幅度也不如往年,选择好offer就要趁早,现在开始准备吧,刷一波Java面试题,能回答70%就去BATJTMD大胆试试~ ...

  7. 【Java面试题系列】:Java基础知识常见面试题汇总 第一篇

    文中面试题从茫茫网海中精心筛选,如有错误,欢迎指正! 1.前言 ​ 参加过社招的同学都了解,进入一家公司面试开发岗位时,填写完个人信息后,一般都会让先做一份笔试题,然后公司会根据笔试题的回答结果,确定 ...

  8. java面试宝典2019(好东西先留着)

    java面试宝典2019 1.meta标签的作用是什么 2.ReenTrantLock可重入锁(和synchronized的区别)总结 3.Spring中的自动装配有哪些限制? 4.什么是可变参数? ...

  9. 挑战10个最难的Java面试题(附答案)【上】

    欢迎添加华为云小助手微信(微信号:HWCloud002 或 HWCloud003),验证通过后,输入关键字"加群",加入华为云线上技术讨论群:输入关键字"最新活动&quo ...

随机推荐

  1. Go学习笔记05-指针

    目录 参数传递 var a int = 2 var pa *int = &a *pa = 3 fmt.Println(a) Go语言中 指针不能运算 参数传递 不像C++.Java.Pytho ...

  2. 创建ssh 服务的镜像

    $ sudo docker run -ti ubuntu:14.04 /bin/bash #首先,使用我们最熟悉的 「-ti」参数来创建一个容器. root@fc1936ea8ceb:/# sshd ...

  3. JavaScript如何计算两个日期间的时间差

    <script type="text/javascript"> /* * 获得时间差,时间格式为 年-月-日 小时:分钟:秒 或者 年/月/日 小时:分钟:秒 * 其中 ...

  4. docker实战练习(一)

    systemctl start docker systemctl pause docker systemctl unpause docker systemctl start docker system ...

  5. 新手PHP连接MySQL数据库出问题(Warning: mysqli_connect(): (HY000/1045): Access denied for user 'root'@'localhost' (using password: YES))

    我用的环境是wampServer集成的软件包 在php连接MySQL数据库的时候老是出现这个问题Warning: mysqli_connect(): (HY000/1045): Access deni ...

  6. # linux文件系统(inode block superblock)

    先说一下格式化:每种操作系统所设置的文件属性/权限并不相同,为了存放这些文件所需的数据,因此就需要将分区格式化,以成为操作系统能够利用的文件系统格式.linux的文件格式为Ext2/Ext3,现在好像 ...

  7. 18.JAVA经典编程题(50题及答案)

    用oop做一个进销存系统:1.货物对象属性:编号(唯一),名称,单价,类别,厂家,厂家地址,厂家联系方式,库存,最后进货时间2.功能:登录,入库,出库,库存查询,操作记录查询3.功能描述:登录:管理员 ...

  8. Y7000安装驱动显卡问题

    整体 https://blog.csdn.net/la9881275/article/details/86720752 详细 https://blog.csdn.net/luteresa/articl ...

  9. lintcode 515. Paint House

    Paint House 自己的写法: class Solution { public: /** * @param costs: n x 3 cost matrix * @return: An inte ...

  10. 强大的原生DOM选择器querySelector和querySelectorAll

    在传统的 JavaScript 开发中,查找 DOM 往往是开发人员遇到的第一个头疼的问题,原生的 JavaScript 所提供的 DOM 选择方法并不多,仅仅局限于通过 tag, name, id ...