<?xml version='1.0' encoding='UTF-8'?>
<rss xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/" version="2.0"><channel><title>学习日记</title><link>https://Eternal4869.github.io</link><description>CodeNode的学习日记</description><copyright>学习日记</copyright><docs>http://www.rssboard.org/rss-specification</docs><generator>python-feedgen</generator><image><url>https://avatars.githubusercontent.com/u/73345601?v=4</url><title>avatar</title><link>https://Eternal4869.github.io</link></image><lastBuildDate>Mon, 06 Apr 2026 11:11:18 +0000</lastBuildDate><managingEditor>学习日记</managingEditor><ttl>60</ttl><webMaster>学习日记</webMaster><item><title>Spring 高级</title><link>https://Eternal4869.github.io/post/Spring%20-gao-ji.html</link><description>## 容器与 bean

### 1) 容器接口

* BeanFactory 接口，典型功能有：
  * getBean

* ApplicationContext 接口，是 BeanFactory 的子接口。</description><guid isPermaLink="true">https://Eternal4869.github.io/post/Spring%20-gao-ji.html</guid><pubDate>Mon, 06 Apr 2026 11:10:48 +0000</pubDate></item><item><title>Java 框架</title><link>https://Eternal4869.github.io/post/Java%20-kuang-jia.html</link><description># 框架篇

## 1. Spring refresh 流程

**要求**

* 掌握 refresh 的 12 个步骤

**Spring refresh 概述**

refresh 是 AbstractApplicationContext 中的一个方法，负责初始化 ApplicationContext 容器，容器必须调用 refresh 才能正常工作。</description><guid isPermaLink="true">https://Eternal4869.github.io/post/Java%20-kuang-jia.html</guid><pubDate>Sat, 28 Mar 2026 10:22:23 +0000</pubDate></item><item><title>Java 虚拟机</title><link>https://Eternal4869.github.io/post/Java%20-xu-ni-ji.html</link><description># 虚拟机篇

## 1. JVM 内存结构

**要求**

* 掌握 JVM 内存结构划分
* 尤其要知道方法区、永久代、元空间的关系

**结合一段 java 代码的执行理解内存划分**

&lt;img width='960' height='391' alt='Image' src='https://github.com/user-attachments/assets/70ee2bb3-6258-40c0-b5f7-e4b4e7ed671c' /&gt;

* 执行 javac 命令编译源代码为字节码
* 执行 java 命令
  1. 创建 JVM，调用类加载子系统加载 class，将类的信息存入**方法区**
  2. 创建 main 线程，使用的内存区域是 **JVM 虚拟机栈**，开始执行 main 方法代码
  3. 如果遇到了未见过的类，会继续触发类加载过程，同样会存入**方法区**
  4. 需要创建对象，会使用**堆**内存来存储对象
  5. 不再使用的对象，会由**垃圾回收器**在内存不足时回收其内存
  6. 调用方法时，方法内的局部变量、方法参数所使用的是  **JVM 虚拟机栈**中的栈帧内存
  7. 调用方法时，先要到**方法区**获得到该方法的字节码指令，由**解释器**将字节码指令解释为机器码执行
  8. 调用方法时，会将要执行的指令行号读到**程序计数器**，这样当发生了线程切换，恢复时就可以从中断的位置继续
  9. 对于非 java 实现的方法调用，使用内存称为**本地方法栈**（见说明）
  10. 对于热点方法调用，或者频繁的循环代码，由 **JIT 即时编译器**将这些代码编译成机器码缓存，提高执行性能

说明

* 加粗字体代表了 JVM 虚拟机组件
* 对于 Oracle 的 Hotspot 虚拟机实现，不区分虚拟机栈和本地方法栈

**会发生内存溢出的区域**

* 不会出现内存溢出的区域 – 程序计数器
* 出现 OutOfMemoryError 的情况
  * 堆内存耗尽 – 对象越来越多，又一直在使用，不能被垃圾回收
  * 方法区内存耗尽 – 加载的类越来越多，很多框架都会在运行期间动态产生新的类
  * 虚拟机栈累积 – 每个线程最多会占用 1 M 内存，线程个数越来越多，而又长时间运行不销毁时
