定义:
进程:是并发执行的程序在执行过程中分配和管理资源的基本单位,是一个动态概念,竞争计算机系统资源的基本单位。
线程:是进程的一个执行单元,是进程内科调度实体。比进程更小的独立运行的基本单位。线程也被称为轻量级进程。
注:一个程序至少一个进程,一个进程至少一个线程。
地址空间:同一进程的线程共享本进程的地址空间,而进程之间则是独立的地址空间
线程执行开销小,但是不利于资源的管理和保护。线程适合在SMP机器(双CPU系统)上运行。
使用场景:
对资源的管理和保护要求高,不限制开销和效率时,使用多进程。
要求效率高,频繁切换时,资源的保护管理要求不是很高时,使用多线程
2.NIO和AIO的区别;
Topic:每条发布到 Kafka 集群的消息都有一个类别,这个类别被称为 Topic。
Partition:Partition 是物理上的概念,每个 Topic 包含一个或多个 Partition。
1. 为查询缓存优化你的查询
2.字段建索引
3.避免 SELECT *
4.远为每张表设置一个ID
5.用 ENUM 而不是 VARCHAR
6.可能的使用 NOT NULL
7固定长度的表会更快
8 拆分大的 DELETE 或 INSERT 语句
9 设计合适的索引,基于主键的查找,上亿数据也是很快的;
10反范式化设计,以空间换时间,避免join,有些join操作可以在用代码实现,没必要用数据库来实现;
11buffer,尽量让内存大于数据.
8.netty的架构
。
同步:在发出一个同步调用时,在没有得到结果之前,该调用就不返回。
异步:在发出一个异步调用后,调用者不会立刻得到结果,该调用就返回了。
阻塞和非阻塞:
阻塞调用是指调用结果返回之前,调用者会进入阻塞状态等待。只有在得到结果之后才会返回。
非阻塞调用是指在不能立刻得到结果之前,该函数不会阻塞当前线程,而会立刻返回。
并发和并行:
并发是指一个时间段内,有几个程序都在同一个CPU上运行,但任意一个时刻点上只有一个程序在处理机上运行。
并行是指一个时间段内,有几个程序都在几个CPU上运行,任意一个时刻点上,有多个程序在同时运行,并且多道程序之间互不干扰
linux系统一般分为4个主要部分:内核、shell+库、文件系统和应用.
通信方式:
spring cloud采用的是其于HTTP 的 REST方式。 严格来说,这两种方式各有优劣。虽然从一定程度度上来说,后者牺牲了服务调用的性能,但也避免了上面提到的原生RPC带来的问题。
而且REST相比RPC更为灵活,服务提供方和调用方的依赖只依堂一纸契约,不存在代码级的强依赖,这在强调快速微服务环境下,显得更加合适。这也是dubbo和spring cloud最本质的区别
架构:
spring cloud比dubbo的功能更完善,涵盖更广,而且作为spring的拳头产品,它能与spring framework,spring boot,springdata等其他spring项目完美融合,使用dubbo就像组装电脑,各个环节的自由度很高,例如注册中心,可以用zookeeper,redis等。spring cloud就像品牌机,在spring source的整合下,做了大量的兼容性测试,保证了机器拥有更高的稳定性
PG相对于MySQL的优势:
1、在SQL的标准实现上要比MySQL完善,而且功能实现比较严谨;
2、存储过程的功能支持要比MySQL好,具备本地缓存执行计划的能力;
3、对表连接支持较完整,优化器的功能较完整,支持的索引类型很多,复杂查询能力较强;
4、PG主表采用堆表存放,MySQL采用索引组织表,能够支持比MySQL更大的数据量。
5、PG的主备复制属于物理复制,相对于MySQL基于binlog的逻辑复制,数据的一致性更加可靠,复制性能更高,对主机性能的影响也更小。
6、MySQL的存储引擎插件化机制,存在锁机制复杂影响并发的问题,而PG不存在。
MySQL相对于PG的优势:
1、innodb的基于回滚段实现的MVCC机制,相对PG新老数据一起存放的基于XID的MVCC机制,是占优的。新老数据一起存放,需要定时触 发VACUUM,会带来多余的IO和数据库对象加锁开销,引起数据库整体的并发能力下降。而且VACUUM清理不及时,还可能会引发数据膨胀;
2、MySQL采用索引组织表,这种存储方式非常适合基于主键匹配的查询、删改操作,但是对表结构设计存在约束;
3、MySQL的优化器较简单,系统表、运算符、数据类型的实现都很精简,非常适合简单的查询操作;
4、MySQL分区表的实现要优于PG的基于继承表的分区实现,主要体现在分区个数达到上千上万后的处理性能差异较大。
5、MySQL的存储引擎插件化机制,使得它的应用场景更加广泛,比如除了innodb适合事务处理场景外,myisam适合静态数据的查询场景。
总体上来说,开源数据库都不是很完善,商业数据库oracle在架构和功能方面都还是完善很多的。从应用场景来说,
PG更加适合严格的企业应用场景(比如金融、电信、ERP、CRM),
而MySQL更加适合业务逻辑相对简单、数据可靠性要求较低的互联网场景(比如google、facebook、alibaba)
26.jvm(java)的内存结构
JVM把内存划分成了如下几个区域:
1.方法区(Method Area):方法区存放了要加载的类的信息(如类名、修饰符等)、静态变量、构造函数、final定义的常量、类中的字段和方法等信息。方法区是全局共享的,在一定条件下也会被GC。当方法区超过它允许的大小时,就会抛出OutOfMemory:PermGen Space异常。
2.堆区(Heap): 堆区是GC最频繁的,也是理解GC机制最重要的区域。堆区由所有线程共享,在虚拟机启动时创建。堆区主要用于存放对象实例及数组,所有new出来的对象都存储在该区域。
3.虚拟机栈(VM Stack): 虚拟机栈占用的是操作系统内存,每个线程对应一个虚拟机栈,它是线程私有的,生命周期和线程一样,每个方法被执行时产生一个栈帧(Statck Frame),栈帧用于存储局部变量表、动态链接、操作数和方法出口等信息,当方法被调用时,栈帧入栈,当方法调用结束时,栈帧出栈。
注:虚拟机栈定义了两种异常类型:StackOverFlowError(栈溢出)和OutOfMemoryError(内存溢出)。如果线程调用的栈深度大于虚拟机允许的最大深度,则抛出StackOverFlowError;不过大多数虚拟机都允许动态扩展虚拟机栈的大小,所以线程可以一直申请栈,直到内存不足时,抛出OutOfMemoryError。
4.本地方法栈(Native Method Stack):本地方法栈用于支持native方法的执行,存储了每个native方法的执行状态。本地方法栈和虚拟机栈他们的运行机制一致,唯一的区别是,虚拟机栈执行Java方法,本地方法栈执行native方法。在很多虚拟机中(如Sun的JDK默认的HotSpot虚拟机),会将虚拟机栈和本地方法栈一起使用。
5.程序计数器(Program Counter Register):程序计数器是一个很小的内存区域,不在RAM上,而是直接划分在CPU上,程序猿无法操作它,它的作用是:JVM在解释字节码(.class)文件时,存储当前线程执行的字节码行号,只是一种概念模型,各种JVM所采用的方式不一样。字节码解释器工作时,就是通过改变程序计数器的值来取下一条要执行的指令,分支、循环、跳转等基础功能都是依赖此技术区完成的。
引用的种类:
强引用:new出来的对象都是强引用,GC无论如何都不会回收,即使抛出OOM异常。
软引用:只有当JVM内存不足时才会被回收。
弱引用:只要GC,就会立马回收,不管内存是否充足。
虚引用:可以忽略不计,JVM完全不会在乎虚引用。它唯一的作用就是做一些跟踪记录,辅助finalize函数的使用。
什么样的类会被回收:
a.该类的所有实例都已经被回收;
b.加载该类的ClassLoad已经被回收;
c.该类对应的反射类java.lang.Class对象没有被任何地方引用。
内存分区:
新生代(Youn Generation):大致分为Eden区和Survivor区,Survivor区又分为大小相同的两部分:FromSpace和ToSpace。新建的对象都是从新生代分配内存,Eden区不足的时候,会把存活的对象转移到Survivor区。当新生代进行垃圾回收时会出发Minor GC(也称作Youn GC)。
旧生代(Old Generation):旧生代用于存放新生代多次回收依然存活的对象,如缓存对象。当旧生代满了的时候就需要对旧生代进行回收,旧生代的垃圾回收称作Major GC(也称作Full GC)。
持久代(Permanent Generation):在Sun 的JVM中就是方法区的意思,尽管大多数JVM没有这一代。
参考地址:https://blog.csdn.net/anjoyandroid/article/details/78609971
27.Synchronize 和 Lock 的区别
>1.原始构成
synchronized 是关键字属于JVM层面,
monitorenter(底层是通过monitor对象来完成,其实wait/notify等方法也依赖于monitor对象只有在同步块或方法中才能调wait/notify等方法,)
monitorexit
Lock是具体类(java.util.concurrent.locks.Lock)是api层面的锁
>2.使用方法
synchronized 不需要用户去手动释放锁,当synchroized代码执行完成后系统会自动让线程释放对锁的占用
ReentrantLock则需要用户去手动释放锁若没有主动释放锁,就有可能导致出现死锁现象。(需要lock()和unlock()方法配合try/finally语句块来完成。)
>3.等待是否可中断
synchronized不可中断,出非抛出异常或者正常运行完成
ReentrantLock可中断:1.设置超时方法try lock(long timeout,TimeUnit unit)2.lockInterruptibly()放代码块中,调用interrupt()方法可中断
>4.加锁是否公平
synchronized是非公平锁
ReentrantLock两者皆可,默认非公平锁,构造方法可以传入boolean值,true为公平锁,false为非公平锁
>5.锁绑定多个条件
synchronized 没有
ReentrantLock用来实现分组唤醒的线程们,可以精确唤醒。而不是像synchronized要么随机唤醒一个线程要么唤醒全部。