欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

安全编程期末复习

程序员文章站 2022-04-20 22:04:54
...

安全编程期末复习

Java的8种基本数据类型

序号 数据类型 位数 默认值 取值范围 举例说明
1 byte(位) 8 0 27271-2^{7}\sim2^{7}-1 byte b = 10;
2 short(短整数) 16 0 2152151-2^{15}\sim2^{15}-1 short s = 10;
3 int(整数) 32 0 2312311-2^{31}\sim2^{31}-1 int i = 10;
4 long(长整数) 64 0 2632631-2^{63}\sim2^{63}-1 long l = 10l;
5 float(单精度) 32 0.0 2312311-2^{31}\sim2^{31}-1 float f = 10.0f;
6 double(双精度) 64 0.0 2632631-2^{63}\sim2^{63}-1 double d = 10.0d;
7 char(字符) 16 null 021610\sim2^{16}-1 char c = ‘c’;
8 boolean(布尔值) 8 false true、false boolean b = true;

享元设计模式flyweight

享元模式的意图是通过共享有效支持大量细粒度的对象,来提高应用程序的性能,节省系统中重复创建对象实例的性能消耗。

何时使用享元模式

  1. 系统中有大量对象时

  2. 这些对象消耗大量内存时

  3. 这些对象的状态大部分可以外部化时

例如:我们在使用输入的法的时候,如果我们每个字都是new一个对象实例的操作,那么内存中的实例就太可怕,这个时候我们可以在内存中创建26个字母的对象,然后重复利用他们。对于需要出现在不同位置的字符,我们可以通过调用其内部的方法来实现,比如字母i需要被放在(x, y)这个位置,就调用, i.display(x, y)

反射

Java反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意方法和属性;这种动态获取信息以及动态调用对象方法的功能称为java语言的反射机制。

反射就是把一个java类中的每一个成分解析成一个个java类。

一个java类用一个Class类的对象来表示,一个类的组成部分:成员变量,方法, 构造方法等信息用一个个的类来表示。这个类的Class需要提供一系列的方法来获得其中的变量,方法,构造方法,修饰符,包等信息,这些信息使用类的实例对象来表示,他们是Field,Method,Contructor,Package等。

一个class中的每个成员都可以用相应的API反射类的对象来表示。

类名 用途
Class类 代表类的实体,在运行的Java应用程序中表示类和接口
Field类 代表类的成员变量(成员变量也称为类的属性)
Method类 代表类的方法
Constructor类 代表类的构造方法

反射为什么用的少?

因为效率低,不到万不得已不会用反射

反射的高明之处在于?

可在程序运行过程中修改代码(比如mysql改成mssql)

Java加载类的原理

当我们定义一个对象Person p= new Person(),java就从把person的字节码加载到内存 中,然后用这个字节码产生对象。

每用到一个新类,就会加载一个新的字节码,每个字节码就是Class的实例对象。

对于Class对象,不存在可供调用的构造函数。

得到一个类的Class对象的方法

  1. Person.class

  2. p1.getClass()

  3. Class.forName(“java.lang.String”)

其中当jvm中没有这个加载这个类的时候,只能用3来获得这个类的Class。

方法3最常见。

为什么class对象在java虚拟机中只可能是0或1个

因为创建的是类加载器先在hashmap寻找有没有,没有才创建类加载器原理

类装载器的委托模式

每个ClassLoader本身只能分别加载特定位置和目录中的类,但是,ClassLoader被设计成了一种委托模式,使得某一个ClassLoader可以委托它的父级类装载器去加载类,从而让应用程序可以借助某一个子级的ClassLoader去多个位置和目录中进行类的加载。

对于一个类,一个类装载器本身可能不能装载它,但是只要它的父类装载器中有可以装载这个类的,那么这个类装载器就可以把这个类委托给它自己的父类装载。

类加载的过程

ClassLoader的loadClass方法先查找这个类是否已被加载,如果没有加载则委托其父级类装载器去加载这个类,如果父级的类装载器无法装载这个类,子级类装载器才调用自己内部的findClass方法去进行真正的加载。

委托过程会一直追溯到BootStrap类装载器,如果委托过程中的所有类装载器都不能完成类的装载,最终就会报告ClassNotFoundException异常。

通过中间变量交换两个变量的值

Void swap(int *a, int *b)
{
	int *t = a;
	*a = *b;
	*b = t;
}

在不定义中间变量的情况下交换两个变量的值

Void swap(int *a, int *b)
{
	*a = *a + *b; //加法可能溢出
	*b = *a - *b;
	*a = *a - *b;
}
Void swap(int *a, int *b)
{
	*a = (*a) * (*b); //乘法可能溢出
	*b = (*a) / (*b); //除法可能有分母为0的问题
	*a = (*a) / (*b);
}
Void swap(int *a, int *b)c
{
	*a = (*a) ^ (*b);
	*b = (*a) ^ (*b);
	*a = (*a) ^ (*b);
}

下面取地址操作是否可行,为什么

  1. int** a=&&b;
  2. int *a=&3;
  3. int *a=&go();

  1. &b取出来的地址放CPU寄存器,不可取&b只能去内存地址
  2. 3是常量,不可用&取址只有变量才有内存地址
  3. go()是函数返回值,在被赋予变量前被放在CPU寄存器

C语言内存管理

内存空间 读写权限
kernel 不可读写
环境变量与命令参数 可读不可写
栈空间 可读可写
共享库动态库 可读不可写
堆空间 申请后可读写
BSS区(初始为0) 可读可写
Data区 可读可写
只读区 可读不可写
代码区 可读不可写