* 出现 StackOverflowError 的区域
  * JVM 虚拟机栈，原因有方法递归调用未正确结束、反序列化 json 时循环引用

**方法区、永久代、元空间**

* **方法区**是 JVM 规范中定义的一块内存区域，用来存储类元数据、方法字节码、即时编译器需要的信息等
* **永久代**是 Hotspot 虚拟机对 JVM 规范的实现（1.8 之前）
* **元空间**是 Hotspot 虚拟机对 JVM 规范的另一种实现（1.8 以后），使用本地内存作为这些信息的存储空间

&lt;img width='805' height='381' alt='Image' src='https://github.com/user-attachments/assets/67c4abec-b405-4418-8689-ef50565ec62e' /&gt;

从这张图学到三点

* 当第一次用到某个类是，由类加载器将 class 文件的类元信息读入，并存储于元空间
* X，Y 的类元信息是存储于元空间中，无法直接访问
* 可以用 X.class，Y.class 间接访问类元信息，它们俩属于 java 对象，我们的代码中可以使用

&lt;img width='829' height='602' alt='Image' src='https://github.com/user-attachments/assets/4bb4b911-69d9-4041-af9e-9c6613301354' /&gt;

从这张图可以学到

* 堆内存中：当一个**类加载器对象**，这个类加载器对象加载的所有**类对象**，这些类对象对应的所有**实例对象**都没人引用时，GC 时就会对它们占用的对内存进行释放
* 元空间中：内存释放**以类加载器为单位**，当堆中类加载器内存释放时，对应的元空间中的类元信息也会释放



## 2. JVM 内存参数

**要求** 

* 熟悉常见的 JVM 参数，尤其和大小相关的

**堆内存，按大小设置**

&lt;img width='727' height='359' alt='Image' src='https://github.com/user-attachments/assets/54e7c404-cef6-4eda-95a0-ee794a2aab22' /&gt;

解释：

* -Xms 最小堆内存（包括新生代和老年代）
* -Xmx 最大对内存（包括新生代和老年代）
* 通常建议将 -Xms 与 -Xmx 设置为大小相等，即不需要保留内存，不需要从小到大增长，这样性能较好
* -XX:NewSize 与 -XX:MaxNewSize 设置新生代的最小与最大值，但一般不建议设置，由 JVM 自己控制
* -Xmn 设置新生代大小，相当于同时设置了 -XX:NewSize 与 -XX:MaxNewSize 并且取值相等
* 保留是指，一开始不会占用那么多内存，随着使用内存越来越多，会逐步使用这部分保留内存。</description><guid isPermaLink="true">https://Eternal4869.github.io/post/Java%20-xu-ni-ji.html</guid><pubDate>Sat, 28 Mar 2026 10:09:08 +0000</pubDate></item><item><title>Java 并发</title><link>https://Eternal4869.github.io/post/Java%20-bing-fa.html</link><description># 并发篇

## 1. 线程状态

**要求**

* 掌握 Java 线程六种状态
* 掌握 Java 线程状态转换
* 能理解五种状态与六种状态两种说法的区别

**六种状态及转换**

&lt;img width='675' height='472' alt='Image' src='https://github.com/user-attachments/assets/24c54d67-f648-4a35-ba04-226470567f32' /&gt;

分别是

* 新建
  * 当一个线程对象被创建，但还未调用 start 方法时处于**新建**状态
  * 此时未与操作系统底层线程关联
* 可运行
  * 调用了 start 方法，就会由**新建**进入**可运行**
  * 此时与底层线程关联，由操作系统调度执行
* 终结
  * 线程内代码已经执行完毕，由**可运行**进入**终结**
  * 此时会取消与底层线程关联
* 阻塞
  * 当获取锁失败后，由**可运行**进入 Monitor 的阻塞队列**阻塞**，此时不占用 cpu 时间
  * 当持锁线程释放锁时，会按照一定规则唤醒阻塞队列中的**阻塞**线程，唤醒后的线程进入**可运行**状态
* 等待
  * 当获取锁成功后，但由于条件不满足，调用了 wait() 方法，此时从**可运行**状态释放锁进入 Monitor 等待集合**等待**，同样不占用 cpu 时间
  * 当其它持锁线程调用 notify() 或 notifyAll() 方法，会按照一定规则唤醒等待集合中的**等待**线程，恢复为**可运行**状态
