<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Java归档 - 帝讯博客</title>
	<atom:link href="https://www.dixunblog.cn/tag/java/feed" rel="self" type="application/rss+xml" />
	<link>https://www.dixunblog.cn/tag/java</link>
	<description>致力于打造专业的互联网资讯平台</description>
	<lastBuildDate>Fri, 03 Apr 2026 08:15:22 +0000</lastBuildDate>
	<language>zh-Hans</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=7.0</generator>

<image>
	<url>https://cdn.hyclive.cn/dixunblog/2025/12/cropped-ico-32x32.png</url>
	<title>Java归档 - 帝讯博客</title>
	<link>https://www.dixunblog.cn/tag/java</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>Java Stream API 最佳实践 &#8211; 实战篇</title>
		<link>https://www.dixunblog.cn/1530.html</link>
					<comments>https://www.dixunblog.cn/1530.html#respond</comments>
		
		<dc:creator><![CDATA[小编]]></dc:creator>
		<pubDate>Fri, 03 Apr 2026 06:07:26 +0000</pubDate>
				<category><![CDATA[技术教程]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[代码教程]]></category>
		<guid isPermaLink="false">https://www.dixunblog.cn/1530.html</guid>

					<description><![CDATA[<p>欢迎来到今天的 Java 教程！Stream API 是 Java 8 引入的强大工具。让集合操作更简洁、更高效。</p>
<p>一、Stream 基础</p>
<p>1.1 什么是 Stream<br />
Stream 是数据元素的序列。支持聚合操作：<br />
<code class="language-java">import java.util.*;<br />
i...</p>
<p><a href="https://www.dixunblog.cn/1530.html">Java Stream API 最佳实践 &#8211; 实战篇</a>最先出现在<a href="https://www.dixunblog.cn">帝讯博客</a>。</p>
]]></description>
										<content:encoded><![CDATA[<figure class="wp-block-image">
<img decoding="async" src="https://cdn.hyclive.cn/dixunblog/2026/04/java_stream_api.jpg" alt="Java Stream API" /><figcaption>Java Stream API 操作流程示意图</figcaption></figure>
<p>欢迎来到今天的 Java 教程！Stream API 是 Java 8 引入的强大工具。让集合操作更简洁、更高效。</p>
<h2>一、Stream 基础</h2>
<h3>1.1 什么是 Stream</h3>
<p>Stream 是数据元素的序列。支持聚合操作：</p>
<pre><code class="language-java">import java.util.*;
import java.util.stream.*;

List&lt;String&gt; list = Arrays.asList("Java", "Python", "Go", "Rust");

// 创建 Stream
Stream&lt;String&gt; stream = list.stream();</code></pre>
<h3>1.2 Stream 特点</h3>
<ul>
<li><strong>不存储数据</strong>：只是数据源的视图</li>
<li><strong>不修改源数据</strong>：操作返回新 Stream</li>
<li><strong>惰性求值</strong>：中间操作延迟执行</li>
<li><strong>只能遍历一次</strong>：用完需要重新创建</li>
</ul>
<h2>二、创建 Stream</h2>
<h3>2.1 从集合创建</h3>
<pre><code class="language-java">List&lt;String&gt; list = Arrays.asList("a", "b", "c");

// 方式 1：stream()
list.stream();

// 方式 2：parallelStream()
list.parallelStream();</code></pre>
<h3>2.2 从数组创建</h3>
<pre><code class="language-java">int[] arr = {1, 2, 3, 4, 5};

// 方式 1：Arrays.stream()
IntStream stream = Arrays.stream(arr);

// 方式 2：Stream.of()
Stream&lt;Integer&gt; stream2 = Stream.of(1, 2, 3);</code></pre>
<h3>2.3 生成 Stream</h3>
<pre><code class="language-java">// 无限流（需要 limit）
Stream&lt;Double&gt; randoms = Stream.generate(Math::random);
randoms.limit(5).forEach(System.out::println);

// 迭代流
Stream.iterate(0, n -&gt; n + 2)
      .limit(5)
      .forEach(System.out::println);  // 0, 2, 4, 6, 8</code></pre>
<h2>三、中间操作</h2>
<h3>3.1 过滤（filter）</h3>
<pre><code class="language-java">List&lt;Integer&gt; numbers = Arrays.asList(1, 2, 3, 4, 5, 6);

// 筛选偶数
numbers.stream()
       .filter(n -&gt; n % 2 == 0)
       .forEach(System.out::println);  // 2, 4, 6</code></pre>
<h3>3.2 映射（map）</h3>
<pre><code class="language-java">List&lt;String&gt; words = Arrays.asList("hello", "world");

// 转大写
words.stream()
     .map(String::toUpperCase)
     .forEach(System.out::println);  // HELLO, WORLD

// 提取长度
words.stream()
     .map(String::length)
     .forEach(System.out::println);  // 5, 5</code></pre>
<h3>3.3 扁平化（flatMap）</h3>
<pre><code class="language-java">List&lt;List&lt;Integer&gt;&gt; nested = Arrays.asList(
    Arrays.asList(1, 2),
    Arrays.asList(3, 4),
    Arrays.asList(5, 6)
);

// 扁平化
nested.stream()
      .flatMap(List::stream)
      .forEach(System.out::println);  // 1, 2, 3, 4, 5, 6</code></pre>
<h3>3.4 去重（distinct）</h3>
<pre><code class="language-java">List&lt;Integer&gt; numbers = Arrays.asList(1, 2, 2, 3, 3, 3);

numbers.stream()
       .distinct()
       .forEach(System.out::println);  // 1, 2, 3</code></pre>
<h3>3.5 排序（sorted）</h3>
<pre><code class="language-java">List&lt;Integer&gt; numbers = Arrays.asList(5, 2, 8, 1, 9);

// 自然排序
numbers.stream()
       .sorted()
       .forEach(System.out::println);  // 1, 2, 5, 8, 9

// 自定义排序
numbers.stream()
       .sorted(Comparator.reverseOrder())
       .forEach(System.out::println);  // 9, 8, 5, 2, 1</code></pre>
<h3>3.6 限制（limit, skip）</h3>
<pre><code class="language-java">List&lt;Integer&gt; numbers = Arrays.asList(1, 2, 3, 4, 5);

// 取前 3 个
numbers.stream().limit(3)
       .forEach(System.out::println);  // 1, 2, 3

// 跳过前 2 个
numbers.stream().skip(2)
       .forEach(System.out::println);  // 3, 4, 5

// 组合使用
numbers.stream().skip(1).limit(3)
       .forEach(System.out::println);  // 2, 3, 4</code></pre>
<h2>四、终端操作</h2>
<h3>4.1 遍历（forEach）</h3>
<pre><code class="language-java">List&lt;String&gt; list = Arrays.asList("a", "b", "c");
list.stream().forEach(System.out::println);</code></pre>
<h3>4.2 收集（collect）</h3>
<pre><code class="language-java">List&lt;String&gt; list = Arrays.asList("Java", "Python", "Go");

// 收集到 List
List&lt;String&gt; result = list.stream()
    .filter(s -&gt; s.length() &gt; 3)
    .collect(Collectors.toList());

// 收集到 Set
Set&lt;String&gt; set = list.stream()
    .collect(Collectors.toSet());

// 收集到 String
String joined = list.stream()
    .collect(Collectors.joining(", "));  // "Java, Python, Go"</code></pre>
<h3>4.3 归约（reduce）</h3>
<pre><code class="language-java">List&lt;Integer&gt; numbers = Arrays.asList(1, 2, 3, 4, 5);

// 求和
int sum = numbers.stream()
    .reduce(0, (a, b) -&gt; a + b);  // 15

// 求最大值
Optional&lt;Integer&gt; max = numbers.stream()
    .reduce(Integer::max);  // 5

// 求乘积
int product = numbers.stream()
    .reduce(1, (a, b) -&gt; a * b);  // 120</code></pre>
<h3>4.4 匹配（anyMatch, allMatch, noneMatch）</h3>
<pre><code class="language-java">List&lt;Integer&gt; numbers = Arrays.asList(1, 2, 3, 4, 5);

// 是否有偶数
boolean hasEven = numbers.stream()
    .anyMatch(n -&gt; n % 2 == 0);  // true

// 是否都大于 0
boolean allPositive = numbers.stream()
    .allMatch(n -&gt; n &gt; 0);  // true

// 是否没有负数
boolean noNegative = numbers.stream()
    .noneMatch(n -&gt; n &lt; 0);  // true</code></pre>
<h3>4.5 查找（findAny, findFirst）</h3>
<pre><code class="language-java">List&lt;Integer&gt; numbers = Arrays.asList(1, 2, 3, 4, 5);

// 查找第一个偶数
Optional&lt;Integer&gt; firstEven = numbers.stream()
    .filter(n -&gt; n % 2 == 0)
    .findFirst();  // 2

// 查找任意元素（并行流有用）
Optional&lt;Integer&gt; any = numbers.stream()
    .findAny();</code></pre>
<h3>4.6 统计（count, min, max）</h3>
<pre><code class="language-java">List&lt;Integer&gt; numbers = Arrays.asList(1, 2, 3, 4, 5);

// 计数
long count = numbers.stream().count();  // 5

// 最小值
Optional&lt;Integer&gt; min = numbers.stream().min(Integer::compareTo);

// 最大值
Optional&lt;Integer&gt; max = numbers.stream().max(Integer::compareTo);</code></pre>
<h2>五、数值流</h2>
<h3>5.1 IntStream、LongStream、DoubleStream</h3>
<pre><code class="language-java">List&lt;Integer&gt; numbers = Arrays.asList(1, 2, 3, 4, 5);

// 转换为 IntStream
IntStream intStream = numbers.stream().mapToInt(Integer::intValue);

// 统计信息
IntSummaryStatistics stats = numbers.stream()
    .mapToInt(Integer::intValue)
    .summaryStatistics();

System.out.println("平均值：" + stats.getAverage());  // 3.0
System.out.println("总和：" + stats.getSum());        // 15
System.out.println("最大值：" + stats.getMax());      // 5
System.out.println("最小值：" + stats.getMin());      // 1</code></pre>
<h2>六、分组和分区</h2>
<h3>6.1 分组（groupingBy）</h3>
<pre><code class="language-java">class Person {
    String name;
    int age;
    String city;
    // 构造方法、getter 省略
}

List&lt;Person&gt; people = Arrays.asList(
    new Person("张三", 25, "北京"),
    new Person("李四", 30, "上海"),
    new Person("王五", 25, "北京")
);

// 按年龄分组
Map&lt;Integer, List&lt;Person&gt;&gt; byAge = people.stream()
    .collect(Collectors.groupingBy(Person::getAge));

// 按城市分组
Map&lt;String, List&lt;Person&gt;&gt; byCity = people.stream()
    .collect(Collectors.groupingBy(Person::getCity));</code></pre>
<h3>6.2 分区（partitioningBy）</h3>
<pre><code class="language-java">// 按是否成年分区
Map&lt;Boolean, List&lt;Person&gt;&gt; byAdult = people.stream()
    .collect(Collectors.partitioningBy(p -&gt; p.getAge() &gt;= 18));

// true 分区：所有成年人
// false 分区：所有未成年人</code></pre>
<h2>七、并行流</h2>
<pre><code class="language-java">List&lt;Integer&gt; numbers = IntStream.rangeClosed(1, 1000000)
    .boxed()
    .collect(Collectors.toList());

// 串行流
long start = System.currentTimeMillis();
numbers.stream()
    .mapToInt(Integer::intValue)
    .sum();
System.out.println("串行：" + (System.currentTimeMillis() - start));

// 并行流
start = System.currentTimeMillis();
numbers.parallelStream()
    .mapToInt(Integer::intValue)
    .sum();
System.out.println("并行：" + (System.currentTimeMillis() - start));
</code></pre>
<hr>
<p><em>关注我们获取更多 Java 教程和最佳实践！</em></p>
<p><a href="https://www.dixunblog.cn/1530.html">Java Stream API 最佳实践 &#8211; 实战篇</a>最先出现在<a href="https://www.dixunblog.cn">帝讯博客</a>。</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.dixunblog.cn/1530.html/feed</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>二叉树遍历算法详解 &#8211; 进阶篇</title>
		<link>https://www.dixunblog.cn/1529.html</link>
					<comments>https://www.dixunblog.cn/1529.html#respond</comments>
		
		<dc:creator><![CDATA[小编]]></dc:creator>
		<pubDate>Fri, 03 Apr 2026 06:07:24 +0000</pubDate>
				<category><![CDATA[技术教程]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[代码教程]]></category>
		<guid isPermaLink="false">https://www.dixunblog.cn/1529.html</guid>

					<description><![CDATA[<p>欢迎来到今天的数据结构教程！二叉树遍历是算法面试的必考题，也是实际开发中的基础技能。</p>
<p>一、二叉树基础</p>
<p>1.1 树的定义<br />
二叉树是每个节点最多有两个子节点的树结构：<br />
<code class="language-c">struct TreeNode {<br />
    int val;<br />
    struct TreeNode ...</p>
<p><a href="https://www.dixunblog.cn/1529.html">二叉树遍历算法详解 &#8211; 进阶篇</a>最先出现在<a href="https://www.dixunblog.cn">帝讯博客</a>。</p>
]]></description>
										<content:encoded><![CDATA[<figure class="wp-block-image">
<img decoding="async" src="https://cdn.hyclive.cn/dixunblog/2026/04/binary_tree_traversal.jpg" alt="二叉树遍历算法" /><figcaption>二叉树三种遍历方式示意图</figcaption></figure>
<p>欢迎来到今天的数据结构教程！二叉树遍历是算法面试的必考题，也是实际开发中的基础技能。</p>
<h2>一、二叉树基础</h2>
<h3>1.1 树的定义</h3>
<p>二叉树是每个节点最多有两个子节点的树结构：</p>
<pre><code class="language-c">struct TreeNode {
    int val;
    struct TreeNode *left;
    struct TreeNode *right;
};</code></pre>
<h3>1.2 创建节点</h3>
<pre><code class="language-c">struct TreeNode* createNode(int val) {
    struct TreeNode* node = (struct TreeNode*)malloc(sizeof(struct TreeNode));
    node-&gt;val = val;
    node-&gt;left = NULL;
    node-&gt;right = NULL;
    return node;
}</code></pre>
<h2>二、前序遍历（Preorder）</h2>
<h3>2.1 遍历顺序</h3>
<p><strong>根节点 → 左子树 → 右子树</strong></p>
<h3>2.2 递归实现</h3>
<pre><code class="language-c">void preorderRecursive(struct TreeNode* root) {
    if (root == NULL) return;
    
    printf("%d ", root-&gt;val);           // 访问根节点
    preorderRecursive(root-&gt;left);      // 遍历左子树
    preorderRecursive(root-&gt;right);     // 遍历右子树
}

// 示例：
//       1
//      / \
//     2   3
//    / \
//   4   5
// 输出：1 2 4 5 3</code></pre>
<h3>2.3 迭代实现（使用栈）</h3>
<pre><code class="language-c">#include &lt;stdlib.h&gt;

void preorderIterative(struct TreeNode* root) {
    if (root == NULL) return;
    
    struct TreeNode* stack[100];
    int top = -1;
    
    stack[++top] = root;
    
    while (top &gt;= 0) {
        struct TreeNode* node = stack[top--];
        printf("%d ", node-&gt;val);
        
        // 先压右子树。后压左子树（栈是 LIFO）
        if (node-&gt;right) stack[++top] = node-&gt;right;
        if (node-&gt;left) stack[++top] = node-&gt;left;
    }
}</code></pre>
<h2>三、中序遍历（Inorder）</h2>
<h3>3.1 遍历顺序</h3>
<p><strong>左子树 → 根节点 → 右子树</strong></p>
<h3>3.2 递归实现</h3>
<pre><code class="language-c">void inorderRecursive(struct TreeNode* root) {
    if (root == NULL) return;
    
    inorderRecursive(root-&gt;left);       // 遍历左子树
    printf("%d ", root-&gt;val);           // 访问根节点
    inorderRecursive(root-&gt;right);      // 遍历右子树
}

// 示例（同上树）：4 2 5 1 3
// 重要：二叉搜索树的中序遍历是有序序列！</code></pre>
<h3>3.3 迭代实现</h3>
<pre><code class="language-c">void inorderIterative(struct TreeNode* root) {
    struct TreeNode* stack[100];
    int top = -1;
    struct TreeNode* current = root;
    
    while (current != NULL || top &gt;= 0) {
        // 一直向左
        while (current != NULL) {
            stack[++top] = current;
            current = current-&gt;left;
        }
        
        current = stack[top--];
        printf("%d ", current-&gt;val);
        current = current-&gt;right;
    }
}</code></pre>
<h2>四、后序遍历（Postorder）</h2>
<h3>4.1 遍历顺序</h3>
<p><strong>左子树 → 右子树 → 根节点</strong></p>
<h3>4.2 递归实现</h3>
<pre><code class="language-c">void postorderRecursive(struct TreeNode* root) {
    if (root == NULL) return;
    
    postorderRecursive(root-&gt;left);     // 遍历左子树
    postorderRecursive(root-&gt;right);    // 遍历右子树
    printf("%d ", root-&gt;val);           // 访问根节点
}

// 示例（同上树）：4 5 2 3 1
// 应用：计算树的高度、释放树的内存</code></pre>
<h3>4.3 迭代实现（双栈法）</h3>
<pre><code class="language-c">void postorderIterative(struct TreeNode* root) {
    if (root == NULL) return;
    
    struct TreeNode* stack1[100];
    struct TreeNode* stack2[100];
    int top1 = -1, top2 = -1;
    
    stack1[++top1] = root;
    
    // 第一个栈：根→右→左
    while (top1 &gt;= 0) {
        struct TreeNode* node = stack1[top1--];
        stack2[++top2] = node;
        
        if (node-&gt;left) stack1[++top1] = node-&gt;left;
        if (node-&gt;right) stack1[++top1] = node-&gt;right;
    }
    
    // 第二个栈：左→右→根
    while (top2 &gt;= 0) {
        printf("%d ", stack2[top2--]-&gt;val);
    }
}</code></pre>
<h2>五、层序遍历（Level Order）</h2>
<h3>5.1 遍历顺序</h3>
<p><strong>从上到下。从左到右（使用队列）</strong></p>
<h3>5.2 实现代码</h3>
<pre><code class="language-c">void levelOrder(struct TreeNode* root) {
    if (root == NULL) return;
    
    struct TreeNode* queue[100];
    int front = 0, rear = 0;
    
    queue[rear++] = root;
    
    while (front &lt; rear) {
        int levelSize = rear - front;
        
        for (int i = 0; i &lt; levelSize; i++) {
            struct TreeNode* node = queue[front++];
            printf("%d ", node-&gt;val);
            
            if (node-&gt;left) queue[rear++] = node-&gt;left;
            if (node-&gt;right) queue[rear++] = node-&gt;right;
        }
        printf("\n");  // 每层换行
    }
}

// 示例（同上树）：
// 第 1 层：1
// 第 2 层：2 3
// 第 3 层：4 5</code></pre>
<h2>六、遍历应用</h2>
<h3>6.1 计算树的高度</h3>
<pre><code class="language-c">int maxDepth(struct TreeNode* root) {
    if (root == NULL) return 0;
    
    int leftHeight = maxDepth(root-&gt;left);
    int rightHeight = maxDepth(root-&gt;right);
    
    return (leftHeight &gt; rightHeight ? leftHeight : rightHeight) + 1;
}</code></pre>
<h3>6.2 查找节点</h3>
<pre><code class="language-c">struct TreeNode* search(struct TreeNode* root, int val) {
    if (root == NULL) return NULL;
    if (root-&gt;val == val) return root;
    
    struct TreeNode* leftResult = search(root-&gt;left, val);
    if (leftResult != NULL) return leftResult;
    
    return search(root-&gt;right, val);
}</code></pre>
<h3>6.3 释放树的内存</h3>
<pre><code class="language-c">void freeTree(struct TreeNode* root) {
    if (root == NULL) return;
    
    freeTree(root-&gt;left);
    freeTree(root-&gt;right);
    free(root);  // 后序遍历释放
}</code></pre>
<h2>七、复杂度分析</h2>
<pre><code class="language-text">遍历方式    时间复杂度    空间复杂度
前序        O(n)         O(h)
中序        O(n)         O(h)
后序        O(n)         O(h)
层序        O(n)         O(w)

n = 节点数。h = 树高。w = 最大宽度</code></pre>
<h2>八、总结</h2>
<p>二叉树遍历是数据结构的基础：</p>
<ol>
<li><strong>前序</strong>：复制树、序列化</li>
<li><strong>中序</strong>：二叉搜索树排序</li>
<li><strong>后序</strong>：释放内存、计算高度</li>
<li><strong>层序</strong>：BFS、层次处理</li>
</ol>
<hr>
<p><em>关注我们获取更多数据结构教程！</em></p>
<p><a href="https://www.dixunblog.cn/1529.html">二叉树遍历算法详解 &#8211; 进阶篇</a>最先出现在<a href="https://www.dixunblog.cn">帝讯博客</a>。</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.dixunblog.cn/1529.html/feed</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>C 语言结构体与指针实战 &#8211; 基础篇</title>
		<link>https://www.dixunblog.cn/1528.html</link>
					<comments>https://www.dixunblog.cn/1528.html#respond</comments>
		
		<dc:creator><![CDATA[小编]]></dc:creator>
		<pubDate>Fri, 03 Apr 2026 06:07:23 +0000</pubDate>
				<category><![CDATA[技术教程]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[代码教程]]></category>
		<guid isPermaLink="false">https://www.dixunblog.cn/1528.html</guid>

					<description><![CDATA[<p>欢迎来到今天的 C 语言教程！结构体和指针是 C 语言的核心，掌握它们对理解内存管理至关重要。</p>
<p>一、结构体基础</p>
<p>1.1 结构体定义<br />
结构体允许我们将不同类型的数据组合在一起：<br />
<code class="language-c">#include &#60;stdio.h&#62;<br />
#include &#60;string....</p>
<p><a href="https://www.dixunblog.cn/1528.html">C 语言结构体与指针实战 &#8211; 基础篇</a>最先出现在<a href="https://www.dixunblog.cn">帝讯博客</a>。</p>
]]></description>
										<content:encoded><![CDATA[<figure class="wp-block-image">
<img decoding="async" src="https://cdn.hyclive.cn/dixunblog/2026/04/c_pointer_tutorial.jpg" alt="C 语言结构体与指针" /><figcaption>C 语言结构体与指针示意图</figcaption></figure>
<p>欢迎来到今天的 C 语言教程！结构体和指针是 C 语言的核心，掌握它们对理解内存管理至关重要。</p>
<h2>一、结构体基础</h2>
<h3>1.1 结构体定义</h3>
<p>结构体允许我们将不同类型的数据组合在一起：</p>
<pre><code class="language-c">#include &lt;stdio.h&gt;
#include &lt;string.h&gt;

// 定义学生结构体
struct Student {
    char name[50];
    int age;
    float score;
};

int main() {
    // 创建结构体变量
    struct Student stu1;
    strcpy(stu1.name, "张三");
    stu1.age = 20;
    stu1.score = 95.5;
    
    printf("姓名：%s, 年龄：%d, 成绩：%.1f\n", 
           stu1.name, stu1.age, stu1.score);
    return 0;
}</code></pre>
<h3>1.2 结构体数组</h3>
<pre><code class="language-c">struct Student class[3] = {
    {"张三", 20, 95.5},
    {"李四", 21, 88.0},
    {"王五", 19, 92.5}
};

// 遍历结构体数组
for (int i = 0; i &lt; 3; i++) {
    printf("%s: %.1f 分\n", class[i].name, class[i].score);
}</code></pre>
<h2>二、指针基础</h2>
<h3>2.1 指针定义</h3>
<p>指针存储变量的内存地址：</p>
<pre><code class="language-c">int num = 42;
int *ptr = &amp;num;  // ptr 指向 num 的地址

printf("num 的值：%d\n", num);
printf("num 的地址：%p\n", (void*)&amp;num);
printf("ptr 的值：%p\n", (void*)ptr);
printf("ptr 指向的值：%d\n", *ptr);  // 解引用</code></pre>
<h3>2.2 指针运算</h3>
<pre><code class="language-c">int arr[] = {10, 20, 30, 40, 50};
int *p = arr;  // p 指向数组首元素

printf("%d\n", *p);      // 10
printf("%d\n", *(p+1));  // 20
printf("%d\n", *(p+2));  // 30

// 指针遍历数组
for (int i = 0; i &lt; 5; i++) {
    printf("%d ", *(p+i));
}</code></pre>
<h2>三、结构体指针</h2>
<h3>3.1 指向结构体的指针</h3>
<pre><code class="language-c">struct Student stu = {"张三", 20, 95.5};
struct Student *ptr = &amp;stu;

// 访问结构体成员（两种方式）
printf("%s\n", ptr-&gt;name);  // 推荐：使用箭头运算符
printf("%d\n", (*ptr).age); // 等价。但不常用</code></pre>
<h3>3.2 结构体指针数组</h3>
<pre><code class="language-c">struct Student s1 = {"张三", 20, 95.5};
struct Student s2 = {"李四", 21, 88.0};
struct Student s3 = {"王五", 19, 92.5};

// 指针数组（存储地址。节省内存）
struct Student *students[] = {&amp;s1, &amp;s2, &amp;s3};

for (int i = 0; i &lt; 3; i++) {
    printf("%s: %d 岁\n", students[i]-&gt;name, students[i]-&gt;age);
}</code></pre>
<h2>四、动态内存分配</h2>
<h3>4.1 malloc 和 free</h3>
<pre><code class="language-c">#include &lt;stdlib.h&gt;

// 动态分配结构体内存
struct Student *createStudent(char *name, int age, float score) {
    struct Student *stu = (struct Student*)malloc(sizeof(struct Student));
    strcpy(stu-&gt;name, name);
    stu-&gt;age = age;
    stu-&gt;score = score;
    return stu;
}

int main() {
    struct Student *stu = createStudent("赵六", 22, 90.0);
    printf("%s: %.1f 分\n", stu-&gt;name, stu-&gt;score);
    
    // 释放内存（重要！）
    free(stu);
    return 0;
}</code></pre>
<h3>4.2 动态结构体数组</h3>
<pre><code class="language-c">int n = 5;
struct Student *class = (struct Student*)malloc(n * sizeof(struct Student));

// 使用
for (int i = 0; i &lt; n; i++) {
    sprintf(class[i].name, "学生%d", i+1);
    class[i].age = 20 + i;
}

// 释放
free(class);</code></pre>
<h2>五、链表实现</h2>
<h3>5.1 链表节点定义</h3>
<pre><code class="language-c">struct Node {
    int data;
    struct Node *next;
};

// 创建新节点
struct Node* createNode(int data) {
    struct Node *newNode = (struct Node*)malloc(sizeof(struct Node));
    newNode-&gt;data = data;
    newNode-&gt;next = NULL;
    return newNode;
}</code></pre>
<h3>5.2 插入节点</h3>
<pre><code class="language-c">void insertAtHead(struct Node **head, int data) {
    struct Node *newNode = createNode(data);
    newNode-&gt;next = *head;
    *head = newNode;
}

// 使用
struct Node *head = NULL;
insertAtHead(&amp;head, 30);
insertAtHead(&amp;head, 20);
insertAtHead(&amp;head, 10);
// 链表：10 -&gt; 20 -&gt; 30</code></pre>
<h3>5.3 遍历链表</h3>
<pre><code class="language-c">void printList(struct Node *head) {
    struct Node *current = head;
    while (current != NULL) {
        printf("%d -&gt; ", current-&gt;data);
        current = current-&gt;next;
    }
    printf("NULL\n");
}</code></pre>
<h2>六、常见错误</h2>
<h3>6.1 野指针</h3>
<pre><code class="language-c">// 错误：未初始化的指针
int *ptr;
*ptr = 42;  // 崩溃！

// 正确：初始化或分配内存
int num = 42;
int *ptr = &amp;num;
*ptr = 42;  // OK</code></pre>
<h3>6.2 内存泄漏</h3>
<pre><code class="language-c">// 错误：分配后未释放
struct Student *stu = malloc(sizeof(struct Student));
// ... 使用
// 忘记 free(stu) - 内存泄漏！

// 正确：成对使用 malloc/free
struct Student *stu = malloc(sizeof(struct Student));
// ... 使用
free(stu);  // 释放内存</code></pre>
<h2>七、总结</h2>
<p>结构体和指针是 C 语言的精髓：</p>
<ol>
<li>结构体用于组织相关数据</li>
<li>指针用于直接操作内存</li>
<li>结构体指针结合两者优势</li>
<li>动态内存分配需要手动管理</li>
<li>链表是指针的经典应用</li>
</ol>
<hr>
<p><em>关注我们获取更多 C 语言教程！</em></p>
<p><a href="https://www.dixunblog.cn/1528.html">C 语言结构体与指针实战 &#8211; 基础篇</a>最先出现在<a href="https://www.dixunblog.cn">帝讯博客</a>。</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.dixunblog.cn/1528.html/feed</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Java 基础语法入门：零基础也能看懂的详细教程</title>
		<link>https://www.dixunblog.cn/1287.html</link>
					<comments>https://www.dixunblog.cn/1287.html#respond</comments>
		
		<dc:creator><![CDATA[小编]]></dc:creator>
		<pubDate>Thu, 26 Mar 2026 16:37:35 +0000</pubDate>
				<category><![CDATA[技术教程]]></category>
		<category><![CDATA[编程代码]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Windows教程]]></category>
		<category><![CDATA[代码教程]]></category>
		<guid isPermaLink="false">https://www.dixunblog.cn/1287.html</guid>

					<description><![CDATA[<p>Java 作为最流行的编程语言之一，广泛应用于企业开发、Android 应用、大数据等领域。本文从零开始讲解 Java 基础语法，包括变量、数据类型、运算符、控制流程、数组、方法、面向对象等核心概念，适合零基础初学者。</p>
<p><a href="https://www.dixunblog.cn/1287.html">Java 基础语法入门：零基础也能看懂的详细教程</a>最先出现在<a href="https://www.dixunblog.cn">帝讯博客</a>。</p>
]]></description>
										<content:encoded><![CDATA[<p>Java 作为最流行的编程语言之一，广泛应用于企业开发、Android 应用、大数据等领域。本文将带你从零开始学习 Java 基础语法。</p>
<p><img fetchpriority="high" decoding="async" class="alignnone size-full wp-image-1325" src="http://cdn.hyclive.cn/dixunblog/2026/03/Java-基础语法入门.png" alt="" width="2730" height="1535" /></p>
<h2>一、第一个 Java 程序</h2>
<pre><code class="language-java">public class HelloWorld {
    public static void main(String[] args) {
        System.out.println("Hello, Java!");
    }
}</code></pre>
<p>运行结果：</p>
<pre><code>Hello, Java!</code></pre>
<h3>代码解析：</h3>
<ul>
<li><code>public class</code>：定义公共类，类名必须与文件名一致</li>
<li><code>main 方法</code>：程序入口，JVM 从这里开始执行</li>
<li><code>System.out.println()</code>：控制台输出语句</li>
</ul>
<h2>二、变量与数据类型</h2>
<h3>1. 基本数据类型</h3>
<pre><code class="language-java">public class DataType {
    public static void main(String[] args) {
        // 整数类型
        int age = 25;
        long population = 7_000_000_000L;
        
        // 浮点类型
        double price = 99.99;
        float pi = 3.14f;
        
        // 字符类型
        char grade = 'A';
        
        // 布尔类型
        boolean isJavaFun = true;
        
        System.out.println("年龄：" + age);
        System.out.println("价格：" + price);
        System.out.println("等级：" + grade);
        System.out.println("有趣吗：" + isJavaFun);
    }
}</code></pre>
<h3>2. 引用数据类型</h3>
<pre><code class="language-java">String name = "张三";
String city = "北京";

System.out.println(name + "住在" + city);</code></pre>
<h2>三、运算符</h2>
<h3>1. 算术运算符</h3>
<pre><code class="language-java">int a = 10, b = 3;

System.out.println("a + b = " + (a + b));  // 13
System.out.println("a - b = " + (a - b));  // 7
System.out.println("a * b = " + (a * b));  // 30
System.out.println("a / b = " + (a / b));  // 3 (整数除法)
System.out.println("a % b = " + (a % b));  // 1 (取余)</code></pre>
<h3>2. 关系运算符</h3>
<pre><code class="language-java">int x = 5, y = 10;

System.out.println("x == y: " + (x == y));  // false
System.out.println("x != y: " + (x != y));  // true
System.out.println("x &gt; y: " + (x &gt; y));    // false
System.out.println("x &lt; y: " + (x = 5: " + (x &gt;= 5));  // true</code></pre>
<h3>3. 逻辑运算符</h3>
<pre><code class="language-java">boolean a = true, b = false;

System.out.println("a &amp;&amp; b: " + (a &amp;&amp; b));  // false (与)
System.out.println("a || b: " + (a || b));  // true (或)
System.out.println("!a: " + (!a));          // false (非)</code></pre>
<h2>四、控制流程</h2>
<h3>1. if-else 条件语句</h3>
<pre><code class="language-java">import java.util.Scanner;

public class IfExample {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        System.out.print("请输入你的年龄：");
        int age = scanner.nextInt();
        
        if (age &lt; 18) {
            System.out.println("未成年");
        } else if (age &lt; 60) {
            System.out.println("成年人");
        } else {
            System.out.println("老年人");
        }
        
        scanner.close();
    }
}</code></pre>
<h3>2. switch 语句</h3>
<pre><code class="language-java">public class SwitchExample {
    public static void main(String[] args) {
        int day = 3;
        String dayName;
        
        switch (day) {
            case 1:
                dayName = "星期一";
                break;
            case 2:
                dayName = "星期二";
                break;
            case 3:
                dayName = "星期三";
                break;
            case 4:
                dayName = "星期四";
                break;
            case 5:
                dayName = "星期五";
                break;
            case 6:
            case 7:
                dayName = "周末";
                break;
            default:
                dayName = "无效的日期";
        }
        
        System.out.println("今天是：" + dayName);
    }
}</code></pre>
<h3>3. for 循环</h3>
<pre><code class="language-java">public class ForLoop {
    public static void main(String[] args) {
        // 计算 1 到 100 的和
        int sum = 0;
        for (int i = 1; i &lt;= 100; i++) {
            sum += i;
        }
        System.out.println("1 到 100 的和：" + sum);
        
        // 打印 99 乘法表
        for (int i = 1; i &lt;= 9; i++) {
            for (int j = 1; j &lt;= i; j++) {
                System.out.print(j + "×" + i + "=" + (i*j) + "  ");
            }
            System.out.println();
        }
    }
}</code></pre>
<h3>4. while 循环</h3>
<pre><code class="language-java">public class WhileLoop {
    public static void main(String[] args) {
        int count = 1;
        
        while (count &lt;= 5) {
            System.out.println("第 " + count + " 次循环");
            count++;
        }
        
        // do-while 循环
        int num = 1;
        do {
            System.out.println("至少执行一次：" + num);
            num++;
        } while (num &lt;= 3);
    }
}</code></pre>
<h2>五、数组</h2>
<pre><code class="language-java">public class ArrayExample {
    public static void main(String[] args) {
        // 声明并初始化数组
        int[] numbers = {1, 2, 3, 4, 5};
        
        // 访问数组元素
        System.out.println("第一个元素：" + numbers[0]);
        System.out.println("数组长度：" + numbers.length);
        
        // 遍历数组
        System.out.print("所有元素：");
        for (int i = 0; i &lt; numbers.length; i++) {
            System.out.print(numbers[i] + " ");
        }
        System.out.println();
        
        // 增强型 for 循环
        System.out.print("增强 for：");
        for (int num : numbers) {
            System.out.print(num + " ");
        }
        
        // 二维数组
        int[][] matrix = {
            {1, 2, 3},
            {4, 5, 6},
            {7, 8, 9}
        };
        
        System.out.println("\n二维数组：");
        for (int[] row : matrix) {
            for (int val : row) {
                System.out.print(val + " ");
            }
            System.out.println();
        }
    }
}</code></pre>
<h2>六、方法（函数）</h2>
<pre><code class="language-java">public class MethodExample {
    
    // 无返回值方法
    public static void sayHello(String name) {
        System.out.println("你好，" + name + "！");
    }
    
    // 有返回值方法
    public static int add(int a, int b) {
        return a + b;
    }
    
    // 可变参数
    public static int sum(int... numbers) {
        int total = 0;
        for (int num : numbers) {
            total += num;
        }
        return total;
    }
    
    // 递归方法：计算阶乘
    public static long factorial(int n) {
        if (n == 0 || n == 1) {
            return 1;
        }
        return n * factorial(n - 1);
    }
    
    public static void main(String[] args) {
        sayHello("张三");
        
        int result = add(10, 20);
        System.out.println("10 + 20 = " + result);
        
        System.out.println("1+2+3+4+5 = " + sum(1, 2, 3, 4, 5));
        
        System.out.println("5 的阶乘 = " + factorial(5));
    }
}</code></pre>
<h2>七、面向对象基础</h2>
<h3>1. 类的定义</h3>
<pre><code class="language-java">// 定义一个学生类
class Student {
    // 成员变量
    String name;
    int age;
    String major;
    
    // 构造方法
    public Student(String name, int age, String major) {
        this.name = name;
        this.age = age;
        this.major = major;
    }
    
    // 成员方法
    public void study() {
        System.out.println(name + "正在学习" + major + "专业");
    }
    
    public void introduce() {
        System.out.println("我叫" + name + "，今年" + age + "岁");
    }
}

// 使用类
public class Main {
    public static void main(String[] args) {
        Student s1 = new Student("李四", 20, "计算机科学与技术");
        Student s2 = new Student("王五", 21, "软件工程");
        
        s1.introduce();
        s1.study();
        
        s2.introduce();
        s2.study();
    }
}</code></pre>
<h2>八、实战练习</h2>
<h3>练习 1：猜数字游戏</h3>
<pre><code class="language-java">import java.util.Random;
import java.util.Scanner;

public class GuessNumber {
    public static void main(String[] args) {
        Random random = new Random();
        int target = random.nextInt(100) + 1;
        Scanner scanner = new Scanner(System.in);
        int attempts = 0;
        
        System.out.println("=== 猜数字游戏 ===");
        System.out.println("我已经想好了一个 1-100 之间的数字");
        
        while (true) {
            System.out.print("请猜：");
            int guess = scanner.nextInt();
            attempts++;
            
            if (guess  target) {
                System.out.println("太大了！");
            } else {
                System.out.println("恭喜你猜对了！");
                System.out.println("总共猜了 " + attempts + " 次");
                break;
            }
        }
        
        scanner.close();
    }
}</code></pre>
<h2>总结</h2>
<p>本文涵盖了 Java 基础语法的核心内容：</p>
<ol>
<li>✅ 变量与数据类型</li>
<li>✅ 运算符（算术、关系、逻辑）</li>
<li>✅ 控制流程（if、switch、for、while）</li>
<li>✅ 数组（一维、二维）</li>
<li>✅ 方法定义与调用</li>
<li>✅ 面向对象基础（类与对象）</li>
</ol>
<h3>学习建议：</h3>
<ul>
<li><strong>多敲代码</strong>：把示例代码都亲手敲一遍</li>
<li><strong>多练习</strong>：完成文中的实战练习</li>
<li><strong>理解原理</strong>：不要死记硬背，理解为什么这样写</li>
<li><strong>循序渐进</strong>：基础打牢后再学习高级特性</li>
</ul>
<hr />
<p><strong>下节预告</strong>：《Java 面向对象进阶：继承、封装、多态》</p>
<p><em>如果觉得本文有帮助，欢迎收藏、转发，让更多人看到！有任何问题欢迎在评论区留言讨论。</em></p>
<p><a href="https://www.dixunblog.cn/1287.html">Java 基础语法入门：零基础也能看懂的详细教程</a>最先出现在<a href="https://www.dixunblog.cn">帝讯博客</a>。</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.dixunblog.cn/1287.html/feed</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>这些Java基础知识，诸佬们都还记得嘛(学习，复习，面试都可)</title>
		<link>https://www.dixunblog.cn/1026.html</link>
					<comments>https://www.dixunblog.cn/1026.html#respond</comments>
		
		<dc:creator><![CDATA[老大]]></dc:creator>
		<pubDate>Mon, 29 Dec 2025 08:58:21 +0000</pubDate>
				<category><![CDATA[编程代码]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[代码教程]]></category>
		<guid isPermaLink="false">https://www.dixunblog.cn/?p=1026</guid>

					<description><![CDATA[<p>JVM线程私有和共享的区域 JVM线程私有的区域有：虚拟机栈，本地方法栈，程序计数器。 虚拟机栈：主要存储方法，局部变量，运行的数据。 本地方法栈：主要存储本地方法（含有Native关键字的方法）。 程序计数器：存储程序运行位置的字节码行号指示器。 JVM线程共享的区域有：Java堆，元空间 Java堆：存储所有创建的对象，数组等。 元空间：存储虚拟机加载的字节码数据，常量，静态变量，运行时常量池等。 线程上下文切换 线程上下文切换，也就是CPU不再执行当前的线程，而去执行其他的线程。那有哪些原因会导致线程的上下文</p>
<p><a href="https://www.dixunblog.cn/1026.html">这些Java基础知识，诸佬们都还记得嘛(学习，复习，面试都可)</a>最先出现在<a href="https://www.dixunblog.cn">帝讯博客</a>。</p>
]]></description>
										<content:encoded><![CDATA[<h2 id="2j9bu">JVM线程私有和共享的区域</h2>
<p><strong>JVM线程私有的区域有：</strong><span class="mod-overview__keyword"><strong>虚拟机</strong></span><strong>栈，本地方法栈，程序计数器</strong>。</p>
<p><strong>虚拟机栈</strong>：主要存储方法，局部变量，运行的数据。 <strong>本地方法栈</strong>：主要存储本地方法（<strong>含有Native关键字的方法</strong>）。 <strong>程序计数器</strong>：存储程序运行位置的字节码行号指示器。</p>
<p><strong>JVM线程共享的区域有：</strong><strong>Java</strong><strong>堆，元空间</strong></p>
<p><span class="mod-overview__keyword"><strong>Java</strong></span><strong>堆</strong>：存储所有创建的对象，数组等。 <strong>元空间</strong>：存储虚拟机加载的字节码数据，常量，静态变量，运行时常量池等。</p>
<h2 id="dpqj">线程上下文切换</h2>
<p><strong>线程上下文切换，也就是CPU不再执行当前的线程，而去执行其他的线程</strong>。那有哪些原因会导致线程的上下文切换呢？</p>
<ol class="ol-level-0">
<li>线程的时间片用完</li>
<li>垃圾回收（会暂停当前工作的线程，先进行垃圾回收）</li>
<li>更高优先级的线程运行</li>
<li>线程主动调用了某些方法，如sleep，yeild，wait，join，synchronized，lock等</li>
</ol>
<p>当发生上下文切换时，操作系统会保存当前线程的状态，恢复另一个线程的状态，此时程序计数器会记住下一条jvm指令的执行地址，同时上文记录，<strong>程序计数器是线程私有的</strong>。</p>
<h2 id="cm987">如何判断对象是否存活</h2>
<p>判断对象是否存活有两种方法：<strong>引用计数算法和可达性分析算法</strong>。</p>
<h3 id="e1rcp">引用计数法</h3>
<p>在对象被创建的时候，会在对象头中分配一个空间，即计时器，来保存这个对象被引用的次数。如果这个对象被其他的对象引用，它的引用计数器会+1，如果删除其他对象对这个对象的引用，则它的引用计数会-1，当对象的引用计数为0时，这个对象就会被当成垃圾回收。</p>
<blockquote><p>优点： 引用计数法实现起来比较简单，判断对象是否存活的效率比较高。 缺点： 无法解决对象之间循环引用的问题，不能检测到环的出现。例如，A和B之间相互引用，此时计数器都会显示为1，此时A和B都无法进行垃圾回收。</p></blockquote>
<h3 id="6i7v0">可达性分析法</h3>
<p>Java虚拟机中的垃圾回收机制都是采用的可达性分析算法来探索存活的对象的。此种方法工作原理是会扫描java堆中的对象，沿着<strong>GC Roots对象</strong>往下寻找，看看是否能在此引用链中找到该对象，如果找不到的话，证明该对象没用了，表示该对象可以回收。</p>
<p><strong>可达性分析算法最大的优点之一就是解决了对象之间的相互循环依赖的问题，目前和引用计数法比起来没有缺点</strong>。</p>
<h2 id="3u2us">JVM中的垃圾回收算法</h2>
<p>对于新生代和老年代的对象，在JVM中会采取不同的垃圾回收算法。年轻代的对象一般都是朝生暮死的，创建之后很快就会被回收，而老年代的对象是需要长期存活的，因此用到的算法大不相同。新生代对应的收集方法为“Minor GC”，老年代对应的收集方法称为“Major GC”，而对于整个堆空间和方法区的回收被称为“Full GC”</p>
<p>&nbsp;</p>
<h3 id="15bgg">标记清除算法</h3>
<p>标记清除算法为最基础的垃圾收集算法，即为每个对象都分配一个标记为，这个标记位会记录对象的状态。标记着所要回收的对象，在标记完成后，统一回收掉所有被标记的对象，也可以标记存活的对象，清理掉未标记的对象。<strong>标记清除算法用于老年代的垃圾回收中</strong>。</p>
<blockquote><p>优点： 基于可达性分析算法，实现起来比较简单，后续的算法都是基于这种思想来实现的。 缺点： 影响最大的一点在于，<strong>标记清除算法会使内存空间碎片化</strong>，即标记并清除垃圾后，会产生很多不连续的内存空间，这将导致较大的对象因为无法找到连续的内存而提前触发一次垃圾回收。 <strong>如果大部分对象需要回收，就会进行大量的标记和清除操作，存活对象数量多时效率会降低</strong>。</p></blockquote>
<h3 id="66m77">复制算法</h3>
<p>复制算法被用于新生代的垃圾回收机制中，新生代有三部分，<strong>Eden（80%），和两个survivor区（From Survivor 和 To Survivor）</strong>。两个Survivor区为<strong>容量大小相等的两块内存</strong>，每次只使用其中的一块内存，当使用的那块内存用完后，就会将内存中还存活着的对象复制到另一块内存上，然后把使用过的那块内存空间清空。</p>
<blockquote><p>优点： 实现起来比较简单，效率也比较高，<strong>可以保证内存有连续的区域</strong>，<strong>能够解决标记清除算法导致的内存碎片问题。</strong> 缺点： 可分配的内存空间缩小了一半儿，<strong>代价比较高，内存空间浪费比较多</strong>； 存活的对象比较多的时候使用复制算法将会导致效率降低。 进行标记清除算法时，会导致应用程序挂起（停顿），即stop the world（STW）。</p></blockquote>
<p>扩展： 90%以上的对象都是朝生暮死的，所以在新生代中，每次为对象分配内存时会使用Eden区和其中的一块Survivor区，<strong>当发生垃圾回收时，JVM会将Eden和Survivor中存活的对象都复制到另一块Survivor区域内，之后清理掉Eden区和Survivor区域中的空间</strong>。综上所述，建立新对象时，新生代可用内存空间为整个儿新生代容量的90%（80%的Eden区和10%的Survivor区），如果发生了极少部分情况，即多于10%的对象存活下来了，没有被垃圾回收器回收掉，此时JVM会触发空间担保机制，即当Survivor空间不足以容纳一次Minor GC后的存活对象时，就需要依赖老年代进行分配担保。</p>
<h3 id="8611l">标记整理算法</h3>
<p>标记整理法是对标记清除算法的一个改进。第一个阶段和标记清除算法一样，都是将对象标记为存活和死亡状态，然而在第二阶段，标记清除算法只是将被标记的对象进行清除，标记整理算法会将存活的对象进行整理并且放到另一个端，然后再把所有的对象清除掉。 <strong>标记整理算法用于老年代的回收机制中</strong>。</p>
<blockquote><p>优点： 不会像垃圾清除算法那样产生不连续的内存碎片空间 不会像复制算法那样划分两个区域，提高了空间的利用率 缺点： 效率上肯定更慢一些，因为多了一步整理的操作过程。</p></blockquote>
<h2 id="dm5u5">如何判断变量是否线程安全</h2>
<p>对于成员变量和静态变量</p>
<ul class="ul-level-0">
<li>如果它们没有被共享，则它们是线程安全的；</li>
<li>如果它们被共享了，根据它们的状态是否能够改变，又会分两种情况：如果只有读操作，则它们是线程安全的；如果有读写操作，则这段代码是临界区，是需要考虑线程安全的。</li>
</ul>
<p>对于局部变量是否线程安全</p>
<ul class="ul-level-0">
<li>局部变量是线程安全的</li>
<li>但局部变量引用的对象则未必线程安全。如果该对象没有逃离方法的作用访问，它是线程安全的；如果该对象逃离方法的作用范围，则是需要考虑线程安全的。</li>
</ul>
<h2 id="5j3en">最长递增子序列</h2>
<p>给你一个整数数组 nums ，找到其中最长严格递增子序列的长度。</p>
<p>子序列 是由数组派生而来的序列，删除（或不删除）数组中的元素而不改变其余元素的顺序。例如，[3,6,2,7] 是数组 [0,3,1,6,2,2,7] 的子序列。</p>
<p>示例 1：</p>
<blockquote><p>输入：nums = [10,9,2,5,3,7,101,18] 输出：4 解释：最长递增子序列是 [2,3,7,101]，因此长度为 4 。</p>
<p>示例 2： 输入：nums = [0,1,0,3,2,3] 输出：4</p>
<p>示例 3： 输入：nums = [7,7,7,7,7,7,7] 输出：1</p></blockquote>
<p>思路：该题让求出最长的递增子序列，因此至少需要一次遍历，考虑到代码进行到每一步的状态才可以，所以动态规划法解决此题比较容易。</p>
<p>代码+详解：</p>
<div class="rno-markdown-code">
<div class="rno-markdown-code-toolbar">
<div class="rno-markdown-code-toolbar-info">
<div class="rno-markdown-code-toolbar-item"><span class="is-m-hidden">代码语言：</span>javascript</div>
</div>
<div class="rno-markdown-code-toolbar-opt">
<div class="rno-markdown-code-toolbar-opt-icon-btn is-ai-btn">
<div class="chat-ui-ai-logo css-2jdwfl"></div>
<p>AI代码解释</p>
</div>
</div>
</div>
<div class="developer-code-block">
<div class="rno-markdown-code-opt-float">
<div class="rno-markdown-code-icon-btn qa-r-editor-btn"></div>
</div>
<pre class="prism-token token line-numbers language-javascript" tabindex="0"><code class="language-javascript"><span class="token keyword">class</span> <span class="token class-name">Solution</span> <span class="token punctuation">{</span>
    <span class="token keyword">public</span> int <span class="token function">lengthOfLIS</span><span class="token punctuation">(</span><span class="token parameter">int<span class="token punctuation">[</span><span class="token punctuation">]</span> nums</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token keyword">if</span><span class="token punctuation">(</span>nums<span class="token punctuation">.</span>length<span class="token operator">==</span><span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">{</span>
            <span class="token keyword">return</span> <span class="token number">0</span><span class="token punctuation">;</span> <span class="token comment">//长度为0直接返回0</span>
        <span class="token punctuation">}</span>
        int <span class="token punctuation">[</span><span class="token punctuation">]</span> dp<span class="token operator">=</span><span class="token keyword">new</span> <span class="token class-name">int</span><span class="token punctuation">[</span>nums<span class="token punctuation">.</span>length<span class="token punctuation">]</span><span class="token punctuation">;</span>
        dp<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token operator">=</span><span class="token number">1</span><span class="token punctuation">;</span> <span class="token comment">//初始化数组，也可以调用库函数Arrays.fill(dp,1)，但是效率会慢些</span>
        int result<span class="token operator">=</span><span class="token number">1</span><span class="token punctuation">;</span><span class="token comment">//初始化结果</span>
        <span class="token keyword">for</span><span class="token punctuation">(</span>int i<span class="token operator">=</span><span class="token number">1</span><span class="token punctuation">;</span>i<span class="token operator">&lt;</span>nums<span class="token punctuation">.</span>length<span class="token punctuation">;</span>i<span class="token operator">++</span><span class="token punctuation">)</span><span class="token punctuation">{</span>
            dp<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token operator">=</span><span class="token number">1</span><span class="token punctuation">;</span><span class="token comment">//初始化数组</span>
            <span class="token keyword">for</span><span class="token punctuation">(</span>int j<span class="token operator">=</span><span class="token number">0</span><span class="token punctuation">;</span>j<span class="token operator">&lt;</span>i<span class="token punctuation">;</span>j<span class="token operator">++</span><span class="token punctuation">)</span><span class="token punctuation">{</span>
                <span class="token keyword">if</span><span class="token punctuation">(</span>nums<span class="token punctuation">[</span>j<span class="token punctuation">]</span><span class="token operator">&lt;</span>nums<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">{</span>
                dp<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token operator">=</span>Math<span class="token punctuation">.</span><span class="token function">max</span><span class="token punctuation">(</span>dp<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">,</span>dp<span class="token punctuation">[</span>j<span class="token punctuation">]</span><span class="token operator">+</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">//循环更新dp[i]的最大值</span>
                <span class="token punctuation">}</span>
            <span class="token punctuation">}</span>
            result<span class="token operator">=</span>Math<span class="token punctuation">.</span><span class="token function">max</span><span class="token punctuation">(</span>result<span class="token punctuation">,</span>dp<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token punctuation">}</span>
        <span class="token keyword">return</span> result<span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span></code></pre>
</div>
</div>
<p><a href="https://www.dixunblog.cn/1026.html">这些Java基础知识，诸佬们都还记得嘛(学习，复习，面试都可)</a>最先出现在<a href="https://www.dixunblog.cn">帝讯博客</a>。</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.dixunblog.cn/1026.html/feed</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>
