当前位置: 首页 > news >正文

JVM总结2

1.基本概念

  • java代码执行

    • 代码编译class:javac
      • 源文件通过编译器产生字节码文件,
      • 字节码文件通过jvm的解释器编译成机器上的机器码
    • 装载class:ClassLoader
    • 执行class:
      • 解释执行
      • 编译执行
        • client compiler
        • server compiler
  • 内存管理

    • 内存空间
      • 方法区
      • 方法栈
      • 本地方法栈
      • pc寄存器
    • 内存分配
      • 堆上分配
      • TLAB分配
      • 栈上分配
    • 内存回收
      • 算法
        • copy
        • mark-sweep
        • mark-compact
      • sun jdk
        • 分代回收
          • 新生代可用的GC
            • 串行copying
            • 并行回收copying
            • 并行copying
          • Minor GC触发机制及日志格式
          • 旧生代可用的GC
            • 串行Mark -Sweep-compact
            • 并行compacting
            • 并发mark-sweep
          • Full GC触发机制以及日志格式
        • GC参数
        • G1
    • 内存状况分析
      • jconsole
      • visuaivm
      • jstat
      • jmap
      • mat
  • 线程资源同步和交互机制

    • 线程资源同步
      • 线程资源执行机制
      • 线程资源同步机制
        • Synchronized实现机制
        • lock/unlock的实现机制
    • 线程交互机制
      • Object.wait/notify/notifyAll-Double check pattem
      • 并发包提供的交互机制
        • semaphore
        • countdownLatch
    • 线程状态及分析方法
      • jstack
      • tda
        2.jvm内存
  • 线程私有

    • 程序计数器
      • 指向虚拟机字节码指令的位置
      • 唯一一个无oom的区域
    • 虚拟机栈
      • 虚拟机栈和线程的生命周期相同
      • 一个线程中,每调用一个方法创建一个栈帧
      • 栈帧
        • 本地变量表
        • 操作数栈
        • 对运行时常量池的引用
      • 异常
        • 线程请求的栈深度大于jvm所允许的深度StackOverflowError
        • 若JVM允许动态扩展,若无法申请到足够内存OutOfMemoryError
    • 本地方法栈
      • 异常
        • 线程请求的栈深度大于jvm所允许的深度StackOverflowError
        • 若jvm允许动态扩展,若无法申请到足够内存OutOfmemeryError
  • 线程共享

    • 方法区(永久代)
      • 运行时常量池
    • 类实例区(java堆-运行时数据区)
      • 创建的对象和数组都保存在java堆内存中,也是垃圾收集器进行垃圾收集的最重要的内存区域。
      • 新生代:eden;from survior;to survivor
      • 老生代
      • 异常
  • 直接内存

    • 不受jvm gc管理

3.jvm运行时内存

  • 新生代:占据堆的1/3空间,会频繁触发MinorGC进行垃圾回收
    • Eden区:java对象出生地,当Eden区不够会触发minorGC,对新生代进行一次垃圾回收
    • ServivorFrom:上一次GC的幸存者,作为这一次GC的被扫描者
    • ServivorTo:保留了一次MinorGC过程中的幸存者
    • MinorGC的过程(复制->清空->互换)
      • eden、servivorFrom复制到ServivorTo,年龄+1
      • 清空eden,servivorFrom
      • servivorTo和servivorFrom互换
  • 老年代
    • 存放应用程序中生命周期长的内存对象 。当无法找到足够大的连续空间分配给新创建的较大对象时也会提前触发一次 MajorGC 进行垃圾回收腾出空间。
    • MajorGC(标记清除算法):扫描一次所有老年代,标记存活对象,回收没有标记的对象,会产生内存碎片,为减少内存损耗,一般需要进行合成或者标记出来方便下次直接分配,当老年代也装不下了,抛出oom异常。
  • 永久代:内存的永久保存区域,存放Class和Meta(元数据)的信息。Class被加载时被放到永久区域,和存放实例区域不同,GC不会在主程序运行期对永久区域进行清理,导致永久代区域会随着加载class的增多而胀满,最终抛出oom异常
    • java8与元数据:元空间不在虚拟机中,而是使用本地内存,元空间大小受本地内存的限制,类的元数据放入native memory 字符串池和类的静态变量放入java堆中,这样可以加载多少类的元数据就不再由maxpermSize控制,而由实际可用空间来控制。

