Java基础知识

Java 的接口组成:

(1)全局常量public static final,如果要省略,只能省略 public)

(2)抽象方法public abstract,如果要省略,可省略任一或全部)

注意:即便省略了,依然代表全部。如:全局常量省略为 static final,其实依然是 public static final。即接口仅包含方法定义和常量值。

方法
  • static void method( ) 静态方法,只有静态方法才能被类名调用
  • public void method( ) 一般方法,只能被实例对象调用
  • final void method( ) final修饰方法,只是说明本方法不能被重写
  • abstract void method( ) abstract修饰方法,表示本方法为抽象方法,没有方法体,且抽象方法必须在抽象类中,但是抽象类中可以没有抽象方法
构造方法(构造函数construct)
  1. 构造函数可以省略,省略后JVM会自动创建一个无参的构造函数 ;
  2. 构造函数必须与public 类同名,方法和类同名;
  3. 一个class可以定义多个构造函数(注意:构造函数可以由任意访问修饰符访问,比如public、protected、private,但不能由static、finally等修饰符修饰);
  4. 构造函数可以重载;
  5. 构造函数在一个对象被new 时执行。
封装

封装使实现的改变对架构的影响小化。

原则:装使对象的属性尽可能的私有,根据需要配上相应的get/set 方法,对象的方法尽可能的公开。该隐藏的一定要隐藏,该公开的一定要公开。

private :仅本类成员可见 default :本类+同包类可见(默认) protected:本类+同包+不同包的子类 public :公开 注:这里的同包指的是跟父类所在的包相同

完全封装:属性全部私有,并提供相应的 get/set 方法。

继承

基于一个已存在的类构造一个新类,在此基础上,还可以在新类中添加一些新的方法和属性。

继承用关键字 extends

Java 中只允许单继承(java 简单性的体现) ,父子类之间的关系是树状关系。(而多继承是网状关系)

父类中的私有属性可以继承但是不能访问。 也可以说父类中的私有属性子类不能继承。

原则:父类放共性,子类放个性。

构造方法不能被子类继承

super 关键字

Super()表示调用父类的构造方法

Super()也和 this 一样必须放在方法的第一行第一句。

Super.表示调用父类的方法或属性。例:super.m();

Super 可以屏蔽子类属性和父类属性重名时带来的冲突

在子类的构造函数中如果没有指定调用父类的哪一个构造方法,那么就会调用父类的无参构造方法,即 super()。

多态

多态指的是编译时的类型变化,而运行时类型不变。

多态的优点

  1. 消除类型之间的耦合关系
  2. 可替换性
  3. 可扩充性
  4. 接口性
  5. 灵活性
  6. 简化性

多态存在的三个必要条件

  1. 继承
  2. 重写
  3. 父类引用指向子类对象

比如:

Parent p = new Child();
复制代码
访问修饰符(类访问控制关键字)

==、equals()和hashCode()
  • 关于==

对于基本数据类型而言,比较就是判断这两个数值是否相等,(基本数据类型没有方法),不存在equals()和hashCode()比较的问题,下面的讨论都是针对引用数据类型展开的。

对于引用对象而言,比较两个引用变量的引用的是否是同一个对象,即比较的是两个引用存储中的对象地址是不是一样

  • 关于equals()

equals()和hashCode()都是从Object类中继承而来的,而Object中equals()默认实现的是比较两个对象是否==,即默认的equals()和==的效果是一样的。但是我们必需清楚,当String 、Math、还有Integer、Double。。。。等这些封装类在使用equals()方法时,已经覆盖了object类的equals()方法。String类中的equals()方法很明显是仅仅进行了对象内容的比较,而没有比较对象存储地址。同理我们可知,Double,Integer,Math等等这些类的equals()方法都是被重写了的,从而比较的都是内容的值。

我们还应该注意,Java语言对equals()的要求如下,这些要求是必须遵循的: • 对称性:如果x.equals(y)返回是“true”,那么y.equals(x)也应该返回是“true”。 • 反射性:x.equals(x)必须返回是“true”。 • 类推性:如果x.equals(y)返回是“true”,而且y.equals(z)返回是“true”,那么z.equals(x)也应该返回是“true”。 • 还有一致性:如果x.equals(y)返回是“true”,只要x和y内容一直不变,不管你重复x.equals(y)多少次,返回都是“true”。 • 任何情况下,x.equals(null),永远返回是“false”;x.equals(和x不同类型的对象)永远返回是“false”。

  • 关于hashCode()

