1.String类可以被继承吗?

 不能。String类在声明中使用final关键字修饰符。使用final关键字修饰的类无法被继承。

Java语言的开发者为什么要将String类定义为final类呢?

•因为当字符串是不可变的,字符串池才有可能实现。字符串池的实现可以在运行时节约很多的堆空间,因为不懂的字符串变量都指向池中的同一个字符串。如果字符串是可变的,那么字符串的驻留将不可能实现,因为这样的话,

如果变量改变了它的值,那么其他指向这个值的变量也会一起改变。如果字符串是可变的那边会引起很严重的安全问题。

•因为字符串是不可变的,所以是多线程安全的。同一个字符串实例可以可以被多个线程共享。这样便不用因为线程安全问题而使用同步。

•因为字符串是不可变的,所以在它创建的时候HashCode就被缓存了,不需要重新计算。这就使得字符串很适合作为Map中的键,字符串中的处理速度要快于其他的键对象。这就是HashMap中的键往往都使用字符串。

2.final修饰符在Java中有什么用?

•final修饰的变量叫做常量,常量必须初始化,初始化后的值不能被修改。

•final修饰的方法不能被重载也不能被重写。

•final修饰的类叫最终类,该类不能被继承。

3.JDK和JRE有什么区别?

JDK:Java Development Kit的简称,Java开发工具包,包含Java开发环境和运行环境。

JRE:Java Runtime Enviroment的简称,Java运行环境,为Java的运行提供了所需的环境。

4.==和equals的区别是什么?

 •==对于基本数据类型和引用类型的作用效果是不同,对于基本数据类型比较的值是否相等,对于引用类型比较的应用是否相等。

•equals默认情况先比较的引用是否相等,只是很多类重写了Object类的equals方法,比如String,Integer把equals方法变成了比较的值是否相等,所以一般情况下equals比较的是值是否相等。

5.&和&&的区别?

 &和&&在程序中最终的运算结果是一致的,区别在于:

•&运算符是:逻辑与,&不管左边表达式的结果是true还是false,右边的表达式都一定会执行;&运算符还可以使用在二进制位运算上。

•&&运算符是:短路与,&&运算符当左边的表达式结果是false时,右边的表达式不执行,存在短路现象。

6.重载(overload)和重写(override)的区别?

方法的重载和重写都是实现多态的方式,区别在于:

•重载实现的是编译时的多态性;重载发生在一个类中,同名的方法如果有不同的参数列表(参数个数,参数类型,顺序不同)则视为重载。

•重载实现的是运行时的多态性;重写发生在子类与父类之间,重写要求子类重写父类的方法后与父类重写的方法有相同的返回类型,比父类被重写方法更好访问,不能比父类被重写方法声明更多的异常(里氏代换原则)。

方法重写的规则:

•参数列表、方法名、返回值类型必须完全一致;

•构造方法不能被重写;

•声明为 final 的方法不能被重写;

•声明为 static 的方法不存在重写(重写和多态联合才有意义);

•访问权限不能比父类更低;

•重写之后的方法不能抛出更宽泛的异常;

7.为什么方法不能根据返回类型来区分重载?

Java 字符串编码面试题 java关于字符串面试题_时间复杂度

在Java语言中,调用一个方法,即使这个方法有返回值,我们也可以不接收这个返回值,例如以上两个方法doSome(),Java编译器无法区分调用的具体是哪个方法。所以对于编译器来说,

doSome()方法不是重载而是重复了,编译器报错。所以区分这两个方法不能依靠方法的返回值类型。

8.抽象类(abstract)和接口(interface)有何异同?

•在实现方面:抽象类的子类用extends关键字来继承;接口必须使用impelements关键字来实现接口。

•关于构造函数:抽象类可以有构造函数,接口不能有。

•关于main方法:抽象了可以有mian方法,并且我们能够运行它,但接口不能有。

•在实现数量:类可以实现多个接口,但只能继承一个抽象类。

•关于访问修饰符:接口中的方法默认的修饰符是public;抽象类中的访问修饰符可以是任意访问修饰符。