4.垃圾回收算法

  • 总结
    • gc
      • 哪些内存需要回收
      • 什么时候回收
      • 怎么回收
    • 哪些对象死亡
      • 引用计数法:循环引用的问题
      • 根搜索算法
        • GC roots:需要经过两次标记,两次标记后仍然是可回收对象,则将面临回收
        • Gc roots(可达性分析)
          • VM栈中的引用
          • 方法区中的静态引用
          • JNI中的引用
    • 垃圾收集算法
      • 标记清除:
        • 标记需回收对象,回收标记的
        • 效率低;内存碎片多
      • 复制:可用内存被压缩到了原本的一半
      • 标记整理:标记后存活对象移向内存一端,清除端边界外的对象
      • 分代收集:根据对象存活的不同生命周期将内存分为不同的域。
        • 新生代与复制算法:eden,from space,to space 8:1:1
        • 老年代和标记复制算法:每次只回收少量对象
    • 垃圾收集器
      • serial;parNew;parallel scavenge;serial old;parallel old;cms
    • 参数
      • Xms;Xmx;Xmn;-XX。。。

5.java四种引用类型

  • 强引用:把一个对象赋给一个引用变量,这个引用变量就是一个强引用。当一个对象被强引用变量引用时,它处于可达状态,它是不可能被垃圾回收机制回收的
  • 软引用:需要用 SoftReference 类来实现,对于只有软引用的对象来说,当系统内存足够时它不会被回收,当系统内存空间不足时它会被回收。软引用通常用在对内存敏感的程序中
  • 弱引用:需要用weakReference类实现,比软引用的生存期更短,对于只有弱引用的对象来说,只要垃圾回收机制一运行,不管jvm的内存空间是否足够,总会回收该对象占用的内存
  • 虚引用:需要用phantomRerence类来实现,不能单独使用,必须和引用队列联合使用,主要作用是跟踪对象被垃圾回收的状态。

6.垃圾收集器

  • Serial垃圾收集器(单线程,复制算法)
  • ParNew垃圾回收器:多线程复制算法,默认开启的cpu数目相同的线程数
  • Parallel scavenge收集器:多线程复制算法,高效。适用于在后台运算二不需要太多交互的任务。
  • Serial old收集器:单线程标记整理算法
    • 与新生代的parallel scavenge收集器搭配使用
    • 作为老年代中使用cms收集器的后备垃圾收集方案
  • parallel old收集器:多线程标记整理算法
  • cms收集器:多线程标记清除算法,主要目标是获取最短垃圾回收停顿时间,多线程清除算法。
    • 初始标记:标记和gc roots 直接关联对象,速度快。
    • 并发标记:进行gc roots 跟踪过程,和用户线程一起工作
    • 重新标记:修正并发标记期间,因用户程序继续运行而导致标记产生变动的那一部分对象的标记记录
    • 并发清除:清除gc roots不可达对象,和用户线程一起工作。
  • G1收集器
    • 基于标记整理算法,不产生内存碎片
    • 精确控制停顿时间,不牺牲吞吐量前提下,实现低停顿垃圾回收。
    • 内存划分为大小固定的几个独立区域,并跟踪这些区域的垃圾收集进度
    • 每次根据所允许的收集时间,优先回收垃圾最多的区域,区域划分和优先级区域回收机制,确保G1收集器可以在有限时间获得最高的垃圾收集效率

