String 能被继承吗?为什么?
1、不可以,String类有final修饰符,而final修饰符类是不可以被继承的。
2、平时定义的String str = “a” 与 String str = new String(“a”)还是有差别的
①前者默认调用的是String.valueOf来返回String实例对象,至于调用哪个取决于赋值,
比如String num=1,调用的是
publicstatic String valueOf(int i) {
return Integer.toString(i);
}
后者则是调用如下部分:
public String(String original) {
this.value = original.value;
this.hash = original.hash;
}
最后我们的变量都存储在一个char数组中
private final char value[];
StringBuffer str1 = new StringBuffer("abcdef");
System.out.print(str1.reverse() + "----");
String字符串常量(final修饰,不可被继承),String是常量创建之后不能更改
StringBuffer字符串变量(线程安全),也是final修饰,不允许被继承,其中绝大多数方法进行了同步处理,包括常用的Append方法也做了同步处理(synchronized修饰)。其自jdk1.0起就已经出现。其toString方法会进行对象缓存,以减少元素复制开销。
public synchronized String toString() {
if (toStringCache == null) {
toStringCache = Arrays.copyOfRange(value, 0, count);
}
return new String(toStringCache, true);
}
StringBuilder字符串变量(非线程安全)其自jdk1.5起开始出现。与StringBuffer一样都继承和实现了同样的接口和类,方法除了没使用synch修饰以外基本一致,不同之处在于最后toString的时候,会直接返回一个新对象。
public String toString() {
// Create a copy, don’t share the array
return new String(value, 0, count);
}
ArrayList和LinkedList都实现了List接口,有以下的不同点:
1、ArrayList是基于索引的数据接口,它的底层是数组。它可以以O(1)时间复杂度对元素进行随机访问。与此对应,LinkedList是以元素列表的形式存储它的数据,每一个元素都和它的前一个和后一个元素链接在一起,在这种情况下,查找某个元素的时间复杂度是O(n)。
2、相对于ArrayList,LinkedList的插入,添加,删除操作速度更快,因为当元素被添加到集合任意位置的时候,不需要像数组那样重新计算大小或者是更新索引。
3、LinkedList比ArrayList更占内存,因为LinkedList为每一个节点存储了两个引用,一个指向前一个元素,一个指向下一个元素。
此题考察的是类加载器实例化时进行的操作步骤(加载–>连接->初始化)。
父类静态代变量、
父类静态代码块、
子类静态变量、
子类静态代码块、
父类非静态变量(父类实例成员变量)、
父类构造函数、
子类非静态变量(子类实例成员变量)、
子类构造函数。
hashMap是线程不安全的,HashMap是数组+链表+红黑树(JDK1.8增加了红黑树部分)实现的,采用哈希表来存储的
参照该链接:https://zhuanlan.zhihu.com/p/21673805
JAVA8 的 ConcurrentHashMap 为什么放弃了分段锁,有什么问题吗,如果你来设计,你如何设计。
参照:https://yq.aliyun.com/articles/36781
TreeMap和LinkedHashMap是有序的(TreeMap默认升序,LinkedHashMap则记录了插入顺序)。
参照:http://uule.iteye.com/blog/1522291
1、抽象类和接口都不能直接实例化,如果要实例化,抽象类变量必须指向实现所有抽象方法的子类对象,接口变量必须指向实现所有接口方法的类对象。
2、抽象类要被子类继承,接口要被类实现。
3、接口只能做方法申明,抽象类中可以做方法申明,也可以做方法实现
4、接口里定义的变量只能是公共的静态的常量,抽象类中的变量是普通变量。
5、抽象类里的抽象方法必须全部被子类所实现,如果子类不能全部实现父类抽象方法,那么该子类只能是抽象类。同样,一个实现接口的时候,如不能全部实现接口方法,那么该类也只能为抽象类。
6、抽象方法只能申明,不能实现。abstract void abc();不能写成abstract voidabc(){}。
7、抽象类里可以没有抽象方法
8、如果一个类里有抽象方法,那么这个类只能是抽象类
9、抽象方法要被实现,所以不能是静态的,也不能是私有的。
10、接口可继承接口,并可多继承接口,但类只能单根继承。
https://my.oschina.net/dyyweb/blog/609021
1、 懒汉,线程不安全
public class Singleton {
private static Singletoninstance;
private Singleton (){}
public static synchronizedSingleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
2、 饿汉
public class Singleton {
private static Singletoninstance = new Singleton();
private Singleton (){}
public static SingletongetInstance() {
return instance;
}
}
Ls,find,tar,tail,cp,rm,vi,grep,ps,pkill等等
Tail -n 5 filename
ps -ef|grep Java
可以使用filter过滤处理
REST 指的是一组架构约束条件和原则。满足这些约束条件和原则的应用程序或设计就是 RESTful。
使用悲观锁 悲观锁本质是当前只有一个线程执行操作,结束了唤醒其他线程进行处理。
也可以缓存队列中锁定主键。
方法的重载和重写都是实现多态的方式,区别在于前者实现的是编译时的多态性,而后者实现的是运行时的多态性。重载发生在一个类中,同名的方法如果有不同的参数列表(参数类型不同、参数个数不同或者二者都不同)则视为重载;重写发生在子类与父类之间,重写要求子类被重写方法与父类被重写方法有相同的返回类型,比父类被重写方法更好访问,不能比父类被重写方法声明更多的异常(里氏代换原则)。重载对返回类型没有特殊的要求。
答:理论上Java因为有垃圾回收机制(GC)不会存在内存泄露问题(这也是Java被广泛使用于服务器端编程的一个重要原因);然而在实际开发中,可能会存在无用但可达的对象,这些对象不能被GC回收也会发生内存泄露。一个例子就是Hibernate的Session(一级缓存)中的对象属于持久态,垃圾回收器是不会回收这些对象的,然而这些对象中可能存在无用的垃圾对象。下面的例子也展示了Java中发生内存泄露的情况:
packagecom.lovo;
//何问起 hovertree.com
importjava.util.Arrays;
importjava.util.EmptyStackException;
publicclass MyStack
private T[] elements;
private int size = 0;
private static final int INIT_CAPACITY =16;
public MyStack() {
elements = (T[]) newObject[INIT_CAPACITY];
}
public void push(T elem) {
ensureCapacity();
elements[size++] = elem;
}
public T pop() {
if(size == 0)
throw newEmptyStackException();
return elements[--size];
}
private void ensureCapacity() {
if(elements.length == size) {
elements = Arrays.copyOf(elements,2 * size + 1);
}
}
}
Reader和Writer最重要的子类是InputStreamReader和OutputStreamWriter类
InputStreamReader类包含了一个底层输入流,可以从中读取原始字节。它根据指定的编码方式,将这些字节转换为Unicode字符。
OutputStreamWriter从运行的程序中接收Unicode字符,然后使用指定的编码方式将这些字符转换为字节,再将这些字节写入底层输出流中。
1. 其是字符流和字节流之间的桥梁
2. 可对读取到的字节数据经过指定编码转换成字符
3. 可对读取到的字符数据经过指定编码转换成字节
1.DOM生成和解析XML文档
为 XML 文档的已解析版本定义了一组接口。解析器读入整个文档,然后构建一个驻留内存的树结构,然后代码就可以使用 DOM
接口来操作这个树结构。优点:整个文档树在内存中,便于操作;支持删除、修改、重新排列等多种功能;缺点:将整个文档调入内存(包括无用的节点),浪费时间和空间;使用
场合:一旦解析了文档还需多次访问这些数据;硬件资源充足(内存、CPU)。
2.SAX生成和解析XML文档
为解决DOM的问题,出现了SAX。SAX
,事件驱动。当解析器发现元素开始、元素结束、文本、文档的开始或结束等时,发送事件,程序员编写响应这些事件的代码,保存数据。优点:不用事先调入整个文档,占用资
源少;SAX解析器代码比DOM解析器代码小,适于Applet,下载。缺点:不是持久的;事件过后,若没保存数据,那么数据就丢了;无状态性;从事件中只能得到文本,但不知该文
本属于哪个元素;使用场合:Applet;只需XML文档的少量内容,很少回头访问;机器内存少;
3.DOM4J生成和解析XML文档
DOM4J 是一个非常非常优秀的Java XML
API,具有性能优异、功能强大和极端易用使用的特点,同时它也是一个开放源代码的软件。如今你可以看到越来越多的 Java 软件都在使用 DOM4J 来读写
XML,特别值得一提的是连 Sun 的 JAXM 也在用 DOM4J。
4.JDOM生成和解析XML
为减少DOM、SAX的编码量,出现了JDOM;优点:20-80原则,极大减少了代码量。使用场合:要实现的功能简单,如解析、创建等,但在底层,JDOM还是使用SAX(最常用)、DOM、
Xanan文档。
A、Application B、Page C、Session D、Request
会话跟踪技术 是保存用户和服务器之间,以上abcd不是会话跟踪(cookie,url重写,session,隐藏域),是JSP的四种范围----
page,request,session,application
page否是代表与一个页面相关的对象和属性。一个页面由一个编译好的Java servlet 类(可以带有任何的include 指令,但是没有include 动作)表示。这既包括servlet 又包括被编译成servlet 的JSP 页面
request是是代表与 Web 客户机发出的一个请求相关的对象和属性。一个请求可能跨越多个页面,涉及多个Web 组件(由于forward 指令和include 动作的关系)
session是代表与用于某个 Web 客户机的一个用户体验相关的对象和属性。一个Web 会话可以也经常会跨越多个客户机请求
application是是代表与整个 Web 应用程序相关的对象和属性。这实质上是跨越整个Web 应用程序,包括多个页面、请求和会话的一个全局作用域
page:在一个页面内保存属性。跳转之后无效
request:在一次服务请求范围内。server跳转后依旧有效
session:-在一次会话范围内,不管何种跳转都能够使用,可是新开浏览器无法使用
application:在整个server上保存,全部用户都能够使用
public void setAttribute(String name,Object value)
public Object getAttribute(String name)
public Object removeAttribute(String name)
Singleton:单例-整个容器只有一个对象实例默认是单例
Prototype:原型-每次获取bean都产生一个新的对象
Request:每次请求时创建一个新的对象
Session:在会话的范围内是一个对象
Global session:--只在portlet下有用,表示application
Application:在应用范围中是一个对象
输出5
request 用户端请求,此请求会包含来自GET/POST请求的参数
response 网页传回用户端的回应
pageContext 网页的属性是在这里管理
session 与请求有关的会话期
application servlet 正在执行的内容
out 用来传送回应的输出
config servlet的构架部件
page JSP网页本身
exception 针对错误网页,未捕捉的例外
常用的组件:request、response、out、session、application、exception
TODO:Struts中action需要实现特定的接口,所有的action只有一个实例,被反复调用
Hibernate中常用的主键:
1.assigned:
主键由外部程序负责生成,无需Hibernate参与。----如果要由程序代码来指定主键,就采有这种.
2.increment:
对 long , short 或 int 的数据列生成自动增长主键。increment主键生成方式的特点是与底层数据库无关性,大部分数据库如 Mysql,MSSQL 和ORACLE等都支持increament生成方式。此方式的实现机制为在当前应用实例中维持一个变量,以保存着当前的最大值,之后每次需要生成主键的时候将此值加1作为主键。increment方式的不足之处是当多个线程并发对数据库表进行写操作时,可能出现相同的主键值,发生主键重复的冲突,因此多线程并发操作时,不应该使用此方法。
3. native:
由Hibernate根据不同的数据库方言,自行判断采用identity、hilo、sequence其中一种作为Hibernate主键生成方式,native的 优点是与底层性无关,便于不同数据库之间的移植,由Hibernate根据不同数据库选择主键的生成方式。在oracle中需要创建叫 Hibernate_sequence名字的sequence,如果设置了Hibernate.hbm2ddl.auto属性,不需要手动建立序列,前提是数据库帐号必须有Create Sequence这种高级权限。mysql等数据库则不用建立sequence。
一般的float型和Double型数据只可以用来做科学计算或者是工程计算,由于在商业计算中,要求的数字精度比较高,所以要用到java.math.BigDecimal类,它支持任何精度的定点数,可以用它来精确计算货币值。
BigDecimal b2 = newBigDecimal(1.23456789);//会造成精度丢失
BigDecimal b1= newBigDecimal("1.23456789");//不会造成精度丢失
b1.setScale(3, BigDecimal.ROUND_HALF_EVEN);//设置精度,在保留小数位时,要设置舍入模式
System.out.println(b1.doubleValue());
System.out.println(b1.floatValue());
System.out.println(b1.longValue());
System.out.println(b1.intValue());
System.out.println(b1.toString());
System.out.println("四舍五入取整:1.23456789="
+ new BigDecimal("1.25456789").setScale(1,BigDecimal.ROUND_HALF_UP));
结果:
1.23456789
1.2345679
1
1
1.23456789
1.3
Date date = new SimpleDateFormat("yyyy-MM-dd").parse("2018-06-09");
Stringnow = new SimpleDateFormat("yyyy年MM月dd日").format(date);
System.out.println(now);
Abcd dcba badc cdba
1、客户端浏览器发出HTTP请求.
2、根据web.xml配置,该请求被FilterDispatcher接收
3、根据struts.xml配置,找到需要调用的Action类和方法, 并通过IoC方式,将值注入给Aciton
4、Action调用业务逻辑组件处理业务逻辑,这一步包含表单验证。
5、Action执行完毕,根据struts.xml中的配置找到对应的返回结果result,并跳转到相应页面
6、返回HTTP响应到客户端浏览器
1、用户发送请求至前端控制器DispatcherServlet
2、DispatcherServlet收到请求调用HandlerMapping处理器映射器。
3、处理器映射器找到具体的处理器,生成处理器对象及处理器拦截器(如果有则生成)一并返回给DispatcherServlet。
4、DispatcherServlet调用HandlerAdapter处理器适配器
5、HandlerAdapter经过适配调用具体的处理器(Controller,也叫后端控制器)。
6、Controller执行完成返回ModelAndView
7、HandlerAdapter将controller执行结果ModelAndView返回给DispatcherServlet
8、DispatcherServlet将ModelAndView传给ViewReslover视图解析器
9、ViewReslover解析后返回具体View
10、DispatcherServlet根据View进行渲染视图(即将模型数据填充至视图中)。
11、DispatcherServlet响应用户
①springmvc的入口是一个servlet即前端控制器,而struts2入口是一个filter过虑器。
②springmvc是基于方法开发,传递参数是通过方法形参,可以设计为单例或多例(建议单例),struts2是基于类开发,传递参数是通过类的属性,只能设计为多例。
③Struts采用值栈存储请求和响应的数据,通过OGNL存取数据, springmvc通过参数解析器是将request对象内容进行解析成方法形参,将响应数据和页面封装成ModelAndView对象,最后又将模型数据通过request对象传输到页面。 Jsp视图解析器默认使用jstl。
答案:存在
解析:如果i为int型,那么当i为int能表示的最大整数时,i+1就溢出变成负数了,此时不就
扩展:存在使i > j || i <= j不成立的数吗()
答案:存在
解析:比如Double.NaN或Float.NaN,感谢@BuilderQiu网友指出。
A 是 B 否
答案:A
解析:Java创建对象的几种方式(重要):
(1) 用new语句创建对象,这是最常见的创建对象的方法。
(2) 运用反射手段,调用java.lang.Class或者java.lang.reflect.Constructor类的newInstance()实例方法。
(3) 调用对象的clone()方法。
(4) 运用反序列化手段,调用java.io.ObjectInputStream对象的 readObject()方法。
(1)和(2)都会明确的显式的调用构造函数 ;(3)是在内存上对已有对象的影印,所以不会调用构造函数;(4)是从文件中还原类的对象,也不会调用构造函数。
class HelloA {
public HelloA() {
System.out.println("HelloA");
}
{System.out.println("I'm A class"); }
static { System.out.println("static A"); }
}
public class HelloB extends HelloA {
public HelloB() {
System.out.println("HelloB");
}
{System.out.println("I'm B class"); }
static { System.out.println("static B"); }
public static void main(String[] args) {
new HelloB();
}
}
结果:
static A
static B
I'm A class
HelloA
I'm B class
HelloB
对象的初始化顺序:(1)类加载之后,按从上到下(从父类到子类)执行被static修饰的语句;(2)当static语句执行完之后,再执行main方法;(3)如果有语句new了自身的对象,将从上到下执行构造代码块、构造器(两者可以说绑定在一起)
import java.io.*;
import java.util.*;
public class foo{
public static void main (String[] args){
String s;
System.out.println("s=" + s);
}
}
A 代码得到编译,并输出“s=”
B 代码得到编译,并输出“s=null”
C 由于String s没有初始化,代码不能编译通过
D 代码得到编译,但捕获到 NullPointException异常
答案:C
解析:开始以为会输出null什么的,运行后才发现Java中所有定义的基本类型或对象都必须初始化才能输出值。
有数字:2,5,7,9能组成多少个互不相同且无重复的数?
从键盘输入m和n,定义n是第一个数,之后的每个数都是前一个的平方根,共m个数,计算和