Java笔记01

简介: Java面试篇

1.谈谈对面向对象思想的理解

*     首先谈谈“面向过程”和“面向对象”,这两者是思考角度的差异,


      面向过程更多是以“执行者”的角度来思考问题,而面向对象更多是以“组织者”的角度来思考问题。

*     举个例子:比如要产生一个0-10之间的随机数,如果以“面向过程”的思维,


   那更多是关注如何去设计一个算法,然后保证比较均衡产生0-10的随机数,

   而面向对象的思维会更多关注找谁来帮我做这件事,比如random类,调用其中的方法即可。

*     面向对象三大特性:封装,继承,多态。


   封装:所有属性私有化,提供get/set方法。

   继承:复用代码,将代码的共性抽取到父类,在子类只需要写特殊的额外的扩展知识

   多态:父类引用指向不同的子类对象,让程序解耦

2.JDK,JRE,JVM有什么区别

JDK:Java Development Kit,Java开发工具包,

提供了java的开发环境和运行环境。包含了翻译Java源文件的编译器Javac,还有调试和分析的工具

JRE:java Runtime Environment,Java运行环境,包含Java虚拟机及一些基础类库

JVM:Java Virtual Machine,Java虚拟机,提供执行字节码文件的能力

如果只是运行Java程序,只需要安装JRE即可。

另外注意,JVM试试先Java跨平台的核心,但JVM本身并不是跨平台的,不同的平台需要安装不同的JVM

3.==和equals的区别

==比较的是值

比较基本的数据类型,比较的是数值

比较引用类型:比较引用指向的值(地址)

equals

默认比较的也是地址,因为这个方法的最初定义在Object上,默认的实现就是比较地址

自定义的类,如果需要比较的是内容,那么就要学String,重写equals方法

代码案例


`String s1 = new String("zs");

String s2 = new String("zs");

System.out.println(s1==s2);//false

String s3 = "zs";

String s4 = "zs";

System.out.println(s3==s4);//true

System.out.println(s3==s1);//false

String s5 = "zszs";

String s6 = s3+s4;

System.out.println(s5==s6);//false

final String s7 = "zs";

final String s8 = "zs";

String s9 = s7+s8;

System.out.println(s5==s9);//true

final String s10 = s3+s4;

System.out.println(s9==s10);//false`


final修饰类,表示不可变,不可继承,比如String,不可变性

final修饰方法,表示该方法不可重写

final修饰常量,这个变量就是常量

**注意**

修饰的基本数据类型,这个值本身不能修改

修饰的是引用类型,引用的指向不能修改


4.String,stringBuffer,StringBuilder区别

String跟其他两个类的区别是

   Stringfinal类型,每次声明的都是不可变得对象

   所以每次操作都会产生新的String对象,然后将指针指向新的String对象

StringBuffer,StringBuilder都是在原有对象上进行操作,

所以需要经常改变字符串内容,则建议采用这两者。

StringBuffer,StringBuilder

前者是线程安全的,后者是线程不安全的

线程不安全性能更高,所以在开发中,优先采用StringBuilder,

**StringBuilder > StringBuffer > String**

在开发中,一般用StringBuilder来解决字符串拼接的问题而写到方法里

StringBuilder sb = new StringBuilder();

sb.append("");

当调用的时候意味着每一个线程会独享每一个StringBuilder,从而不会产生线程安全的问题



**不要产生这样的思想:**

不考虑安全的情况,选用StringBuilder

不考虑性能的情况,选用StringBuffer    

什么时候会考虑线程安全问题?

多线程访问同一个资源的时候才需要,单线程不需要考虑


5.接口和抽象类的区别

*   JDK1.8之前

   *   语法

       *    抽象类:方法可以有抽象的,也可以有非抽象的,有构造器

       *    接口:方法都是抽象的,属性都是常量,默认有public static final修饰

   *   设计

       *   抽象类:同一类事物的抽取,比如针对Dao层操作的封装,如:BaseDao,BaseServiceImpl

       *   接口:通常更像是一种标准的制定,定制系统之间对接的标准

       *   例子:

       *   1.单体项目,分层开发,interface作为各层之间的纽带,在controller中注入IUserService,在Service注入IUserDao

       *   2.分布式项目,面向服务的开发,抽取服务Service,这个时候,就会产生服务的提供者和服务的消费者两个角色

       *   这两个之间的纽带依然是接口

*   JDk1.8之后

   *   接口里面可以有实现的方法,注意要在方法的声明上加上default或者static


  最后区分几个概念

   *   多继承,多重继承,多实现

       *   多重继承:A->B->C (爷孙三代的关系)

       *   对实现:person implement IRunable,IEatable(符合多项国际化标准)

       *   多继承:接口可以多继承,类只支持单继承  


6.算法题 n的阶乘

求n的阶乘

1.什么是递归?

   递归就是方法内部调用自身

   递归的注意事项:

   找到规律,编写递归公式

   找到出口(边界值),让递归有结束边界

   注意:如果递归太多层,或者没有正确结束递归,则会出现“栈内存溢出Error”

   问题:为什么会出现栈内存溢出,而不是堆内存溢出?

        当调用方法时,会栈中创建一个栈帧,反复调用之后就会溢出

       

   

