[搞定面试] java开篇

爬起来复习了,春招要开始了!

前言

各种知识多而且容易遗忘,还不容易复习。最好的方法当然是自己给自己提问,不断补缺查漏,缺什么补什么。本文将各类知识归类,并将全文知识点浓缩在自问自查中,并且都写好目录,自问自查时可以随时跳转过去,方便大家系统的学习复习知识。 水平有限,有错误敬请指正

食用方法
自问自查---阅读原文---自问自查--阅读原文...
无限循环


传送门(含目录)
计网分层:https://blog.csdn.net/qq_45021207/article/details/112387871
计网应用层:https://blog.csdn.net/qq_45021207/article/details/112723944
计网传输层:https://blog.csdn.net/qq_45021207/article/details/113184737
计网网络层&数据链路层 :https://blog.csdn.net/qq_45021207/article/details/113248814
数据库:https://blog.csdn.net/qq_45021207/article/details/113427419
java开篇: https://blog.csdn.net/qq_45021207/article/details/113770277

自查自问

1. 静态代理,动态代理,区别,优缺点,动态的两种实现
2. String,Stringbuffer,Stringbuilder  为什么不变 线程安全与否
3. 泛型擦除  泛型扩展
4. java 值传递 
5. comparable&compartor 区别
6. 面向对象,面向过程 优缺点
7. 成员方法变量,类方法变量,this
8. 异常 
9. object有哪些方法
10. 接口和抽象类 区别
11. 修饰符 类修饰符
12. 字符编码 utf 
13. 重写重载 
14. 父指子 访问权限

动静态代理

静态代理:
由程序员创建或工具生成代理类的源码,再编译代理类。所谓静态也就是在程序运行前就已经存在代理类的字节码文件,代理类和委托类的关系在运行前就确定了。

与静态代理类对照的是动态代理类,动态代理类的字节码在程序运行时由Java反射机制动态生成,无需程序员手工编写它的源代码。动态代理类不仅简化了编程工作,而且提高了软件系统的可扩展性,因为Java 反射机制可以生成任意类型的动态代理类。java.lang.reflect 包中的Proxy类和InvocationHandler 接口提供了生成动态代理类的能力。

动态代理:
JDK动态代理和CGLIB动态代理:
①JDK动态代理只提供接口的代理,不支持类的代理。核心InvocationHandler接口和Proxy类,InvocationHandler 通过invoke()方法反射来调用目标类中的代码,动态地将横切逻辑和业务编织在一起;接着,Proxy利用 InvocationHandler动态创建一个符合某一接口的的实例, 生成目标类的代理对象。

②如果代理类没有实现 InvocationHandler 接口,那么Spring AOP会选择使用CGLIB来动态代理目标类。CGLIB(Code Generation Library),是一个代码生成的类库,可以在运行时动态的生成指定类的一个子类对象,并覆盖其中特定方法并添加增强代码,从而实现AOP。CGLIB是通过继承的方式做的动态代理,因此如果某个类被标记为final,那么它是无法使用CGLIB做动态代理的。

源码示例:
JDK动态代理中包含一个类和一个接口:
InvocationHandler接口:
Object proxy:指被代理的对象
Method method:要调用的方法
Object[] args:方法调用时所需要的参数

public interface InvocationHandler {
public Object invoke(Object proxy,Method method,Object[] args) throws Throwable;
}

参数说明:

Object proxy:指代理对象。
Method method:要调用的方法
Object[] args:方法调用时所需要的参数
可以将InvocationHandler接口的子类想象成一个代理的最终操作类。

Proxy类:
Proxy类是专门完成代理的操作类,可以通过此类为一个或多个接口动态地生成代理类,此类提供了如下的操作方法:

public static Object newProxyInstance (ClassLoader loader, Class<?>[] interfaces,
InvocationHandler h) throws IllegalArgumentException

参数说明:
ClassLoader loader:类加载器 //被代理类的
Class<?>[] interfaces:得到全部的接口 //被代理类的
InvocationHandler h:得到InvocationHandler接口的子类实例