hashCode()方法返回的是一个数值,称之为hashCode。hashCode()方法在Object类中的定义如下:public native int hashCode();这是一个本地方法,其实现跟本地机器相关。当然我们可以再自定义类中覆盖hashCode()方法,比如String、Integer、Double等等这些类都是覆盖了hashCode()方法的。

例如在String类中定义的hashcode()会等于s[0]*31^(n-1) + s[1]*31^(n-2) + ... + s[n-1] 。 使用 int 算法,这里 s[i] 是字符串的第 i 个字符,n 是字符串的长度,^ 表示求幂。(空字符串的哈希码为 0。)

  • equals()和hashCode()千丝万缕的关系

hashCode()方法常被设计用来提高性能,其两者的关系在于:①若两个对象相等(equals),那么这两个对象一定有相同的哈希值(hashCode);②若两个对象的哈希值相同,但这两个对象并不一定相等。

  • equals()和hashCode()方法在HashSet、HashMap、Hashtable中的应用

在java的集合中,判断两个对象是否相等的规则是: 1) 判断两个对象的hashCode是否相等。如果不相等,认为两个对象也不相等,完毕; 如果相等,转入2) (这一点只是为了提高存储效率而要求的,其实理论上没有也可以,但如果没有,实际使用时效率会大大降低,所以我们这里将其做为必需的。后面会重点讲到这个问题。) 2) 判断两个对象用equals运算是否相等 。如果不相等,认为两个对象也不相等;如果相等,认为两个对象相等(equals()是判断两个对象是否相等的关键) 为什么是两条准则,难道用第一条不行吗?不行,因为前面已经说了,hashCode()相等时,equals()方法也可能不等,所以必须用第2条准则进行限制,才能保证加入的为非重复元素。

以HashSet集合为例具体说明:

Hashset是继承Set接口,Set接口又实现Collection接口,这是层次关系。那么hashset是根据什么原理来存取对象的呢? 在hashset中不允许出现重复对象,元素的位置也是不确定的。在hashset中又是怎样判定元素是否重复的呢?即上面的规则。

关于在hibernate的pojo类中,重新equals()和hashcode()的问题:

  1. 重点是equals,重写hashCode只是技术要求(为了提高效率)
  2. 为什么要重写equals呢,因为在java的集合框架中,是通过equals来判断两个对象是否相等的
  3. 在hibernate中,经常使用set集合来保存相关对象,而set集合是不允许重复的。我们再来谈谈前面提到在向hashset集合中添加元素时,怎样判断对象是否相同的准则,前面说了两条,其实只要重写equals()这一条也可以。 但当hashset中元素比较多时,或者是重写的equals()方法比较复杂时,我们只用equals()方法进行比较判断,效率也会非常低,所以引入了hashcode()这个方法,只是为了提高效率,但是我觉得这是非常有必要的(所以我们在前面以两条准则来进行hashset的元素是否重复的判断)。

详见来源

泛型

泛型仅仅是java的语法糖,它不会影响java虚拟机生成的汇编代码,在编译阶段,虚拟机就会把泛型的类型擦除,还原成没有泛型的代码,顶多编译速度稍微慢一些,执行速度是完全没有什么区别的.

泛型方法

泛型方法,该方法在调用时可以接收不同类型的参数。根据传递给泛型方法的参数类型,编译器适当地处理每一个方法调用。

定义泛型方法的规则:

  • 所有泛型方法声明都有一个类型参数声明部分(由尖括号分隔),该类型参数声明部分在方法返回类型之前;
  • 每一个类型参数声明部分包含一个或多个类型参数,参数间用逗号隔开。一个泛型参数,也被称为一个类型变量,是用于指定一个泛型类型名称的标识符。
  • 类型参数能被用来声明返回值类型,并且能作为泛型方法得到的实际参数类型的占位符。
  • 泛型方法体的声明和其他方法一样。注意类型参数只能代表引用型类型,不能是原始类型(像int,double,char的等)。​

例:

public static < E > void printArray( E[] inputArray )
复制代码

