LDAP 简明科普

1. 什么是 LDAP LDAP(Lightweight Directory Access Protocol) 是一种用于查询和管理目录信息的协议。 简单说: LDAP 是一个“按层级组织的用户信息数据库 + 查询方式” 2. LDAP 存什么 常见内容包括: 用户账号(用户名、ID) 密码(加密存储) 用户组(权限) 部门 / 组织结构 邮箱、电话等信息 3. 数据结构(像树) LDAP 的数据是树状结构: graph TD A[公司] --> B[技术部] A --> C[人事部] B --> D[用户A] B --> E[用户B] C --> F[用户C] 每个节点都有唯一标识(DN)。 4. LDAP 能做什么 用户登录认证(验证账号密码) 查询用户信息 管理组织结构 权限分组管理 5. 常见使用场景 公司统一账号系统 内部系统登录(单点登录基础) 权限集中管理 6. 常见实现 OpenLDAP Active Directory(微软) 7. 一句话总结 LDAP 是一个“按树组织的用户信息数据库 + 查询协议”,用于统一管理账号和组织结构

2026年4月8日 · 1 分钟

SSH、跳板机和隧道

1. SSH 是什么 SSH(Secure Shell) 是一种用于远程登录和通信的加密协议。 核心作用 远程登录服务器 执行命令 安全传输数据 建立加密通道 简单理解 就像一根“加密的远程操作线”,你在本地操作,实际在远程执行。 图示 graph LR A[本地电脑] -- SSH连接 --> B[远程服务器] A -->|输入命令| B B -->|返回结果| A 2. 跳板机(Bastion Host)是什么 跳板机是一台中间服务器,用于访问内网机器。 为什么需要 内网服务器不能直接暴露到公网 提供统一入口(安全控制、审计) 简单理解 像“门卫”,必须先经过它,才能进入内部系统。 图示 graph LR A[本地电脑] --> B[跳板机] B --> C[内网服务器] 常见连接方式 ssh -J user@跳板机 user@内网服务器 3. 隧道(SSH Tunnel)是什么 SSH 隧道是一种通过 SSH 转发网络流量的技术。 本质 把本地请求“通过 SSH 转发到远程” 3.1 本地端口转发(Local Forward) 示例 ssh -L 3307:127.0.0.1:3306 user@服务器 ...

2026年4月8日 · 1 分钟

加密体系

1. 三个核心问题 整个体系其实在解决三件事: 你是谁?(身份认证) 数据能不能被偷看?(加密传输) 如何安全地交换密钥?(密钥分发) 2. 非对称加密(公钥 / 私钥) 核心定义 使用一对密钥:公钥 + 私钥 公钥:可以公开 私钥:必须保密 二者不可互相推导 两种用途(关键区分) ① 加密通信 graph LR A[发送方] -->|公钥加密| B[密文] B --> C[接收方] C -->|私钥解密| D[明文] ② 身份认证(SSH) sequenceDiagram participant A as 客户端(私钥) participant B as 服务器(公钥) B->>A: challenge A->>B: signature B->>B: 公钥验证 B->>A: 通过/拒绝 关键公式 signature = Sign(私钥, challenge) Verify(公钥, challenge, signature) = true 本质总结 私钥负责“生成证明”,公钥负责“验证证明” 3. SSH:基于签名的认证机制 文件结构 ~/.ssh/id_ed25519 # 私钥 ~/.ssh/id_ed25519.pub # 公钥 ~/.ssh/authorized_keys # 服务器保存公钥 免密登录本质 服务器信任“某个公钥”,允许对应私钥登录 ...

2026年4月8日 · 2 分钟

Java虚拟机栈

与程序计数器一样,Java虚拟机栈(Java Virtual Machine Stack)也是线程私有的,它的生命周期与线程相同。虚拟机栈描述的是Java方法执行的线程内存模型:每个方法被执行的时候,Java虚拟机都会同步创建一个栈帧(Stack Frame)用于存储局部变量表、操作数栈、动态连接、方法出口等信息。每一个方法被调用直至执行完毕的过程,就对应着一个栈帧在虚拟机栈中从入栈到出栈的过程。 经常有人把Java内存区域笼统地划分为堆内存(Heap)和栈内存(Stack),这种划分方式直接继承自传统的C、C++程序的内存布局结构,在Java语言里就显得有些粗糙了,实际的内存区域划分要比这更复杂。不过这种划分方式的流行也间接说明了程序员最关注的、与对象内存分配关系最密切的区域是“堆”和“栈”两块。其中,“堆”在稍后笔者会专门讲述,而“栈”通常就是指这里讲的虚拟机栈,或者更多的情况下只是指虚拟机栈中局部变量表部分。 在《Java虚拟机规范》中,对这个内存区域规定了两类异常状况:如果线程请求的栈深度大于虚拟机所允许的深度,将抛出StackOverflowError异常;如果Java虚拟机栈容量可以动态扩展,当栈扩展时无法申请到足够的内存会抛出OutOfMemoryError异常。

