JVM--垃圾回收
垃圾回收的概念
垃圾回收主要针对的是堆中的对象,堆是一个共享的区域,创建的对象和数组都放在这个位置。但是我们不能一直的创建对象,也不是所有的对象能一直存放,如果不进行垃圾回收,内存迟早会耗尽,及时的垃圾回收能提高内存的利用率以及存储效率。
什么样的对象进行垃圾回收?
如果一个或多个对象没有任何的引用指向它了,那么这个对象现在就是垃圾,如果定位了垃圾,则有可能会被垃圾回收器回收。
如何定位垃圾?
引用计数法:一个对象被引用了一次,在当前对象头上递增一次引用次数,如果这个对象的引用次数为0,代表这个对象可以回收。
在创建对象时,对象对应的引用次数为1,如果后续给对象赋值NULL,则对象的引用次数会变为0,此时表明当前的对象是可以被垃圾回收的。
当对象间出现了循环引用时,引用计数法就会失效。会导致内存泄露
创建a和b之后,并且创建的对象之间有循环引用,则两个对象的堆内存的ref初始值为2,在设置对象a和b为null后,由于循环引用的存在,内存区域的ref为1,导致这两块内存区域一直不能回收
可达性分析算法
现在的虚拟机采用的都是通过可达性分析算法来确定哪些内容是垃圾。
- Java虚拟机中的垃圾回收器采用可达性分析来探索所有存活的对象
- 可达性算法的流程:扫描堆中的对象,看是否能够沿着GCRoot对象为起点的引用链找到该对象,找不到,表示可以回收
如上图所示,由于从GC Roots开始沿着引用链进行寻找,并不能找到X 和 Y,因此X和Y可以回收
哪些对象可以作为GC Root呢?
1.虚拟机栈(栈帧中的本地变量表)中引用的对象
2.方法区中类静态属性引用的对象
3.方法区中常量引用的对象
4.本地方法栈中JNI(即一般说的Native方法)引用的对象
垃圾回收算法
JVM垃圾回收算法有哪些?
标记清除算法
将垃圾回收分为2个阶段,分别是标记和清除。
1.根据可达性分析算法得出的垃圾进行标记
2.对这些标记为可回收的内容进行垃圾回收
标记清除算法的优缺点
优点:标记和清除的速度很快
缺点:碎片化较为严重,内存不连贯
复制算法
1.将内存划分为两个区域根据可达性分析算法得出的垃圾进行标记
2.将存活的对象复制到另一块内存区域。然后清理边界以外的垃圾
复制算法的优缺点
优点:在垃圾对象多的情况下,效率较高。清理后,内存无碎片。
缺点:分配的2块内存空间,在同一时刻,只能使用1个,内存的使用率较低
标记整理算法
1.根据可达性分析算法得出的垃圾进行标记
2.对这些标记为可回收的内容进行垃圾回收
3.清除之后,将存活的对象进行整理,向一端移动,然后清理边界意外的垃圾
优缺点同标记清除算法,解决了标记清除算法的碎片化的问题,同时,标记压缩算法多了一步,对象移动内存位置的步骤,其效率也有有一定的影响。
JVM的分代回收
堆的区域划分
在java8时,堆被分为了两份:新生代和老年代【1:2]
对于新生代,内部又被分为了三个区域。
- 伊甸园区Eden,新生的对象都分配到这里
- 幸存者区survivor(分成from和to)
Eden区,from区,to区[8:1:1]
对象回收分代回收策略
- 新创建的对象,都会先分配到eden区
- 当伊甸园内存不足,标记伊甸园与from(现阶段没有)的存活对象
- 将存活对象采用复制算法复制到to中,复制完毕后,伊甸园和from内存都得到释放
- 经过一段时间后伊甸园的内存又出现不足,标记eden区域to区存活的对象,将存活的对象复制from区
- 当幸存区对象熬过几次回收(最多15次),晋升到老年代(幸存区内存不足或大对象会导致提前晋升)
MinorGC、Mixed GC、FulIGC的区别是什么?
MinorGC【youngGC】:发生在新生代的垃圾回收,暂停时间短(STW)
MixedGC:新生代+老年代部分区域的垃圾回收,G1收集器特有
FulIGC:新生代+老年代完整垃圾回收,暂停时间长(STW),应尽力避免
STW(Stop-The-World):暂停所有应用程序线程,等待垃圾回收的完战
JVM中的垃圾回收器
在jvm中,实现了多种垃圾收集器,包括:
- 串行垃圾收集器:Serial GC、Serial Old GC
- 并行垃圾收集器:Parallel Old GC、ParNew GC
- CMS(并发)垃圾收集器:CMSGC,作用在老年代
- G1垃圾收集器,作用在新生代和老年代
串行垃圾回收器
- Serial和SerialOld串行垃圾收集器,是指使用单线程进行垃圾回收,堆内存较小,适合个人电脑
- Serial 作用于新生代,采用复制算法
- SerialOld 作用于老年代,采用标记-整理算法
- 垃圾回收时,只有一个线程在工作,并且java应用中的所有线程都要暂停(STW),等待垃圾回收的完成。
并行垃圾收集器
- ParallelNew和ParallelOld是一个并行垃圾回收器,JDK8默认使用此垃圾回收器
- ParallelNew 作用于新生代,采用复制算法
- ParallelOld 作用于老年代,采用标记-整理算法
- 垃圾回收时,多个线程在工作,并且java应用中的所有线程都要暂停(STW),等待垃圾回收的完成。
CMS(并发)垃圾收集器
CMS全称ConcurrentMarkSweep,是一款并发的、使用标记-清除算法的垃圾回收器,该回收器是
针对老年代垃圾回收的,是一款以获取最短回收停顿时间为目标的收集器,停顿时间短,用户体验
就好。其最大特点是在进行垃圾回收时,应用仍然能正常运行。
为什么要进行重新标记?
可能出现一种情况,当X一开始没有在引用链上,但是在并发标记期间,某个对象对X引用,此时就不能对X进行回收,因此需要重新标记。
G1垃圾回收器
- 应用于新生代和老年代,在JDK9之后默认使用G1
- 划分成多个区域,每个区域都可以充当eden,survivor,old,humongous,其中humongous专为大对象准备
- 采用复制算法
- 响应时间与吞吐量兼顾
- 分成三个阶段:新生代回收(stw)、并发标记(重新标记stw)、混合收集
- 如果并发失败(即回收速度赶不上创建新对象速度),会触发FullGC
垃圾回收的流程
YoungCollection(年轻代垃圾回收)
1.初始时,所有区域都处于空闲状态
2.创建了一些对象,挑出一些空闲区域作为伊甸园区存储这些对象
3.当伊甸园需要垃圾回收时,挑出一个空闲区域作为幸存区,用复制算法复制存活对象,需要暂停用户线程
在标记的过程中或者是在复制的过程中,都需要触发STW
4.随着时间流逝,伊甸园的内存又有不足,将伊甸园以及之前幸存区中的存活对象,采用复制算法,复制到新的幸存区,其中较老对象晋升至老年代
YoungCollection+ConcurrentMark(年轻代垃圾回收+并发标记)
5.当老年代占用内存超过阈值(默认是45%)后,触发并发标记,在老年代中找到存活的对象,这时无需暂停用户线程
6.并发标记之后,会有重新标记阶段解决漏标问题,此时需要暂停用户线程。
MixedCollection(混合垃圾回收)
混合收集阶段中,参与复制的有eden、survivor、old。此时不会对所有老年代区域进行回收,而是根据暂停时间目标优先回收价值高(存活对象少)的区域(这也是GabageFirst 名称的由来)。复制完成,内存得到释放。进入下一轮的新生代回收、并发标记、混合收集。
混合收集可能会持续多次。
新生代中存活的对象会被复制到最新的幸存区,之前的幸存区以及老年代中存活的对象,将会放在一个老年代中。
强引用、软引用,弱引用,虚引用的区别
强引用:只有所有GCRoots对象都不通过【强引用】引用该对象,该对象才能被垃圾回收。只要所有GC Roots能找到,就不会被回收
软引用:需要配合SoftReference使用,当垃圾多次回收,内存依然不够的时候会回收软引用对象
弱引用:需要配合WeakReference使用,只要进行了垃圾回收,就会把弱引用对象回收
虚引用:必须配合引用队列使用,被引用对象回收时,会将虚引用入队,由ReferenceHandler线程调用虚引l用相关方法释放直接内存(虚引用的外部资源)
相关文章:
JVM--垃圾回收
垃圾回收的概念 垃圾回收主要针对的是堆中的对象,堆是一个共享的区域,创建的对象和数组都放在这个位置。但是我们不能一直的创建对象,也不是所有的对象能一直存放,如果不进行垃圾回收,内存迟早会耗尽,及时…...
Spring boot3-Http Interface: 声明式编程
来吧 1.首先引入pom.xml依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-webflux</artifactId> </dependency> 2.创建WebClientController控制器 import com.atguigu.boot3_07_http.serv…...
springboot EasyExcel 实现导入导出
1. 添加依赖 确保 Maven 依赖中包含 EasyExcel 3.0.5: <dependency><groupId>com.alibaba</groupId><artifactId>easyexcel</artifactId><version>3.0.5</version></dependency><!-- excel工具 --><dep…...
基于RAGFlow本地部署DeepSpeek-R1大模型与知识库:从配置到应用的全流程解析
作者:后端小肥肠 🍊 有疑问可私信或评论区联系我。 🥑 创作不易未经允许严禁转载。 姊妹篇: DeepSpeek服务器繁忙?这几种替代方案帮你流畅使用!(附本地部署教程)-CSDN博客 10分钟上手…...
spring 创建单例 Bean 源码分析
一、创建单例Bean 1、创建单例 Bean 通过方法getBean()来创建单例bean。 代码入口: org.springframework.beans.factory.support.DefaultListableBeanFactory#preInstantiateSingletons spring boot version:2.6.13 org.springframework.beans.factory…...
GetCurrentTime
在实际编程中难免要获取当前时间并且进行格式化,本文给出了多种 GetCurrentTime() 方法以供选择。 C语言下使用strftime C 语言中可以使用 <time.h> 中的函数来获取和格式化时间 #include <stdio.h> #include <time.h>char* getCurrentTime() …...
HTB 学习笔记 【中/英】《Web 应用简介》P1
📌 这篇文章讲了什么? 介绍了 Web 应用 的概念、架构,以及与传统网站的区别。重点讲解了 Web 安全风险,包括 常见攻击方法(SQL 注入、文件包含、不安全的文件上传等)。介绍了 Web 渗透测试 的重要性&#…...
ROS catkin_make编译报错问题
对问题 CMake Error at graduation_design/CMakeLists.txt:226 (add_dependencies): The dependency target "graduation_design_generate_messages_cpp" of target "listener" does not exist 检查 generate_messages() 是否被注释 对 CMake Error at …...
【结构设计】3D打印创想三维Ender 3 v2
【结构设计】3D打印创想三维Ender 3 v2 文章目录 前言一、Creality Slicer1.2.3打印参数设置二、配件更换1.捆扎绑扎线2.气动接头3D打印机配件插头3.3D打印机配件Ender3pro/V2喷头套件4.读卡器 TF卡5.micro sd卡 三、调平四、参考文章总结 前言 使用工具: 1.创想三…...
并发编程2
接并发编程1 synchronized锁的实现 通过底层指令控制实现,Java提供的一种原子性内置锁,在进入synchronized后会从主内存复制一份共享变量到自己的工作内存,在工作内存中修改完成后,退出时会把工作内存的值写入到主内存ÿ…...
Linux 中 Git 使用指南:从零开始掌握版本控制
目录 1. 什么是 Git? Git 的核心功能: 2. Git 的安装 Ubuntu/Debian 系统: 验证安装: 3.gitee库 4. Git 的首次配置 配置用户名和邮箱: 查看配置: 5. Git 的基本使用 初始化仓库 添加文件到暂存区…...
C# Exe + Web 自动化 (BitComet 绿灯 自动化配置、设置)
BitComet GreenLight,内网黄灯转绿灯 (HighID), 增加p2p连接率提速下载-CSDN博客 前两天写个这个,每次开机关机后要重来一遍很麻烦的索性写个自动化。 先还是按照上面的教程自己制作一遍,留下Luck 以及 路由器相关的 端口记录信息。 (因为自…...
2024年12月CCF-GESP编程能力等级认证C++编程四级真题解析
四级真题的难度: 一、总体难度评价 CCF-GESP编程能力等级认证C++四级真题的难度通常被认为相对较高。它不仅要求考生具备扎实的C++编程基础,还需要考生掌握一定的算法和数据结构知识,以及良好的问题解决能力。 二、具体难度分析 理论知识考察: 单选题和判断题中,会涉…...
谷歌Chrome或微软Edge浏览器修改网页任意内容
在谷歌或微软浏览器按F12,打开开发者工具,切换到console选项卡: 在下面的输入行输入下面的命令回车: document.body.contentEditable"true"效果如下:...
《DeepSeek深度使用教程:开启智能交互新体验》Deepseek深度使用教程
《DeepSeek使用教程:开启智能交互新体验》 在当今数字化时代,人工智能技术正以前所未有的速度改变着我们的生活和工作方式。DeepSeek作为一款强大的人工智能工具,凭借其卓越的自然语言处理能力和多领域应用潜力,受到了众多开发者…...
Dijkstra算法
Dijkstra算法(迪杰斯特拉算法)是一种经典的单源最短路径算法,用于在加权图中找到从一个源点到所有其他顶点的最短路径。它要求图中不能有负权边,因为负权边可能会导致算法的贪心策略失效。 Dijkstra算法的基本思想 Dijkstra算法…...
Python中的静态方法如何使用?
在Python里,类当中的方法可以分为多种不同的类型,其中staticmethod是一个十分有趣而又实用的功能。我们来好好地聊一聊什么是静态方法,它的用途是什么,以及如何在实际应用中使用它们! 首先,定义一下静态方…...
【最后203篇系列】016 Q201架构思考
前言 Q200已经达到了我既定的目标,在最近的3个月,我需要进一步完善,达到可以试产的程度。 在这个过程当中,许多知识和体会一直在变。 qtv200到目前,虽然通过习惯(每晚运行离线策略和比对)方式维持了注意力的集中&…...
小脑萎缩会致命吗?
小脑萎缩,顾名思义,是指小脑的体积减小或结构发生异常,进而影响其正常功能。小脑作为人体重要的协调和运动控制中心,负责维持身体平衡、调节肌肉张力和协调运动等关键功能。当小脑出现萎缩时,患者可能会出现步态不稳、…...
pip install和conda install的区别
这里写目录标题 一、什么是 Python 依赖(Python Dependencies)?1. 依赖的作用2. 如何管理 Python 依赖3. 依赖管理问题4. 依赖锁定总结 二、使用pip安装包venv隔离环境方法 1:使用 venv(推荐)创建虚拟环境激…...
這是我第一次寫關於aapenal服務器管理控制面板的文章
首先我們來認識一下服務器管理面板的所有功能 網站管理功能: 支持創建和管理多個網站。配置虛擬主機(Vhost)和域名綁定。自動安裝常用應用(如WordPress、Joomla等)。 文件管理功能: 文件上傳、…...
requests库的request和response对象的属性和方法
Python requests库 request 参数信息 response 参数信息...
8664蛋糕的美味值
8664蛋糕的美味值 ⭐️难度:中等 🌟考点:枚举 📖 📚 import java.util.Scanner;public class Main {public static void main(String[] args) {Scanner sc new Scanner(System.in );int n sc.nextInt();int k s…...
【MySQL】数据库简要介绍和简单应用
目录 数据库简要介绍 SQL 的简单应用 需要注意的: 数据库简要介绍 数据库(database)是指长期存储在计算机内,有组织的、可共享的数据集合。它可视为一个电子化的文件柜,用来存储电子文件,用户可以对文件中的数据进行査询、新增、更新、删…...
yolo环境 pytorch环境配置 CUDA安装
我的成功案例:首先安装python 3.12.9的conda虚拟环境 (如果不安装3.12的会报错误ModuleNotFoundError:没有名为“numpy._core”的模块) 然后安装11.8cuda (其实我是可以最高安装12.6的cuda但我实测,太高版…...
camellia redis proxy v1.3.3对redis主从进行读写分离(非写死,自动识别故障转移)
1 概述 camellia-redis-proxy是一款高性能的redis代理(https://github.com/netease-im/camellia),使用netty4开发,主要特性如下: 支持代理到redis-standalone、redis-sentinel、redis-cluster。支持其他proxy作为后端…...
python相关语法的学习文档1
python相关语法的学习文档1 1、tqdm tqdm 是 Python 中一个非常流行的进度条库,可以实时显示循环或任务的进度。它简单易用,支持多种场景(如循环、文件处理、多线程/进程等)。以下是详细的使用讲解: 1.1 安装 pip install tqdm1.2 基本用法 from tqdm import tqdm impo…...
Web元件库 ElementUI元件库+后台模板页面(支持Axure9、10、11)
Axure是一款非常强大的原型设计工具,它允许设计师和开发者快速创建高保真原型,以展示应用或网站的设计和功能。通过引入各种元件库,如ElementUI元件库,可以极大地丰富Axure的原型设计能力,使其更加贴近实际开发中的UI组…...
Java 并发编程——BIO NIO AIO 概念
参考 Java 并发编程——BIO NIO AIO 概念 阻塞与非阻塞、同步与异步概念 系统调用、缓存、物理设备阻塞与非阻塞同步与异步 四种主要的 IO 模型 同步阻塞 IO同步非阻塞 IOIO 多路复用异步 IO select,poll,epoll 系统调用命令...
在微信小程序或前端开发中,picker 和 select 都是用户交互中用于选择的组件,但它们在功能、设计和使用场景上有一定的区别
在微信小程序或前端开发中,picker 和 select 都是用户交互中用于选择的组件,但它们在功能、设计和使用场景上有一定的区别。 1. picker 的特点 描述: picker 是微信小程序中的原生组件,通常用于选择单项或多项值,如时…...
笔记本 Win10 部署阿里通义千问 1.5-0.5B 大模型 mini 版
文章目录 1.环境准备1.1 硬件环境1.2 OS 环境1.3 Python 环境 2.环境安装2.1 CUDA 驱动下载安装2.2 torch 库下载安装2.3 transformers 库安装2.3 accelerate 库安装2.4 验证 CUDA 是否可用2.5 下载 Qwen1.5-0.5B 大模型 3.测试大模型3.1 加载大模型3.2 简单对话3.3 亲测体验感…...
SpringBoot事件驱动
1、概述 Spring事件驱动采用了观察者设计模式,主要作用就是实现对象之间的松耦合通信。它的核心思想是通过事件的发布和监听来实现不同组件之间的交互。(跟mq挺像) 基础概念: 事件(Event): 在Spring中&am…...
nginx中间件部署
普通权限账户安装NGINX中间件 1、拥有高级权限的账户安装必要的插件 sudo yum install -y gcc-c make pcre pcre-devel zlib zlib-devel openssl openssl-devel 2、普通账户进行NGINX的脚本式安装 vi nginx_intall.sh #!/bin/bash TAR_NAME"$1" TAR_NAME_DIRba…...
Qt程序基于共享内存读写CodeSys的变量
文章目录 1.背景2.结构体从CodeSys导出后导入到C2.1.将结构体从CodeSys中导出2.2.将结构体从m4文件提取翻译成c格式 3.添加RTTR注册信息4.读取PLC变量值5.更改PLC变量值 1.背景 在文章【基于RTTR在C中实现结构体数据的多层级动态读写】中,我们实现了通过字符串读写…...
vulnhub-Hackme-隧道建立、SQL注入、详细解题、思路清晰。
vulnhub-Hackme-隧道建立、SQL注入、详细解题、思路清晰。 一、信息收集 2025.3.14 PM 12:18 1、主机发现 arp-scan -l nmap -sn 192.168.66.0/24 2、端口扫描 1、nmap --min-rate 10000 -p- 192.168.66.182 -oA port 查看所有开放端口2、map -sS -sV 192.168.6…...
技术-NBIOT
是什么? 窄带物联网(Narrow Band Internet of Things, NB-IoT)成为万物互联网络的一个重要分支支持低功耗设备在广域网的蜂窝数据连接,也被叫作低功耗广域网(LPWAN)NB-IoT支持待机时间长、对网络连接要求较高设备的高效连接NB-Io…...
【论文阅读】AlexNet——深度学习奠基作之一
原文链接 Step 1 1. titleabstract 第一句:告诉我干了什么事情 我们训练了一个很大很深的卷积神经网络,用来对120w个图片作分类,这里面有1000个类 第二句:结果 在测试集上面,top-1 error37.5%,top-517.0…...
【云原生技术】编排与容器的技术演进之路
一、编排与容器的技术演进之路 1.1 DockerClient 此时 K8s 只是编排领域的一个选择,而 Docker 此时一家独大,所以 K8s 的客户端只 是作为 Docker 的客户端来调用 Docker 引擎来完成服务。 1.2 RUNC&Shim OCI催生 runcrunc,剥离 Docke…...
鸿蒙编译框架插件HvigorPlugin接口的用法介绍
鸿蒙系统中HvigorPlugin接口实现自定义编译插件,实现编译前后自定义功能。 在鸿蒙(HarmonyOS)开发中,HvigorPlugin 是用于扩展 Hvigor 构建工具功能的接口。通过实现此接口,开发者可以自定义构建任务、修改构建流程或…...
Springboot+mybatis实现增删改查操作
继续写一下删除操作,删除有些不一样,首先在controller里面,我们需要改一下路由,我们后面要写/{id}传入路径参数,用PathVariable注解绑定id,剩下的都一样,传入id,然后写service和mapp…...
Java中的I/O
1.I/O流 1.1I/O概述 1.2.基本用法 1.3.字节输出流写数据的细节 1.4.FileOutPutStream写数据的三种方式 明天再更~~~~,先混个流量券。...
前端组件封装艺术:设计原则与最佳实践指南
文章目录 一、组件封装的核心原则1.1 设计原则概览1.2 组件生命周期 二、组件设计准则2.1 单一职责原则2.2 高内聚低耦合 三、组件接口设计3.1 Props设计规范3.2 代码示例 四、组件状态管理4.1 状态设计原则4.2 代码示例 五、组件样式处理5.1 样式方案对比5.2 代码示例 六、组件…...
SpringMVC(五)拦截器
目录 拦截器基本概念 一 单个拦截器的执行 1 创建拦截器 2 SpringMVC配置,并指定拦截路径。 3 运行结果展示: 二 多个拦截器的执行顺序 三 拦截器与过滤器的区别 拦截器基本概念 SpringMVC内置拦截器机制,允许在请求被目标方法处理的…...
jupyter无法转换为PDF,HTMLnbconvert failed: Pandoc wasn‘t found.
无法转为PDF 手动下载工具 https://github.com/jgm/pandoc/releases/tag/3.6.3 似乎跟我想的不大一样,还有新的报错 https://nbconvert.readthedocs.io/en/latest/install.html#installing-tex 不知道下的啥玩意儿 sudo apt-get install texlive-xetex texlive-fon…...
【红黑树】—— 我与C++的不解之缘(二十五)
前言 学习了avl树,现在来学习红黑树。 一、什么是红黑树 红黑树是一颗平衡二叉搜索树,它每一个节点增加了一个存储位表示节点的颜色,可以是红色或者黑色。 相比较于AVL树,红黑树也是一个自平衡二叉搜索树,但是它与AVL树…...
机器学习 Day05 pandas库
1.pandas介绍和优点 Pandas 是 2008 年由 Wes McKinney 开发的开源 Python 库 。它专门用于数据挖掘和数据分析,具有以下特点: 数据结构独特:核心数据结构为 Series(一维)和 DataFrame(二维) …...
布达佩斯召开 | 2025年第五届能源与环境工程国际会议(CoEEE 2025)
会议简介 Brief Introduction 2025年第五届能源与环境工程国际会议(CoEEE 2025) 会议时间:2025年7月25日-27日 召开地点:匈牙利布达佩斯 大会官网:www.coeee.org CoEEE 2025将围绕“能源与环境工程”的最新研究领域而展开,为研究人…...
[C语言日寄] qsort函数的练习
【作者主页】siy2333 【专栏介绍】⌈c语言日寄⌋:这是一个专注于C语言刷题的专栏,精选题目,搭配详细题解、拓展算法。从基础语法到复杂算法,题目涉及的知识点全面覆盖,助力你系统提升。无论你是初学者,还是…...
单引号与双引号在不同编程语言中的使用与支持
在编程语言中,单引号和双引号是常见的符号,它们通常用来表示字符和字符串。然而,如何使用这两种符号在不同的编程语言中有所不同,甚至有一些语言并不区分单引号和双引号的用途。本文将详细介绍不同编程语言中单引号与双引号的支持…...
Next.js项目实战——MindAI
我的整个毕业论文,是基于Next.js搭建完成的。项目的搭建过程分为多个章节,循序渐进: 1.环境准备与项目初始化 Node.js和npm的安装配置创建Next.js 14项目TypeScript配置项目目录结构说明Git初始化和.gitignore配置 2.基础架构搭建 Tailwi…...