写出下列代码中变量的位置

全局变量和任何static变量都在全局区,这些变量赋值就在Data区,不赋值就在BSS区

int a=3; 				//全局区的Data区
int b; 					//全局区的BSS区
static int c=4; 		//全局区的Data区
static int d; 			//全局区的BSS区
int main(void)
{
	int e; 				//栈空间
	int f=5; 			//栈空间
	static int g; 		//全局区的BSS区
	static int h = 6; 	//全局区的Data区
	if(1)
	{
		int i=7; 		//栈空间
	}
	char *p=malloc(10); //p在栈空间 malloc(10)在堆空间
	char *str="hello"; 	//str在栈空间 "hello"在只读区
}

单例模式和静态方法的区别

  1. 静态方法性能更好,在编译期就已经绑定好了

  2. 单例模式可以延迟初始化,静态方法在第一次使用时初始化。如果需要加载比较重的对象,用单例模式会更好

  3. 单例模式可以被继承,方法可以被重写,静态方法不行

单子模式适用场景

  1. 需要频繁实例化然后销毁的对象。
  2. 创建对象时耗时过多

单子模式的三要素

  1. 私有静态属性,用于存取类的唯一实例。

  2. 公共静态方法,用于提供对该唯一实例的存取访问,如果实例未创建,则创建该实例 。

  3. 私有构建函数,用于限制类再次实例化的方式。

单例模式的优点

  1. 在内存中只有一个对象,节省内存空间
  2. 避免频繁的创建销毁对象,可以提高性能
  3. 避免对共享资源的多重占用。
  4. 可以全局访问

单子模式可不可以new出多个实例?

可以,用反射技术

单子模式示例代码

/*
   饿汉模式:“比较勤”,实例在初始化的时候就已经建好了,
         不管有没有用到,都先建好了再说。
         好处是没有线程安全的问题,坏处是浪费内存空间
*/
public class Singleton {
   //1 私有构造器 外部不能访问
   private Singleton(){

   }
   //2 声明一个静态的自己的类
   private static Singleton singleton = new Singleton();
   //3 返回一个返回自己类的方法
   public static  Singleton getSingleton(){
      return singleton;
   }
}
/*
	懒汉模式:实例在用到的时候才去创建,“比较懒”,
			用的时候才去检查有没有实例,如果有则返回,没有则新建
			线程不安全,严格意义上不是不是单例模式
*/
public class Singleton{
	//1 私有构造器 外部不能访问
	private Singleton(){

	}
	//2 声明一个静态的自己的类
	private static Singleton singleton = null;
	//3 返回一个返回自己类的方法
	public static Singleton getSingleton() {
		if(singleton == null) {
			singleton = new Singleton();
		}
		return singleton;
	}
}

实现多线程的方法

  1. 继承Thread类
  2. 实现Runnable接口

什么是死锁

不同的线程都在等待那些根本不可能被释放的锁,从而导致没有外力作用时无法推进,所有的工作都无法完成。

为什么会发生死锁

竞争资源、进程推进顺序不当

JavaBean定义

JavaBean是一种 JAVA 语言写成的可重用组件。JavaBean 通过提供符合一致性设计模式的 公共方法将内部域暴露成员属性,set和get方法获取。JavaBean定义了一组规则JavaBean就是遵循此规则的平常的Java对象

JavaBean满足这三个条件:

  1. 执行java.io.Serializable接口

  2. 提供无参数的构造器

  3. 提供getter和setter方法访问它的属性.

Javabean可以根据get和set方法推断出类内部私有变量的名字

JavaBean示例代码

/*
	老师的例子
*/
public class Point {
	private String name;
	private int age = 20;

	public Point(String name, int age) {
		this.name = name;
		this.age = age;
	}

	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}

	public int getAge() {
		return age;
	}
	public void setAge(int age) {
	this.age = age;
	}
}

基本内置注解

@Override 覆写 函数名和参数必须和父类一样 重写父类的方法

@Deprecated 弃用

@SuppressWarnings 抑制警告

Java异常类层次结构图

安全编程期末复习

Error和Exception 的区别

安全编程期末复习

堆和栈

栈空间:

  1. 由编译器自动分配释放,存放函数的参数值,局部变量的值等;
  2. 操作方式类似于数据结构中的栈,占用连续存储空间;
  3. 栈空间向着内存地址减小的方向消耗空间;
  4. 栈空间的大小一般是2M,从栈获得的空间较小;由计算机底层的支持,压栈和出栈都有专门的指令,效率较高。

堆空间:

  1. 由程序员分配释放,若程序员不释放,程序结束时可能由操作系统回收;
  2. 操作方式类似链表,更新频繁,造成可用空间碎片化,每块可用空间都很小;
  3. 堆获得的空间比较灵活,也比较大,向着内存地址增大的方向消耗空间;
  4. 堆空间通过可用空间链表的扫描、合并等操作动态的获取空间,效率相对较低。

下面代码的区别

int num = 10; 				
//局部变量num保存在stack中,stack一般1M
String str = "hello"; 
//str在栈中,保存的是一个引用,指向"hello"首字母;
//"hello"在堆中,底层是为hello做一次malloc

如果我们做如下修改,内存中发生了什么?

Num=20; 
//栈中10变20 (20覆盖原来的10)
Str="nuist";
//java在内存(堆)中重新开辟一个区域(malloc)存放nuist,并且str指向这个新的字符串。
//原来的hello字符串会被java垃圾回收器回收(free)
相关标签: 期末复习

上一篇: 简单错误记录

下一篇: SSM错误记录