9.String str = "i" 和String str = new String("1")一样吗?

不一样,因为内存的分配方式不一样。String str = "i"的方式JVM会将其分配到常量池中,而String str = new String("i")JVM会将其分配到堆内存中。

10.阐述静态变量和实例变量的区别?

不管创建多少个对象,静态变量在内存中有且仅有一个;实例变量必须依存于某一实例,需要先创建对象然后通过对象才能访问到它。静态变量可以实现让多个对象共享内存。

11.String s = "Hello";s = s + " world!";这两行代码执行后,原始的 String 对象中的内容变了没有?

没有,因为 String被设计成不可变类,所以它的所有对象都是不可变对象。在这段代码中,s原先指向一个 String 对象,内容是 "Hello",然后对 s 进行了“+”操作,但是 s 所指向的那个对象是还是没有改变,这时s不指向原来那个对象,而指向了另一个 String 对象,内容为"Hello world!",原来那个对象还存在于内存之中,只是 s 这个引用变量不再指向它。

12.Java 中操作字符串都有哪些类?它们之间有什么区别?

操作字符串的类有:String、StringBuffer、StringBuilder。
String 和 StringBuffer、StringBuilder 的区别在于 String 声明的是不可变的对象,每次操作都会生成新的 String 对象,再将指针指向新的 String 对象,而 StringBuffer 、 StringBuilder 可以在原有对象的基础上进行操作,所以在经常改变字符串内容的情况下最好不要使用 String。
StringBuffer 和 StringBuilder 最大的区别在于,StringBuffer 是线程安全的,而 StringBuilder 是非线程安全的,但 StringBuilder 的性能却高于 StringBuffer,所以在单线程环境下推荐使用 StringBuilder,多线程环境下推荐使用 StringBuffer。

13.抽象类一定要有抽象方法吗?

不需要,抽象类不一定要有抽象方法。

14.Java中IO流分为几种?

按功能来分:输入流(input),输出流(outpu)。

按类型来分:字节流和字符流。

15.BIO、NIO和AIO有什么区别?

BIO:Block IO 同步阻塞式 IO,就是我们平常使用的传统 IO,它的特点是模式简单使用方便,并发处理能力低。

NIO:New IO 同步非阻塞 IO,是传统 IO 的升级,客户端和服务器端通过 Channel(通道)通讯,实现了多路复用。

AIO:Asynchronous IO 是 NIO 的升级,也叫 NIO2,实现了异步非堵塞 IO ,异步 IO 的操作基于事件和回调机制。

16.普通类和抽象类有什么区别?

•普通类不能包含抽象方法,抽象类可以包含抽象方法。

•普通类可以直接实例化,而抽象类不能被直接实例化。

 17.Files常用的方法都有那些?

•Files.exists();检测文件路径是否存在。

•Files.createFile();创建文件。

•Files.createDirectory();创建目录。

•Files.delete();删除一个文件或者目录。

•Files.copy();复制一个文件。

•Files.move();移动一个文件。

•Files.size();查看文件个数。

•Files.read();读取文件。

•Files.write();写入文件。

18.String类的常用方法有哪些?

•indexof();返回指定字符的的索引。

•charAt();返回指定索引处的字符。

•replace();字符串替换。

•trim();去除字符串两端空格。

•splt();字符串分割,返回分割后的字符串数组。

•getBytes();返回字符串byte类型数组。

•length();返回字符串长度。

•toLowerCase();将字符串转换为小写字母。

•toUpperCase();将字符串转换为大写字母。

•substring();字符串截取。

•equals();比较字符串是否相等。

19.简述Java math类中三个方法ceil,floor,round。

•ceil()方法表示向上取整。Math.ceil(12.3)的结果是13,Math.ceil(-12.7)的结果是12。

•floor()方法表示向下取整。Math.floor(12.7)的结果是12,Math.floor(-12.3)的结果是-13。

•round()方法表示"四舍五入"。Math.round(12.3)的结果是12,Math.round(-12.7)的结果是-13。