泛型类

泛型类的声明和非泛型类的声明类似,除了在类名后面添加了类型参数声明部分。

和泛型方法一样,泛型类的类型参数声明部分也包含一个或多个类型参数,参数间用逗号隔开。一个泛型参数,也被称为一个类型变量,是用于指定一个泛型类型名称的标识符。因为他们接受一个或多个参数,这些类被称为参数化的类或参数化的类型。

例:

public class Box<T> 
复制代码

类型通配符

1、类型通配符一般是使用**?代替具体的类型参数。例如 List<?> 在逻辑上是List,List** 等所有List<具体类型实参>的父类。

2、类型通配符上限通过形如List<? extends Number> data来定义,如此定义就是通配符泛型值接受Number及其下层子类类型。

3、类型通配符下限通过形如 **List<? super Number>**来定义,表示类型只能接受Number及其三层父类类型,如Objec类型的实例。

使用泛型的好处

1,类型安全。 泛型的主要目标是提高 Java 程序的类型安全。通过知道使用泛型定义的变量的类型限制,编译器可以在一个高得多的程度上验证类型假设。没有泛型,这些假设就只存在于程序员的头脑中(或者如果幸运的话,还存在于代码注释中)。

2,消除强制类型转换。 泛型的一个附带好处是,消除源代码中的许多强制类型转换。这使得代码更加可读,并且减少了出错机会。

3,潜在的性能收益。 泛型为较大的优化带来可能。在泛型的初始实现中,编译器将强制类型转换(没有泛型的话,程序员会指定这些强制类型转换)插入生成的字节码中。但是更多类型信息可用于编译器这一事实,为未来版本的 JVM 的优化带来可能。由于泛型的实现方式,支持泛型(几乎)不需要 JVM 或类文件更改。所有工作都在编译器中完成,编译器生成类似于没有泛型(和强制类型转换)时所写的代码,只是更能确保类型安全而已。

所以泛型只是提高了数据传输安全性,并没有改变程序运行的性能

来源

Java内存模型

JMM通过控制主内存与每个线程的本地内存之间的交互,来为java程序员提供内存可见性保证

在Java的内存模型中,分为主内存和工作内存。每个线程都有自己的工作内存,对变量的修改和读取都在工作内存中进行,所以,会有线程安全的问题。

因此有了synchronizevoliate,前者保证了原子性、可见性。后者只保证了可见性。

“synchronized” — 保证在块开始时都同步主内存的值到工作内存,而块结束时将变量同步回主内存

“volatile” — 保证修饰后在对变量读写前都会与主内存更新。

synchronized可见性的保证,就是因为锁,也就是同步块。voliate可见性的保证,就是因为在os的指令前加了一个lock,这个指令是使所有的线程工作内存无效,强制从主内存读写。

final关键字的可见性是指: 被final修饰的字段在构造前中一旦初始化完成,并且构造器没有把“this”的引用传递出去(this引用逃逸是一件很危险的事情,其他线程有可能通过这个引用访问到“初始化了一半”的对象),那在其他线程中就能看见final字段的值。

Spring

spring框架模块组成

垃圾回收

垃圾回收主要针对的是堆区的回收,因为栈区的内存是随着线程而释放的。堆区分为三个区:年轻代(Young Generation)、年老代(Old Generation)、永久代(Permanent Generation,也就是方法区)。

年轻代:对象被创建时(new)的对象通常被放在Young(除了一些占据内存比较大的对象),经过一定的Minor GC(针对年轻代的内存回收)还活着的对象会被移动到年老代(一些具体的移动细节省略)。

年老代:就是上述年轻代移动过来的和一些比较大的对象。Major GC(FullGC)是针对年老代的回收

永久代:存储的是final常量,static变量,常量池。

wait()方法

wait() 方法要以 try/catch 包覆,或是掷出InterruptedException 才行

调用wait或者notify方法必须采用当前锁调用,即必须采用synchronized中的对象

匿名内部类

匿名内部类没有名字,创建格式如下:

new 父类构造器(参数列表)|实现接口()  
    {  
     //匿名内部类的类体部分  
    }
复制代码