public class BookFacadeImpl implements BookFacade {  //BookFacade的接口已经写好
    @Override
    public void addBook() {
        System.out.println("增加图书方法。。。");
    }
}


class BookFacadeProxy implements InvocationHandler {
    private Object target;

    /*  绑定委托对象并返回一个代理类*/
    public Object bind(Object target) {
        this.target = target;
        //取得代理对象
        return Proxy.newProxyInstance(target.getClass().getClassLoader(),
                target.getClass().getInterfaces(), this);   //要绑定接口(这是一个缺陷,cglib弥补了这一缺陷)
    }


    /**
     * 调用方法,加入加强部分
     调用方法时候触发此方法
     */
@Override
    public Object invoke(Object proxy, Method method, Object[] args)  
            throws Throwable {
        Object result=null;
        System.out.println("事物开始");
        //执行方法
        result=method.invoke(target, args);  //调用被代理类的方法,并返回结果,如果为基础类型返回他的包装类
        System.out.println("事物结束");
        return result;
    }

}

class TestProxy {

    public static void main(String[] args) {
        BookFacadeProxy proxy = new BookFacadeProxy();
        BookFacade bookProxy = (BookFacade) proxy.bind(new BookFacadeImpl());  
        bookProxy.addBook();
    }

}

https://www.cnblogs.com/jqyp/archive/2010/08/20/1805041.html

String,Stringbuffer,Stringbuilder

char编码 utf-16

String类被final修饰,不可被继承。
String的成员变量char数组value被final修饰,初始化后不可更改引用。

String不可变一方面保证了String池的存在,另一方线程是安全的

ensureCapacityInternal()方法是检查StringBuilder的对象的原字符数组的容量能不能盛下新的字符串

Stringbuilder不安全的原因:两个同时对数组append 原来是4容量5 两个同时确认实可以装下
然后 两个装完 到6了

Stringbuffer
加synchronized

public synchronized StringBuffer append(String str) { 
        toStringCache = null; 
        super.append(str); 
        return this; }

https://www.cnblogs.com/Jacian/p/11553320.html

泛型擦除

在编译期间,所有的泛型信息都会被擦除,List<integer>和List<string>类型,在编译后都会变成List类型(原始类型)在生成的字节码中是不包含泛型中的类型信息的</string></integer>

既然说类型变量会在编译的时候擦除掉,那为什么定义了ArrayList<integer>泛型类型,而不允许向其中插入String对象呢?不是说泛型变量Integer会在编译时候擦除变为原始类型Object吗,为什么不能存放别的类型呢?既然类型擦除了,如何保证我们只能使用泛型变量限定的类型呢?
java是如何解决这个问题的呢?java编译器是通过先检查代码中泛型的类型,然后再进行类型擦除,再进行编译的。</integer>

擦除getValue()的返回类型后将返回Object类型,编译器自动插入Integer的强制类型转换。也就是说,编译器把这个方法调用翻译为两条字节码指令:

1、对原始方法Pair.getValue的调用

2、将返回的Object类型强制转换为Integer

此外,存取一个泛型域时,也要插入强制类型转换。因此,我们说Java的泛型是在编译器层次进行实现的,被称为“伪泛型”
————————————————
List<? extends Number>
List集合装载的元素只能是Number的子类或自身

在这里插入图片描述
https://blog.51cto.com/flyingcat2013/1616068
原文链接:https://blog.csdn.net/sunxianghuang/article/details/51982979

java 值传递

值传递(pass by value)是指在调用函数时将实际参数复制一份传递到函数中,这样在函数中如果对参数进行修改,将不会影响到实际参数。

引用传递(pass by reference)是指在调用函数时将实际参数的地址直接传递到函数中,那么在函数中对参数所进行的修改,将影响到实际参数。

值传递和引用传递的区别并不是传递的内容。而是实参到底有没有被复制一份给形参。

把实际参数的引用的地址复制了一份,传递给了形式参数。所以,上面的参数其实是值传递,把实参对象引用的地址当做值传递给了形式参数。

也就是说引用是不可改变的,但是引用的对象的内容实可以改变的;

Java中其实还是值传递的,只不过对于对象参数,值的内容是对象的引用。