20.char型变量中能否能不能存储一个中文汉字,为什么?

char可以存储一个中文汉字,因为Java中使用的编码是Unicode(不选择不选择任何特定的编码,直接使用字符在字符集中的编号,这是统一的唯一方法),一个char 类型占2个字节(16 比特),所以放一个中文是没问题的。

21.简述servlet(服务连接器)的生命周期

servlet简介:称为小服务程序或者服务连接器,用Java编写的服务器端程序,具有独立平台和协议的特性,主要的功能是在于交互式地浏览和生成数据,生成动态的web数据。

servlet的生命周期是指servlet从加载、实例化、初始化、服务(请求处理)到销毁的一个过程,也就是servlet从出生到结束。

服务器启动时或者第一次请求servlet时,就会初始化一个servlet对象,就会执行初始化方法init(servletConfig),该servlet去处理客户端请求,service(ServeltRequset req,ServeltResponse res)方法中执行,最后服务器关闭时,才会销毁这个servlet。

22.cookie的弊端?

•安全隐患,cookie使用明文传输,如果有人拦截了cookie则可以获取所有的session信息。

•cooke的数量和长度限制,每个domian最多只能有20条cookie,每个cookie长度不能超过4KB,否则会被截掉。

最多只能有20条cookie,每个cookie长度不能超过4KB,否则会被截掉。

22.Session的生命周期?

Session生效:

Sessinon在用户第一次访问服务器时创建,需要注意只有访问JSP、Servlet等程序时才会创建Session,只访问HTML、IMAGE等静态资源并不会创建Session,可调用request.getSession(true)强制生成Session。

Session失效:

1.服务器会把长时间没有活动的Session从服务器内存中清除,此时Session便失效。Tomcat中Session的默认失效时间为20分钟。

2.调用Session的invalidate方法。

23.JSP和Servlet的区别?

1、jsp经编译后就变成了Servlet。

2、jsp更擅长表现于页面显示,servlet更擅长于逻辑控制。

3、Servlet中没有内置对象,Jsp中的内置对象都是必须通过HttpServletResponse对象以及HttpServlet对象得到。

4、而Servlet则是个完整的Java类,这个类的Service方法用于生成对客户端的响应。


 

24.Java中HashMap的底层原理?

HashMap是基于hashing的原理,我们使用put(key, value)存储对象到HashMap中,使用get(key)从HashMap中获取对象。当我们给put()方法传递键和值时,我们先对键调用hashCode()方法,返回的hashCode用于找到bucket位置来储存Entry对象。”这里关键点在于指出,HashMap是在bucket中储存键对象和值对象,作为Map.Entry。这一点有助于理解获取对象的逻辑。如果你没有意识到这一点,或者错误的认为仅仅只在bucket中存储值的话,你将不会回答如何从HashMap中获取对象的逻辑。这个答案相当的正确,也显示出面试者确实知道hashing以及HashMap的工作原理。但是这仅仅是故事的开始,当面试官加入一些Java程序员每天要碰到的实际场景的时候,错误的答案频现。下个问题可能是关于HashMap中的碰撞探测(collision detection)以及碰撞的解决方法:

“当两个对象的hashcode相同会发生什么?” 从这里开始,真正的困惑开始了,一些面试者会回答因为hashcode相同,所以两个对象是相等的,HashMap将会抛出异常,或者不会存储它们。然后面试官可能会提醒他们有equals()和hashCode()两个方法,并告诉他们两个对象就算hashcode相同,但是它们可能并不相等。一些面试者可能就此放弃,而另外一些还能继续挺进,他们回答“因为hashcode相同,所以它们的bucket位置相同,‘碰撞’会发生。因为HashMap使用链表存储对象,这个Entry(包含有键值对的Map.Entry对象)会存储在链表中。”这个答案非常的合理,虽然有很多种处理碰撞的方法,这种方法是最简单的,也正是HashMap的处理方法。但故事还没有完结,面试官会继续问:

“如果两个键的hashcode相同,你如何获取值对象?” 面试者会回答:当我们调用get()方法,HashMap会使用键对象的hashcode找到bucket位置,然后获取值对象。面试官提醒他如果有两个值对象储存在同一个bucket,他给出答案:将会遍历链表直到找到值对象。面试官会问因为你并没有值对象去比较,你是如何确定确定找到值对象的?除非面试者直到HashMap在链表中存储的是键值对,否则他们不可能回答出这一题。

其中一些记得这个重要知识点的面试者会说,找到bucket位置之后,会调用keys.equals()方法去找到链表中正确的节点,最终找到要找的值对象。完美的答案!

许多情况下,面试者会在这个环节中出错,因为他们混淆了hashCode()和equals()方法。因为在此之前hashCode()屡屡出现,而equals()方法仅仅在获取值对象的时候才出现。一些优秀的开发者会指出使用不可变的、声明作final的对象,并且采用合适的equals()和hashCode()方法的话,将会减少碰撞的发生,提高效率。不可变性使得能够缓存不同键的hashcode,这将提高整个获取对象的速度,使用String,Interger这样的wrapper类作为键是非常好的选择。

如果你认为到这里已经完结了,那么听到下面这个问题的时候,你会大吃一惊。“如果HashMap的大小超过了负载因子(load factor)定义的容量,怎么办?”除非你真正知道HashMap的工作原理,否则你将回答不出这道题。默认的负载因子大小为0.75,也就是说,当一个map填满了75%的bucket时候,和其它集合类(如ArrayList等)一样,将会创建原来HashMap大小的两倍的bucket数组,来重新调整map的大小,并将原来的对象放入新的bucket数组中。这个过程叫作rehashing,因为它调用hash方法找到新的bucket位置。

如果你能够回答这道问题,下面的问题来了:“你了解重新调整HashMap大小存在什么问题吗?”你可能回答不上来,这时面试官会提醒你当多线程的情况下,可能产生条件竞争(race condition)。

当重新调整HashMap大小的时候,确实存在条件竞争,因为如果两个线程都发现HashMap需要重新调整大小了,它们会同时试着调整大小。在调整大小的过程中,存储在链表中的元素的次序会反过来,因为移动到新的bucket位置的时候,HashMap并不会将元素放在链表的尾部,而是放在头部,这是为了避免尾部遍历(tail traversing)。如果条件竞争发生了,那么就死循环了。这个时候,你可以质问面试官,为什么这么奇怪,要在多线程的环境下使用HashMap呢?:)

热心的读者贡献了更多的关于HashMap的问题:

1.为什么String, Interger这样的wrapper类适合作为键? String, Interger这样的wrapper类作为HashMap的键是再适合不过了,而且String最为常用。因为String是不可变的,也是final的,而且已经重写了equals()和hashCode()方法了。其他的wrapper类也有这个特点。不可变性是必要的,因为为了要计算hashCode(),就要防止键值改变,如果键值在放入时和获取时返回不同的hashcode的话,那么就不能从HashMap中找到你想要的对象。不可变性还有其他的优点如线程安全。如果你可以仅仅通过将某个field声明成final就能保证hashCode是不变的,那么请这么做吧。因为获取对象的时候要用到equals()和hashCode()方法,那么键对象正确的重写这两个方法是非常重要的。如果两个不相等的对象返回不同的hashcode的话,那么碰撞的几率就会小些,这样就能提高HashMap的性能。

2.我们可以使用自定义的对象作为键吗? 这是前一个问题的延伸。当然你可能使用任何对象作为键,只要它遵守了equals()和hashCode()方法的定义规则,并且当对象插入到Map中之后将不会再改变了。如果这个自定义对象时不可变的,那么它已经满足了作为键的条件,因为当它创建之后就已经不能改变了。

3.我们可以使用CocurrentHashMap来代替Hashtable吗?这是另外一个很热门的面试题,因为ConcurrentHashMap越来越多人用了。我们知道Hashtable是synchronized的,但是ConcurrentHashMap同步性能更好,因为它仅仅根据同步级别对map的一部分进行上锁。ConcurrentHashMap当然可以代替HashTable,但是HashTable提供更强的线程安全性。