7.Java IO/NIO

  • 阻塞IO模型:读写数据过程中会发生阻塞现象。
    • 用户线程发出 IO 请求之后,内核会去查看数据是否就绪,
      • 没有就绪就会等待数据就绪,而用户线程就会处于阻塞状态,用户线程交出 CPU。
      • 当数据就绪之后,内核会将数据拷贝到用户线程,并返回结果给用户线程,用户线程才解除 block 状态。
      • 典型的阻塞 IO 模型的例子为: data = socket.read();如果数据没有就绪,就会一直阻塞在 read 方法
  • 非阻塞IO模型:
    • 当用户线程发起一个 read 操作,不需要等待,马上就得到了一个结果。
      • 如果结果是一个error 时,数据还没有准备好,可以再次发送 read 操作。
      • 内核中的数据准备好了,并又再次收到了用户线程的请求,它马上就将数据拷贝到了用户线程,然后返回。
      • 非阻塞 IO 模型中,用户线程需要不断地询问内核数据是否就绪,非阻塞 IO不会交出 CPU,一直占用 CPU。
      • 问题: while 循环中需要不断地去询问内核数据是否就绪,这样会导致 CPU 占用率非常高,因此一般情况下很少使用 while 循环这种方式来读取数据。
  • 多路复用IO模型:
    • 有一个线程不断去轮询多个 socket 的状态,只有当 socket 真正有读写事件时,才真正调用实际的 IO 读写操作。
    • 通过 selector.select()去查询每个通道是否有到达事件,没有事件,则一直阻塞在那里,这种方式会导致用户线程的阻塞。只有当socket 真正有读写事件发生才会占用资源来进行实际的读写操作。
    • 多路复用 IO 比较适合连接数比较多的情况。
    • 注意:多路复用 IO 模型是通过轮询的方式来检测是否有事件到达,并且对到达的事件逐一进行响应。因此对于多路复用 IO 模型来说, 一旦事件响应体很大,那么就会导致后续的事件迟迟得不到处理,并且会影响新的事件轮询
  • 信号驱动IO模型:
    • 当用户线程发起一个 IO 请求操作,会给对应的 socket 注册一个信号函
      数,用户线程会继续执行,当内核数据就绪时会发送一个信号给用户线程,用户线程接收到信号之后,便在信号函数中调用 IO 读写操作来进行实际的 IO 请求操作
  • 异步IO模型:
    • 用户线程发起 read 操作之后,立刻就可以开始去做其它的事。从内核的角度,当它受到一个 asynchronous read 之后,会立刻返回,说明 read 请求已经成功发起了,因此不会对用户线程产生任何 block。内核会等待数据准备完成,然后将数据拷贝到用户线程,当这一切都完成之后,内核会给用户线程发送一个信号,告诉它 read 操作完成了。
    • 用户线程只需要先发起一个请求,当接收内核返回的成功信号时表示 IO 操作已经完成,可以直接去使用数据了。
    • 异步 IO 模型中, IO 操作的两个阶段都不会阻塞用户线程,这两个阶段都是由内核自动完成,然后发送一个信号告知用户线程操作已完成。用户线程中不需要再次调用 IO 函数进行具体的读写。
      • 在信号驱动模型中,当用户线程接收到信号表示数据已经就绪,然后需要用户线程调用 IO 函数进行实际的读写操作;
      • 在异步 IO 模型中,收到信号表示 IO 操作已经完成,不需要再在用户线程中调用 IO 函数进行实际的读写操作。
  • java NIO
    • 三大核心部分: Channel(通道)、Buffer(缓冲区)、Selector
    • 数据总是从通道读取到缓冲区中,或者从缓冲区写入到通道中。Selector(选择区)用于监听多个通道的事件(比如:连接打开,数据到达)。因此,单个线程可以监听多个数据通道。
    • NIO 和传统 IO 之间区别是, IO 是面向流的, NIO 是面向缓冲区的
    • 缓冲区
      • Java IO 面向流:每次从流中读一个或多个字节,直至读取所有字节,它们没有被缓存在任何地方。此外,它不能前后移动流中的数据。如果需要前后移动从流中读取的数据, 需要先将它缓存到一个缓冲区。
      • NIO :数据读取到一个稍后处理的缓冲区,需要时可在缓冲区中前后移动。增加了处理过程中的灵活性。但是,需检查是否该缓冲区中包含所有需要处理的数据。而且,需确保当更多的数据读入缓冲区时,不要覆盖缓冲区里尚未处理的数据
    • 非阻塞
      • IO 的各种流是阻塞的。当一个线程调用 read() 或 write()时,该线程被阻塞,直到有一些数据被读取,或数据完全写入。该线程在此期间不能再干任何事情了。
      • NIO 的非阻塞模式,使一个线程从某通道发送请求读取数据,但仅能得到目前可用的数据,如果目前没有数据可用时,就什么都不会获取。而不是保持线程阻塞,所以直至数据变的可以读取之前,该线程可以继续做其他的事情。 非阻塞写也是如此。一个线程请求写入一些数据到某通道,但不需要等待它完全写入,这个线程同时可以去做别的事情。 线程通常将非阻塞 IO 的空闲时间用于在其它通道上
        执行 IO 操作,所以一个单独的线程现在可以管理多个输入和输出通道(channel)。
    • channel:Channel 和 IO 中的 Stream(流)是差不多一个等级的。
      • Stream 是单向的: InputStream, OutputStream,
      • Channel 是双向的,既可以用来进行读操作,又可以用来进行写操作。主要实现有:FileChannel、DatagramChannel、SocketChannel、ServerSocketChannel分别可以对应文件 IO、 UDP 和 TCP(Server 和 Client)。
    • Buffer:缓冲区,一个连续数组,channel提供从文件、网络读取数据的渠道,但读取或写入的数据必须经由Buffer。
      • 客户端发送数据先将数据存到Buffer,然后将Buffer中的内容写入通道
      • 服务端接收数据通过Channel将数据读入到Buffer中,然后再从Buffer中取出数据来处理。
    • Selector:能够检测多个注册的通道上是否有事件发生,如果有时间发生,便获取事件然后针对每个事件进行相应的响应处理。一个单线程管理多个通道,管理多个连接。