* 有时限等待
  * 当获取锁成功后，但由于条件不满足，调用了 wait(long) 方法，此时从**可运行**状态释放锁进入 Monitor 等待集合进行**有时限等待**，同样不占用 cpu 时间
  * 当其它持锁线程调用 notify() 或 notifyAll() 方法，会按照一定规则唤醒等待集合中的**有时限等待**线程，恢复为**可运行**状态，并重新去竞争锁
  * 如果等待超时，也会从**有时限等待**状态恢复为**可运行**状态，并重新去竞争锁
  * 还有一种情况是调用 sleep(long) 方法也会从**可运行**状态进入**有时限等待**状态，但与 Monitor 无关，不需要主动唤醒，超时时间到自然恢复为**可运行**状态

&gt; ***其它情况（只需了解）***
&gt;
&gt; * 可以用 interrupt() 方法打断**等待**、**有时限等待**的线程，让它们恢复为**可运行**状态
&gt; * park，unpark 等方法也可以让线程等待和唤醒

**五种状态**

五种状态的说法来自于操作系统层面的划分

&lt;img width='679' height='479' alt='Image' src='https://github.com/user-attachments/assets/ee958dde-b10b-4ff3-90a6-d6bc35889090' /&gt;

* 运行态：分到 cpu 时间，能真正执行线程内代码的
* 就绪态：有资格分到 cpu 时间，但还未轮到它的
* 阻塞态：没资格分到 cpu 时间的
  * 涵盖了 java 状态中提到的**阻塞**、**等待**、**有时限等待**
  * 多出了阻塞 I/O，指线程在调用阻塞 I/O 时，实际活由 I/O 设备完成，此时线程无事可做，只能干等
* 新建与终结态：与 java 中同名状态类似，不再啰嗦



## 2. 线程池

**要求**

* 掌握线程池的 7 大核心参数

**七大参数**

1. corePoolSize 核心线程数目 - 池中会保留的最多线程数
2. maximumPoolSize 最大线程数目 - 核心线程+救急线程的最大数目
3. keepAliveTime 生存时间 - 救急线程的生存时间，生存时间内没有新任务，此线程资源会释放
4. unit 时间单位 - 救急线程的生存时间单位，如秒、毫秒等
5. workQueue - 当没有空闲核心线程时，新来任务会加入到此队列排队，队列满会创建救急线程执行任务
6. threadFactory 线程工厂 - 可以定制线程对象的创建，例如设置线程名字、是否是守护线程等
7. handler 拒绝策略 - 当所有线程都在繁忙，workQueue 也放满时，会触发拒绝策略
   1. 抛异常 java.util.concurrent.ThreadPoolExecutor.AbortPolicy
   2. 由调用者执行任务 java.util.concurrent.ThreadPoolExecutor.CallerRunsPolicy
   3. 丢弃任务 java.util.concurrent.ThreadPoolExecutor.DiscardPolicy
   4. 丢弃最早排队任务 java.util.concurrent.ThreadPoolExecutor.DiscardOldestPolicy

&lt;img width='796' height='510' alt='Image' src='https://github.com/user-attachments/assets/c754e80d-e69b-4779-8229-946e188d87ed' /&gt;

&gt; ***代码说明***
&gt;
&gt; day02.TestThreadPoolExecutor 以较为形象的方式演示了线程池的核心组成



## 3. wait vs sleep

**要求**

* 能够说出二者区别

**一个共同点，三个不同点**

共同点

* wait() ，wait(long) 和 sleep(long) 的效果都是让当前线程暂时放弃 CPU 的使用权，进入阻塞状态

不同点

* 方法归属不同
  * sleep(long) 是 Thread 的静态方法
  * 而 wait()，wait(long) 都是 Object 的成员方法，每个对象都有

* 醒来时机不同
  * 执行 sleep(long) 和 wait(long) 的线程都会在等待相应毫秒后醒来
  * wait(long) 和 wait() 还可以被 notify 唤醒，wait() 如果不唤醒就一直等下去
  * 它们都可以被打断唤醒

