笔试刷题记录(一)
静态方法 重载
package com.szs.algorithm.test3; import java.util.*; public class Demo { public static void main(String[] args) { Collection[] collections = {new HashSet(), new ArrayList(), new HashMap().values()}; Super subToSuper = new Sub(); for(Collection collection: collections) { System.out.println(subToSuper.getType(collection)); } } abstract static class Super { public static String getType(Collection collection) { return "Super:collection"; } public static String getType(List list) { return "Super:list"; } public String getType(ArrayList list) { return "Super:arrayList"; } public static String getType(Set set) { return "Super:set"; } public String getType(HashSet set) { return "Super:hashSet"; } } static class Sub extends Super { public static String getType(Collection collection) { return "Sub"; } } }
Super:collection Super:collection Super:collection
考了两个知识点: 1. 静态方法,不存在重写,重写只对可见的实例方法有效。静态方法只有隐藏。 2. 重载是根据形参的静态类型确定调用的方法版本,重写是根据调用者在运行期的实际类型来确定调用的方法版本。 public class Demo { public static void main(String[] args) { Collection[] collections = // 注意, collections数组的静态类型是Collection的。 { new HashSet(),new ArrayList(),new HashMap().values()};//map.values()方法的返回值是Collection Super subToSuper = new Sub();//静态类型是Super,实际类型是Sub for(Collection collection: collections) { System.out.println(subToSuper.getType(collection));//静态方法不存在重写,这里调用的是父类的getType方法,父类中有很多重载,根据数组的静态类型,确定调用版本 } }
会话跟踪
会话跟踪���一种灵活、轻便的机制,它使Web上的状态编程变为可能。 HTTP是一种无状态协议,每当用户发出请求时,服务器就会做出响应,客户端与服务器之间的联系是离散的、非连续的。当用户在同一网站的多个页面之间转换时,根本无法确定是否是同一个客户,会话跟踪技术就可以解决这个问题。当一个客户在多个页面间切换时,服务器会保存该用户的信息。 有四种方法可以实现会话跟踪技术:URL重写、隐藏表单域、Cookie、Session。 1).隐藏表单域:,非常适合步需要大量数据存储的会话应用。 2).URL 重写:URL 可以在后面附加参数,和服务器的请求一起发送,这些参数为名字/值对。 3).Cookie:一个 Cookie 是一个小的,已命名数据元素。服务器使用 SET-Cookie 头标将它作为 HTTP 响应的一部分传送到客户端,客户端被请求保存 Cookie 值,在对同一服务器的后续请求使用一个 Cookie 头标将之返回到服务器。与其它技术比较,Cookie 的一个优点是在浏览器会话结束后,甚至 在客户端计算机重启后它仍可以保留其值 4).Session:使用 setAttribute(String str,Object obj)方法将对象捆绑到一个会话
JDK提供的用于并发编程的同步器有哪些?
答案:ABC A,Java 并发库 的Semaphore 可以很轻松完成信号量控制,Semaphore可以控制某个资源可被同时访问的个数,通过 acquire() 获取一个许可,如果没有就等待,而 release() 释放一个许可。 B,CyclicBarrier 主要的方法就是一个:await()。await() 方法没被调用一次,计数便会减少1,并阻塞住当前线程。当计数减至0时,阻塞解除,所有在此 CyclicBarrier 上面阻塞的线程开始运行。 C,直译过来就是倒计数(CountDown)门闩(Latch)。倒计数不用说,门闩的意思顾名思义就是阻止前进。在这里就是指 CountDownLatch.await() 方法在倒计数为0之前会阻塞当前线程。 D,Counter不是并发编程的同步器
内部类
在Java中,可以将一个类定义在另一个类里面或者一个方法里边,这样的类称为内部类,广泛意义上的内部类一般包括四种:成员内部类,局部内部类,匿名内部类,静态内部类 。
- 成员内部类
(1)该类像是外部类的一个成员,可以无条件的访问外部类的所有成员属性和成员方法(包括private成员和静态成员);
(2)成员内部类拥有与外部类同名的成员变量时,会发生隐藏现象,即默认情况下访问的是成员内部类中的成员。如果要访问外部类中的成员,需要以下形式访问:【外部类.this.成员变量 或 外部类.this.成员方法】;
(3)在外部类中如果要访问成员内部类的成员,必须先创建一个成员内部类的对象,再通过指向这个对象的引用来访问;
(4)成员内部类是依附外部类而存在的,也就是说,如果要创建成员内部类的对象,前提是必须存在一个外部类的对象;
(5)内部类可以拥有private访问权限、protected访问权限、public访问权限及包访问权限。如果成员内部类用private修饰,则只能在外部类的内部访问;如果用public修饰,则任何地方都能访问;如果用protected修饰,则只能在同一个包下或者继承外部类的情况下访问;如果是默认访问权限,则只能在同一个包下访问。外部类只能被public和包访问两种权限修饰。
- 局部内部类
(1)局部内部类是定义在一个方法或者一个作用域里面的类,它和成员内部类的区别在于局部内部类的访问仅限于方法内或者该作用域内;
(2)局部内部类就像是方法里面的一个局部变量一样,是不能有public、protected、private以及static修饰符的。
- 匿名内部类
(1)一般使用匿名内部类的方法来编写事件监听代码;
(2)匿名内部类是不能有访问修饰符和static修饰符的;
(3)匿名内部类是唯一一种没有构造器的类;
(4)匿名内部类用于继承其他类或是实现接口,并不需要增加额外的方法,只是对继承方法的实现或是重写。
- 内部静态类
(1)静态内部类是不需要依赖于外部类的,这点和类的静态成员属性有点类似;
(2)不能使用外部类的非static成员变量或者方法。
- 成员内部类:
成员内部类是定义在另一个类里面的类,它可以访问外部类的所有成员(包括私有成员)。成员内部类不能含有 static 的变量和方法。
class Outer { private int x = 10; class Inner { public void print() { System.out.println("x = " + x); } } } public class Main { public static void main(String[] args) { Outer outer = new Outer(); Outer.Inner inner = outer.new Inner(); inner.print(); // 输出 "x = 10" } }
- 局部内部类:
局部内部类是定义在一个方法或者一个作用域里面的类,它只能访问当前方法或作用域内的变量。
public class Main { public void test() { int x = 10; class LocalInner { public void print() { System.out.println("x = " + x); } } LocalInner localInner = new LocalInner(); localInner.print(); // 输出 "x = 10" } }
- 匿名内部类:
匿名内部类是没有名字的内部类,通常用于实现接口或者继承抽象类。匿名内部类只能使用一次。
interface MyInterface { void print(); } public class Main { public static void main(String[] args) { MyInterface myInterface = new MyInterface() { @Override public void print() { System.out.println("Hello, world!"); } }; myInterface.print(); // 输出 "Hello, world!" } }
- 静态内部类:
静态内部类是定义在另一个类里面的静态类,它可以不依赖于外部类的实例而独立存在。静态内部类只能访问外部类的静态成员。
class Outer { private static int x = 10; static class StaticInner { public void print() { System.out.println("x = " + x); } } } public class Main { public static void main(String[] args) { Outer.StaticInner staticInner = new Outer.StaticInner(); staticInner.print(); // 输出 "x = 10" } }
对于外部类来说,只有两种修饰,public和默认(default),因为外部类放在包中,只有两种可能,包可见和包不可见。 对于内部类来说,可以有所有的修饰,因为内部类放在外部类中,与成员变量的地位一致,所以有四种可能。