最近在从java基础开始复习,记录一下:
https://pan.baidu.com/s/1mXQiIzRF-MdeWJOcnFRk7Q?pwd=nnt8(资料地址)
Integer类型在-128-->127范围之间是被缓存了的,也就是每个对象的内存地址是相同的,赋值就直接从缓存中取,不会有新的对象产生,而大于这个范围,将会重新创建一个Integer对象,也就是new一个对象出来,当然地址就不同了,也就!=;
父类静态代码块
子类静态代码块
父类初始化块
父类构造方法
子类初始化块
子类构造方法
LTS:长期支持版 (jdk8,11,17)
变量:存储数据的,本质是内存中的一块区域
8进制0开头(int a = 0141 -------97)(int a = 0XFA -------258)
byte = -128~127 short型数据-32768~ 32 767 long x = 1221641561L(注意L,float同理)
小类型转换为大类型,自动转换(byte a = 1; int b = a可以) byte-short-int-long-flort-double
在表达式中,byte,short,char是直接转换为int!!!!!!!!!!!!!!!!(担心运算超过范围)!!!!!!!!!!!
强制转换(大转小)
字面量:给基本类型变量赋值的方式就叫做字面量或者字面值
-= += 包含前面类型变量的强制转换
&& 优先级高于||
switch不写容易出现穿透 return new int[]{first,last}; 【】里面不能含有数字
申明了两个静态成员变量x,y,并没有赋初值,会有默认出值,int类型为0】
方法区(字节码文件)、栈(方面运行时进入内存,变量也存在这里)、堆(new出来的东西)
Arrays.sort() 方法使用不同的排序算法,具体取决于输入数据的类型和大小。Java的排序算法库根据不同的情况使用不同的排序算法,以获得最佳性能。以下是一些情况:
基本数据类型的排序: 对于int、long、float、double等基本数据类型的数组,Arrays.sort() 使用一种基于快速排序的排序算法,通常称为“双轴快速排序”(Dual-Pivot QuickSort)。这是Java 7及更高版本的默认算法。
对象数组的排序: 对于包含对象的数组,Arrays.sort() 使用一种基于归并排序的稳定排序算法,通常称为“归并排序”(Merge Sort)
方法被调用的时候,是进入到栈内存中的,执行完会被释放掉
注意引用类型的形参会改变(传送的是地址)
方法重载:出现多个方法名称相同,形参列表不同(顺序、类型、个数。修饰符、返回类型一样是否都无所谓)
************************************************
1. 内存分配策略
按照编译原理的观点,程序运行时的内存分配有三种策略,分别是静态的,栈式的,和堆式的。
静态存储分配是指在编译时就能确定每个数据目标在运行时刻的存储空间需求,因而在编译时就可以给他们分配固定的内存空间。这种分配策略要求程序代码中不允许有可变数据结构(比如可变数组)的存在,也不允许有嵌套或者递归的结构出现,因为它们都会导致编译程序无法计算准确的存储空间需求。
栈式存储分配也可称为动态存储分配,是由一个类似于堆栈的运行栈来实现的。和静态存储分配相反,在栈式存储方案中,程序对数据区的需求在编译时是完全未知的,只有到运行的时候才能够知道,但是规定在运行中进入一个程序模块时,必须知道该程序模块所需的数据区大小才能够为其分配内存。和我们在数据结构所熟知的栈一样,栈式存储分配按照先进后出的原则进行分配。
静态存储分配要求在编译时能知道所有变量的存储要求,栈式存储分配要求在过程的入口处必须知道所有的存储要求,而堆式存储分配则专门负责在编译时或运行时模块入口处都无法确定存储要求的数据结构的内存分配,比如可变长度串和对象实例。堆由大片的可利用块或空闲块组成,堆中的内存可以按照任意顺序分配和释放。
2. JVM中的堆和栈
JVM是基于堆栈的虚拟机。JVM为每个新创建的线程都分配一个堆栈,也就是说,对于一个Java程序来说,它的运行就是通过对堆栈的操作来完成的。堆栈以帧为单位保存线程的状态。JVM对堆栈只进行两种操作:以帧为单位的压栈和出栈操作。
java把内存分两种:一种是栈内存,另一种是堆内存
栈(stack)与堆(heap)都是Java用来在Ram中存放数据的地方。与C++不同,Java自动管理栈和堆,程序员不能直接地设置栈或堆。
栈(stack):是一个先进后出的数据结构,通常用于保存方法(函数)中的参数,局部变量。
堆(heap):是一个可动态申请的内存空间(其记录空闲内存空间的链表由操作系统维护),是一个运行时数据区,C中的malloc语句所产生的内存空间就在堆中。
3. 堆和栈优缺点比较
栈的优势是,存取速度比堆要快,仅次于直接位于CPU中的寄存器。但缺点是,存在栈中的数据大小与生存期必须是确定的,缺乏灵活性。另外,栈数据可以共享,详见第3点。
堆的优势是可以动态地分配内存大小,生存期也不必事先告诉编译器,Java的垃圾收集器会自动收走这些不再使用的数据。但缺点是,由于要在运行时动态分配内存,存取速度较慢。
4. Java中的数据类型有两种
一种是基本类型
共有8种,即int, short, long, byte, float, double, boolean, char(注意,并没有string的基本类型)。
这种类型的定义是通过诸如int a = 3; long b = 255L;的形式来定义的,称为自动变量。值得注意的是,自动变量存的是字面值,不是类的实例,即不是类的引用,这里并没有类的存在。如int a = 3; 这里的a是一个指向int类型的引用,指向3这个字面值。这些字面值的数据,由于大小可知,生存期可知(这些字面值固定定义在某个程序块里面,程序块退出后,字段值就消失了),出于追求速度的原因,就存在于栈中。
另外,栈有一个很重要的特殊性,就是存在栈中的数据可以共享。假设我们同时定义:
int a = 3;
int b = 3;
编译器先处理int a = 3;首先它会在栈中创建一个变量为a的引用,然后查找有没有字面值为3的地址,没找到,就开辟一个存放3这个字面值的地址,然后将a指向3的地址。接着处理int b = 3;在创建完b的引用变量后,由于在栈中已经有3这个字面值,便将b直接指向3的地址。这样,就出现了a与b同时均指向3的情况。
特别注意的是,这种字面值的引用与类对象的引用不同。假定两个类对象的引用同时指向一个对象,如果一个对象引用变量修改了这个对象的内部状态,那么另一个对象引用变量也即刻反映出这个变化。相反,通过字面值的引用来修改其值,不会导致另一个指向此字面值的引用的值也跟着改变的情况。如上例,我们定义完a与b的值后,再令a=4;那么,b不会等于4,还是等于3。在编译器内部,遇到a=4;时,它就会重新搜索栈中是否有4的字面值,如果没有,重新开辟地址存放4的值;如果已经有了,则直接将a指向这个地址。因此a值的改变不会影响到b的值。
另一种是包装类数据
如Integer, String, Double等将相应的基本数据类型包装起来的类。这些类数据全部存在于堆中,Java用new()语句来显示地告诉编译器,在运行时才根据需要动态创建,因此比较灵活,但缺点是要占用更多的时间。
String是一个特殊的包装类数据。即可以用String str = new String(“abc”);的形式来创建,也可以用String str = “abc”;的形式来创建(作为对比,在JDK 5.0之前,你从未见过Integer i = 3;的表达式,因为类与字面值是不能通用的,除了String。而在JDK 5.0中,这种表达式是可以的!因为编译器在后台进行Integer i = new Integer(3)的转换)。前者是规范的类的创建过程,即在Java中,一切都是对象,而对象是类的实例,全部通过new()的形式来创建。Java中的有些类,如DateFormat类,可以通过该类的getInstance()方法来返回一个新创建的类,似乎违反了此原则。其实不然。该类运用了单例模式来返回类的实例,只不过这个实例是在该类内部通过new()来创建的,而getInstance()向外部隐藏了此细节。那为什么在String str = “abc”;中,并没有通过new()来创建实例,是不是违反了上述原则?其实没有。
5.String在内存中的存放
String是一个特殊的包装类数据,可以用用以下两种方式创建:
String str = new String(“abc”);第一种创建方式是用new()来新建对象的,它会存放于堆中。每调用一次就会创建一个新的对象。
String str = “abc”; 第二种创建方式先在栈中创建一个对String类的对象引用变量str,然后在栈中查找有没有存放值为”abc”的地址,如果没有,则开辟一个存放字面值为”abc”的地址,接着创建一个新的String类的对象o,并将o的字符串值指向这个地址,而且在栈中这个地址旁边记下这个引用的对象o。如果已经有了值为”abc”的地址,则查找对象o,并返回o的地址,最后将str指向对象o的地址。
值得注意的是,一般String类中字符串值都是直接存值的。但像String str = “abc”;这种场合下,其字符串值却是保存了一个指向存在栈中数据的引用!
6.数组在内存中的存放
int x[] 或者int []x 时,在内存栈空间中创建一个数组引用,通过该数组名来引用数组。
x = new int[5] 将在堆内存中分配5个保存int型数据的空间,堆内存的首地址放到栈内存中,每个数组元素被初始化为0。
7.static变量在内存中的存放
用 static的修饰的变量和方法,实际上是指定了这些变量和方法在内存中的“固定位置”-static storage。既然要有“固定位置”那么他们的 “大小”似乎就是固定的了,有了固定位置和固定大小的特征了,在栈中或堆中开辟空间那就是非常的方便了。如果静态的变量或方法在不出其作用域的情况下,其引用句柄是不会发生改变的。
8. java中变量在内存中的分配
1、类变量(static修饰的变量)
在程序加载时系统就为它在堆中开辟了内存,堆中的内存地址存放于栈以便于高速访问。静态变量的生命周期一直持续到整个”系统”关闭
2、实例变量
当你使用java关键字new的时候,系统在堆中开辟并不一定是连续的空间分配给变量(比如说类实例),然后根据零散的堆内存地址,通过哈希算法换算为一长串数字以表征这个变量在堆中的”物理位置”。 实例变量的生命周期–当实例变量的引用丢失后,将被GC(垃圾回收器)列入可回收“名单”中,但并不是马上就释放堆中内存
3、局部变量
局部变量,由声明在某方法,或某代码段里(比如for循环),执行到它的时候在栈中开辟内存,当局部变量一但脱离作用域,内存立即释放
作者:PlanckStar
链接:https://www.nowcoder.com/exam/test/73953407/submission?examPageSource=Intelligent&pid=52945738&testCallback=https%3A%2F%2Fwww.nowcoder.com%2Fexam%2Fintelligent%3FquestionJobId%3D10%26tagId%3D21003&testclass=%E8%BD%AF%E4%BB%B6%E5%BC%80%E5%8F%91
来源:牛客网
************************************************
finally是无论是否抛出异常必定执行的语句
//
1.抽象方法只能定义在抽象类中,抽象方法和抽象类必须由abstract修饰,abstract关键字只能描述类和方法,不能描述变量。抽象方法只定义方法声明,不定义方法实现。抽象类不可以被实例化(创建对象),只有通过子类继承抽象类并覆盖抽象类中的所有抽象方法后,该子类才可以被实例化,否则该子类还是一个抽象类。抽象类中有构造函数用于给子类对象进行初始化,同时抽象类中可以含有非抽象方法。abstract关键字不可以与final,private,static关键字共存,因为被final修饰的方法不可以被重写,意味着子类不可以重写该方法,如果abstract和final共同修饰父类中的方法,子类要实现抽象方法(abstract的作用),而final又不让该方法重写,这相互矛盾。如果private和abstract共同修饰父类中的方法,private修饰则该方法不可以被子类访问,但是abstract修饰需要子类去实现,两者产生矛盾。如果static和abstract共同修饰父类中的方法,static表示是静态的方法,随着类的加载而加载,则该方法不需要在子类中去实现,这与abstract关键字矛盾。
2.static用于修饰成员变量和成员函数,想要实现对象中的共性数据的对象共享,可以将这个数据进行静态修饰,被静态修饰的成员可以直接被类名调用,静态随着类的加载而加载,而且优先于对象存在。静态方法只能访问静态成员(静态方法和静态变量),不可以访问非静态成员,这是因为静态方法加载时,优先于对象存在,所以没有办法访问对象中的成员。静态方法中不能使用this和super关键字,因为this代表本类对象,super代表父类对象,而静态时,有可能没有对象存在,所以this和super无法使用。 3.final关键字可以修饰类,方法,变量(成员变量内,局部变量,静态变量),被final修饰的类是一个最终类,不可以被继承,被final修饰的方法是一个最终方法,不可以被覆盖,但是可以被继承。被final修饰的变量只能是一个常量,只能赋值一次。内部类被定义在类中的局部位置上时,只能访问局部被final修饰的局部变量。
作者:冰封无痕
链接:https://www.nowcoder.com/exam/test/73953407/submission?examPageSource=Intelligent&pid=52945738&testCallback=https%3A%2F%2Fwww.nowcoder.com%2Fexam%2Fintelligent%3FquestionJobId%3D10%26tagId%3D21003&testclass=%E8%BD%AF%E4%BB%B6%E5%BC%80%E5%8F%91
来源:牛客网
//
!!!!!!!!!面向对象编程!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
对象==实例
!!!!!!!!!!这个重要
string的对象是不可变字符串对象: 最开始是存在与常量池中
结论:每次试图改变字符串对象实际上是新产生了新的字符串对象了,变量每次都是指向了新的字符串对象,
之前字符串对象的内容确实是没有改变的,因此说String的对象是不可变的。
类变量被所有对象共享,会被加载到堆内存中
getParameter()是获取POST/GET传递的参数值;
getInitParameter获取Tomcat的server.xml中设置Context的初始化参数
★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★
抽象类
特点:
1.抽象类中可以构造方法
2.抽象类中可以存在普通属性,方法,静态属性和方法。
3.抽象类中可以存在抽象方法。
4.如果一个类中有一个抽象方法,那么当前类一定是抽象类;抽象类中不一定有抽象方法。
5.抽象类中的抽象方法,需要有子类实现,如果子类不实现,则子类也需要定义为抽象的。
接口
1.在接口中只有方法的声明,没有方法体。
2.在接口中只有常量,因为定义的变量,在编译的时候都会默认加上
public static final
3.在接口中的方法,永远都被public来修饰。
4.接口中没有构造方法,也不能实例化接口的对象。
5.接口可以实现多继承
6.接口中定义的方法都需要有实现类来实现,如果实现类不能实现接口中的所有方法
7.则实现类定义为抽象类。
Java 8新增了default方法,它可以在接口添加新功能特性,而且还不影响接口的实现类。
作者:ridikuius
链接:https://www.nowcoder.com/exam/test/74028339/submission?examPageSource=Intelligent&pid=52996734&testCallback=https%3A%2F%2Fwww.nowcoder.com%2Fexam%2Fintelligent%3FquestionJobId%3D10%26tagId%3D21004&testclass=%E8%BD%AF%E4%BB%B6%E5%BC%80%E5%8F%91
来源:牛客网
子类不可以继承父类的构造方法,只可以调用父类的构造方法。子类中所有的构造函数都会默认访问父类中的空参数构造函数,这是因为子类的构造函数内第一行
都有默认的super()语句。super()表示子类在初始化时调用父类的空参数的构造函数来完成初始化。一个类都会有默认的空参数的构造函数,若指定了带参构造函数,
那么默认的空参数的构造函数,就不存在了。这时如果子类的构造函数有默认的super()语句,那么就会出现错误,因为父类中没有空参数的构造函数。
因此,在子类中默认super()语句,在父类中无对应的构造函数,必须在子类的构造函数中通过this或super(参数)指定要访问的父类中的构造函数。
作者:冰封无痕
链接:https://www.nowcoder.com/exam/test/74061004/submission?examPageSource=Intelligent&pid=53018554&testCallback=https%3A%2F%2Fwww.nowcoder.com%2Fexam%2Fintelligent%3FquestionJobId%3D10%26tagId%3D21003&testclass=%E8%BD%AF%E4%BB%B6%E5%BC%80%E5%8F%91
来源:牛客网
★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★
单例模式:Runtime、任务管理器
重写:名字,参数列表一样(就近原则)
子类默认都会调取父类得午餐构造器(构造函数) super()、this() 有括号的都是对构造器的操作
多态 变量:编译看左边,运行看右边
变量:2种 局部+成员
接口是多继承的
内部类从JDK16才开始定义成员变量(理解为成员方法--可以访问外部类成员变量)
★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★
application对象是共享的,多个用户共享一个,以此实现数据共享和通信 JSP内置对象和属性列举如下:
1.request对象 客户端的请求信息被封装在request对象中,通过它才能了解到客户的需求,然后做出响应。它是HttpServletRequest类的实例。
2.response对象 response对象包含了响应客户请求的有关信息,但在JSP中很少直接用到它。它是HttpServletResponse类的实例。
3.session对象 session对象指的是客户端与服务器的一次会话,从客户连到服务器的一个WebApplication开始,直到客户端与服务器断开连接为止。
它是HttpSession类的实例. 4.out对象 out对象是JspWriter类的实例,是向客户端输出内容常用的对象 5.page对象
page对象就是指向当前JSP页面本身,有点象类中的this指针,它是java.lang.Object类的实例 6.application对象
application对象实现了用户间数据的共享,可存放全局变量。它开始于服务器的启动,直到服务器的关闭,在此期间,
此对象将一直存在;这样在用户的前后连接或不同用户之间的连接中,可以对此对象的同一属性进行操作;在任何地方对此对象属性的操作,
都将影响到其他用户对此的访问。服务器的启动和关闭决定了application对象的生命。它是ServletContext类的实例。 7.exception对象
exception对象是一个例外对象,当一个页面在运行过程中发生了例外,就产生这个对象。如果一个JSP页面要应用此对象,就必须把isErrorPage设为true,
否则无法编译。他实际上是java.lang.Throwable的对象 8.pageContext对象 pageContext对象提供了对JSP页面内所有的对象及名字空间的访问,也
就是说他可以访问到本页所在的SESSION,也可以取本页面所在的application的某一属性值,他相当于页面中所有功能的集大成者,它的本 类名也叫pageContext。
9.config对象 config对象是在一个Servlet初始化时,JSP引擎向它传递信息用的,此信息包括Servlet初始化时所要用到的参数(通过属性名和属性值构成)
以及服务器的有关信息(通过传递一个ServletContext对象)
知识点:Java
★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★
/** * String split 这个方法默认返回一个数组, * 如果没有找到分隔符, * 会把整个字符串当成一个长度为1的字符串数组 * 返回到结果, 所以此处结果就是1 */
匿名内内部类(重要)
★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★
\d 匹配一个数字字符。等价于 [0-9]。
\D 匹配一个非数字字符。等价于 [^0-9]。
\f 匹配一个换页符。等价于 \x0c 和 \cL。
\n 匹配一个换行符。等价于 \x0a 和 \cJ。
\r 匹配一个回车符。等价于 \x0d 和 \cM。
\s 匹配任何空白字符,包括空格、制表符、换页符等等。等价于 [ \f\n\r\t\v]。
\S 匹配任何非空白字符。等价于 [^ \f\n\r\t\v]。
\t 匹配一个制表符。等价于 \x09 和 \cI。
\v 匹配一个垂直制表符。等价于 \x0b 和 \cK。
\w 匹配字母、数字、下划线。等价于'[A-Za-z0-9_]'。
\W 匹配非字母、数字、下划线。等价于 '[^A-Za-z0-9_]'。
作者:咸鱼小哲
链接:https://www.nowcoder.com/exam/test/74086828/submission?examPageSource=Intelligent&pid=53035880&testCallback=https%3A%2F%2Fwww.nowcoder.com%2Fexam%2Fintelligent%3FquestionJobId%3D10%26tagId%3D21003&testclass=%E8%BD%AF%E4%BB%B6%E5%BC%80%E5%8F%91
来源:牛客网
★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★
★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★
重写:
参数列表必须与被重写方法的相同。
重写方法不能限制比被重写方法更严格的访问级别
重写方法不能抛出新的异常或者比被重写方法声明的检查异常更广的检查异常
返回类型必须与被重写方法的返回类型相同。仅当返回值为类类型时,重写的方法才可以修改返回值类型,且必须是父类方法返回值的子类。
★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★
count = count++ 原理是 temp = count; count = count+1 ; count = temp; 因此count始终是0 这仅限于java 与c是不一样的
/
abstract:
1、abstract类不能用来创建abstract类的对象;
2、final类不能用来派生子类,因为用final修饰的类不能被继承;
3、如2所述,final不能与abstract同时修饰一个类,abstract类就是被用来继承的;
4、类中有abstract方法必须用abstract修饰,但abstract类中可以没有抽象方法,接口中也可以有abstract方法
作者:BrainerGao
链接:https://www.nowcoder.com/exam/test/74089803/submission?examPageSource=Intelligent&pid=53037831&testCallback=https%3A%2F%2Fwww.nowcoder.com%2Fexam%2Fintelligent%3FquestionJobId%3D10%26tagId%3D21002&testclass=%E8%BD%AF%E4%BB%B6%E5%BC%80%E5%8F%91
来源:牛客网
//
枚举类的构造器是私有的
注意Object和Objects的区别: Objects是工具类 对象比较最好用Objects.equals()相对于s1.equals()不会出现空指针异常
开发中尽量使用BigDecimal不会出现double相加运算失真的情况(0.1+0.2=0.300000000000000000004)
重载的实现是编译器根据函数的不同的参数表,对同名函数的名称做修饰,那么对于编译器而言,这些同名函数就成了不同的函数。
但重写则是子类方法对父类的方法的延申,即子类不仅继承了父类的方法,还向父类的方法中添加了属于自己的内容,改变了父类方法原本的内容,
而final代表了一种不可变,这明显与重写形成了冲突。因此被final修饰的类可以被重载但不能被重写
///
Java运行时内存
1. 程序计数器,线程私有。可以看作是当前线程所执行的字节码的行号指示器,字节码解释器工作时就是通过改变整个计数器的值来选取下一条需要执行的字节码指令,分支、循环、跳转、异常处理、线程恢复等功能。
由于JVM的多线程是通过线程轮流切换并分配处理器执行时间的方式来实现的,在任何一个确定的时刻,一个处理器(对于多核处理器来说是一个内核)都只会执行一条线程中的指令。因此为了线程切换后能恢复到正确的执行位置,每条线程都需要一个独立的程序计数器,各条线程之间计数器互不影响,独立存储,所以线程私有。
程序计数器是唯一一个在Java虚拟机规范中没有规定任何OOM的区域。
2. Java虚拟机栈,线程私有。生命周期和线程相同。虚拟机栈描述的是Java方法执行的内存模型,每个方法在执行的同时都会创建一个栈帧。每个方法从调用到执行完成的过程,就对应着一个栈帧在虚拟机中入栈到出栈的过程。
3. 本地方法栈,线程私有。和虚拟机栈的区别就在于一个是为了执行Java方法服务,一个是为了虚拟机使用到的Native方法服务。
4. 堆,线程共享。存放对象实例和数组。
5. 方法区,线程共享。存放已经被JVM加载的类信息,常量,静态变量,即时编译器编译后的代码。
作者:bbblemon
链接:https://www.nowcoder.com/exam/test/74148928/submission?examPageSource=Intelligent&pid=53075889&testCallback=https%3A%2F%2Fwww.nowcoder.com%2Fexam%2Fintelligent%3FquestionJobId%3D10%26tagId%3D21002&testclass=%E8%BD%AF%E4%BB%B6%E5%BC%80%E5%8F%91
来源:牛客网
///
Servlet过滤器的配置包括两部分: 第一部分是过滤器在Web应用中的定义,由<filter>元素表示,包括<filter-name>和<filter-class>两个必需的子元素 第二部分是过滤器映射的定义,由<filter-mapping>元素表示,可以将一个过滤器映射到一个或者多个Servlet或JSP文件,也
可以采用url-pattern将过滤器映射到任意特征的URL
\\w{2,}@\\w{2,20}(\\.w{2,10}){1,2} 邮箱正则表达式
hash值可能相同
客户端通过new Socket()方法创建通信的Socket对象
服务器端通过new ServerSocket()创建TCP连接对象 accept接纳客户端请求
子类构造方法在调用时必须先调用父类的,由于父类没有无参构造,必须在子类中显式调用
///
,重载的实现是编译器根据函数的不同的参数表,对同名函数的名称做修饰,那么对于编译器而言,这些同名函数就成了不同的函数。但重写则是子类方法对父类的方法的延申,即子类不仅继承了父类的方法,还向父类的方法中添加了属于自己的内容,改变了父类方法原本的内容,
而final代表了一种不可变,这明显与重写形成了冲突。因此被final修饰的类可以被重载但不能被重写
///
排序Map的键重复后会值会被覆盖
//
堆区:只存放类对象,线程共享;
方法区:又叫静态存储区,存放class文件和静态数据,线程共享;
栈区:存放方法局部变量,基本类型变量区、执行环境上下文、操作指令区,线程不共享;
HashTable是线程安全的
Vector是线程安全的ArrayList
TreeSet和LinkedList都不是线程安全的
///
***************
Java一律采用Unicode编码方式,每个字符无论中文还是英文字符都占用2个字节。 B 也是不正确的,不同的编码之间是可以转换的,
通常流程如下: 将字符串S以其自身编码方式分解为字节数组,再将字节数组以你想要输出的编码方式重新编码为字符串。
例:String newUTF8Str = new String(oldGBKStr.getBytes("GBK"), "UTF8"); C 是正确的。Java虚拟机中通常使用UTF-16的
方式保存一个字符 D 也是正确的。ResourceBundle能够依据Local的不同,选择性的读取与Local对应后缀的properties文件,以达到国际化的目的。
***************
被static修饰的变量称为静态变量,静态变量属于整个类,而局部变量属于方法,只在该方法内有效,所以static不能修饰局部变量
/***************************
含有abstract修饰符的class即为抽象类,abstract类不能创建的实例对象。含有abstract方法的类必须定义为abstract class,
abstract class类中的方法不必是抽象的。abstract class类中定义抽象方法必须在具体(Concrete)子类中实现,所以,不能有抽象构造方法
或抽象静态方法。如果的子类没有实现抽象父类中的所有抽象方法,那么子类也必须定义为abstract类型。 接口(interface)可以说成是
抽象类的一种特例,接口中的所有方法都必须是抽象的。接口中的方法定义默认为public abstract类型,接口中的成员变量类型默认为
public static final。 下面比较一下两者的语法区别: 1.抽象类可以有构造方法,接口中不能有构造方法。 2.抽象类中可以有普通成员变量,
接口中没有普通成员变量 3.抽象类中可以包含非抽象的普通方法,接口中的所有方法必须都是抽象的,不能有非抽象的普通方法。
4. 抽象类中的抽象方法的访问类型可以是public,protected和(默认类型,虽然 eclipse下不报错,但应该也不行),但接口中的抽象
方法只能是public类型的,并且默认即为public abstract类型。 5. 抽象类中可以包含静态方法,接口中不能包含静态方法
6. 抽象类和接口中都可以包含静态成员变量,抽象类中的静态成员变量的访问类型可以任意,但接口中定义的变量只能是public static final类型,
并且默认即为public static final类型。 7. 一个类可以实现多个接口,但只能继承一个抽象类。 下面接着再说说两者在应用上的区别:
接口更多的是在系统架构设计方法发挥作用,主要用于定义模块之间的通信契约。而抽象类在代码实现方面发挥作用,可以实现代码的重用,
例如,模板方法设计模式是抽象类的一个典型应用,假设某个项目的所有Servlet类都要用相同的方式进行权限判断、记录访问日志和处理异常,
那么就可以定义一个抽象的基类,让所有的Servlet都继承这个抽象基类,在抽象基类的service方法中完成权限判断、记录访问日志和处理异常的代码,
在各个子类中只是完成各自的业务逻辑代码,伪代码如下: package com.lei; import java.io.IOException;
import javax.servlet.ServletException; import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; public abstract class BaseServlet extends HttpServlet
{ /** * serialVersionUID属性概述 * */ private static final long serialVersionUID = 1L;
public final void service(HttpServletRequest request, HttpServletResponse response)
throws IOException, ServletException { // 记录访问日志 // 进行权限判断 if (true)// if条件里写的是“具有权限” {
try { doService(request, response); } catch (IOException e) { // 记录异常信息 } } }
protected abstract void doService(HttpServletRequest request,
HttpServletResponse response) throws IOException, ServletException; } 实现类如下:
package com.lei; import java.io.IOException; import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse;
public class MyServlet extends BaseServlet{ /** * serialVersionUID属性概述 * */
private static final long serialVersionUID = 1L; @Override protected void doService(HttpServletRequest request,
HttpServletResponse response) throws IOException, ServletException { // TODO Auto-generated method stub } }
父类方法中间的某段代码不确定,留给子类干,就用模板方法设计模式。 备注:这道题的思路是先从总体解释抽象类和接口的基本概念,
然后再比较两者的语法细节,最后再说两者的应用区别。 比较两者语法细节区别的条理是:先从一个类中的构造方法、普通成员变量和方法
(包括抽象方法),静态变量和方法,继承性等6个方面逐一去比较回答,接着从第三者继承的角度的回答,特别是最后用了一个典型的例子
来展现自己深厚的技术功底。
***************************/
final修饰方法后,方法是不可被重写的,因为它已经是“最终形态”了。但不会影响重载
/
关于抽象类
JDK 1.8以前,抽象类的方法默认访问权限为protected
JDK 1.8时,抽象类的方法默认访问权限变为default
关于接口
JDK 1.8以前,接口中的方法必须是public的
JDK 1.8时,接口中的方法可以是public的,也可以是default的
JDK 1.9时,接口中的方法可以是private的
作者:herock
链接:https://www.nowcoder.com/exam/test/74723974/submission?examPageSource=Intelligent&pid=53467540&testCallback=https%3A%2F%2Fwww.nowcoder.com%2Fexam%2Fintelligent%3FquestionJobId%3D10%26tagId%3D21002&testclass=%E8%BD%AF%E4%BB%B6%E5%BC%80%E5%8F%91
来源:牛客网
///
修饰非静态方法 锁的是this 对象
修饰静态方法 锁的是class对象
重写 要求两同两小一大原则, 方法名相同,参数类型相同,子类返回类型小于等于父类方法返回类型, 子类抛出异常小于等于父类方法抛出异常,
子类访问权限大于等于父类方法访问权限。[注意:这里的返回类型必须要在有继承关系的前提下比较]
throws表示出现异常的一种可能性,并不一定会发生异常;throw则是抛出了异常,执行throw则一定抛出了某种异常。
在同一个java原文件中,可以有多个class类,但是只有有一个公共的 public class
+ Java 的垃圾回收器(GC)主要针对堆区,所以在栈区中的方法调用就不会由GC释放。
在Try catch finally体系当中,在return之前始终会执行finally里面的代码,如果finally里面有return,则数据跟随finally改变。
如果没有return,则原数据不跟随finally里改变的数据改变。
采用synchronized修饰符实现的同步机制叫做互斥锁机制,它所获得的锁叫做互斥锁。每个对象都有一个monitor(锁标记),
当线程拥有这个锁标记时才能访问这个资源,没有锁标记便进入锁池。任何一个对象系统都会为其创建一个互斥锁,这个锁是为了分配给线程的,
防止打断原子操作。每个对象的锁只能分配给一个线程,因此叫做互斥锁。
在这里帮大家总结一下hashMap和hashtable方面的知识点吧: 1. 关于HashMap的一些说法: a)
HashMap实际上是一个“链表散列”的数据结构,即数组和链表的结合体。HashMap的底层结构是一个数组,数组中的每一项是一条链表。
b) HashMap的实例有俩个参数影响其性能: “初始容量” 和 装填因子。 c) HashMap实现不同步,线程不安全。
HashTable线程安全 d) HashMap中的key-value都是存储在Entry中的。 e)
HashMap可以存null键和null值,不保证元素的顺序恒久不变,它的底层使用的是数组和链表,通过hashCode()方法和equals方法保证键的唯一性
f) 解决冲突主要有三种方法:定址法,拉链法,再散列法。HashMap是采用拉链法解决哈希冲突的。 注:
链表法是将相同hash值的对象组成一个链表放在hash值对应的槽位;
用开放定址法解决冲突的做法是:当冲突发生时,使用某种探查(亦称探测)技术在散列表中形成一个探查(测)序列。
字符串比较:在编译时对"my" + "String"进行拼接成myString字符串,再去常量池查找,找到之后指向该字符串地址
& 与操作;| 或操作;!非操作;~按位取反操作