* 锁特性不同（重点）
  * wait 方法的调用必须先获取 wait 对象的锁，而 sleep 则无此限制
  * wait 方法执行后会释放对象锁，允许其它线程获得该对象锁（我放弃 cpu，但你们还可以用）
  * 而 sleep 如果在 synchronized 代码块中执行，并不会释放对象锁（我放弃 cpu，你们也用不了）



## 4. lock vs synchronized

**要求**

* 掌握 lock 与 synchronized 的区别
* 理解 ReentrantLock 的公平、非公平锁
* 理解 ReentrantLock 中的条件变量

**三个层面**

不同点

* 语法层面
  * synchronized 是关键字，源码在 jvm 中，用 c++ 语言实现
  * Lock 是接口，源码由 jdk 提供，用 java 语言实现
  * 使用 synchronized 时，退出同步代码块锁会自动释放，而使用 Lock 时，需要手动调用 unlock 方法释放锁
* 功能层面
  * 二者均属于悲观锁、都具备基本的互斥、同步、锁重入功能
  * Lock 提供了许多 synchronized 不具备的功能，例如获取等待状态、公平锁、可打断、可超时、多条件变量
  * Lock 有适合不同场景的实现，如 ReentrantLock， ReentrantReadWriteLock
* 性能层面
  * 在没有竞争时，synchronized 做了很多优化，如偏向锁、轻量级锁，性能不赖
  * 在竞争激烈时，Lock 的实现通常会提供更好的性能

**公平锁**

* 公平锁的公平体现
  * **已经处在阻塞队列**中的线程（不考虑超时）始终都是公平的，先进先出
  * 公平锁是指**未处于阻塞队列**中的线程来争抢锁，如果队列不为空，则老实到队尾等待
  * 非公平锁是指**未处于阻塞队列**中的线程来争抢锁，与队列头唤醒的线程去竞争，谁抢到算谁的
* 公平锁会降低吞吐量，一般不用

**条件变量**

* ReentrantLock 中的条件变量功能类似于普通 synchronized 的 wait，notify，用在当线程获得锁后，发现条件不满足时，临时等待的链表结构
* 与 synchronized 的等待集合不同之处在于，ReentrantLock 中的条件变量可以有多个，可以实现更精细的等待、唤醒控制

&gt; ***代码说明***
&gt;
&gt; * day02.TestReentrantLock 用较为形象的方式演示 ReentrantLock 的内部结构



## 5. volatile

**要求**

* 掌握线程安全要考虑的三个问题
* 掌握 volatile 能解决哪些问题

**原子性**

* 起因：多线程下，不同线程的**指令发生了交错**导致的共享变量的读写混乱
* 解决：用悲观锁或乐观锁解决，volatile 并不能解决原子性

**可见性**

* 起因：由于**编译器优化、或缓存优化、或 CPU 指令重排序优化**导致的对共享变量所做的修改另外的线程看不到
* 解决：用 volatile 修饰共享变量，能够防止编译器等优化发生，让一个线程对共享变量的修改对另一个线程可见

**有序性**

* 起因：由于**编译器优化、或缓存优化、或 CPU 指令重排序优化**导致指令的实际执行顺序与编写顺序不一致
* 解决：用 volatile 修饰共享变量会在读、写共享变量时加入不同的屏障，阻止其他读写操作越过屏障，从而达到阻止重排序的效果
* 注意：
  * **volatile 变量写**加的屏障是阻止上方其它写操作越过屏障排到 **volatile 变量写**之下
  * **volatile 变量读**加的屏障是阻止下方其它读操作越过屏障排到 **volatile 变量读**之上
  * volatile 读写加入的屏障只能防止同一线程内的指令重排

&gt; ***代码说明***
&gt;
&gt; * day02.threadsafe.AddAndSubtract 演示原子性
&gt; * day02.threadsafe.ForeverLoop 演示可见性
&gt;   * 注意：本例经实践检验是编译器优化导致的可见性问题
&gt; * day02.threadsafe.Reordering 演示有序性
&gt;   * 需要打成 jar 包后测试
&gt; * 请同时参考视频讲解



## 6. 悲观锁 vs 乐观锁

**要求**

* 掌握悲观锁和乐观锁的区别

**对比悲观锁与乐观锁**

