首页 > 编程语言 >java-base-three

java-base-three

时间:2023-07-22 19:11:07浏览次数:37  
标签:java 内部 静态 three base 线程 static 方法 public




  1. #在java中,对象的内存在哪个时刻回收,取决于垃圾回收器何时运行。

    一旦垃圾回收器准备好释放对象占用的存储空间,将首先调用其finalize()方法, 并且在下一次垃圾回收动作发生时,才会真正的回收对象占用的内存(《java 编程思想》) 在C++中,对象的内存在哪个时刻被回收,是可以确定的,在C++中,析构函数和资源的释放息息相关,能不能正确处理析构函数,关乎能否正确回收对象内存资源。 在java中,对象的内存在哪个时刻回收,取决于垃圾回收器何时运行,在java中,所有的对象,包括对象中包含的其他对象,它们所占的内存的回收都依靠垃圾回收器,因此不需要一个函数如C++析构函数那样来做必要的垃圾回收工作。当然存在本地方法时需要finalize()方法来清理本地对象。在《java编程思想》中提及,finalize()方法的一个作用是用来回收“本地方法”中的本地对象

    #一个对象成为垃圾是因为不再有引用指着它,就可能被垃圾回收器回收,主线程开启一个线程,当主线程运行完成,没有引用指向运行的线程,但是开启的线程还在运行,知道run方法运行结束退出,这一点和对象的垃圾回收是不一样的。

  2. 在Java中,可以将一个类定义在另一个类里面或者一个方法里边,这样的类称为内部类,广泛意义上的内部类一般包括四种:成员内部类,局部内部类,匿名内部类,静态内部类 。

    1.成员内部类

    (1)该类像是外部类的一个成员,可以无条件的访问外部类的所有成员属性和成员方法(包括private成员和静态成员)

    (2)成员内部类拥有与外部类同名的成员变量时,会发生隐藏现象,即默认情况下访问的是成员内部类中的成员。如果要访问外部类中的成员,需要以下形式访问:【外部类.this.成员变量  或  外部类.this.成员方法】;

    (3)在外部类中如果要访问成员内部类的成员,必须先创建一个成员内部类的对象,再通过指向这个对象的引用来访问;

    (4)成员内部类是依附外部类而存在的,也就是说,如果要创建成员内部类的对象,前提是必须存在一个外部类的对象;

    (5)内部类可以拥有private访问权限、protected访问权限、public访问权限及包访问权限。如果成员内部类用private修饰,则只能在外部类的内部访问;如果用public修饰,则任何地方都能访问;如果用protected修饰,则只能在同一个包下或者继承外部类的情况下访问;如果是默认访问权限,则只能在同一个包下访问。外部类只能被public和包访问两种权限修饰。

    2.局部内部类

    (1)局部内部类是定义在一个方法或者一个作用域里面的类,它和成员内部类的区别在于局部内部类的访问仅限于方法内或者该作用域内;

    (2)局部内部类就像是方法里面的一个局部变量一样,是不能有public、protected、private以及static修饰符的

    3.匿名内部类

    (1)一般使用匿名内部类的方法来编写事件监听代码;

    (2)匿名内部类是不能有访问修饰符和static修饰符的

    (3)匿名内部类是唯一一种没有构造器的类

    (4)匿名内部类用于继承其他类或是实现接口,并不需要增加额外的方法,只是对继承方法的实现或是重写。

    4.内部静态类

    (1)静态内部类是不需要依赖于外部类的,这点和类的静态成员属性有点类似;

    (2)不能使用外部类的非static成员变量或者方法


  3.  
    InterruptedException:当线程在活动之前或活动期间处于正在等待、休眠占用状态且该线程被中断时,抛出该异常。
    suspendsuspend方法作用是阻塞一个线程,不会释放锁,直到其他的线程调用resume方法,才能继续向下执行。被打断不会导致InterruptedException。
    且suspend()方法容易造成死锁,已被标记过时

  4.  

     

    实现多线程有以下四种方式

    实现多线程有以下四种方式:
    1. 继承Thread类

    2.实现Runnable接口

    3.实现Callable接口

    4.线程池:提供了一个线程队列,队列中保存着所有等待状态的线程。避免了创建与销毁额外开销,提高了响应的速度。

    https://www.cnblogs.com/big-keyboard/p/16813151.html





  5.  1)Cookie[] getCookies()
    返回一个数组,包含客户端发送该请求的所有的 Cookie 对象。

    2)Object getAttribute(String name)
    以对象形式返回已命名属性的值,如果没有给定名称的属性存在,则返回 null。 3)String getHeader(String name)
    以字符串形式返回指定的请求头的值。Cookie也是头的一种; 4)String getParameter(String name)
    以字符串形式返回请求参数的值,或者如果参数不存在则返回 null。

  6. Java到底是值传递还是引用传递?
    https://www.cnblogs.com/kisshappyboy/p/17309704.html

    经过上述分析,Java参数传递中,不管传递的是基本数据类型还是引用类型,都是值传递。

     

    当传递基本数据类型,比如原始类型(int、long、char等)、包装类型(Integer、Long、String等),实参和形参都是存储在不同的栈帧内,修改形参的栈帧数据,不会影响实参的数据。

     

    当传参的引用类型,形参和实参指向同一个地址的时候,修改形参地址的内容,会影响到实参。当形参和实参指向不同的地址的时候,修改形参地址的内容,并不会影响到实参。

     



  7. java中String并没有fromBytes、encode、decode方法


  8.  例子1如下:url格式不正确 且 url地址不存在,结果为抛出异常。

    例子2如下:url格式正确 且 url地址不存在,结果正常打印输出url字符串。
    例子3如下:url格式不正确 且 地址存在,结果为抛出异常。
    例子4如下:url格式正确 且 地址存在,结果正常打印输出url字符串。
    综上4个例子所述:
    创建URL对象时,必须捕获异常。但是此异常仅用于捕获URL字符串格式不当错误,而并非用于检查URL中对应的网站是否存在。

  9. getDeclaredField:查找该Class所有声明属性(静态/非静态),但是他不会去找实现的接口/父类的属性 getField:只查找该类public类型的属性,如果找不到则往上找他的接口、父类,依次往上,直到找到或者已经没有接口/父类  



  10. 1.session用来表示用户会话,session对象在服务端维护,一般tomcat设定session生命周期为30分钟,超时将失效,也可以主动设置无效; 2.cookie存放在客户端,可以分为内存cookie和磁盘cookie。内存cookie在浏览器关闭后消失,磁盘cookie超时后消失。当浏览器发送请求时,将自动发送对应cookie信息,前提是请求url满足cookie路径; 3.可以将sessionId存放在cookie中,也可以通过重写url将sessionId拼接在url。因此可以查看浏览器cookie或地址栏url看到sessionId; 4.请求到服务端时,将根据请求中的sessionId查找session,如果可以获取到则返回,否则返回null或者返回新构建的session,老的session依旧存在,请参考API。

         程序一般都是在用户做log off的时候发个指令去删除session,然而浏览器从来不会主动在关闭之前通知服务器它将要被关闭,因此服务器根本不会有机会知道浏览器已经关闭。服务器会一直保留这个会话对象直到它处于非活动状态超过设定的间隔为止。

        大部分session机制都使用会话cookie来保存session id,而关闭浏览器后这个session id就消失了,再次连接到服务器时也就无法找到原来的session。如果服务器设置的cookie被保存到硬盘上,或者使用某种手段改写浏览器发出的HTTP请求报头,把原来的session id发送到服务器,则再次打开浏览器仍然能够找到原来的session。
        恰恰是由于关闭浏览器不会导致session被删除,迫使服务器为session设置了一个失效时间,当距离客户上一次使用session的时间超过了这个失效时间时,服务器就可以认为客户端已经停止了活动,才会把session删除以节省存储空间。

        由此我们可以得出如下结论: 关闭浏览器,只会是浏览器端内存里的session cookie消失,但不会使保存在服务器端的session对象消失,同样也不会使已经保存到硬盘上的持久化cookie消失。


  11.  



     A 首先final声明的方法是不能被覆盖的,但是这里并不错误,因为方法是private的,也就是子类没有继承父类的run方法,因此子类的run方法跟父类的run方法无关,并不是覆盖。new Car().run()也是调用子类的run方法。

  12. 效率:System.arraycopy > clone > System.copyOf > for循环
    System.arraycopy():native方法+JVM手写函数,在JVM里预写好速度最快 clone():native方法,但并未手写,需要JNI(Java Native Interface)转换,速度其次 Arrays.copyof():本质是调用1的方法 for():全是深复制,并且不是封装方法,最慢情有可原

  13.  abstract class表示的是"is-a"关系,interface表示的是"like-a"关系。
    is-a,理解为是一个,代表继承关系。 如果A is-a B,那么B就是A的父类。 like-a,理解为像一个,代表组合关系。 如果A like a B,那么B就是A的接口。 has-a,理解为有一个,代表从属关系。 如果A has a B,那么B就是A的组成部分。

  14. 以java8为准,switch支持10种类型

    基本类型:byte char short int 与其包装类 :Byte,Short,Character,Integer  以及String 和 枚举类型enum
    1、实际只支持int类型 Java实际只能支持int类型的switch语句,那其他的类型时如何支持的?
    a、基本类型byte char short 原因:这些基本数字类型可自动向上转为int, 实际还是用的int。
    b、基本类型包装类Byte,Short,Character,Integer 原因:java的自动拆箱机制 可看这些对象自动转为基本类型
    c、String 类型 原因:实际switch比较的string.hashCode值,它是一个int类型

     

  15.  


    this调用自身的构造器,super调用父类的构造器

  16.  

    java程序的种类 1.Application:Java应用程序,是可以由Java解释器直接运行的程序。 2.Applet:即Java小应用程序,是可随网页下载到客户端由浏览器解释执行的Java程序,不用main方法,继承applet类即可
    3.Servlet:Java服务器端小程序,由Web服务器(容器)中配置运行的Java程序 

  17.  



    首先,for(表达式1;表达式2;表达式3){代码块} 执行顺序 ①表达式1——>②表达式2(T->代码块;F->⑤)——>③表达式3——>④跳转到②——⑤结束 表达式3中i++和++i起到的效果一样
    其次,

     不管怎样线程对a的操作就是+1后-2

    因为+=不是原子操作,所以导致多线程操作a的结果有多种
    1.线程1执行完再线程2执行,1-2+1-2=-2 2.线程1和2同时+1,再-2不同时,1-2-2=-3 3.线程1和2不同时+1,同时-2,1+1-2=0 4.线程1和2既同时+1又同时-2,1-2=-1 没有结果为1的情况

    补充:可能存在同时吗?
    存在,
    一是考虑多核CPU,必然可以多个线程同时执行。
    二是就算CPU为单核,也是支持多线程的,因为,每个程序上线程分为多条语句,每个程序语句在编译后会变成多条汇编语句,每个汇编语句在执行时变成多条指令等等,
    所以线程对于CPU来说并非不可划分,而CPU计算速度非常快,完全可以实现微观上指令级的交替执行,宏观上的并行执行

     

  18.  

     wait():等待时线程别人可以用。

    sleep():等待时线程还是自己的,别人不能用。 yield():不释放锁,使当前线程重新回到可执行状态,所以执行yield()的线程有可能在进入到可执行状态后马上又被执行。
    join():  当有新的线程加入时,主线程会进入等待状态,一直到调用join()方法的线程执行结束为止。如:t.join();//主要用于等待t线程运行结束,若无此句,main则会执行完毕,导致结果不可预测。

    为什么wait(),notify(),notifyAll()必须在同步(Synchronized)方法/代码块中调用?
    https://blog.csdn.net/yinni11/article/details/82350271


  19. 斐波那契数列 
    你需要爬11楼的时候,你倒回去一步只能待在第10楼或者第9楼。换句话说就是到达第9楼的方法次数加上第10楼的方法次数。

    如果你待在第10楼,就得待在第9楼或者第8楼

    如果你待在第9楼,就得待在第8楼或者第7楼

    ......

    如果你待在第3楼,就得待在第1楼或者第2楼
    or
    概率论

    走2阶台阶的次数可能会出现0-5种情况,计算每一次总步数中的哪几步是走2阶台阶的所有可能 C(0,11)+C(1,10)+C(2,9)+C(3,8)+C(4,7)+C(5,6)=1+10+36+56+35+6=144 C(N,M)表示从M个数中,随机抽取N个数的所有情况

  20. ThreadLocal
    1) ThreadLocal叫做线程变量,意思是ThreadLocal中填充的变量属于当前线程,该变量对其他线程而言是隔离的
    也就是说该变量是当前线程独有的变量。ThreadLocal为变量在每个线程中都创建了一个副本,那么每个线程可以访问自己内部的副本变量。

    2) ThreadLoal 变量,线程局部变量,同一个 ThreadLocal 所包含的对象,在不同的 Thread 中有不同的副本。这里有几点需要注意:

                  因为每个 Thread 内有自己的实例副本,且该副本只能由当前 Thread 使用。这是也是 ThreadLocal 命名的由来。

                  既然每个 Thread 有自己的实例副本,且其它 Thread 不可访问,那就不存在多线程间共享的问题。

    ThreadLocal 提供了线程本地的实例。
    它与普通变量的区别在于,每个使用该变量的线程都会初始化一个完全独立的实例副本。ThreadLocal 变量通常被private static修饰。当一个线程结束时,它所使用的所有 ThreadLocal 相对的实例副本都可被回收。

    总的来说,ThreadLocal 适用于每个线程需要自己独立的实例且该实例需要在多个方法中被使用,也即变量在线程间隔离而在方法或类间共享的场景

     

     ThreadLocal与Synchronized的区别:

    ThreadLocal<T>其实是与线程绑定的一个变量。ThreadLocal和Synchonized都用于解决多线程并发访问。

    但是ThreadLocal与synchronized有本质的区别:

    1、Synchronized用于线程间的数据共享,而ThreadLocal则用于线程间的数据隔离。

    2、
    Synchronized是利用锁的机制,使变量或代码块在某一时该只能被一个线程访问。
    而ThreadLocal为每一个线程都提供了变量的副本,使得每个线程在某一时间访问到的并不是同一个对象,这样就隔离了多个线程对数据的数据共享。

    而Synchronized却正好相反,它用于在多个线程间通信时能够获得数据共享。

    ThreadLocal 常见使用场景

    如上文所述,ThreadLocal 适用于如下两种场景

    1、每个线程需要有自己单独的实例

    2、实例需要在多个方法中共享,但不希望被多线程共享

    对于第一点,每个线程拥有自己实例,实现它的方式很多。例如可以在线程内部构建一个单独的实例。ThreadLocal 可以以非常方便的形式满足该需求。

    对于第二点,可以在满足第一点(每个线程有自己的实例)的条件下,通过方法间引用传递的形式实现。ThreadLocal 使得代码耦合度更低,且实现更优雅。

    1)存储用户Session

     

    一个简单的用ThreadLocal来存储Session的例子: 

    private static final ThreadLocal threadSession = new ThreadLocal();
     
        public static Session getSession() throws InfrastructureException {
            Session s = (Session) threadSession.get();
            try {
                if (s == null) {
                    s = getSessionFactory().openSession();
                    threadSession.set(s);
                }
            } catch (HibernateException ex) {
                throw new InfrastructureException(ex);
            }
            return s;
        }
    

     

      

  21.  
  22.  

    方法的重写(override)两同两小一大原则

    方法名相同,参数类型相同 子类返回类型小于等于父类方法返回类型, 子类抛出异常小于等于父类方法抛出异常, 子类访问权限大于等于父类方法访问权限。
  23. StringBuffer中的capacity的扩增机制
    capacity增长的规律为 旧值*2+2
    初始值:

    当设置StringBuffer的容量 1、小于当前容量时,容量不变,默认为16。
    2、大于当前容量,并且小于(当前容量+1)*2,则容量变为(当前容量+1)*2。
    3、大于当前容量,并且大于(当前容量+1)*2,则容量变为用户所设置的容量。

  24. A subclass inherits all the members (fields, methods, and nested classes) from its superclass. Constructors are not members,
    so they are not inherited by subclasses, but the constructor of the superclass can be invoked from the subclass.  
    [子类从其父类继承所有成员(字段,方法和嵌套类)。 构造函数不是成员,所以它们不被子类继承,但是可以从子类调用超类的构造函数。]
    使用反射可以看出子类是继承了父类的私有方法的(不管是否是final),只是直接调用父类的私有方法是不可以的,但是利用反射的方式可以调用。字段同理。

  25. volatile与synchronized的区别: volatile本质是在告诉jvm当前变量在寄存器中的值是不确定的,需要从主存中读取,synchronized则是锁定当前变量,只有当前线程可以访问该变量,其他线程被阻塞住. volatile仅能使用在变量级别,synchronized则可以使用在变量,方法. volatile仅能实现变量的修改可见性,但不具备原子特性,而synchronized则可以保证变量的修改可见性和原子性. volatile不会造成线程的阻塞,而synchronized可能会造成线程的阻塞. volatile标记的变量不会被编译器优化,而synchronized标记的变量可以被编译器优化.

  26. JDK8之前版本,HashMap的数据结构是数组+链表,JDK8及其以后版本,HashMap的数据结构是数组+链表+红黑树




  27. Lanbda表达式的主要作用就是代替匿名内部类的繁琐语法, 它由三部分组成:

    (1) 形参列表。形参列表允许省略形参类型。如果形参列表中只有一个参数,甚至连形参列表的圆括号也可以省略。 (2) 箭头(→)。必须通过英文中画线和大于符号组成。 (3)代码块。如果代码块只包含一条语句,Lambda表达式允许省略代码块的花括号,那么那条语句就不要用花括号表示语句结束。Lambda代码块只有一条return语句,甚至可以省略return关键字。Lambda表达式需要返回值,而它的代码块中仅有一套省略了return的语句。Lambda表达式会自动返回这条语句的值。

  28. JSP中一共预先定义了9个这样的对象,分别为:request、response、session、application、out、pagecontext、config、page、exception

    1、pageContext 表示页容器 EL表达式、 标签 、上传
    2、request 服务器端取得客户端的信息:头信息 、Cookie 、请求参数 ,最大用处在MVC设计模式上
    3、response 服务器端回应客户端信息:Cookie、重定向
    4、session 表示每一个用户,用于登录验证上
    5、application 表示整个服务器
    6、config 取得初始化参数,初始化参数在web.xml文件中配置
    7、exception 表示的是错误页的处理操作
    8、page 如同this一样,代表整个jsp页面自身
    9、out 输出 ,但是尽量使用表达式输出

  29. tips:被static修饰的变量称为静态变量,静态变量属于整个类,而局部变量属于方法,只在该方法内有效,所以static不能修饰局部变量

  30. Java四种创建对象的方式

    new/Reflect/Clone/Serialization

  31.  

    通过单例模式可以保证系统中一个类只有一个实例而且该实例易于被外界访问,从而方便对实例个数的控制并节约系统资源。
    如果希望在系统中某个类的对象只能存在一个,单例模式是最好的解决办法。 

    饿汉式单例类

    public class EagerSingleton {
        //可以由名知意,太饥饿了,一大早就准备好了实例等待使用,但很有可能一直没人使用
        private static final EagerSingleton instance = new EagerSingleton();
        private EagerSingleton() {}
        public static EagerSingleton getInstance() {
            return instance;
        }
    }

    懒汉式单例类

    public class LazySingleton {
           //等到人家使用才生产一个实例,所以叫懒汉模式
        private static LazySingleton instance = null;
        private LazySingleton() {}
        public static LazySingleton getInstance() {
            if(instance == null) {
                instance = new LazySingleton();
            }
            return instance;
        }
    }

    懒汉式单例类在实例化时,必须处理好多个线程同时首次引用此类时的访问限制问题。

    为了实现懒汉式单例类的线程安全,必须加锁 synchronized 实现单例,但加锁会影响效率。

    public class LazySingleton {
        private static LazySingleton instance = null;
        private LazySingleton() {}
        public static synchronized LazySingleton getInstance() {
            if(instance == null) {
                instance = new LazySingleton();
            }
            return instance;
        }
    }

    双重校验锁懒汉模式(DCL)

    在保证安全的前提下保持高性能的实现方式

    public class LazySingleton {
        // 防止指令重排序以及保证变量在多线程运行时的可见性 volatile
        private volatile static LazySingleton instance = null;
        private LazySingleton() {}
        public static LazySingleton getInstance() {
            //    由于单例模式只需创建一次实例即可
            //    所有当已经创建一个实例之后,再次调用就不需要进入同步代码块中了
            //    避免线程之间互相竞争锁,提高了性能
            if(instance == null) {
                synchronized(LazySingleton.class) {
                    //    防止二次创建实例
                    if(instance == null) {
                        instance = new LazySingleton();
                    }
                }
            }
            return instance;
        }
    }

    静态内部类模式

    内部类都是在第一次使用时才会被加载,而且静态内部类的加载不需要依附外部类,在使用时才加载。多个线程用到同一个类,而这个类还未被加载,则只有一个线程去加载类,其他线程等待。因此静态内部类模式的单例可以保证线程安全。

    public class Singleton {
        private static class SingletonHolder {
            private static final Singleton INSTANCE = new Singleton();
        }
        private Singleton(){}
        private static final Singleton getInstance() {
            return SingletonHolder.INSTANCE;
        }
    }

    枚举模式

    枚举天然解决了多线程同步执行的问题,而且还自动支持序列化机制,防止反序列化重新创建新的对象,绝对防止多次实例化。

    public enum Singleton {
        INSTANCE;
        public void method() {}
    }



    https://www.cnblogs.com/Yee-Q/p/12459989.html

  32. 简单记忆线程安全的集合类:
    喂!SHE!  
    喂是指 
      Vector,
    S是指    Stack,

    H是指    Hashtable,
    E是指: Eenumeration




  33. 开始时JVM加载B.class,对所有的静态成员进行声明,t1 t2被初始化为默认值,为null,又因为t1 t2需要被显式初始化,所以对t1进行显式初始化,初始化代码块→构造函数(没有就是调用默认的构造函数),咦!静态代码块咋不初始化?因为在开始时已经对static部分进行了初始化,虽然只对static变量进行了初始化,但在初始化t1时也不会再执行static块了,因为JVM认为这是第二次加载类B了,所以static会在t1初始化时被忽略掉,所以直接初始化非static部分,也就是构造块部分(输出''构造块'')接着构造函数(无输出)。接着对t2进行初始化过程同t1相同(输出'构造块'),此时就对所有的static变量都完成了初始化,接着就执行static块部分(输出'静态块'),接着执行,main方法,同样也,new了对象,调用构造函数输出('构造块')

     

    正确的理解是这样的:

    并不是静态块最先初始化,而是静态域. 而静态域中包含静态变量、静态块和静态方法,其中需要初始化的是静态变量和静态块.而他们两个的初始化顺序是靠他们俩的位置决定的,非静态变量和代码块同理

     

     

     


  34. 节点流:从一个节点读取数据

    处理流:对一个已存在的流进行封装


  35. jvm中变量的存放位置

  36.  




  37.   首先,要注意是(short)10/10.2*2,而不是(short) (10/10.2*2),前者只是把10强转为short,
      又由于式子中存在浮点数,所以会对结果值进行一个自动类型的提升,浮点数默认为double,所以答案是double;后者是把计算完之后值强转short。

  38. 转发(forward)与 重定向(redirect)的区别

    1.从地址栏显示来说
    forward是服务器请求资源,服务器直接访问目标地址的URL,把那个URL的响应内容读取过来,然后把这些内容再发给浏览器.浏览器根本不知道服务器发送的内容从哪里来的,所以它的地址栏还是原来的地址.
    redirect是服务端根据逻辑,发送一个状态码,告诉浏览器重新去请求那个地址.所以地址栏显示的是新的URL.

    2.从数据共享来说
    forward:转发页面和转发到的页面可以共享request里面的数据. redirect:不能共享数据.

    3.从运用地方来说
    forward:一般用于用户登陆的时候,根据角色转发到相应的模块. redirect:一般用于用户注销登陆时返回主页面和跳转到其它的网站等.

    4.从效率来说 forward:高. redirect:低.

     

    解释一  

    一句话,转发是服务器行为,重定向是客户端行为。为什么这样说呢,这就要看两个动作的工作流程:
    转发过程:客户浏览器发送http请求----》web服务器接受此请求--》调用内部的一个方法在容器内部完成请求处理和转发动作----》将目标资源 发送给客户;
    在这里,转发的路径必须是同一个web容器下的url,其不能转向到其他的web路径上去,中间传递的是自己的容器内的request。
    在客户浏览器路径栏显示的仍然是其第一次访问的路径,也就是说客户是感觉不到服务器做了转发的。转发行为是浏览器只做了一次访问请求。

    重定向过程:
    客户浏览器发送http请求----》web服务器接受后发送302状态码响应及对应新的location给客户浏览器--》客户浏览器发现 是302响应,则自动再发送一个新的http请求,请求url是新的location地址----》服务器根据此请求寻找资源并发送给客户。
    在这里 location可以重定向到任意URL,既然是浏览器重新发出了请求,则就没有什么request传递的概念了。在客户浏览器路径栏显示的是其重定向的 路径,客户可以观察到地址的变化的。重定向行为是浏览器做了至少两次的访问请求的。

    解释二
    重定向,其实是两次request, 第一次,客户端request A,服务器响应,并response回来,告诉浏览器,你应该去B。这个时候IE可以看到地址变了,而且历史的回退按钮也亮了。
    重定向可以访问自己web应用以外的资源。在重定向的过程中,传输的信息会被丢失。

    解释三 假设你去办理某个执照,
    重定向:你先去了A局,A局的人说:“这个事情不归我们管,去B局”,然后,你就从A退了出来,自己乘车去了B局。
    转发:你先去了A局,A局看了以后,知道这个事情其实应该B局来管,但是他没有把你退回来,而是让你坐一会儿,自己到后面办公室联系了B的人,让他们办好后,送了过来。
     

  39. 在java 中,声明一个数组时,不能直接限定数组长度,只有在创建实例化对象时,才能对给定数组长度.




  40.  对于管道,有下面这几种类型:

    ①普通管道(PIPE):通常有两种限制,一是单工,即只能单向传输;二是血缘,即常用于父子进程间(或有血缘关系的进程间)。

    ②流管道(s_pipe):去除了上述的第一种限制,实现了双向传输。

    ③命名管道(name_pipe):去除了上述的第二种限制,实现了无血缘关系的不同进程间通信。 显然,要求是对于不同的服务器之间的通信,是要要求全双工形式的,而管道只能是半双工,虽然可以双向,但是同一时间只能有一个方向传输,全双工和半双工的区别可以如下图示理解

     

  41. 在接口里面的变量默认都是public static final 的,它们是公共的,静态的,最终的常量.相当于全局常量,可以直接省略修饰符。

  42.  



      A.程序计数器是一块较小的内存空间,它的作用可以看做是当前线程所执行的字节码的信号指示器(偏移地址),Java编译过程中产生的字节码有点类似编译原理的指令,程序计数器的内存空间存储的是当前执行的字节码的偏移地址,每一个线程都有一个独立的程序计数器(程序计数器的内存空间是线程私有的),因为当执行语句时,改变的是程序计数器的内存空间,因此它不会发生内存溢出 ,并且程序计数器是jvm虚拟机规范中唯一一个没有规定 OutOfMemoryError 异常 的区域;

    B.java虚拟机栈:线程私有,生命周期和线程一致。描述的是 Java 方法执行的内存模型:每个方法在执行时都会床创建一个栈帧(Stack Frame)用于存储局部变量表、操作数栈、动态链接、方法出口等信息。每一个方法从调用直至执行结束,就对应着一个栈帧从虚拟机栈中入栈到出栈的过程。  没有类信息,类信息是在方法区中

    C.java堆:对于绝大多数应用来说,这块区域是 JVM 所管理的内存中最大的一块。线程共享,主要是存放对象实例和数组

    D.方法区:属于共享内存区域,存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。

     

  43. final方法为何会高效?

      final方法会在编译的过程中利用内嵌机制进行inline优化
    inline优化是指:在编译的时候直接调用函数代码替换,而不是在运行时调用函数。 inline需要在编译的时候就知道最后要用哪个函数,显然,非final是不行的。
    非final方法可能在子类中被重写,由于可能出现多态的情况,编译器在编译阶段 并不能确定将来调用方法的对象的真正类型,也就无法确定到底调用哪个方法。
    对于编译期常量的这种情况,编译器可以将该常量值代入任何可能用到它的计算式中,也就是说,可以在编译期就执行计算式,这减轻了一些运行时的负担。在java中,这类常量必须是基本类型,并且以final表示。在对这个常量定义时,必须进行赋值。
    https://www.cnblogs.com/nextnj/archive/2013/06/05/3119106.html

    final用于声明属性、方法和类:
    • final属性不可变,指的是引用不可变,而不关心指向对象内容的变化,被final修饰的变量必须初始化
      (当final修饰一个基本数据类型时,表示该基本数据类型的值一旦在初始化后便不能发生变化;如果final修饰一个引用类型时,则在对其初始化之后便不能再让其指向其他对象了,但该引用所指向的对象的内容是可以发生变化的。)
    • final方法不可被子类重写,可以实现inline(内联)的机制
    • final类不可以被继承(如String、StringBuffer),所有的方法不可以被重写,但其内的非final变量可以被修改



     


  44.  构造函数的作用是完成对象的初始化。当程序执行到new操作符时, 首先去看new操作符后面的类型,因为知道了类型,才能知道要分配多大的内存空间。
     分配完内存之后,再调用构造函数,填充对象的各个域,这一步叫做对象的初始化。
     选项B、D中,对象的初始化并不是通过构造函数完成的,而是读取别的内存区域中的对象的各个域来完成。



  45. 1)  HTTP是“无状态”协议:客户程序每次读取 Web 页面,都打开到 Web 服务器的单独的连接,并且,服务器也不自动维护客户的上下文信息。即使那些支持持续性 HTTP 连接的服务器,尽管多个客户请求连续发生且间隔很短时它们会保持 socket 打开,但是,它们也没有提供维护上下文信息的内建支持。上下文的缺失引起许多困难。例如,在线商店的客户向他们的购物车中加入商品时,服务器如何知道购物车中己有何种物品呢?类似地,在客户决定结账时,服务器如何能确定之前创建的购物车中哪个属于此客户呢?这些问题虽然看起来十分简单,但是由于 HTTP 的不足,解答它们却异常复杂困难。对于这个问题,存在 3 种典型的解决方案:

    2)Cookie(结合session使用)
    可以使用 cookie 存储购物会话的 ID;在后续连接中,取出当前的会话 ID,并使用这个 ID 从服务器上的查找表(lookup table)中提取出会话的相关信息。 以这种方式使用 cookie 是一种绝佳的解决方案,也是在处理会话时最常使用的方式。但是,sevlet 中最好有一种高级的 API 来处理所有这些任务,以及下面这些冗长乏味的任务:从众多的其他cookie中(毕竟可能会存在许多cookie)提取出存储会话标识符的 cookie;确定空闲会话什么时候过期,并回收它们;将散列表与每个请求关联起来;生成惟一的会话标识符。

    3)URL 重写
    采用这种方式时,客户程序在每个URL的尾部添加一些额外数据。这些数据标识当前的会话,服务器将这个标识符与它存储的用户相关数据关联起来。 URL重写是比较不错的会话跟踪解决方案,即使浏览器不支持 cookie 或在用户禁用 cookie 的情况下,这种方案也能够工作。URL 重写具有 cookie 所具有的同样缺点,也就是说,服务器端程序要做许多简单但是冗长乏味的处理任务。即使有高层的 API 可以处理大部分的细节,仍须十分小心每个引用你的站点的 URL ,以及那些返回给用户的 URL。即使通过间接手段,比如服务器重定向中的 Location 字段,都要添加额外的信息。这种限制意味着,在你的站点上不能有任何静态 HTML 页面(至少静态页面中不能有任何链接到站点动态页面的链接)。因此,每个页面都必须使用 servlet 或 JSP 动态生成。即使所有的页面都动态生成,如果用户离开了会话并通过书签或链接再次回来,会话的信息也会丢失,因为存储下来的链接含有错误的标识信息。

    4)隐藏的表单域
    HTML 表单中可以含有如下的条目:<input type="hidden" name="session" value="a1234">
    这个条目的意思是:在提交表单时,要将指定的名称和值自动包括在 GET 或 POST 数据中。这个隐藏域可以用来存储有关会话的信息,但它的主要缺点是:仅当每个页面都是由表单提交而动态生成时,才能使用这种方法。单击常规的超文本链接并不产生表单提交,因此隐藏的表单域不能支持通常的会话跟踪,只能用于一系列特定的操作中,比如在线商店的结账过程

     




  46.  主要考核了这几个知识点:
    1)静态内部类才可以声明静态方法

    2)静态方法不可以使用非静态变量 3)抽象方法不可以有函数体

    1.为什么使用内部类?
    使用内部类最吸引人的原因是:每个内部类都能独立地继承一个(接口的)实现,所以无论外围类是否已经继承了某个(接口的)实现,
    对于内部类都没有影响
    1.1.使用内部类最大的优点就在于它能够非常好的解决多重继承的问题,使用内部类还能够为我们带来如下特性:
    (1)、内部类可以用多个实例,每个实例都有自己的状态信息,并且与其他外围对象的信息相互独立。
    (2)、在单个外围类中,可以让多个内部类以不同的方式实现同一个接口,或者继承同一个类。
    (3)、创建内部类对象的时刻并不依赖于外围类对象的创建。
    (4)、内部类并没有令人迷惑的“is-a”关系,他就是一个独立的实体。
    (5)、内部类提供了更好的封装,除了该外围类,其他类都不能访问。
    2.内部类分类:
    (一).成员内部类:
    public class Outer{
    		private int age = 99;
    		String name = "Coco";
    		public class Inner{
    			String name = "Jayden";
    			public void show(){
    				System.out.println(Outer.this.name);
    				System.out.println(name);
    				System.out.println(age);
    			}
    		}
    		public Inner getInnerClass(){
    			return new Inner();
    		}
    		public static void main(String[] args){
    			Outer o = new Outer();
    			Inner in = o.new Inner();
    			in.show();
    		}
    	}
    1.Inner 类定义在 Outer 类的内部,相当于 Outer 类的一个成员变量的位置,Inner 类可以使用任意访问控制符,
    如 public 、 protected 、 private 等
    2.Inner 类中定义的 show() 方法可以直接访问 Outer 类中的数据,而不受访问控制符的影响,
    如直接访问 Outer 类中的私有属性age
    3.定义了成员内部类后,必须使用外部类对象来创建内部类对象,而不能直接去 new 一个内部类对象
    即:内部类 对象名 = 外部类对象.new 内部类( );
    4.编译上面的程序后,会发现产生了两个 .class 文件: Outer.class,Outer$Inner.class{}
    5.成员内部类中不能存在任何 static 的变量和方法,可以定义常量:
    (1).因为非静态内部类是要依赖于外部类的实例,而静态变量和方法是不依赖于对象的,仅与类相关,
    简而言之:在加载静态域时,根本没有外部类,所在在非静态内部类中不能定义静态域或方法,编译不通过;
    非静态内部类的作用域是实例级别
    (2).常量是在编译器就确定的,放到所谓的常量池了
    ★★友情提示:
    1.外部类是不能直接使用内部类的成员和方法的,可先创建内部类的对象,然后通过内部类的对象来访问其成员变量和方法;
    2.如果外部类和内部类具有相同的成员变量或方法,内部类默认访问自己的成员变量或方法,如果要访问外部类的成员变量,
    可以使用 this 关键字,如:Outer.this.name
    (二).静态内部类: 是 static 修饰的内部类,
    1.静态内部类不能直接访问外部类的非静态成员,但可以通过 new 外部类().成员 的方式访问
    2.如果外部类的静态成员与内部类的成员名称相同,可通过“类名.静态成员”访问外部类的静态成员;
    如果外部类的静态成员与内部类的成员名称不相同,则可通过“成员名”直接调用外部类的静态成员
    3.创建静态内部类的对象时,不需要外部类的对象,可以直接创建 内部类 对象名 = new 内部类();
    public class Outer{
    			private int age = 99;
    			static String name = "Coco";
    			public static class Inner{
    				String name = "Jayden";
    				public void show(){
    					System.out.println(Outer.name);
    					System.out.println(name);					
    				}
    			}
    			public static void main(String[] args){
    				Inner i = new Inner();
    				i.show();
    			}
    		}
    (三).方法内部类:其作用域仅限于方法内,方法外部无法访问该内部类
    (1).局部内部类就像是方法里面的一个局部变量一样,是不能有 public、protected、private 以及 static 修饰符的
    (2).只能访问方法中定义的 final 类型的局部变量,因为:
    当方法被调用运行完毕之后,局部变量就已消亡了。但内部类对象可能还存在,
    直到没有被引用时才会消亡。此时就会出现一种情况,就是内部类要访问一个不存在的局部变量;
    ==>使用final修饰符不仅会保持对象的引用不会改变,而且编译器还会持续维护这个对象在回调方法中的生命周期.
    局部内部类并不是直接调用方法传进来的参数,而是内部类将传进来的参数通过自己的构造器备份到了自己的内部,
    自己内部的方法调用的实际是自己的属性而不是外部类方法的参数;
    防止被篡改数据,而导致内部类得到的值不一致
       /*
    		使用的形参为何要为 final???
    		 在内部类中的属性和外部方法的参数两者从外表上看是同一个东西,但实际上却不是,所以他们两者是可以任意变化的,
    		 也就是说在内部类中我对属性的改变并不会影响到外部的形参,而然这从程序员的角度来看这是不可行的,
    		 毕竟站在程序的角度来看这两个根本就是同一个,如果内部类该变了,而外部方法的形参却没有改变这是难以理解
    		 和不可接受的,所以为了保持参数的一致性,就规定使用 final 来避免形参的不改变
    		 */
    		public class Outer{
    			public void Show(){
    				final int a = 25;
    				int b = 13;
    				class Inner{
    					int c = 2;
    					public void print(){
    						System.out.println("访问外部类:" + a);
    						System.out.println("访问内部类:" + c);
    					}
    				}
    				Inner i = new Inner();
    				i.print();
    			}
    			public static void main(String[] args){
    				Outer o = new Outer();
    				o.show();
    			}
    		}    
    
    
    (3).注意:在JDK8版本之中,方法内部类中调用方法中的局部变量,可以不需要修饰为 final,匿名内部类也是一样的,主要是JDK8之后增加了 Effectively final 功能 http://docs.oracle.com/javase/tutorial/java/javaOO/localclasses.html 反编译jdk8编译之后的class文件,发现内部类引用外部的局部变量都是 final 修饰的 (四).匿名内部类: (1).匿名内部类是直接使用 new 来生成一个对象的引用; (2).对于匿名内部类的使用它是存在一个缺陷的,就是它仅能被使用一次,创建匿名内部类时它会立即创建一个该类的实例,
    该类的定义会立即消失,所以匿名内部类是不能够被重复使用;
    (3).使用匿名内部类时,我们必须是继承一个类或者实现一个接口,但是两者不可兼得,同时也只能继承一个类或者实现一个接口;
    (4).匿名内部类中是不能定义构造函数的,匿名内部类中不能存在任何的静态成员变量和静态方法;
    (5).匿名内部类中不能存在任何的静态成员变量和静态方法,匿名内部类不能是抽象的,它必须要实现继承的类或者实现的接口的所有抽象方法
    (6).匿名内部类初始化:使用构造代码块!利用构造代码块能够达到为匿名内部类创建一个构造器的效果
      public class OuterClass {
                public InnerClass getInnerClass(final int   num,String str2){
                    return new InnerClass(){
                        int number = num + 3;
                        public int getNumber(){
                            return number;
                        }
                    };        /* 注意:分号不能省 */
                }
                public static void main(String[] args) {
                    OuterClass out = new OuterClass();
                    InnerClass inner = out.getInnerClass(2, "chenssy");
                    System.out.println(inner.getNumber());
                }
            }
            interface InnerClass {
                int getNumber();
            }          

     

    checked exception:指的是编译时异常,该类异常需要本函数必须处理的,用try和catch处理,或者用throws抛出异常,然后交给调用者去处理异常。

    runtime exception:指的是运行时异常,该类异常不必须本函数必须处理,当然也可以处理

    正则表达式:大写表示非,小写表示是
    例如:

    https://www.runoob.com/regexp/regexp-syntax.html

     