8.JVM类加载机制

  • 类加载机制:加载,验证,准备,解析,初始化
  • 加载:会在内存中生成一个代表这个类的 java.lang.Class 对象, 作为方法区这个类的各种数据的入口。可以从 ZIP 包中读取(比如从 jar 包和 war 包中读取),也可以在运行时计算生成(动态代理),也可以由其它文件生成(比如将 JSP 文件转换成对应的 Class 类)。
  • 验证:主要目的是为了确保class文件的字节流中包含的信息是否符合当前虚拟机的要求,并且不会危害虚拟机自身安全
  • 准备:正式为类变量分配内存并设置类变量的初始值阶段,即在方法区中分配这些变量所使用的内存空间
  • 解析:虚拟机将常量池中的符号引用替换为直接引用的过程
    • 符号引用:引用的目标并不一定要已经加载到内存中。 各种虚拟机实现的内存布局可以各不相同,
    • 直接引用:指向目标的指针,相对偏移量或是一个能间接定位到目标的句柄。如果有了直接引用,那引用的目标必定已经在内存中存在
  • 初始化:类加载的最后阶段,真正执行类中定义的java程序代码
    • 执行类构造器方法的过程。

9.类加载器

  • 启动类加载器(Bootstrap ClassLoader): 负责加载 JAVA_HOME\lib 目录中的, 或通过-Xbootclasspath 参数指定路径中的, 且被虚拟机认可(按文件名识别, 如 rt.jar) 的类。
  • 扩展类加载器(Extension ClassLoader):负责加载 JAVA_HOME\lib\ext 目录中的,或通过 java.ext.dirs 系统变量指定路径中的类库。
  • 应用程序类加载器(Application ClassLoader):负责加载用户路径(classpath)上的类库。JVM 通过双亲委派模型进行类的加载, 也可以通过继承 java.lang.ClassLoader实现自定义的类加载器。