在使用匿名内部类的过程中,我们需要注意如下几点:

  1. 使用匿名内部类时,我们必须是继承一个类或者实现一个接口,但是两者不可兼得,同时也只能继承一个类或者实现一个接口。
  2. 匿名内部类中是不能定义构造函数的。
  3. 匿名内部类中不能存在任何的静态成员变量和静态方法。
  4. 匿名内部类为局部内部类,所以局部内部类的所有限制同样对匿名内部类生效。
  5. 匿名内部类不能是抽象的,它必须要实现继承的类或者实现的接口的所有抽象方法。
  6. 当所在的方法的形参需要被内部类里面使用时,该形参必须为final。
  7. 利用构造代码块达到为匿名内部类创建一个构造器的效果,以完成某个实例的初始化工作

来源

类加载与方法重写override

类的加载顺序

(1) 父类静态代码块(包括静态初始化块,静态属性,但不包括静态方法)

(2) 子类静态代码块(包括静态初始化块,静态属性,但不包括静态方法 )

(3) 父类非静态代码块( 包括非静态初始化块,非静态属性 )

(4) 父类构造函数

(5) 子类非静态代码块 ( 包括非静态初始化块,非静态属性 )

(6) 子类构造函数

其中:类中静态块按照声明顺序执行,并且(1)和(2)不需要调用new类实例的时候就执行了(意思就是在类加载到方法区的时候执行的)

方法重写实现多态

以Base b = new Sub()为例,它为多态的一种表现形式,声明是Base,实现是Sub类, 理解为b 编译时表现为Base类特性,运行时表现为Sub类特性。

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

方法名相同,参数类型相同

子类返回类型小于等于父类方法返回类型,

子类抛出异常小于等于父类方法抛出异常,

子类访问权限大于等于父类方法访问权限

Java关键字

synchronized : 用来给对象和方法或者代码块加锁,当它锁定一个方法或者一个代码块的时候,同一时刻最多只有一个线程执行这个段代码,即各线程互斥访问。

volatile:用来确保将变量的跟新操作通知到其他线程,当把变量声明为volatile类型后,编译器与运行时都会注意到这个变量是共享的,因此不会将该变量上的操作与其他内存操作一起重排序。然而,在访问volatile变量时不会执行加锁操作,因此也就不会使执行线程阻塞,因此volatile变量是一种比 synchronized关键字更轻量级的同步机制。volatile变量的特性(1)保证可见性,不保证原子性(2)禁止指令重排序

volatile禁止指令重排序前提:执行到volatile变量时,其前面的所有语句都执行完,后面所有语句都未执行。且前面语句的结果对volatile变量及其后面语句可见。

**serialize:**Java 对象序列化为二进制文件。

更多查看

abstract关键字

abstract修饰符可以用于类、方法、事件和索引指示器(indexer),表示其为抽象成员,抽象方法是没有方法体的方法。

抽象方法不能用private修饰,因为抽象方法必须被子类实现(覆写),而private权限对于子类来 说是不能访问的

抽象方法也不能用static修饰,因为抽象方法没有主体,没有任何业务逻辑,用static修饰后通过类名调 用毫无意义。

用abstract关键字来表达的类,其表达形式为:(public)abstract class 类名{}

抽象类不能被实例化,本身就代表了一个类型,有自己的构造方法

抽象类与接口(interface)有很大的不同之处,接口中不能有实例方法去实现业务逻辑,而抽象类 中可以有实例方法,并实现业务逻辑,比如我们可以在抽象类中创建和销毁一个线程池。

抽象类不能使用finally关键字修饰,因为finally修饰的类是无法被继承,而对于抽象类来说就是 需要通过继承去实现抽象方法

详见来源

this关键字

这是一个引用当前对象的引用变量。

java this关键字的用法如下:

  1. this关键字可用来引用当前类的实例变量。
  2. this关键字可用于调用当前类方法(隐式)。
  3. this()可以用来调用当前类的构造函数。
  4. this关键字可作为调用方法中的参数传递。
  5. this关键字可作为参数在构造函数调用中传递。
  6. this关键字可用于从方法返回当前类的实例。
final关键字