25.http和https的区别?

•https协议需要到CA  (Certificate Authority,证书颁发机构)申请证书,一般免费证书较少,因而需要一定费用。(原来网易官网是http,而网易邮箱是https。)

•http是超文本传输协议,信息是明文传输,https则是具有安全性的ssl加密传输协议。

•http和https使用的是完全不同的连接方式,用的端口也不一样,前者是80,后者是443。

•http的连接很简单,是无状态的。Https协议是由SSL+Http协议构建的可进行加密传输、身份认证的网络协议,比http协议安全。(无状态的意思是其数据包的发送、传输和接收都是相互独立的。无连接的意思是指通信双方都不长久的维持对方的任何信息。)。

 26.时间复杂度和空间复杂度? 

算法的性能分析是算法设计中非常重要的方面,要想编写出能高效运行的程序,我们就需要考虑到算法的效率。 
算法的效率主要由以下两个复杂度来评估:

 
时间复杂度:评估执行程序所需的时间。可以估算出程序对处理器的使用程度。算法的时间复杂度一般是问题规模的函数,通常用T=T(n)表示,其中,n表示问题的规模,即算法所处理的数据量。T表示算法所用时间。

算法的执行时间=该算法所有语句执行次数(包括重复执行次数)* 执行每条语句所花费时间总和。由于每条语句的执行时间是cpu速度决定的,对计算机而言是常数,因此可以忽略不计,只考虑语句的执行次数(频率或频度)。为了进一步简化计算,可以只用算法中某条重要语句(执行时间最长的语句)的执行频度。换句话说就是时间复杂度是主要语句频度的倍数。

备注:一个算法执行所耗费的时间,从理论上是不能算出来的,必须上机运行测试才能知道。但我们不可能也没有必要对每个算法都上机测试,只需知道哪个算法花费的时间多,哪个算法花费的时间少就可以了。并且一个算法花费的时间与算法中语句的执行次数成正比例,哪个算法中语句执行次数多,它花费时间就多。一个算法中的语句执行次数称为语句频度或时间频度。记为T(n)。

 
空间复杂度:评估执行程序所需的存储空间。可以估算出程序对计算机内存的使用程度。不包括算法程序代码和所处理的数据本身所占空间部分。通常用所使用额外空间的字节数表示。其算法比较简单,记为S=S(n),其中,n表示问题规模。

设计算法时,一般是要先考虑系统环境,然后权衡时间复杂度和空间复杂度,选取一个平衡点。不过,时间复杂度要比空间复杂度更容易产生问题,因此算法研究的主要也是时间复杂度,不特别说明的情况下,复杂度就是指时间复杂度。 

评价算法时间复杂度大小需要考虑的因素:

1,计算机硬件系统的运行速度。

2,所使用的软件环境。

3,算法本身的策略,采用不同的存储结构和不同的算法过程,是影响时间复杂度的本质原因之一。

4,所处理的数据量多少。

算法性能的评价方法:

1,事后统计法。

2,预先计算估算法。

 1>精确计算法

 2>近似估算法

这里我介绍数据结构最常用的方法,也就是第二种的第二类。

T(n)=O(f(n));S(n)=O(g(n))

其中,f(n)和g(n)是一个已知的函数,作为计较的尺度。

通常的比较尺度有:

O(1)称为常量级,算法的时间复杂度是一个常数。

O(n)称为线性级,时间复杂度是数据量n的线性函数。

O(n²)称为平方级,与数据量n的二次多项式函数属于同一数量级。

O(n³)称为立方级,是n的三次多项式函数。

O(logn)称为对数级,是n的对数函数。

O(nlogn)称为介于线性级和平方级之间的一种数量级

O(2ⁿ)称为指数级,与数据量n的指数函数是一个数量级。

O(n!)称为阶乘级,与数据量n的阶乘是一个数量级。

 

它们之间的关系是: O(1)<O(logn)<O(n)<O(nlogn)<O(n²)<O(n³)<O(2ⁿ)<O(n!)