10.双亲委派

  • 类收到了类加载请求,他首先不会尝试自己去加载这个类,而是把这个请求委派给父类去完成,每一个层次类加载器都是如此,因此所有的加载请求都应该传送到启动类加载其中,
  • 只有当父类加载器反馈自己无法完成这个请求的时候(在它的加载路径下没有找到所需加载的Class), 子类加载器才会尝试自己去加载。
  • 好处是比如加载位于 rt.jar 包中的类 java.lang.Object,不管是哪个加载器加载这个类,最终都是委托给顶层的启动类加载器进行加载,这样就保证了使用不同的类加载器最终得到的都是同样一个 Object 对象

相关文章:

JVM总结2

1.基本概念 java代码执行 代码编译class:javac 源文件通过编译器产生字节码文件,字节码文件通过jvm的解释器编译成机器上的机器码 装载class:ClassLoader执行class: 解释执行编译执行 client compilerserver compiler 内存管理…...

servlet三大类HttpSevlet,HttpServletRequest,HttpServletResponse介绍

一、HttpServlet HttpServlet类是一个被继承的方法,可以看做一个专门用来响应http请求的类,这个类的所有方法都是为响应http请求服务的,要对一个某个路径谁知http响应时,需要写一个类来继承HttpServlet类,并重写里面的…...

【雕爷学编程】Arduino动手做(12)---霍尔模块之霍尔磁感应声光报警器(磁控开关,接220V)

37款传感器与模块的提法,在网络上广泛流传,其实Arduino能够兼容的传感器模块肯定是不止37种的。鉴于本人手头积累了一些传感器和执行器模块,依照实践出真知(一定要动手做)的理念,以学习和交流为目的&#x…...

认识 SQL