getDeclaredField:查找该Class所有声明属性(静态/非静态),但是他不会去找实现的接口/父类的属性 getField:只查找该类public类型的属性,如果找不到则往上找他的接口、父类,依次往上,直到找到或者已经没有接口/父类
volatile

标签:java,内部,静态,three,base,线程,static,方法,public
From: https://www.cnblogs.com/miku831/p/17574025.html

相关文章

  • SpringBoot整合Liquibase
    1、是什么?Liquibase官网Liquibase是一个开源的数据库管理工具,可以帮助开发人员管理和跟踪数据库变更。它可以与各种关系型数据库和NoSQL数据库一起使用,并提供多种数据库任务自动化功能,例如数据库迁移、版本控制和监控。Liquibase还提供了一个Web界面,可以方便地管理和跟踪数据库......
  • java游戏服务器2023年7月22日
    name卡牌军团放置卡牌游戏开发语言:javamysql通信http账号服务器提供验证等功能中心服务器跨服功能排行榜公会......
  • Java多线程详解——一篇文章搞懂Java多线程
    Java多线程详解——一篇文章搞懂Java多线程目录1.基本概念2.线程的创建和启动2.1.多线程实现的原理2.2.多线程的创建,方式一:继承于Thread类2.3.多线程的创建,方式一:创建Thread匿名子类(也属于方法一)2.4.多线程的创建,方式二:实现Runnable接口2.4.1.比较创建线程的两种......
  • 316. 去除重复字母 (JAVA)
    给你一个字符串s,请你去除字符串中重复的字母,使得每个字母只出现一次。需保证返回结果的字典序最小(要求不能打乱其他字符的相对位置)。 示例1:输入:s="bcabc"输出:"abc"示例2:输入:s="cbacdcbc"输出:"acdb" 提示:1<=s.length<=10^4解题思路:当前字母比前一个字母小,......
  • java学习笔记
    目录值传递&引用传递WeakHashMap-弱引用MapHashMapResponseEntityMessageFormat.format-代码里直接打印输出如何将java项目的依赖打成一个大的jar包加载证书报错:Couldnotparsecertificate:java.io.IOException:Incompletedatapowermock使用注意jpa的使用注意AOP切面java......
  • JavaScript继承
    继承—通过原型1.共同functionA(){}functionB(){}constg={a:1,b:2,};我想让从A、B构造出来的对象都具有g其中的属性,就可以通过继承A.prototype=gA.prototype.constructor=Aconsole.log(A.prototype)//{a:1,b:2,constructor:[Function:Man]}......
  • java内存分析工具使用
    目录参考链接1、名词解释2、常见异常java堆内存异常java栈内存异常方法区内存异常3、解决思路4、生成dump文件的三种方式jvisualvmjmap命令应用启动配置5、MemoryAnalyzer分析工具参考链接Java内存溢出OOM之dump分析1、名词解释内存泄露:代码中的某个对象本应该被虚拟机回收,......
  • java源码加密代码
    1、java代码想加密怎么处理?2、java加密解密代码3、如何有效防止Java程序源码被人偷窥?4、Java编程实现将文件加密,将源程序补充完整5、用java写个文件加密的代码该怎么写6、java项目如何加密?java代码想加密怎么处理?只给编译后java源码加密的.jar文件java源码加密,不给......
  • java开发工程师工作总结
    1、java主要是做什么的?2、java核心思想小结3、javaweb开发需要哪些技术请总结全点4、为什么java开发游戏性能和效率差java主要是做什么的?、科学应用现在Java经常是科学应用java开发年终总结的默认选择java开发年终总结,包括了自然语言处理。这主要的原因是因为Java比起C+......
  • 修改java路径
    修改Java路径在进行Java编程时,我们经常需要配置Java的路径。Java路径包括JavaDevelopmentKit(JDK)的安装路径和JavaRuntimeEnvironment(JRE)的安装路径。本文将为您介绍如何修改Java路径,并提供代码示例来帮助您更好地了解这个过程。为什么需要修改Java路径?在某些情况下,......