https://blog.csdn.net/bjweimengshu/article/details/79799485?depth_1-utm_source=distribute.pc_relevant.none-task&utm_source=distribute.pc_relevant.none-task

comparable&compartor

static class MyComparatorAge implements Comparator<User>{
@Override
public int compare(User u1, User u2) {
return (u1.getAge() - u2.getAge());
}
}



public class Student implements Comparable<Student>{
@Override
public int compareTo(Student o) {
return (this.no - o.getNo());
}

}
Comparator提供外部对比  有equals方法

Comparable提供对象自身对比

面向对象,面向过程

面向对象易维护,易复用,易扩展

面向过程比较快:

在这里插入图片描述
Java语言是一种特殊的语言,它采用的形式为先编译,再解释的执行方式。也就是先把Java语言的源代码编译成中间代码class文件,然后在运行时根据class文件的内容解释执行。

成员方法变量,类方法变量,this

成员变量:包括实例变量和类变量,用static修饰的是类变量,不用static修饰的是实例变量,所有类的成员变量可以通过this来引用。

类变量:静态域,静态字段,或叫静态变量,它属于该类所有实例共有的属性。而且所有的实例都可以修改这个类变量的值(这个类变量没有被final修饰的情况),而且访问类变量的时候不用实例,直接用类名.的方式就可以。

成员方法:包括实例方法和类方法,用static的方法就是类方法,不用static修饰的就是实例方法。实例方法必须在创建实例之后才可以调用。

类方法:和类变量一样,可以不用实例,直接用类就可以调用类方法。

this :
this关键字必须放在非静态方法里面
this关键字代表自身,在程序中主要的使用用途有以下几个方面:
? 使用this关键字引用成员变量
? 使用this关键字在自身构造方法内部引用其它构造方法
? 使用this关键字代表自身类的对象
? 使用this关键字引用成员方法

异常

必检异常 免检异常

object有哪些方法

protected Object clone() 创建并返回此对象的一个副本。 浅层复制
boolean equals(Object obj) 指示其他某个对象是否与此对象“相等”。
protected void finalize() 当垃圾回收器确定不存在对该对象的更多引用时,由对象的垃圾回收器调用此方法。
Class getClass() 返回此 Object 的运行时类。
int hashCode() 返回该对象的哈希码值。
void notify() 唤醒在此对象监视器上等待的单个线程。
void notifyAll() 唤醒在此对象监视器上等待的所有线程。
String toString() 返回该对象的字符串表示。
void wait() 在其他线程调用此对象的 notify() 方法或 notifyAll() 方法前,导致当前线程等待。

接口和抽象类

接口中的方法都是默认public 实现时候 注意加 public

接口没有方法体
在jdk1.8中,接口里可以有静态方法,接口里的有静态方法 必须要有body。有静态方法不需要实现。

接口中的变量必须是 public static final ( 因为一个接口可以被多个类实现)
抽象类变量随意
https://www.cnblogs.com/bpynfy/p/5984177.html

抽象类对方法没有要求 但是非抽象方法必须要有方法体,
抽象方法不能有方法体,

实现接口或继承抽象类的子类必须实现接口的所有方法或抽象类的所有抽象方法。
接口中的所有方法均为抽象方法,抽象类中包含非抽象方法和抽象方法。如果一个类实现了接口,那么该子类必须实现父接口的所有方法。如果一个类继承了抽象类,那么该子类必须实现抽象类的所有抽象方法。

如果是抽象类要实现接口,可以实现部分或者一个都不实现就行,要是具体类就必须实现所有的方法”

,一个类只能继承一个抽象类,而一个类却可以实现多个接口。

修饰符

在这里插入图片描述
java中外部类的访问修饰符有如下四种:
public,默认,abstract,final
其中public表示任意位置都可以访问该类;
不写表示默认访问修饰符,即在同一个包中可以访问;
abstract是表示该类为一个抽象类,不能实例化该类,即不能使用Test3 test3 = new Test3();的方式获取Test3的实例。如果要使用它则需要找一个类继承该类;
final表示该类不能被子类继承,该类即为最终类,不可再被继承。

字符编码 utf

ASCII数字 字母 符号