`privatestaticintgetResult(int n) {

   if (n<0){

       thrownewValidateException("非法参数");

   }

   if( n==1 || n==0){

       return1;

   }

       returngetResult(n-1)*n;

   }`


7.算法题-求解斐波那契数列的第N个数是几

数字的规律是1,1,2,3,5,8,13,21

分析编写如下

   `/*

规律:每个数等于前两个数之和

出口:第一项和第二项都等于1

*/

publicstaticintgetFeiBo(int n){

   if ( n<0 ){

       return-1;

}

   if( n==1 || n==2 ) {

       return1;

}else{

       returngetFeiBo(n-1)+getFeiBo(n-2);

}

}`


8.Integer&int(缓存&自动装箱和拆箱)

`Integer i1 = newInteger(12);

Integer i2 = newInteger(12);

System.out.println(i1 == i2);//false

Integer i3 = 126;

Integer i4 = 126;

int i5 = 126;

System.out.println(i3 == i4);//true

System.out.println(i3 == i5);//true

Integer i6 = 128;

Integer i7 = 128;

int i8 = 128;

System.out.println(i6 == i7);//false

System.out.println(i6 == i8);//true`


9.方法的重载和重写

*重载:发生在一个类里,方法名相同,参数不同,参数列表不同(混淆点:跟返回类型没关系)

*重写:发生在父类和子类之间的,方法名相同,参数列表相同

`/*

   此代码不构成重载和重写,会在编译时报错

   */

publicdoubleadd(int a,int b)

publicintadd(int a,int b)`


10.谈谈ArrayList和Linkedlist的区别

1.底层数据结构的差异

   ArrayList:数组,连续一块内存空间

   LinkedList:双向链表,不是连续的内存空间

 

2.一个常规的言论

   ArrayList:查找快,因为是连续的内存空间,方便寻址,但删除,插入慢,因为需要发生数据迁移

   LinkedList:查找慢,因为需要通过指针一个一个寻找,但删除,插入快,因为只要改变前后节点的指针指向即可

   但是并不严谨

   比如说

   ArrayList->a,b,c,d

   LinkedList->a,b,c,d

   当查找第2个元素是ArrayList自然会比LinkedList快

   若是需要查找b元素的话,这两个List都只能通过遍历的方式查找,速度都差不多,因为不知道b是哪个元素,所有ArrayList没有优势

   当要在中间插入一个元素时,LinkedList>ArrayList

   若是在末尾插入一个元素,速度也是差不多的

   

     

     


   




相关文章
|
2月前
|
Java 开发工具 Android开发
Kotlin语法笔记(26) -Kotlin 与 Java 共存(1)
本系列教程笔记详细讲解了Kotlin语法,适合需要深入了解Kotlin的开发者。若需快速学习Kotlin,建议查看“简洁”系列教程。本期重点介绍了Kotlin与Java的共存方式,包括属性、单例对象、默认参数方法、包方法、扩展方法以及内部类和成员的互操作性。通过这些内容,帮助你在项目中更好地结合使用这两种语言。
45 1
|
2月前
|
Java 开发工具 Android开发
Kotlin语法笔记(26) -Kotlin 与 Java 共存(1)
Kotlin语法笔记(26) -Kotlin 与 Java 共存(1)
34 2
|
2月前
|
Java 开发工具 Android开发
Kotlin教程笔记(26) -Kotlin 与 Java 共存(一)
Kotlin教程笔记(26) -Kotlin 与 Java 共存(一)
|
26天前
|
安全 Java 编译器
Kotlin教程笔记(27) -Kotlin 与 Java 共存(二)
Kotlin教程笔记(27) -Kotlin 与 Java 共存(二)
|
26天前
|
Java 开发工具 Android开发
Kotlin教程笔记(26) -Kotlin 与 Java 共存(一)
Kotlin教程笔记(26) -Kotlin 与 Java 共存(一)
|
26天前
|
Java 编译器 Android开发
Kotlin教程笔记(28) -Kotlin 与 Java 混编
Kotlin教程笔记(28) -Kotlin 与 Java 混编
|
12天前
|
Java 编译器 Android开发
Kotlin教程笔记(28) -Kotlin 与 Java 混编
Kotlin教程笔记(28) -Kotlin 与 Java 混编
10 0
|
2月前
|
Java 编译器 Android开发
Kotlin语法笔记(28) -Kotlin 与 Java 混编
本系列教程详细讲解了Kotlin语法,适合需要深入了解Kotlin的开发者。对于希望快速学习Kotlin的用户,推荐查看“简洁”系列教程。本文档重点介绍了Kotlin与Java混编的技巧,包括代码转换、类调用、ProGuard问题、Android library开发建议以及在Kotlin和Java之间互相调用的方法。
24 1
|
2月前
|
安全 Java 编译器
Kotlin语法笔记(27) -Kotlin 与 Java 共存(二)
本教程详细讲解Kotlin语法,适合希望深入了解Kotlin的开发者。若需快速入门,建议查阅“简洁”系列教程。本文重点探讨Kotlin与Java共存的高级话题,包括属性访问、空安全、泛型处理、同步机制及SAM转换等,助你在项目中逐步引入Kotlin。
27 1
|
2月前
|
Java 编译器 Android开发
Kotlin语法笔记(28) -Kotlin 与 Java 混编
Kotlin语法笔记(28) -Kotlin 与 Java 混编
27 2