11.虚拟内存
1. 什么是虚拟内存?解决了什么问题?虚拟内存是操作系统内存管理的一种技术,每个进程启动时,操作系统会提供一个独立的虚拟地址空间,这个地址空间是连续的,进程可以很方便的访问内存,这里的内存指的是访问虚拟内存。虚拟内存的目的,一是方便进程进行内存的访问,二是可以使有限的物理内存运行一个比它大很多的程序。
虚拟内存的基本思想:每个程序拥有自己的地址空间,这个空间被分割成很多块,每块称为一页,每一页地址都是连续的地址范围。这些页被映射到物理内存,但不要求是连续的物理内存,也不需要所有的页都映射到物理内存,而是按需分配,在程序片段需要分配内存时由硬件执行映射(通常是 MMU),调入内存中执行。
2. 说说分页和分段的机制?分页是实现虚拟内存的技术,虚拟内存按照固定的大小分为页面,物理内存也会按照固定的大小分成页框,页面和页框大小通常是一样的,一般是 4KB,页面和页框可以实现一对一的映射。分页是一维的,主要是为了获得更大的线性地址空间。但是一个地址空间可能存在很多个表,表的数据大小是动态增长的,由于多个表都在一维空间中,有可能导致一个表的数据覆盖了另一个表。
分段是把虚拟内存划分为多个独立的地 ...
10.进程间通信
进程间8种通信方式详解进程通信:
每个进程各自有不同的用户地址空间,任何一个进程的全局变量在另一个进程中都看不到,所以进程之间要交换数据必须通过内核,在内核中开辟一块缓冲区,进程A把数据从用户空间拷到内核缓冲区,进程B再从内核缓冲区把数据读走,内核提供的这种机制称为进程间通信。
1 匿名管道通信
匿名管道( pipe ):管道是一种半双工的通信方式,数据只能单向流动,而且只能在具有亲缘关系的进程间使用。进程的亲缘关系通常是指父子进程关系。
// 需要的头文件
#include <unistd.h>
// 通过pipe()函数来创建匿名管道
// 返回值:成功返回0,失败返回-1
// fd参数返回两个文件描述符
// fd[0]指向管道的读端,fd[1]指向管道的写端
// fd[1]的输出是fd[0]的输入。
int pipe (int fd[2]);
通过匿名管道实现进程间通信的步骤如下:
父进程创建管道,得到两个⽂件描述符指向管道的两端
父进程fork出子进程,⼦进程也有两个⽂件描述符指向同⼀管道。
父进程关闭fd[0],子进程关闭fd[1],即⽗进程 ...
https保证传输安全
1. HTTP存在的问题传统的不使用SSL/TLS的HTTP协议,是不加密的通信。无论是客户端发送给服务端的请求体,还是服务端响应给客户端的响应体,都是明文传输的,这会带来几个问题:
1. 窃听 第三方劫持请求后可以获取通信内容。对于一些敏感数据,这是不被允许的。
2. 篡改 第三方劫持请求后可以篡改通信内容。例如银行系统中,张三本来要给李四转账,第三方劫持请求后篡改了请求数据,将收款方改为自己,导致用户资金流失。
3. 冒充 第三方可以冒充客户端发送数据。由于是明文传输,没有「加签/验签」操作,服务端无法保证请求来源的合法性。
正是因为这些问题,HTTP通信存在巨大的安全隐患,于是HTTPS出现了。 本文将一步步深入,看看HTTPS是如何解决这些问题的。
2. SSL/TLS在介绍HTTPS之前,必须先了解SSL/TLS协议,因为HTTPS是构建在此基础之上的,了解了SSL/TLS基本也就清楚HTTPS的工作原理了。
SSL(Secure Sockets Layer)译为「安全套接字协议」,TLS(Transport Layer Security)译为「传输层安全性协议」。
简单回 ...
12.MySql事务
什么是事务?事务(Transaction),一般是指要做的或所做的事情。在计算机术语中是指访问并可能更新数据库中各种数据项的一个程序执行单元。事务通常由高级数据库操作语言或编程语言(如 SQL,C++ 或 Java)书写的用户程序的执行所引起,并用形如begin transaction和end transaction语句(或函数调用)来界定。事务由事务开始(begin transaction)和事务结束(end transaction)之间执行的全部操作组成。
对于 MySQL 数据库来说,事务是指以执行start transaction命令开始,到执行commit或者rollback命令结束之间的全部 SQL 操作,如果这些 SQL 操作全部执行成功,则执行commit命令提交事务,表示事务执行成功;如果这些 SQL 操作中任一操作执行失败,则执行rollback命令回滚事务,表示事务执行失败,并将数据库回滚到执行start transaction命令之前的状态。特别地,在现阶段的 MySQL 数据库中,仅 InnoDB 和 NDB 两个存储引擎是支持事务的。
以 MySQL 的 I ...
Redis的持久化
前言
什么是持久化 : Redis读写速度快、性能优越是因为它将所有数据存在了内存中,然而,当Redis进程退出或重启后,所有数据就会丢失,所以我们希望Redis能保存数据到硬盘中,在Redis服务重启之后,原来的数据能够恢复,这个过程就叫持久化.- MySQL的InnoDB存储引擎通过 redo log、bin log 这两个日志保证了持久化.
Redis的两种持久化方式 — RDB、AOF
Redis 提供了两种持久化功能 : RDB、AOF ,但两种功能无论在磁盘上的存储格式、使用性能、安全性以及使用场景等方面上是有区别的.
RDB
RDB持久化既可以手动执行,也可以根据服务器配置选项定期执行(即可以在某个时间点上达到配置选项的条件而进行持久化RDB文件中).由于RDB文件是保存在磁盘中,所以Redis服务器进程退出后,甚至运行的计算机停机了,只要RDB文件存在,Redis服务器就可以利用RDB文件来还原数据库状态.
接下来分别看看RDB的两种执行方式 : 手动执行、配置选项定期执行.
手动执行
手动执行 : Redis提供了SAVE、BGSAVE两种命 ...
15.多线程打印
一道面试中常考的并发编程的代码题:
三个线程T1、T2、T3轮流打印ABC,打印n次,如ABCABCABCABC…….
两个线程交替打印1-100的奇偶数
N个线程循环打印1-100
……
其实这类问题本质上都是线程通信问题,思路基本上都是一个线程执行完毕,阻塞该线程,唤醒其他线程,按顺序执行下一个线程。下面先来看最简单的,如何按顺序执行三个线程。
synchronized+wait/notify基本思路就是线程A、线程B、线程C三个线程同时启动,因为变量num的初始值为0,所以线程B或线程C拿到锁后,进入while()循环,然后执行wait()方法,线程线程阻塞,释放锁。只有线程A拿到锁后,不进入while()循环,执行num++,打印字符A,最后唤醒线程B和线程C。此时num值为1,只有线程B拿到锁后,不被阻塞,执行num++,打印字符B,最后唤醒线程A和线程C,后面以此类推。
123456789101112131415161718192021222324252627282930public class Wait_Notify_ABC { private vol ...
9.进程的状态
Linux系统之进程状态
D:uninterruptible sleep (usually IO)
R:running or runnable (on run queue)
S:interruptible sleep (waiting for an event to complete)
T:stopped by job control signal
t:stopped by debugger during the tracing
W:paging (not valid since the 2.6.xx kernel)
X:dead (should never be seen)
Z:defunct (“zombie”) process, terminated but not - reaped by its parent
1、R (TASK_RUNNING),可执行状态只有在该状态的进程才可能在CPU上运行。而同一时刻可能有多个进程处于可执行状态,这些进程的task_struct结构(进程控制块)被放入对应CPU的可执行队列中(一个进程最多只能出现在一个CPU的可执行队列中)。进而,进程 ...
05.编写Netty应用程序
05.Netty服务启动之前讲过的 EchoServer:
123456789101112131415161718192021222324252627282930313233343536373839404142public final class EchoServer { static final int PORT = Integer.parseInt(System.getProperty("port", "8007")); public static void main(String[] args) throws Exception { // 1. 声明线程池 EventLoopGroup bossGroup = new NioEventLoopGroup(1); EventLoopGroup workerGroup = new NioEventLoopGroup(); EchoServerHandler echoServerHandler = new Ec ...
04.编写Netty应用程序
编写Netty应用程序从 netty-example 工程下抄了一份 EchoServer 过来,并删减了部分代码,归纳出来一份编写 Netty 服务端程序的模板,我把它称为 “Netty 编码十步曲”。
1. 声明线程池(必须)一般来说,我们会声明两个 Group,一个是 bossGroup,用于处理 Accept 事件,一个是 workerGroup,用于处理消息的读写事件。其中,bossGroup 一般声明为一个线程。当然,如果声明一个 Group 也是可以的,只是不建议。
12EventLoopGroup bossGroup = new NioEventLoopGroup(1);EventLoopGroup workerGroup = new NioEventLoopGroup();
这就像是大型餐厅一般有接待生和服务员两种职位一样,接待生一般形象良好,专门负责接待客人,服务员形象稍差,专门负责上菜收碟,你要说不区分两种职位,混用行不行呢,当然也可以,只是不建议,专人干专事。
2. 创建服务端引导类(必须)引导类,是用来集成所有配置,引导程序加载的,分成两种,一种是客户端引 ...
03.Java NIO的核心组件
03.Java NIO的核心组件Channel什么是 Channel 呢? 让我们来看看 JDK 怎么说:
// java.nio.channels.Channel
A nexus for I/O operations.
A channel represents an open connection to an entity such as a hardware device, a file, a network socket, or a program component that is capable of performing one or more distinct I/O operations, for example reading or writing.
Channel 是一种 IO 操作的连接(nexus,连接的意思),它代表的是到实体的开放连接,这个实体可以是硬件设备、文件、网络套接字或者可执行 IO 操作(比如读、写)的程序组件。
在 linux 系统中,一切皆可看作是文件,所以,简单点讲,Channel 就是到文件的连接,并可以通过 IO 操作这些文件。
因此 ...