* 悲观锁的代表是 synchronized 和 Lock 锁
  * 其核心思想是【线程只有占有了锁，才能去操作共享变量，每次只有一个线程占锁成功，获取锁失败的线程，都得停下来等待】
  * 线程从运行到阻塞、再从阻塞到唤醒，涉及线程上下文切换，如果频繁发生，影响性能
  * 实际上，线程在获取 synchronized 和 Lock 锁时，如果锁已被占用，都会做几次重试操作，减少阻塞的机会

* 乐观锁的代表是 AtomicInteger，使用 cas 来保证原子性
  * 其核心思想是【无需加锁，每次只有一个线程能成功修改共享变量，其它失败的线程不需要停止，不断重试直至成功】
  * 由于线程一直运行，不需要阻塞，因此不涉及线程上下文切换
  * 它需要多核 cpu 支持，且线程数不应超过 cpu 核数

&gt; ***代码说明***
&gt;
&gt; * day02.SyncVsCas 演示了分别使用乐观锁和悲观锁解决原子赋值
&gt; * 请同时参考视频讲解



## 7. Hashtable vs ConcurrentHashMap

**要求**

* 掌握 Hashtable 与 ConcurrentHashMap 的区别
* 掌握 ConcurrentHashMap 在不同版本的实现区别

&gt; 更形象的演示，见资料中的 hash-demo.jar，运行需要 jdk14 以上环境，进入 jar 包目录，执行下面命令
&gt;
&gt; ```
&gt; java -jar --add-exports java.base/jdk.internal.misc=ALL-UNNAMED hash-demo.jar
&gt; ```

**Hashtable 对比 ConcurrentHashMap**

* Hashtable 与 ConcurrentHashMap 都是线程安全的 Map 集合
* Hashtable 并发度低，整个 Hashtable 对应一把锁，同一时刻，只能有一个线程操作它
* ConcurrentHashMap 并发度高，整个 ConcurrentHashMap 对应多把锁，只要线程访问的是不同锁，那么不会冲突

**ConcurrentHashMap 1.7**

* 数据结构：`Segment(大数组) + HashEntry(小数组) + 链表`，每个 Segment 对应一把锁，如果多个线程访问不同的 Segment，则不会冲突
* 并发度：Segment 数组大小即并发度，决定了同一时刻最多能有多少个线程并发访问。</description><guid isPermaLink="true">https://Eternal4869.github.io/post/Java%20-bing-fa.html</guid><pubDate>Sat, 28 Mar 2026 09:47:31 +0000</pubDate></item><item><title>Java 基础</title><link>https://Eternal4869.github.io/post/Java%20-ji-chu.html</link><description># 基础篇

&gt; ***基础篇要点：算法、数据结构、基础设计模式***

## 1. 二分查找

**要求**

* 能够用自己语言描述二分查找算法
* 能够手写二分查找代码
* 能够解答一些变化后的考法

**算法描述**

1. 前提：有已排序数组 A（假设已经做好）

2. 定义左边界 L、右边界 R，确定搜索范围，循环执行二分查找（3、4两步）

3. 获取中间索引 M = Floor((L+R) /2)

4. 中间索引的值  A[M] 与待搜索的值 T 进行比较

   ① A[M] == T 表示找到，返回中间索引

   ② A[M] &gt; T，中间值右侧的其它元素都大于 T，无需比较，中间索引左边去找，M - 1 设置为右边界，重新查找

   ③ A[M] &lt; T，中间值左侧的其它元素都小于 T，无需比较，中间索引右边去找， M + 1 设置为左边界，重新查找

5. 当 L &gt; R 时，表示没有找到，应结束循环

&gt; *更形象的描述请参考：binary_search.html*

**算法实现**

```java
public static int binarySearch(int[] a, int t) {
    int l = 0, r = a.length - 1, m;
    while (l &lt;= r) {
        m = (l + r) / 2;
        if (a[m] == t) {
            return m;
        } else if (a[m] &gt; t) {
            r = m - 1;
        } else {
            l = m + 1;
        }
    }
    return -1;
}
```

**测试代码**

```java
public static void main(String[] args) {
    int[] array = {1, 5, 8, 11, 19, 22, 31, 35, 40, 45, 48, 49, 50};
    int target = 47;
    int idx = binarySearch(array, target);
    System.out.println(idx);
}
```