表Unicode的出现
Unicode 为世界上所有字符都分配了一个唯一的数字编号,这个编号范围从 0x000000 到 0x10FFFF (十六进制),有 110 多万,每个字符都有一个唯一的 Unicode 编号,这个编号一般写成 16 进制,在前面加上 U+。例如:“马”的 Unicode 是U+9A6C。

Unicode 就相当于一张表,建立了字符与编号之间的联系。
在这里插入图片描述

它是一种规定,Unicode 本身只规定了每个字符的数字编号是多少,并没有规定这个编号如何存储。
有的人会说了,那我可以直接把 Unicode 编号直接转换成二进制进行存储,是的,你可以,但是这个就需要人为的规定了,而 Unicode 并没有说这样弄,因为除了你这种直接转换成二进制的方案外,还有其他方案,接下来我们会逐一看到。
编号怎么对应到二进制表示呢?有多种方案:主要有 UTF-8,UTF-16,UTF-32。

utf-8为了节省资源,采用变长编码,utf-16是用两个字节来编码所有的字符,utf-32则选择用4个字节来编码,

UTF-8、UTF-16、UTF-32 都是 Unicode 的一种实现。

重写重载

重写
* 1、参数列表必须完全与被重写的方法相同,否则不能称其为重写而是重载。
*
2、返回的类型必须一直与被重写的方法的返回类型相同或其子类

3、访问修饰符的权限一定要大于被重写方法的访问修饰符(public>protected>default>private)
4、重写方法一定不能抛出新的检查异常或者比被重写方法申明更加宽泛的检查型异常。例如:
父类的一个方法申明了一个检查异常IOException,在重写这个方法是就不能抛出Exception,只能抛出IOException的子类异常,可以抛出非检查异常。
————————————————

重载:

光根据返回值无法确定重载 是另一个方法了

(1)、必须具有不同的参数列表;

(2)、可以有不同的返回类型,只要参数列表不同就可以了;

(3)、可以有不同的访问修饰符;

(4)、可以抛出不同的异常;

在这里插入图片描述

int,Integer

在这里插入图片描述
总结:除了局部变量存放在栈中,其它变量都在堆中

Integer a = 300;
Integer b = 300;
int c = 300;
a == b; false
a >b false
a >= b true
a == c true (自动转型为int)

int占用4个字节。 integer占用16个字节

装箱,拆箱原理:
Java的自动拆装箱发生在编译期,即javac编译的那一刻,而不是在运行期!

如果编译器发现需要自动装箱,会用语法糖的方法自动给你加上Integer.valueOf(),即将A类里面的1变成Integer.valueOf(1)

拆箱 int b = a.intValue();

https://blog.csdn.net/Sun_flower77/article/details/78002736?utm_medium=distribute.pc_relevant_t0.none-task-blog-BlogCommendFromMachineLearnPai2-1.add_param_isCf&depth_1-utm_source=distribute.pc_relevant_t0.none-task-blog-BlogCommendFromMachineLearnPai2-1.add_param_isCf

父指子

父类对象不可以访问,子类方法(重写除外)。

对于父类中定义的方法,如果子类中重写了该方法,那么父类类型的引用将会调用子类中的这个方法

某个类型的引用只能调用自己得方法(被重写得方法就调用子类的)


自查自问

1. 静态代理,动态代理,区别,优缺点,动态的两种实现
2. String,Stringbuffer,Stringbuilder  为什么不变 线程安全与否
3. 泛型擦除  泛型扩展
4. java 值传递 
5. comparable&compartor 区别
6. 面向对象,面向过程 优缺点
7. 成员方法变量,类方法变量,this
8. 异常 
9. object有哪些方法
10. 接口和抽象类 区别
11. 修饰符 类修饰符
12. 字符编码 utf 
13. 重写重载 
14. 父指子 访问权限
#春招##Java#
全部评论
Mark
点赞 回复
分享
发布于 2021-02-16 19:46
Mark too
点赞 回复
分享
发布于 2021-02-17 13:41
小红书
校招火热招聘中
官网直投

相关推荐

31 262 评论
分享
牛客网
牛客企业服务