final可以用来修饰类、方法和变量(包括成员变量和局部变量),但修饰的**** 不能被继承,但是可以被重载,修饰的**方法** 不能被重写属性不能改。final 定义的**变量**,不是必须要在定义的同时完成初始化,也可以在构造方法中完成初始化,初始化后该参数是不可改变的,。引用变量被final修饰之后,虽然不能再指向其他对象,但是它指向的对象的内容是可变的。

static关键字

static关键字最基本的用法是修饰成员变量和成员方法:

1、被static修饰的变量属于类变量,可以通过类名.静态变量名直接引用,而不需要new出一个类来

2、被static修饰的方法属于类方法,可以通过类名.静态方法名()直接引用,而不需要new出一个类来

用public修饰的static成员变量和成员方法可以理解为全局变量和全局方法,当声明它为类的对象时,不生成static变量的副本,而是类的所有实例共享同一个static变量。 static变量前可以有private修饰,表示这个变量只能在本类中使用,但是不能在其他类中通过类名来直接引用

静态方法中不能用this和super关键字,不能直接访问所属类的实例变量和实例方法,因为this和super是随着构造方法而出现,而静态优先于构造出现,所以静态只能访问静态,不能访问非静态,但是非静态可以访问静态。

一般在需要实现以下两个功能时推荐用static修饰:

1.表征类的属性或者被类中所有对象共享

2.方便资源调用

详见来源

try块

如果finally块中有return语句的话,它将覆盖掉函数中其他return语句。

finally中的语句一定会执行。catch捕获到异常后程序结束。

HashMap

HashMap可以插入null的key或value,插入的时候,检查是否已经存在相同的key,如果不存在,则直接插入,如果存在,则用新的value替换旧的value

forword与redirect

redirect:请求重定向:客户端行为,本质上为2次请求,服务器向用户发送转向的地址,地址栏改变,前一次请求对象消失。

forward:请求转发:服务器行为,服务器获取跳转页面内容传给用户,用户地址栏不变。

内存存储区

堆区:只存放类对象,线程共享;

方法区:又叫静态存储区,存放class文件和静态数据,线程共享;

栈区:存放方法局部变量,基本类型变量区、执行环境上下文、操作指令区,线程不共享;

Java程序分类

Application——可独立运行的 是可以独立运行的Java程序,由Java解释器控制执行。 Applet——内嵌于Web文件中 是Java小程序,不能独立运行(嵌入到Web页中)由Java兼容浏览器控制执行。

Servlet——服务器端程序

字符与字符串

字符用单引号,字符串用双引号,与引号中的内容无关

面向对象的五大基本原则

单一职责原则 SRP(Single-Resposibility Principle):一个类,最好只做一件事,只有一个引起它的变化。单一职责原则可以看做是低耦合、高内聚在面向对象原则上的引申,将职责定义为引起变化的原因,以提高内聚性来减少引起变化的原因。 开放封闭原则 OCP(Open-Closed principle):软件实体应该是可扩展的,而不可修改的。也就是,对扩展开放,对修改封闭的。 里氏替换原则 LSP(Liskov-Substituion Principle):子类必须能够替换其基类。这一思想体现为对继承机制的约束规范,只有子类能够替换基类时,才能保证系统在运行期内识别子类,这是保证继承复用的基础。 依赖倒置原则 DIP(Dependecy-Inversion Principle):依赖于抽象。具体而言就是高层模块不依赖于底层模块,二者都同依赖于抽象;抽象不依赖于具体,具体依赖于抽象。 接口隔离原则 ISP(Interface-Segregation Principle):使用多个小的专门的接口,而不要使用一个大的总接口

存根stub

为屏蔽客户调用远程主机上的对象,必须提供某种方式来模拟本地对象,这种本地对象称为存根(stub),存根负责接收本地方法调用,并将它们委派给各自的具体实现对象。

这种方式符合等到程序要运行时将目标文件动态进行链接的思想