**解决整数溢出问题**

当 l 和 r 都较大时，`l + r` 有可能超过整数范围，造成运算错误，解决方法有两种：

```java
int m = l + (r - l) / 2;
```

还有一种是：

```java
int m = (l + r) &gt;&gt;&gt; 1;
```

**其它考法**

1. 有一个有序表为 1,5,8,11,19,22,31,35,40,45,48,49,50 当二分查找值为 48 的结点时，查找成功需要比较的次数 

2. 使用二分法在序列 1,4,6,7,15,33,39,50,64,78,75,81,89,96 中查找元素 81 时，需要经过（   ）次比较

3. 在拥有128个元素的数组中二分查找一个数，需要比较的次数最多不超过多少次

对于前两个题目，记得一个简要判断口诀：奇数二分取中间，偶数二分取中间靠左。</description><guid isPermaLink="true">https://Eternal4869.github.io/post/Java%20-ji-chu.html</guid><pubDate>Sat, 28 Mar 2026 09:40:43 +0000</pubDate></item><item><title>Java basic</title><link>https://Eternal4869.github.io/post/Java%20basic.html</link><description>[Java八股.pdf](https://github.com/user-attachments/files/25562849/Java.pdf)。</description><guid isPermaLink="true">https://Eternal4869.github.io/post/Java%20basic.html</guid><pubDate>Thu, 26 Feb 2026 03:05:03 +0000</pubDate></item><item><title>容器接口（未完）</title><link>https://Eternal4869.github.io/post/rong-qi-jie-kou-%EF%BC%88-wei-wan-%EF%BC%89.html</link><description># `BeanFactory` 和 `ApplicationContext` 之间的关系

- `BeanFactory` 是 Spring的核心容器。</description><guid isPermaLink="true">https://Eternal4869.github.io/post/rong-qi-jie-kou-%EF%BC%88-wei-wan-%EF%BC%89.html</guid><pubDate>Mon, 22 Sep 2025 11:56:47 +0000</pubDate></item><item><title>MFC ActiveX 微软官方文档</title><link>https://Eternal4869.github.io/post/MFC%20ActiveX%20-wei-ruan-guan-fang-wen-dang.html</link><description>https://learn.microsoft.com/zh-cn/cpp/mfc/mfc-activex-controls?view=msvc-170。</description><guid isPermaLink="true">https://Eternal4869.github.io/post/MFC%20ActiveX%20-wei-ruan-guan-fang-wen-dang.html</guid><pubDate>Sat, 30 Aug 2025 14:49:47 +0000</pubDate></item><item><title>QT-Lambda表达式</title><link>https://Eternal4869.github.io/post/QT-Lambda-biao-da-shi.html</link><description># QT-Lambda表达式

##  lambda表达式构成

&gt; [函数对象参数](操作符重载函数参数)mutable -&gt; 返回值 {函数体}

```C++
[capture](parameter) mutable -&gt; return-type
{
    statement
}
```

- `[]`: 标识Lambda表达式的开始，这部分必须存在，不能省略。</description><guid isPermaLink="true">https://Eternal4869.github.io/post/QT-Lambda-biao-da-shi.html</guid><pubDate>Sat, 17 May 2025 10:56:53 +0000</pubDate></item><item><title>QT-QT4的信号连接方式</title><link>https://Eternal4869.github.io/post/QT-QT4-de-xin-hao-lian-jie-fang-shi.html</link><description># QT-QT4的信号连接方式

## 连接方式

```C++
connect(信号的发送者, SIGNAL(信号函数), 信号接收者, SLOT(槽函数));
```

## 优缺点

- 优点: 参数直观。</description><guid isPermaLink="true">https://Eternal4869.github.io/post/QT-QT4-de-xin-hao-lian-jie-fang-shi.html</guid><pubDate>Sat, 17 May 2025 09:47:35 +0000</pubDate></item><item><title>QT-信号连接信号</title><link>https://Eternal4869.github.io/post/QT--xin-hao-lian-jie-xin-hao.html</link><description># QT-信号连接信号

