JAVA 语言基础

StringBuilder buffer ,String 区别

  • 线程安全

    • string不可变 final 修饰,线程安全
    • buffer 安全 ,用了 syncrhonized 同步 ,可变字符串
    • builder 没有锁,不安全
  • 可变

    • string 是 底层用了个 final 的 char 数组,不可变
    • builder和 buffer 也是有个数组,但是 是可变的,底层其实 类似 ArrayList 自动扩容这种
  • 单线程 直接用 builder 【如果字符串 经常变的话】

buffer 的

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
 public final class StringBuffer
    extends AbstractStringBuilder
    implements java.io.Serializable, CharSequence
{

    /**
     * A cache of the last value returned by toString. Cleared
     * whenever the StringBuffer is modified.
     */
    private transient char[] toStringCache;

    /** use serialVersionUID from JDK 1.0.2 for interoperability */
    static final long serialVersionUID = 3388685877147921107L;
 

@Override
    public synchronized StringBuffer append(Object obj) {
        toStringCache = null;
        super.append(String.valueOf(obj));
        return this;
    }

    @Override
    public synchronized StringBuffer append(String str) {
        toStringCache = null;
        super.append(str);
        return this;
    }
stringBuilder
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
   @Override
    public StringBuilder append(CharSequence s, int start, int end) {
        super.append(s, start, end);
        return this;
    }

    @Override
    public StringBuilder append(char[] str) {
        super.append(str);
        return this;
    }

    /**
     * @throws IndexOutOfBoundsException {@inheritDoc}
     */
    @Override
    public StringBuilder append(char[] str, int offset, int len) {
        super.append(str, offset, len);
        return this;
    }

session cookie原理

用户访问服务器,服务器 返回一个 set-cookie 里面带有 一个 jsessionid ,这个相当于一个 令牌,标识当前用户,

下次访问,浏览器 请求的话会 携带 这个 jsessionid 去 访问服务器 。 服务器 通过 jsessionid 就知道是哪个用户了。

注意 这里会有个跨域问题,不同端口,不同域名 会跨域,主要是浏览器同源策略, 用户跨域 携带 jsessionid 的话,跨域服务器 获得这个用户这个域名的 cookie 或者 sessionid ,这个用户就不安全了。

session 的过期时间 是 默认 30分钟,可以设置 【tomcat默认过期时间】

  • setMaxAge(int) 方法设置缓存客户端时间
  • setMaxInactiveInterval 设置 过段时间销毁
  • invalidate 强制结束 cookie的缓存时间

反射API

具体可以参考我的博客

  • class 内部的方法

    • 静态方法
      • forName
    • getDeclaredFields
    • getDeclaredField
    • newInstance
    • getConstructor
  • Field 方法

    • setAccessible
    • set
      • set、get
      • getType
      • getGenericType
    • get
    • getModifiers
1
2
3
4
5
6
7
8
Field[] testFields = this.getClass().getDeclaredFields();
Object object = null;
if (testFields[0].getGenericType().getTypeName().equals("String")) {
	object = String.valueOf(field.get(this));
}
if (field.getGenericType().getTypeName().equals("Integer")) {
	object = field.getInt(this);
}

实现一个mapToObject 方法

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21

    public static Object mapToObject(Map<String, Object> map, Class<?> beanClass){      
        if (map == null)    
            return null;      
        Object obj = null;  
        try {  
            obj = beanClass.newInstance();    
            Field[] fields = obj.getClass().getDeclaredFields();                       for (Field field : fields) {      
                int mod = field.getModifiers();      
                //判断 不是 static 和 final的属性
                if(Modifier.isStatic(mod) || Modifier.isFinal(mod)){      
                    continue;      
                }      
                field.setAccessible(true);      
                field.set(obj, map.get(field.getName()));     
            }  
        } catch (Exception e) {  
            e.printStackTrace();  
        }     
        return obj;      
    }

== 、 equals、 hashCode

== 比较地址, equals 默认也是比较的地址

重写 equals 自己可以定义 对象 的比较逻辑

hashCode 是 用来个 HashMap ,hashSet 用的

compare 和 compareTo方法

compareTo(Object o)方法是java.lang.Comparable接口中的方法,当需要对某个类的对象进行排序时,该类需要实现Comparable接口的,必须重写public int compareTo(T o)方法。

compare(Object o1,Object o2)方法是java.util.Comparator接口的方法,它实际上用的是待比较对象的compareTo(Object o)方法。 对于它,则是针对一些本身没有比较能力的对象(数组)为它们实现比较的功能,所以它叫做比较器,是一个外部的东西,通过它定义比较的方式,再传到Collection.sort()和Arrays.sort()中对目标排序,而且通过自身的方法compare()定义比较的内容和结果的升降序;

对对象排序 ,可以自定义一个比较器【策略模式】

JMM

  1. 元空间【方法区,永久代】
  2. 程序计数器
  3. 局部变量表
  4. 本地内存

内存交互的 8种操作,虚拟机实现 必须保证每一个操作都是 原子的,不可再分的

lock 锁定 : 作用域主内存的变量,把一个变量标识为线程独占状态 【volatile原理 】

unlock 解锁 : 解除锁定的变量 才能被其他线程锁定

read 作用域主内存, 它把一个变量值从 主内存 传输到线程的工作内存, 以便随后的load 动作使用

load 载入: 作用于工作内存的变量,把read操作从 主存中变量放入工作内存中

use 使用: 作用于工作内存中的变量,它把工作内中的变量传输给执行引擎,每当虚拟机遇到需要使用的变量 ,就会使用这个指令

assign 赋值: 作用 于工作内存中的变量, 把执行引擎接收到的值存入工作内存的变量副本中

store 存储: 作用域主内存, 把工作内存的变量传输到主内存,方便后序 write

write 写入: 作用于主内存, 把store操作从工作内存中得到的变量放入主内存的变量中

JMM 八种指令有 如下规则

  1. 不允许 read 和 load 、store 和 write 操作之一单独出现。即使用了read 必须 load,store 必须 write
  2. 不允许线程丢弃他最近 assign的操作,即工作变量数据改后,必须同步回主存
  3. 不允许线程将没有 assign的数据同步回主存
  4. 一个新变量必须从主存中诞生,不允许工作内存直接使用未初始化的变量。就是对变量 实施use、store操作之前,必须 经过 assign 和 load操作
  5. 一个变量同一时间只有一个线程 能对其进行lock。 多次 lock 后,必须执行相同次数的unlock才能解锁
  6. 对一个变量进行 lock操作,会清空工作内存中此变量的值, 在执行引擎使用这个变量前,必须重新 load 或 assign 操作初始化这个变量的值
  7. 如果一个变量没有被lock ,就不能unlock。 也不能unlock 一个被其他线程锁住的变量
  8. 对一个变量进行 unlock操作前,必须把此变量同步回主内存

volatile原理

image-20211008104730024

操作数栈

image-20211008124759280