struts1与struts2的区别
  1. Struts1要求Action类继承一个抽象基类。Struts1的一个普遍问题是使用抽象类编程而不是接口。
  2. Struts 2 Action类可以实现一个Action接口,也可实现其他接口,使可选和定制的服务成为可能。Struts2提供一个ActionSupport基类去实现常用的接口。Action接口不是必须的,任何有execute标识的POJO对象都可以用作Struts2的Action对象。 从Servlet 依赖分析:
  3. Struts1 Action 依赖于Servlet API ,因为当一个Action被调用时HttpServletRequest 和 HttpServletResponse 被传递给execute方法。
  4. Struts 2 Action不依赖于容器,允许Action脱离容器单独被测试。如果需要,Struts2 Action仍然可以访问初始的request和response。但是,其他的元素减少或者消除了直接访问HttpServetRequest 和 HttpServletResponse的必要性。 从action线程模式分析:
  5. Struts1 Action是单例模式并且必须是线程安全的,因为仅有Action的一个实例来处理所有的请求。单例策略限制了Struts1 Action能作的事,并且要在开发时特别小心。Action资源必须是线程安全的或同步的。
  6. Struts2 Action对象为每一个请求产生一个实例,因此没有线程安全问题。(实际上,servlet容器给每个请求产生许多可丢弃的对象,并且不会导致性能和垃圾回收问题)

详见

会话跟踪技术
  1. URL重写

    在 URL 后面附加参数,和服务器的请求一起发送,这些参数为键值对

    • (参数存放)参数是存放在 url 里的,长度限制为1024
    • (Cookie禁用)当Cookie被禁用时依旧能够工作
    • (持久性)不存在持久性,一旦浏览器关闭就结束
  2. 隐藏表单域

    <input type="hidden" id="xxx" value="xxx">
    复制代码
    • (参数存放)参数是存放在请求实体里的,因此没有长度限制,但是不支持 GET 请求方法,因为 GET 没有请求实体
    • (Cookie禁用)当Cookie被禁用时依旧能够工作
    • (持久性)不存在持久性,一旦浏览器关闭就结束
  3. Cookie

    Cookie 是浏览器保存的一个小文件,其包含多个键值对

    服务器首先使用 Set-Cookie 响应头传输多个参数给浏览器,浏览器将其保存为 Cookie,后续对同一服务器的请求都使用 Cookie 请求头将这些参数传输给服务器

    • (参数存放)参数是存放在请求头部里的,也存在长度限制,但这个限制是服务器配置的限制,可以更改
    • (Cookie禁用)可能会禁用Cookie
    • (持久性)浏览器可以保存Cookie一段时间,在此期间Cookie持续有效
  4. Session

    基于前三种会话跟踪技术之一(一般是基于Cookie技术基础,如果浏览器禁用Cookie则可以采用URL重写技术),在每一次请求中只传输唯一一个参数:JSESSIONID,即会话id,服务器根据此会话id开辟一块会话内存空间,以存放其他参数

    • 会话数据全部存放在服务端,减轻了客户端及网络压力,但加剧了服务端压力
    • 既然是基于前三种会话技术之一(Cookie、url重写、隐藏表单域),因此也具备其对应的几个特点

来源

J2EE

J2EE是什么?

​ Je22是Sun公司提出的多层(multi-diered),分布式(distributed),基于组件(component-base)的企业级应用模型(enterpriese application model).在这样的一个应用系统中,可按照功能划分为不同的组件,这些组件又可在不同计算机上,并且处于相应的层次(tier)中。所属层次包括客户层(clietn tier)组件,web层和组件,Business层和组件,企业信息系统(EIS)层。

J2EE是技术还是平台还是框架? 什么是J2EE

​ J2EE本身是一个标准,一个为企业分布式应用的开发提供的标准平台。

​ J2EE也是一个框架,包括JDBC、JNDI、RMI、JMS、EJB、JTA等技术。