文章目录 1.简介2.组成3.工作原理4.五种子语言5.注释方式6.字符串表示方式参考文献 1.简介 SQL(Structured Query Language,结构化查询语言)是一种用于管理和操作关系型数据库的标准化查询语言。它是一种领域特定语言(DSL&#x…...

【剑指Offer 58】翻转单词顺序,Java解密。

LeetCode 剑指Offer 75道练习题 文章目录 剑指Offer:翻转单词顺序示例:限制:解题思路:剑指Offer:翻转单词顺序 【题目描述】 输入一个英文句子,翻转句子中单词的顺序,但单词内字符的顺序不变。为简单起见,标点符号和普通字母一样处理。例如输入字符串"I am a stu…...

微服务Ribbon-负载均衡原理

目录 一、LoadBalancerIntercepor 二、LoadBalancerClient 三、负载均衡策略IRule 四、总结 上一篇中,我们添加了LoadBalanced注解,即可实现负载均衡功能,这是什么原理呢? SpringCloud底层其实是利用了一个名为Ribbon的组件&…...

如何实现Vue的异步组件?如何在Vue中使用本地存储?什么是Vue的指令模块化?

1、如何实现Vue的异步组件&#xff1f; 在Vue中&#xff0c;可以使用异步组件来加载远程数据&#xff0c;或者在组件的生命周期中执行一些耗时操作。实现异步组件&#xff0c;需要使用Vue的异步组件和Vue的组件系统。 下面是一个基本的示例&#xff1a; <template><…...

《HeadFirst设计模式(第二版)》第六章代码——命令模式

代码文件目录&#xff1a; Command package Chapter6_CommandPattern.Command;/*** Author 竹心* Date 2023/8/6**/public interface Command {public void execute();public void undo();//撤销该指令 }CeilingFan package Chapter6_CommandPattern.ElectricAppliance;/*** …...

JS 原型与继承2

//***-、原型、原型链、构造函数 prototype、 proto_、constructor function Foo(){this.a1} var foo new Foo(); Object.getPrototypeOf(foo);//访问对象原型 效果等同于&#xff0c;foo. proto &#xff0c;只是更推荐使用 Es6的 Object.getPrototypeof()方式 // construct…...

账号登录相关的一点随笔

最后更新于2023年8月8日 14:25:32 JWT验证&#xff1a; 简单&#xff1a;一个token验证&#xff1b; 前端发来登录信息&#xff0c;后端验证通过后&#xff0c;将token发回前端&#xff1b; 复杂&#xff1a;Access Token Refresh Token验证&#xff1a; 将Access Token和R…...

常见的一些BUG

常见的一些BUG&#xff0c;但实际上在编写代码时&#xff0c;我们应该尽可能避免这些类型的错误&#xff1a; 变量名与函数名冲突&#xff1a; def main(): print("Hello, World!") main 5 print("The value of main is:", main) 函数参数传递错误&…...

ChatGPT在智能社交网络分析和关系挖掘中的应用如何?

智能社交网络分析和关系挖掘是当今信息时代中的重要研究领域&#xff0c;它们通过运用人工智能、机器学习和数据挖掘技术&#xff0c;从社交网络中提取有价值的信息&#xff0c;洞察用户之间的关系和行为模式。ChatGPT作为一种强大的自然语言处理模型&#xff0c;在智能社交网络…...

你不了解的Dictionary和ConcurrentDictionary

最近在做项目时&#xff0c;多线程中使用Dictionary的全局变量时&#xff0c;发现数据并没有存入到Dictionary中&#xff0c;但是程序也没有报错&#xff0c;经过自己的一番排查&#xff0c;发现Dictionary为非线程安全类型&#xff0c;因此我感觉数据没有写进去的原因是多线程…...

c++类模板,嵌套类模板,模板链表,动态数组

c类模板&#xff0c;嵌套类模板&#xff0c;模板链表&#xff0c;动态数组 一.类模板 1.类模板的书写 代码如下 template<typename T>//模板 class CTest {//类 public:T m_a;CTest(const T&a):m_a(a){}void fun1() {cout << typeid(m_a).name() << …...

【Flutter】【基础】CustomPaint 绘画功能,绘制各种图形(二)

CustomPaint 使用实例和代码&#xff1a; 1.canvas.drawColor 绘制背景颜色 class MyPainter1 extends CustomPainter {overridevoid paint(Canvas canvas, Size size) {//绘制背景颜色&#xff0c;整个UI 现在就是红色的canvas.drawColor(Colors.red, BlendMode.srcATop);}…...

YOLOv5修改注意力机制CBAM

直接上干货 CBAM注意力机制是由通道注意力机制&#xff08;channel&#xff09;和空间注意力机制&#xff08;spatial&#xff09;组成。 传统基于卷积神经网络的注意力机制更多的是关注对通道域的分析&#xff0c;局限于考虑特征图通道之间的作用关系。CBAM从 channel 和 sp…...

计算机网络 网络层 概述

...

算法练习--动态规划 相关

文章目录 走方格的方案 走方格的方案 请计算n*m的棋盘格子&#xff08;n为横向的格子数&#xff0c;m为竖向的格子数&#xff09;从棋盘左上角出发沿着边缘线从左上角走到右下角&#xff0c;总共有多少种走法&#xff0c;要求不能走回头路&#xff0c;即&#xff1a;只能往右和…...

JAVA volatile 关键字

volatile 是JAVA虚拟机提供的轻量级的同步机制&#xff0c;有三大特性 1、保证可见性 2、不保证原子性 3、禁止指令重排 JMM JAVA内存模型本身是一种抽象的概念并不真实存在 它描述的是一组规则或规范&#xff0c;提供这组规范定义了程序中各个变量&#xff08;包括实例变…...

[Leetcode] [Tutorial] 回溯

文章目录 46. 全排列Solution 78. 子集Solution 17. 电话号码的字母组合Solution 39. 组合总和Solution 22. 括号生成Solution 46. 全排列 给定一个不含重复数字的数组 nums &#xff0c;返回其 所有可能的全排列 。你可以 按任意顺序 返回答案。 示例&#xff1a; 输入&…...

dedecms 织梦自定义表单留言增加ajax验证码功能

增加ajax功能模块&#xff0c;用户不点击提交按钮&#xff0c;只要输入框失去焦点&#xff0c;就会提前提示验证码是否正确。 一&#xff0c;模板上增加验证码 <input name"vdcode"id"vdcode" placeholder"请输入验证码" type"text&quo…...

视频字幕质量评估的大规模细粒度基准

大家读完觉得有帮助记得关注和点赞&#xff01;&#xff01;&#xff01; 摘要 视频字幕在文本到视频生成任务中起着至关重要的作用&#xff0c;因为它们的质量直接影响所生成视频的语义连贯性和视觉保真度。尽管大型视觉-语言模型&#xff08;VLMs&#xff09;在字幕生成方面…...

【分享】推荐一些办公小工具

1、PDF 在线转换 https://smallpdf.com/cn/pdf-tools 推荐理由&#xff1a;大部分的转换软件需要收费&#xff0c;要么功能不齐全&#xff0c;而开会员又用不了几次浪费钱&#xff0c;借用别人的又不安全。 这个网站它不需要登录或下载安装。而且提供的免费功能就能满足日常…...

通过MicroSip配置自己的freeswitch服务器进行调试记录

之前用docker安装的freeswitch的&#xff0c;启动是正常的&#xff0c; 但用下面的Microsip连接不上 主要原因有可能一下几个 1、通过下面命令可以看 [rootlocalhost default]# docker exec -it freeswitch fs_cli -x "sofia status profile internal"Name …...

uniapp 实现腾讯云IM群文件上传下载功能

UniApp 集成腾讯云IM实现群文件上传下载功能全攻略 一、功能背景与技术选型 在团队协作场景中&#xff0c;群文件共享是核心需求之一。本文将介绍如何基于腾讯云IMCOS&#xff0c;在uniapp中实现&#xff1a; 群内文件上传/下载文件元数据管理下载进度追踪跨平台文件预览 二…...

如何配置一个sql server使得其它用户可以通过excel odbc获取数据

要让其他用户通过 Excel 使用 ODBC 连接到 SQL Server 获取数据&#xff0c;你需要完成以下配置步骤&#xff1a; ✅ 一、在 SQL Server 端配置&#xff08;服务器设置&#xff09; 1. 启用 TCP/IP 协议 打开 “SQL Server 配置管理器”。导航到&#xff1a;SQL Server 网络配…...

【UE5 C++】通过文件对话框获取选择文件的路径

目录 效果 步骤 源码 效果 步骤 1. 在“xxx.Build.cs”中添加需要使用的模块 &#xff0c;这里主要使用“DesktopPlatform”模块 2. 添加后闭UE编辑器&#xff0c;右键点击 .uproject 文件&#xff0c;选择 "Generate Visual Studio project files"&#xff0c;重…...

xmind转换为markdown

文章目录 解锁思维导图新姿势&#xff1a;将XMind转为结构化Markdown 一、认识Xmind结构二、核心转换流程详解1.解压XMind文件&#xff08;ZIP处理&#xff09;2.解析JSON数据结构3&#xff1a;递归转换树形结构4&#xff1a;Markdown层级生成逻辑 三、完整代码 解锁思维导图新…...

密码学基础——SM4算法

博客主页&#xff1a;christine-rr-CSDN博客 ​​​​专栏主页&#xff1a;密码学 &#x1f4cc; 【今日更新】&#x1f4cc; 对称密码算法——SM4 目录 一、国密SM系列算法概述 二、SM4算法 2.1算法背景 2.2算法特点 2.3 基本部件 2.3.1 S盒 2.3.2 非线性变换 ​编辑…...

Java后端检查空条件查询

通过抛出运行异常&#xff1a;throw new RuntimeException("请输入查询条件&#xff01;");BranchWarehouseServiceImpl.java // 查询试剂交易&#xff08;入库/出库&#xff09;记录Overridepublic List<BranchWarehouseTransactions> queryForReagent(Branch…...