2025年3月15日 · 1 分钟

java代码的运行

Java 代码如何运行 我们写的 Java 代码是高级语言,机器肯定是读不懂的。所以我们需要将它转换成机器能读懂的机器语言 (机器码)。 转换工作主要分为以下几个步骤: 前端编译器 javac 就是前端编译器,可以将 java 文件编译成字节码组成的 class 文件。 java 代码如下: public class Info { public static void main(String[] args) { int a = 1; System.out.println(a); } } 复制代码 执行 javac Info.java 生成 Info.class 文件, 再使用 javap -c Info.class 来查看其中的字节码。 class 中字节码内容如下: 解释器和即时编译器 我们通过 javac 将 java 文件编译成 class 文件,当 jvm 启动加载 class,需要逐条执行字节码指令来完成程序功能。但是程序的执行还是得在机器上,但是机器是不认识字节码的,所以我们需要将字节码转换成机器码,这样才能让机器执行程序。 什么是机器码? 机器码就是用二进制代码表示的计算机能直接识别和执行的一种机器指令的集合。 而解释器和即时编译器 (Just In Time Compiler,JIT) 就是 JVM 中将字节码转化为机器码的工具。 解释器 解释器是一行一行地将字节码解析成机器码,解释到哪就执行到哪,狭义地说,就是 for 循环 100 次,你就要将循环体中的代码逐行解释执行 100 次。当程序需要迅速启动和执行时,解释器可以首先发挥作用,省去编译的时间,立即执行。 ...

2025年3月1日 · 1 分钟

GC Roots

·在虚拟机栈(栈帧中的本地变量表)中引用的对象,譬如各个线程被调用的方法堆栈中使用到的参数、局部变量、临时变量等。 ·在方法区中类静态属性引用的对象,譬如Java类的引用类型静态变量。 ·在方法区中常量引用的对象,譬如字符串常量池(String Table)里的引用。 ·在本地方法栈中JNI(即通常所说的Native方法)引用的对象。 ·Java虚拟机内部的引用,如基本数据类型对应的Class对象,一些常驻的异常对象(比如NullPointExcepiton、OutOfMemoryError)等,还有系统类加载器。 ·所有被同步锁(synchronized关键字)持有的对象。 ·反映Java虚拟机内部情况的JMXBean、JVMTI中注册的回调、本地代码缓存等。 除了这些固定的GC Roots集合以外,根据用户所选用的垃圾收集器以及当前回收的内存区域不同,还可以有其他对象“临时性”地加入,共同构成完整GC Roots集合。譬如后文将会提到的分代收集和局部回收(Partial GC),如果只针对Java堆中某一块区域发起垃圾收集时(如最典型的只针对新生代的垃圾收集),必须考虑到内存区域是虚拟机自己的实现细节(在用户视角里任何内存区域都是不可见的),更不是孤立封闭的,所以某个区域里的对象完全有可能被位于堆中其他区域的对象所引用,这时候就需要将这些关联区域的对象也一并加入GC Roots集合中去,才能保证可达性分析的正确性。 目前最新的几款垃圾收集器 无一例外都具备了局部回收的特征,为了避免GC Roots包含过多对象而过度膨胀,它们在实现上也做出了各种优化处理。

2025年2月15日 · 1 分钟

Exact VM

Exact VM因它使用准确式内存管理(Exact Memory Management,也可以叫Non-Con-servative/Accurate Memory Management)而得名。 准确式内存管理是指虚拟机可以知道内存中某个位置的数据具体是什么类型。 譬如内存中有一个32bit的整数123456,虚拟机将有能力分辨出它到底是一个指向了123456的内存地址的引用类型还是一个数值为123456的整数,准确分辨出哪些内存是引用类型,这也是在垃圾收集时准确判断堆上的数据是否还可能被使用的前提。 由于使用了准确式内存管理,Exact VM可以抛弃掉以前Classic VM基于句柄(Handle)的对象查找方式(原因是垃圾收集后对象将可能会被移动位置,如果地址为123456的对象移动到654321,在没有明确信息表明内存中哪些数据是引用类型的前提下,那虚拟机肯定是不敢把内存中所有为123456的值改成654321的,所以要使用句柄来保持引用值的稳定),这样每次定位对象都少了一次间接查找的开销,显著提升执行性能。