J2EE中常用的名词解释(或简单描述)

   web容器:给处于其中的应用程序组件(JSP,SERVLET)提供一个环境,使JSP,SERVLET直接跟容器中的环境变量接口交互,不必关注其它系统问题。主要有WEB服务器来实现。例如:TOMCAT,WEBLOGIC,WEBSPHERE等。该容器提供的接口严格遵守J2EE规范中的WEB APPLICATION 标准。我们把遵守以上标准的WEB服务器就叫做J2EE中的WEB容器。
   
   EJB容器:Enterprise java bean 容器。更具有行业领域特色。他提供给运行在其中的组件EJB各种管理功能。只要满足J2EE规范的EJB放入该容器,马上就会被容器进行高效率的管理。并且可以通过现成的接口来获得系统级别的服务。例如邮件服务、事务管理。

   JNDI:(Java Naming & Directory Interface)JAVA命名目录服务。主要提供的功能是:提供一个目录系统,让其它各地的应用程序在其上面留下自己的索引,从而满足快速查找和定位分布式应用程序的功能。

   JMS:(Java Message Service)JAVA消息服务。主要实现各个应用程序之间的通讯。包括点对点和广播。

   JTA:(Java Transaction API)JAVA事务服务。提供各种分布式事务服务。应用程序只需调用其提供的接口即可。

   JAF:(Java Action FrameWork)JAVA安全认证框架。提供一些安全控制方面的框架。让开发者通过各种部署和自定义实现自己的个性安全控制策略。

   RMI/IIOP:(Remote Method Invocation /internet对象请求中介协议)他们主要用于通过远程调用服务。例如,远程有一台计算机上运行一个程序,它提供股票分析服务,我们可以在本地计算机上实现对其直接调用。当然这是要通过一定的规范才能在异构的系统之间进行通信。RMI是JAVA特有的。
复制代码

详见来源

Java之IO流

更多详见来源

JSP 生命周期
  • 编译阶段

    servlet容器编译servlet源文件,生成servlet类

  • 初始化阶段

    加载与JSP对应的servlet类,创建其实例,并调用它的初始化方法

  • 执行阶段

    调用与JSP对应的servlet实例的服务方法

  • 销毁阶段

    调用与JSP对应的servlet实例的销毁方法,然后销毁servlet实例

Jsp只会在客户端第一次发请求的时候被编译,之后的请求不会再编译,同时tomcat能自动检测jsp变更与否,变更则再进行编译。

第一次编译并初始化时调用: init() ;销毁调用: destroy() 。在整个jsp生命周期中均只调用一次。

service()方法是接收请求,返回响应的方法。每次请求都执行一次,该方法被HttpServlet封装为doGet和doPost方法

JSP生命周期的四个主要阶段和servlet生命周期非常相似,下面给出图示:

详见来源

字符编码ANSI和ASCII、Unicode和UTF-8

ASCII码:全名是American Standard Code for Information Interchange, 叫做“美国信息交换标准码”。标准ASCII只使用7个bit,扩展的ASCII使用8个bit。ASCII码中,一个英文字母(不分大小写)占一个字节的空间,一个中文汉字占两个字节的空间。

ANSI码:ANSI编码是一种对ASCII码的拓展:ANSI编码用0x00~0x7f (即十进制下的0到127)范围的1 个字节来表示 1 个英文字符,超出一个字节的 0x80~0xFFFF 范围来表示其他语言的其他字符。也就是说,ANSI码仅在前128(0-127)个与ASCII码相同,之后的字符全是某个国家语言的所有字符。值得注意的是,两个字节最多可以存储的字符数目是2的16次方,即65536个字符,这对于一个语言的字符来说,绝对够了。还有ANSI编码其实包括很多编码:中国制定了GB2312编码,用来把中文编进去另外,日本把日文编到Shift_JIS里,韩国把韩文编到Euc-kr里,各国有各国的标准。受制于当时的条件,不同语言之间的ANSI码之间不能互相转换,这就会导致在多语言混合的文本中会有乱码。

Unicode编码:为了解决不同国家ANSI编码的冲突问题,Unicode应运而生,这是一种所有符号的编码。Unicode标准也在不断发展,但最常用的是用两个字节表示一个字符(如果要用到非常偏僻的字符,就需要4个字节)。现代操作系统和大多数编程语言都直接支持Unicode。原本可以用一个字节存储的英文字母在Unicode里面必须存两个字节(规则就是在原来英文字母对应ASCII码前面补0),产生了浪费。

UTF-8编码:这是一种变长的编码方式:它可以使用1~4个字节表示一个符号,根据不同的符号而变化字节长度,当字符在ASCII码的范围时,就用一个字节表示,保留了ASCII字符一个字节的编码做为它的一部分,如此一来UTF-8编码也可以是为视为一种对ASCII码的拓展。值得注意的是unicode编码中一个中文字符占2个字节,而UTF-8一个中文字符占3个字节。从unicode到uft-8并不是直接的对应,而是要过一些算法和规则来转换。

来源

转载于:https://juejin.im/post/5c680dbf518825625e4ac611

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值