操作系统 核心概念
进程 & 进程管理
跑起来的程序就是进程~~
操作系统会创建一个PCB 把这个PCB加入到链表上
进程调度:
1.为啥要调度? 狼多肉少
2.CPU按照并发的方式来执行进程的
3.PCB中提供了一些属性,进程的状态,进程的上下文,进程的记账信息.......
引入进程,目的就是为了能够是实现 多个任务 并发执行 这样的效果
进程有个重大的问题,比较重量,如果频繁的创建/销毁进程,成本比较高~~(资源分配)
线程
进程包含线程
一个进程里可以有一个线程,或者多个线程
每个线程都是一个独立的执行流程,多个线程之间,也是并发执行的。
(多个线程可能是在多个CPU核心上,同时运行
也可能是在一个CPU核心上,通过快速调度,进行运行~~)
前面所说的“调度进程”指的是这些进程里面只有一个线程
操作系统,真正调度的,是在调度线程,而不是进程~~
(线程是 操作系统 调度运行 的基本单位
进程是 操作系统 资源分配 的基本单位)
一个进程中的多个线程之间,共用一份系统资源
1)内存空间
2)文件描述符
只有在进程启动,创建第一个进程的时候,需要花成本去申请系统资源
一旦进程(第一个进程)创建完毕,此时,后续在创建的线程,就不必再申请资源了~~,创建/销毁 的效率就提高了不少了
进程和线程之间的区别~~
(谈到 JavaSE,最高频的问题,让你谈谈多态)
同一件事,发生在不同的对象身上,就会产生不同的结果.
1.2 多态的实现条件
在Java中要实现多态,必须要满足如下条件,
1.必须在继承体系下
2.子类必须要对父类中的方法进行重写
3.通过父类的引用调用重写的方法
4.向上转型
1.3 向上转型和向下转型
1.3.1 向上转型:实际就是创建一个子类对象,将其当成父类对象来使用.
语法格式: 父类类型 对象名 = new 子类类型();
Animal animal = new Dog();
class Animal { //父类
public String name;
public int age;
public void eat(){
System.out.println(name+"正在吃饭!");
}
}
class Dog extends Animal { //狗类
public void Wangwang(){
System.out.println(name+"正在汪汪叫");
}
}
class Bird extends Animal {//鸟类
public String Wing;
public void fly(){
System.out.println(name+"正在飞!");
}
}
public class Test {
public static void main1(String[] args)
Dog dog = new Dog();
dog.name = "大黄";
dog.eat();
dog.Wangwang();
//他们是在继承关系之上,
Animal animal = dog;//可以这样理解Animal类的引用指向dog类这个对象
Brid brid = new Brid();
brid.name = "圆圆";
Animal animal2 = brid;//同理brid类也可以这样理解
}
public static void main(String[] args) {
Animal animal = new Dog();//直接赋值:子类对象赋值给父类对象
animal.name = "大黄";
animal.eat();
}
}
向上转型的缺陷:就是不能通过父类的引用去访问子类特有的成员
当发生向上转型后,此时通过父类的引用只能访问父类自己的成员,不能访问到子类特有的成
1.3.2 向下转型
将一个子类对象经过向上转型之后当成父类方法使用,在无法调用子类的方法,但有时候可能需要调用特有的方法,此时:将父类引用再还原为子类对象即可
2.重写
重写(Override):也成为覆盖.重写是子类对父类非静态,非private修饰,非final修饰,非构造方法等的实现过程进行重新编写,返回值和形参都不能改变.即外壳不变核心重写!重写的好处在于子类可以根据需要,定义特定于自己的行为.
重写的条件:
1.方法名称相同
2.参数列表相同
3.返回值相同
(谈到 数据结构,最高频的问题,让你谈谈哈希表)
哈希表:通过键key和一个映射函数Hash(key)计算出对应的值value,把关键码值映射到表中一个位置来访问记录,以加快查找的速度.
哈希函数:将哈希表中元素的关键键值映射为元素储存位置的函数
哈希冲突:不同的关键字通过通一哈希函数可能得到同一哈希地址
(谈到 数据库,最高频的问题,让你谈谈索引和事务)
索引是一种用于快速查询和检索数据的数据结构.常见的索引结构有:B树,B+树和Hash
索引的优点:可以大大加快 数据的检索速度(大大减少检索的数量)
索引的缺点:创建索引和维护索引需要耗费许多时间,占物理存储空间
索引的类型:
主键索引(primary key):一张表有只有一个主键,并且主键不能为null,不能重复
二级索引:二级索引的叶子节点存储的数据是主键,通过二级索引可以定位主键的位置
唯一索引,普通索引,前缀索引等索引属于二级索引
(谈到 系统编程,最高频的问题,让你谈谈 进程 和线程 基本概念和区别)
进程和线程之间的区别~~
1.进程包含线程
2.进程有自己独立的内存空间和文件描述符表。同时一个进程中的多个线程之间,共享同一份地址空间和文件描述符表
3.进程是操作系统资源分配的基本单位,线程是操作系统调度执行的基本单位
4.进程之间具有独立性,一个进程挂了,不会影响到别的进程;同一个进程里的多个线程
之间,一个线程挂了,可能会把整个进程带走,影响其他线程的。
每次运行一个exe程序 cctalk,画图板,都是一个一个的进程~~
每个进程里可以在并发的执行多个功能,就可以通过多线程来完成了~~
多进程 和 多线程 在在咱们的电脑中都是同时存在的
不是说 多线程就完全代替了多进程~~
多个进程/多个线程都是可以并发和并行的~~
系统自带的任务管理器看不到线程,只能看到进程级别
需要使用其他的第三方工具才能看到Windbg...
Java 进行多线程编程
java 标准提供了一个类Thread能够表示一个 线程 ~~
方法重载? overload
方法重写? override
先创建MyThread实例
t的引用实际上是指向子类的实例
启动线程
在线程中搞了另外一个流水线,新的流水线开始并发的执行
另外一个逻辑了~~
上述代码涉及到两个线程
1.main方法所对应的线程(一个进程里至少得有一个线程) 也可以称为 主线程
2.通过t.start 创建的新线程
点击这里运行程序,其实是ideal 对应的进程,创建了一个新的java 进程,这个Java进程来执行咱们自己写的代码。
这个java 进程就有两个进程
一个是main,一个是t
调整代码,具体仔细看看,体会一下,“每个线程是一个独立的执行流”
此时看到的效果,hello t 和 hello main 都能打印出来~~
t.start();另外启动了一个执行流,新的执行流(新的进程) 来执行
同时执行
线程是能够交替运行
但是打印出来的结果肯定是有先有后的~~
因为是两个线程往同一个控制台上打印,同一个控制台必须地顺序
输出~~
通过上述日志,这俩线程就是在同时执行
打印了几个hello main 再打印几个 hello t
再打印几个 hello main....
如果是单个线程的话,此时就是只能打其中一个,看不到另外一个的~~
此处,代码没有创建其他的线程
两个死循环都在同一个线程中的
执行到第一个死循环,代码就出不来了
第二个循环进不去了~~
run不是一个顺便的方法,是重写父类的方法
这种重写一般就是 功能扩展
t.start();
调用操作系统的api,创建新线程
新的线程里调用t.run
如果找不到jconsole可以打开ideal的jdk路径