2025年2月1日 · 1 分钟

深入理解jvm

第一部分 走进java 第一章 走进java 1.2 java技术体系 1.3 java发展史 Jigsaw项目:虚拟机层面的模块化支持。 DLL HELL : 模块地狱 1.4 jvm家族 1.4.1 虚拟机始祖:Sun Classic/Exact VM 编译器/解释器/即时编译器 : java代码的运行 Exact VM 使用准确式内存管理(Exact Memory Management,也可以叫Non-Con-servative/Accurate Memory Management) 1.4.2 武林盟主:HotSpot VM HotSpot虚拟机是Sun/OracleJDK和OpenJDK中的默认Java虚拟机,也是目前使用范围最广的Java虚拟机。 1.6 实战:自己编译JDK 1.6.1 获取源码 OpenJDK 12地址 jdk8和jdk8u有什么区别? 1.6.2 系统需求 推荐linux 64位和mac os 64位 查看位数命令: getconf LONG_BIT 第二部分 自动内存管理 第2章 Java内存区域与内存溢出异常 2.2 运行时数据区域 2.2.1 程序计数器 程序计数器(Program Counter Register)是一块较小的内存空间,它可以看作是当前线程所执行的字节码的行号指示器。 2.2.2 Java虚拟机栈 与程序计数器一样,Java虚拟机栈(Java Virtual Machine Stack)也是线程私有的,它的生命周期与线程相同。虚拟机栈描述的是Java方法执行的线程内存模型:每个方法被执行的时候,Java虚拟机都会同步创建一个栈帧 用于存储局部变量表、操作数栈、动态连接、方法出口等信息。每一个方法被调用直至执行完毕的过程,就对应着一个栈帧在虚拟机栈中从入栈到出栈的过程。 ...

2025年1月4日 · 1 分钟

局部变量表

局部变量表存放了编译期可知的各种Java虚拟机基本数据类型(boolean、byte、char、short、int、float、long、double)、对象引用(reference类型,它并不等同于对象本身,可能是一个指向对象起始地址的引用指针,也可能是指向一个代表对象的句柄或者其他与此对象相关的位置)和returnAddress类型(指向了一条字节码指令的地址)。 这些数据类型在局部变量表中的存储空间以局部变量槽(Slot)来表示,其中64位长度的long和double类型的数据会占用两个变量槽,其余的数据类型只占用一个。局部变量表所需的内存空间在编译期间完成分配,当进入一个方法时,这个方法需要在栈帧中分配多大的局部变量空间是完全确定的,在方法运行期间不会改变局部变量表的大小。请读者注意,这里说的“大小”是指变量槽的数量,虚拟机真正使用多大的内存空间(譬如按照1个变量槽占用32个比特、64个比特,或者更多)来实现一个变量槽,这是完全由具体的虚拟机实现自行决定的事情。

2024年12月21日 · 1 分钟

程序计数器

程序计数器(Program Counter Register)是一块较小的内存空间,它可以看作是当前线程所执行的字节码的行号指示器。在Java虚拟机的概念模型里,字节码解释器工作时就是通过改变这个计数器的值来选取下一条需要执行的字节码指令,它是程序控制流的指示器. 由于Java虚拟机的多线程是通过线程轮流切换、分配处理器执行时间的方式来实现的,在任何一个确定的时刻,一个处理器(对于多核处理器来说是一个内核)都只会执行一条线程中的指令。因此,为了线程切换后能恢复到正确的执行位置,每条线程都需要有一个独立的程序计数器,各条线程之间计数器互不影响,独立存储,我们称这类内存区域为“线程私有”的内存。 如果线程正在执行的是一个Java方法,这个计数器记录的是正在执行的虚拟机字节码指令的地址;如果正在执行的是本地(Native)方法,这个计数器值则应为空(Undefined)。此内存区域是唯一一个在《Java虚拟机规范》中没有规定任何OutOfMemoryError情况的区域。

2024年12月7日 · 1 分钟