&gt; 窗口有一个按钮，按钮点击（信号）触发下课函数（信号），下课函数触发老师饿了，老师饿了，学生请客。</description><guid isPermaLink="true">https://Eternal4869.github.io/post/QT--xin-hao-lian-jie-xin-hao.html</guid><pubDate>Sat, 17 May 2025 09:41:09 +0000</pubDate></item><item><title>QT-自定义信号和槽的重载问题</title><link>https://Eternal4869.github.io/post/QT--zi-ding-yi-xin-hao-he-cao-de-zhong-zai-wen-ti.html</link><description># QT-自定义信号和槽的重载问题

&gt; 当自定义的信号和槽发生重载时，会引发编译问题。</description><guid isPermaLink="true">https://Eternal4869.github.io/post/QT--zi-ding-yi-xin-hao-he-cao-de-zhong-zai-wen-ti.html</guid><pubDate>Sun, 11 May 2025 11:45:28 +0000</pubDate></item><item><title>QT-自定义的信号和槽</title><link>https://Eternal4869.github.io/post/QT--zi-ding-yi-de-xin-hao-he-cao.html</link><description># QT-自定义的信号和槽

&gt; 实现该需求: 下课后，老师饿了，学生请客。</description><guid isPermaLink="true">https://Eternal4869.github.io/post/QT--zi-ding-yi-de-xin-hao-he-cao.html</guid><pubDate>Sun, 11 May 2025 09:14:49 +0000</pubDate></item><item><title>QT-信号和槽</title><link>https://Eternal4869.github.io/post/QT--xin-hao-he-cao.html</link><description># QT-信号与槽

&gt; connect(信号的发送者, 信号, 信号的接收者, 信号的处理-槽函数);

信号槽的优点:
- 松散耦合: 信号发送端和接收端本身并无关联，通过 `connect()` 函数将两端耦合在一起。</description><guid isPermaLink="true">https://Eternal4869.github.io/post/QT--xin-hao-he-cao.html</guid><pubDate>Sun, 11 May 2025 08:36:10 +0000</pubDate></item><item><title>QT-初识</title><link>https://Eternal4869.github.io/post/QT--chu-shi.html</link><description># QT项目下的文件

&gt;QT creator创建的 `.pro` 文件并未列出

1. 头文件 
 
- `mywidget.h`

```C++
#ifndef MYWIDGET_H
#define MYWIDGET_H

#include &lt;QWidget&gt;

class myWidget : public QWidget
{
    Q_OBJECT

public:
    myWidget(QWidget *parent = nullptr);
    ~myWidget();
};
#endif // MYWIDGET_H
```

2. 源文件

- `main.cpp`

```C++
#include 'mywidget.h'

#include &lt;QApplication&gt;

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    // window
    myWidget w;
    // make window shown
    w.show();
    // make a into cycle
    return a.exec();
}
```

- `mywidget.cpp`

```C++
#include 'mywidget.h'
#include &lt;QPushButton&gt;

myWidget::myWidget(QWidget *parent)
    : QWidget(parent)
{
    // 创建按钮
    QPushButton *button = new QPushButton;
    // 设置父窗口
    button-&gt;setParent(this);
    // 设置文本
    button-&gt;setText('Hello');
    QPushButton *button2 = new QPushButton('Second', this);
    // 移动按钮
    button2-&gt;move(400, 300);
    // 设置窗口大小（mywidget的大小）
    // resize(500, 400);
    // 设置窗口为固定大小（不可伸缩）
    setFixedSize(800, 500);
    // 设置窗口标题
    setWindowTitle(' ');
    // 设置窗口为无边框样式
    setWindowFlags(Qt::FramelessWindowHint);
    // 移动窗口至 `0, 0` 的位置
    this-&gt;move(0,0);
}

myWidget::~myWidget() {}
```。</description><guid isPermaLink="true">https://Eternal4869.github.io/post/QT--chu-shi.html</guid><pubDate>Sun, 11 May 2025 03:23:21 +0000</pubDate></item><item><title>亻尔女子月月友</title><link>https://Eternal4869.github.io/post/ren-er-nv-zi-yue-yue-you.html</link><description>Test  Documentation.。</description><guid isPermaLink="true">https://Eternal4869.github.io/post/ren-er-nv-zi-yue-yue-you.html</guid><pubDate>Thu, 11 Jul 2024 01:39:54 +0000</pubDate></item></channel></rss>