操作系统课程设计

摘  要

本项目旨在深入设计与实现一套基于Java的模拟操作系统,模拟和实现常见操作系统的核心功能,包括进程管理、内存分配与调度、高效的文件系统和多样化设备的管理。通过该模拟操作系统的开发,探索计算机操作系统的基础理论与实际工程细节,进而提升对计算机系统的深刻理解和实际应用能力。项目采用模块化设计与实现,旨在展示各功能模块之间的紧密交互与高效协作,以达到高度模拟真实操作系统的目标。

关键字:Java;模拟操作系统;进程管理;内存分配与调度;文件系统;设备管理;

ABSTRACT

This project aims to comprehensively design and implement a Java-based simulated operating system, simulating and implementing core functionalities typical of operating systems. These include process management, memory allocation and scheduling, efficient file systems, and diverse device management. Through the development of this simulated operating system, it explores fundamental theories and practical engineering details of computer operating systems, thereby enhancing a profound understanding and practical application capabilities of computer systems. The project employs modular design and implementation to demonstrate close interaction and efficient collaboration among various functional modules, aiming to achieve a high fidelity simulation of real-world operating systems.

Keywords:Java; simulated operating system; process management; memory allocation and scheduling; file system; device management;

  

一、 功能需求

(一) 功能任务

(二) 使用的开发工具

(三) 设计界面

(四) 预期指标说明

二、 详细设计

(一) 功能结构

(二) 实现方法与思想

(三) 算法描述

(四) 数据组织结构

四、程序、算法流程图

五、程序实现

(一) 内存管理代码

(二) 设备管理代码

(三) 主控界面代码

六、程序测试

七、总结个人心得体会及建议

参考文献

致  谢

  • 功能需求
  • 功能任务
    1. 进程管理
  1. 创建、销毁进程
  2. 进程调度算法实现(如FCFS、SJF、优先级调度等)
  3. 进程状态管理(就绪、运行、阻塞、结束等)
    1. 内存管理
  1. 内存分配策略(如分区分配、动态分区分配、页面置换等)
  2. 内存保护与地址映射
  3. 虚拟内存管理(如页面置换算法实现)
  1. 文件系统
  1. 文件的创建、删除、读写等基本操作
  2. 文件系统的组织结构(如FAT、inode等)
  3. 文件权限与共享管理
  1. 设备管理
  1. 设备分配与调度(如设备分配表、中断驱动程序等)
  2. 设备状态管理(空闲、占用、等待等)
  3. 设备驱动程序的模拟实现
  • 使用的开发工具
  1. 开发语言:Java
  2. 集成开发环境:IntelliJ IDEA
  3. 构建工具:Maven
  4. 数据库:MySQL

  • 预期指标说明

在开发模拟操作系统的过程中,我们设定了以下预期指标,以评估项目的成功程度和达成的目标:

功能完整性: 模拟操作系统应具备基本的操作系统功能,如进程管理、内存管理、文件系统、用户界面等。预期能够模拟基本的操作系统行为和用户交互。

性能优化: 系统应具备较高的运行效率和响应速度,能够处理多任务并发和资源管理,确保系统运行稳定性和效率。

代码质量: 代码应符合Java编码规范,结构清晰,模块化设计,易于扩展和维护。代码应通过单元测试和集成测试,确保功能的正确性和稳定性。

用户体验: 操作系统界面应设计友好,用户能够轻松理解和操作系统的功能,提供必要的帮助和文档支持。

安全性: 系统应具备基本的安全措施,防止未经授权的访问和数据泄露,确保系统和用户数据的安全性。 

扩展性: 系统设计应具备一定的扩展性和灵活性,能够支持未来功能的增加和系统的升级。

设计界面

  • 详细设计
  • 功能结构

功能:

用户可以输入进程名称和需要分配的内存大小(以KB为单位)。可以通过按钮执行分配内存和释放内存的操作。显示当前内存分配情况,并在分配或释放后更新显示。

结构:

MemoryManagementApp 类:主要的应用程序类,包含了界面的构建和事件处理逻辑。

MemoryManager 类:负责实际的内存管理操作,包括分配和释放内存。

MemoryBlock 类:表示内存中的一个块,包含标识、大小、分配状态等信息。

  • 实现方法与思想

界面构建:

使用 JFrame 构建主窗口,通过 JPanel、JLabel、JTextField、JButton 等构建输入框、标签和按钮。

使用 JTextArea 显示当前内存状态,通过 JScrollPane 支持滚动显示。

事件处理:

allocateButton 按钮的事件监听器处理分配内存操作:获取用户输入的进程名称和内存大小。调用 memoryManager.allocate() 方法尝试分配内存。

根据操作结果更新界面显示,并通过 showAlert() 方法显示结果提示框。

freeButton 按钮的事件监听器处理释放内存操作:

获取用户输入的进程名称。调用 memoryManager.free() 方法尝试释放内存。

同样更新界面显示,并通过 showAlert() 方法显示结果提示框。

内存管理:

MemoryManager 类维护一个 List<MemoryBlock> 来管理内存块的状态。

allocate() 方法实现了简单的首次适应算法:

遍历现有的内存块列表,找到合适大小的空闲块进行分配,或者创建新的内存块。

free() 方法根据进程名称找到对应的内存块,将其标记为未分配状态。

  • 算法描述

首次适应算法:

MemoryManager.allocate() 方法遍历现有的内存块列表,找到第一个大小足够的空闲块。

如果找到合适的块,则将其分配给请求的进程;如果没有找到,则创建新的内存块。

数据管理:

MemoryManager 维护了一个列表 memoryBlocks,每个元素是一个 MemoryBlock 对象,用于存储和管理模拟内存中的块。

  • 数据组织结构

MemoryBlock 类:

包含 id、大小、分配状态等属性,提供方法进行分配和释放操作。

MemoryManager 类:

维护一个 List<MemoryBlock>,通过列表管理所有的内存块。提供了 allocate() 和 free() 方法来实现内存的分配和释放操作。

四、程序、算法流程图

五、程序实现

  • 内存管理代码
  • MemoryManagementApp.java
    import javax.swing.*;
    import java.awt.*;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import java.util.ArrayList;
    import java.util.List;public class MemoryManagementApp {private MemoryManager = new MemoryManager();private JFrame frame;private JTextField processNameField;private JTextField blockSizeField;private JTextArea memoryDisplay;public MemoryManagementApp() {frame = new JFrame("内存管理模拟器");frame.setLayout(new BorderLayout());frame.setSize(600, 400);frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);JPanel inputPanel = new JPanel();inputPanel.setLayout(new FlowLayout());JLabel processLabel = new JLabel("进程名称:");processNameField = new JTextField(10);JLabel blockSizeLabel = new JLabel("内存大小(KB):");blockSizeField = new JTextField(10);JButton allocateButton = new JButton("分配内存");JButton freeButton = new JButton("释放内存");inputPanel.add(processLabel);inputPanel.add(processNameField);inputPanel.add(blockSizeLabel);inputPanel.add(blockSizeField);inputPanel.add(allocateButton);inputPanel.add(freeButton);memoryDisplay = new JTextArea(20, 40);memoryDisplay.setEditable(false);JScrollPane scrollPane = new JScrollPane(memoryDisplay);frame.add(inputPanel, BorderLayout.NORTH);frame.add(scrollPane, BorderLayout.CENTER);allocateButton.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {try {String processName = processNameField.getText();int blockSize = Integer.parseInt(blockSizeField.getText());boolean allocated = memoryManager.allocate(processName, blockSize);if (allocated) {updateMemoryDisplay();showAlert("成功分配 " + blockSize + " KB 内存给进程 " + processName);} else {showAlert("内存不足,无法分配 " + blockSize + " KB 内存给进程 " + processName);}} catch (NumberFormatException ex) {showAlert("请输入有效的整数!");}}});freeButton.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {String processName = processNameField.getText();boolean freed = memoryManager.free(processName);if (freed) {updateMemoryDisplay();showAlert("成功释放进程 " + processName + " 的内存");} else {showAlert("进程 " + processName + " 不存在或未分配内存");}}});frame.setVisible(true);}private void updateMemoryDisplay() {List<MemoryBlock> blocks = memoryManager.getMemoryBlocks();StringBuilder sb = new StringBuilder();sb.append("当前内存状态:\n");sb.append("--------------------------------\n");for (MemoryBlock block : blocks) {sb.append(block.toString()).append("\n");}memoryDisplay.setText(sb.toString());}private void showAlert(String message) {JOptionPane.showMessageDialog(frame, message);}// 内存管理类,用于模拟内存分配与释放逻辑private class MemoryManager {private List<MemoryBlock> memoryBlocks = new ArrayList<>();private int totalMemory = 1024; // 假设总内存大小为 1024 KBpublic boolean allocate(String processName, int size) {if (size <= 0) return false;// 模拟首次适应算法for (MemoryBlock block : memoryBlocks) {if (!block.isAllocated() && block.getSize() >= size) {block.allocate(processName, size);return true;}}// 如果没有足够的连续空闲空间,则分配新的内存块int remainingMemory = totalMemory - getAllocatedMemory();if (size <= remainingMemory) {MemoryBlock newBlock = new MemoryBlock(memoryBlocks.size(), size);newBlock.allocate(processName, size);memoryBlocks.add(newBlock);return true;}return false;}public boolean free(String processName) {for (MemoryBlock block : memoryBlocks) {if (block.getProcessName() != null && block.getProcessName().equals(processName)) {block.free();return true;}}return false;}public List<MemoryBlock> getMemoryBlocks() {return memoryBlocks;}private int getAllocatedMemory() {int allocated = 0;for (MemoryBlock block : memoryBlocks) {if (block.isAllocated()) {allocated += block.getSize();}}return allocated;}}// 内存块类,表示内存中的一个块private class MemoryBlock {private int id;private String processName;private int size;private boolean allocated;public MemoryBlock(int id, int size) {this.id = id;this.size = size;this.allocated = false;}public void allocate(String processName, int size) {this.processName = processName;this.allocated = true;}public void free() {this.processName = null;this.allocated = false;}public int getId() {return id;}public String getProcessName() {return processName;}public int getSize() {return size;}public boolean isAllocated() {return allocated;}@Overridepublic String toString() {if (allocated) {return "内存块 " + id + ": 已分配给进程 " + processName + ",大小 " + size + " KB";} else {return "内存块 " + id + ": 空闲,大小 " + size + " KB";}}}public static void main(String[] args) {SwingUtilities.invokeLater(new Runnable() {public void run() {new MemoryManagementApp();}});}
    }(一)设备管理代码
    DeviceManagementSystem.java
    import javax.swing.*;
    import javax.swing.table.DefaultTableModel;
    import java.awt.*;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;public class DeviceManagementSystem extends JFrame {private DefaultTableModel tableModel;private JTable deviceTable;private JTextField deviceNumberField;public DeviceManagementSystem() {setTitle("设备管理系统");setSize(600, 400);setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);// Create componentsJPanel topPanel = new JPanel(new FlowLayout());JPanel bottomPanel = new JPanel(new BorderLayout());JButton allocateButton = new JButton("分配设备");JButton deallocateButton = new JButton("回收设备");JButton searchButton = new JButton("按设备编号搜索");JLabel deviceNumberLabel = new JLabel("设备编号:");deviceNumberField = new JTextField(10);// Table setupString[] columns = {"设备编号", "状态"};tableModel = new DefaultTableModel(columns, 0);deviceTable = new JTable(tableModel);// Add components to panelstopPanel.add(allocateButton);topPanel.add(deallocateButton);topPanel.add(deviceNumberLabel);topPanel.add(deviceNumberField);topPanel.add(searchButton);bottomPanel.add(new JScrollPane(deviceTable), BorderLayout.CENTER);// Add panels to frameadd(topPanel, BorderLayout.NORTH);add(bottomPanel, BorderLayout.CENTER);// Button actionsallocateButton.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {allocateDevice();}});deallocateButton.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {deallocateDevice();}});searchButton.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {searchDevice();}});// Add some initial devicesaddInitialDevices();}private void addInitialDevices() {String[] initialDevices = {"001", "002", "003"};for (String deviceNumber : initialDevices) {String[] rowData = {deviceNumber, "未分配"};tableModel.addRow(rowData);}}private void allocateDevice() {String deviceNumber = deviceNumberField.getText().trim();if (deviceNumber.isEmpty()) {JOptionPane.showMessageDialog(this, "请输入设备编号.");return;}// Check if device number already existsfor (int row = 0; row < tableModel.getRowCount(); row++) {String existingDeviceNumber = (String) tableModel.getValueAt(row, 0);if (existingDeviceNumber.equals(deviceNumber)) {JOptionPane.showMessageDialog(this, "设备已分配.");return;}}// Add new row to table with default status "Allocated"String[] rowData = {deviceNumber, "已分配"};tableModel.addRow(rowData);deviceNumberField.setText("");}private void deallocateDevice() {int selectedRow = deviceTable.getSelectedRow();if (selectedRow == -1) {JOptionPane.showMessageDialog(this, "请选择要回收的设备.");return;}String deviceNumber = (String) tableModel.getValueAt(selectedRow, 0);tableModel.setValueAt("未分配", selectedRow, 1); // Change status to "Not Allocated"JOptionPane.showMessageDialog(this, "设备 " + deviceNumber + " 已回收.");}private void searchDevice() {String searchNumber = deviceNumberField.getText().trim();if (searchNumber.isEmpty()) {JOptionPane.showMessageDialog(this, "请输入要搜索的设备编号.");return;}boolean found = false;for (int row = 0; row < tableModel.getRowCount(); row++) {String deviceNumber = (String) tableModel.getValueAt(row, 0);if (deviceNumber.equals(searchNumber)) {deviceTable.setRowSelectionInterval(row, row);JOptionPane.showMessageDialog(this, "找到设备 " + searchNumber + ".");found = true;break;}}if (!found) {JOptionPane.showMessageDialog(this, "未找到设备 " + searchNumber + ".");}}public static void main(String[] args) {SwingUtilities.invokeLater(new Runnable() {@Overridepublic void run() {DeviceManagementSystem system = new DeviceManagementSystem();system.setVisible(true);}});}
    }
    (二)主控界面代码       
    import javax.swing.*;
    import java.awt.*;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import java.util.ArrayList;
    import java.util.List;public class MemoryManagementApp {private MemoryManager = new MemoryManager();private JFrame frame;private JTextField processNameField;private JTextField blockSizeField;private JTextArea memoryDisplay;public MemoryManagementApp() {frame = new JFrame("内存管理模拟器");frame.setLayout(new BorderLayout());frame.setSize(600, 400);frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);JPanel inputPanel = new JPanel();inputPanel.setLayout(new FlowLayout());JLabel processLabel = new JLabel("进程名称:");processNameField = new JTextField(10);JLabel blockSizeLabel = new JLabel("内存大小(KB):");blockSizeField = new JTextField(10);JButton allocateButton = new JButton("分配内存");JButton freeButton = new JButton("释放内存");inputPanel.add(processLabel);inputPanel.add(processNameField);inputPanel.add(blockSizeLabel);inputPanel.add(blockSizeField);inputPanel.add(allocateButton);inputPanel.add(freeButton);memoryDisplay = new JTextArea(20, 40);memoryDisplay.setEditable(false);JScrollPane scrollPane = new JScrollPane(memoryDisplay);frame.add(inputPanel, BorderLayout.NORTH);frame.add(scrollPane, BorderLayout.CENTER);allocateButton.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {try {String processName = processNameField.getText();int blockSize = Integer.parseInt(blockSizeField.getText());boolean allocated = memoryManager.allocate(processName, blockSize);if (allocated) {updateMemoryDisplay();showAlert("成功分配 " + blockSize + " KB 内存给进程 " + processName);} else {showAlert("内存不足,无法分配 " + blockSize + " KB 内存给进程 " + processName);}} catch (NumberFormatException ex) {showAlert("请输入有效的整数!");}}});freeButton.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {String processName = processNameField.getText();boolean freed = memoryManager.free(processName);if (freed) {updateMemoryDisplay();showAlert("成功释放进程 " + processName + " 的内存");} else {showAlert("进程 " + processName + " 不存在或未分配内存");}}});frame.setVisible(true);}private void updateMemoryDisplay() {List<MemoryBlock> blocks = memoryManager.getMemoryBlocks();StringBuilder sb = new StringBuilder();sb.append("当前内存状态:\n");sb.append("--------------------------------\n");for (MemoryBlock block : blocks) {sb.append(block.toString()).append("\n");}memoryDisplay.setText(sb.toString());}private void showAlert(String message) {JOptionPane.showMessageDialog(frame, message);}// 内存管理类,用于模拟内存分配与释放逻辑private class MemoryManager {private List<MemoryBlock> memoryBlocks = new ArrayList<>();private int totalMemory = 1024; // 假设总内存大小为 1024 KBpublic boolean allocate(String processName, int size) {if (size <= 0) return false;// 模拟首次适应算法for (MemoryBlock block : memoryBlocks) {if (!block.isAllocated() && block.getSize() >= size) {block.allocate(processName, size);return true;}}// 如果没有足够的连续空闲空间,则分配新的内存块int remainingMemory = totalMemory - getAllocatedMemory();if (size <= remainingMemory) {MemoryBlock newBlock = new MemoryBlock(memoryBlocks.size(), size);newBlock.allocate(processName, size);memoryBlocks.add(newBlock);return true;}return false;}public boolean free(String processName) {for (MemoryBlock block : memoryBlocks) {if (block.getProcessName() != null && block.getProcessName().equals(processName)) {block.free();return true;}}return false;}public List<MemoryBlock> getMemoryBlocks() {return memoryBlocks;}private int getAllocatedMemory() {int allocated = 0;for (MemoryBlock block : memoryBlocks) {if (block.isAllocated()) {allocated += block.getSize();}}return allocated;}}// 内存块类,表示内存中的一个块private class MemoryBlock {private int id;private String processName;private int size;private boolean allocated;public MemoryBlock(int id, int size) {this.id = id;this.size = size;this.allocated = false;}public void allocate(String processName, int size) {this.processName = processName;this.allocated = true;}public void free() {this.processName = null;this.allocated = false;}public int getId() {return id;}public String getProcessName() {return processName;}public int getSize() {return size;}public boolean isAllocated() {return allocated;}@Overridepublic String toString() {if (allocated) {return "内存块 " + id + ": 已分配给进程 " + processName + ",大小 " + size + " KB";} else {return "内存块 " + id + ": 空闲,大小 " + size + " KB";}}}public static void main(String[] args) {SwingUtilities.invokeLater(new Runnable() {public void run() {new MemoryManagementApp();}});}
    }

    七、总结个人心得体会及建议

    1. 理论与实践的结合

    在开发模拟操作系统的过程中,内存管理是一个至关重要的组成部分。我负责的任务是设计和实现内存的分配与回收机制,这不仅要求理解操作系统的内存管理理论,还需要将这些理论知识有效地应用于实际的代码实现中。

    首先,理论知识的掌握是基础。我深入学习了内存分区、分页和分段等常见的内存管理技术,以及它们的优缺点。理论的学习帮助我了解到不同的内存分配策略(如首次适应、最佳适应、最坏适应等)以及如何有效地进行内存回收(如标记清除、引用计数等算法)。

    2. 实践中的挑战与解决方案

    在实际开发中,我面临了多方面的挑战。其中包括:

    性能优化: 内存管理的效率直接影响到操作系统整体的性能。通过采用合适的数据结构和算法,我努力提高了内存分配和回收的速度,避免了不必要的内存碎片和过度消耗CPU资源。

    安全性与稳定性: 内存管理必须保证系统的稳定性和安全性。我实现了严格的边界检查和错误处理机制,防止了内存泄漏和越界访问等问题的发生。

    资源管理: 在模拟操作系统中,资源的管理尤为重要。除了内存管理外,还需要考虑与其他子系统(如进程管理、文件系统等)的资源协调和共享。

    3. 建议与未来展望

    基于我在内存管理部分的经验,我对于未来的模拟操作系统开发提出以下建议:

    持续学习与更新: 操作系统领域的技术日新月异,需要持续关注最新的研究和技术进展,以不断优化和改进内存管理策略。

    跨学科合作: 内存管理涉及到计算机体系结构、数据结构、算法等多个领域,建议与其他团队成员和专家进行密切合作,共同解决复杂的技术问题。

    开源与社区参与: 参与开源项目或者操作系统社区,可以获得更多的反馈和经验分享,进一步提高自己的技术水平和解决问题的能力。

    用户体验优化: 最终用户是操作系统的使用者,因此在设计和实现内存管理时,要考虑到用户体验的方面,如提供友好的错误提示和清晰的内存使用信息。

    通过这次项目,我深刻体会到内存管理在操作系统中的关键性作用。我将继续努力学习,不断提升自己在操作系统开发和其他相关领域的技术能力,为未来的项目贡献更多的价值。

  •                                                                     致谢

    在此论文完成之际,我要向我的导师XX老师表达最诚挚的感谢。从最初的选题、开题报告到最终的论文定稿,XX老师始终以认真负责的态度对待我的每一个阶段。在选题阶段,XX老师帮助我确定了研究方向,并为我提供了许多宝贵的建议,使我能够更加清晰地认识到研究的价值和意义。

    在写作过程中,XX老师不仅详细审阅了我的每一部分内容,还针对每一个细节提出了中肯的修改意见。特别是在数据分析和结论部分,XX老师耐心地指导我如何更好地运用统计方法和理论框架,以确保研究结果的准确性和科学性。每一次讨论和反馈,XX老师都不厌其烦地解答我的疑问,并鼓励我不断深入思考和完善论文。

    此外,我还要感谢我的同学们,在我论文修改期间,他们热心地帮助我进行格式调整和细节校对,确保了论文的规范性和专业性。正是他们的无私帮助和支持,才使得论文的呈现更加完美。

    最后,再次衷心感谢所有在我论文写作过程中给予帮助和支持的每一个人。没有你们的关怀和指导,我无法顺利完成这篇论文。这段经历不仅使我在学术上取得了进步,更让我学会了如何面对挑战和克服困难。我将铭记这段宝贵的时光,并继续在未来的学术道路上努力前行。

    参考文献

    [1]孟斌. OpenHarmony操作系统的UI界面自动化测试方法[J]. 电脑知识与技术, 2022, 32(1): 1-1.

    [2]蒋赛文, 沈利迪. 基于Java Swing技术的企业进销存管理系统的设计与实现. 现代工业经济和信息化, 2022-02-28.

    [3]海玲, 刘文, 刘岩, 王子斌, 周天佑. 基于实践教学的轨道交通联锁模拟仿真平台的设计. 工业控制计算机, 2024-06-24.

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/495606.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

css改变输入右下角图标

前言 正常情况下&#xff0c;HTML textarea 多行文本输入框会存如下图所示图标&#xff0c; 用户可拉动它改变高度&#xff0c;这是我们不想看到的&#xff0c;所以要去掉它。 去掉后&#xff1a; 解决方案 设置 resize 属性即可&#xff0c;如下代码所示&#xff1a; <…

HTML-CSS(day01)

W3C标准&#xff1a; W3C&#xff08; World Wide Web Consortium&#xff0c;万维网联盟&#xff09; W3C是万维网联盟&#xff0c;这个组成是用来定义标准的。他们规定了一个网页是由三部分组成&#xff0c;分别是&#xff1a; 三个组成部分&#xff1a;&#xff08;1&…

2024-12-24 NO1. XR Interaction ToolKit 环境配置

文章目录 1 软件配置2 安装 XRToolKit3 配置 OpenXR4 安装示例场景5 运行测试 1 软件配置 Unity 版本&#xff1a;Unity6000.0.26 ​ 2 安装 XRToolKit 创建新项目&#xff08;URP 3D&#xff09;&#xff0c;点击进入 Asset Store。 进入“Unity Registry”页签&#xff0…

C语言基础——指针(4)

一&#xff0e; 字符指针变量 字符指针变量的使用和整型指针变量的使用方法相似&#xff0c;以下是其基本使用方法的例子&#xff1a; &#xff08;1&#xff09;字符指针变量还有一种使用方法&#xff1a; const char* p "abcd" 需…

week 11 - BCNF

1. More on functional dependencies (功能依赖的更多内容) Lossless decomposition (无损分解) 研究如何在分解表的过程中不丢失信息&#xff0c;也就是说&#xff0c;通过分解后的表可以无损地重建原始表。 2. BCNF (Boyce-Codd Normal Form, BCNF范式) &#xff08;1&…

嵌入式学习-QT-Day06

嵌入式学习-QT-Day06 六、多窗口编程 1、QMessageBox 消息对话框 2、QWidget类 3、parent参数 4、堆栈窗口&#xff08;QStackedWidget&#xff09; 5、新建自定义窗口类 6、对象传值 6.1 父对象 → 子对象 6.2 子对象 → 父对象 7、事件机制 8、QMainWindow主窗口类 8.1 QMenu…

《战神:诸神黄昏》游戏运行时提示找不到gamede.dll文件怎么办?gamede.dll丢失的修复指南

在沉浸于《战神&#xff1a;诸神黄昏》的壮阔世界时&#xff0c;突然弹出的“找不到gamede.dll文件”错误提示可能会让玩家措手不及。作为一名经验丰富的软件开发从业者&#xff0c;我深知这类问题对游戏体验的影响。今天&#xff0c;我将为大家详细解析gamede.dll文件丢失的原…

1.系统学习-线性回归

系统学习-线性回归 前言线性回归介绍误差函数梯度下降梯度下降示例 回归问题常见的评价函数1. MAE, mean absolutely error2. MSE, mean squared error3. R square &#xff08;决定系数或R方&#xff09; 机器学习建模流程模型正则化拓展阅读作业 链接: 2.系统学习-逻辑回归 …

基于微信小程序的校园访客登记系统

基于微信小程序的校园访客登记系统 功能列表 用户端功能 注册与登录 &#xff1a;支持用户通过手机号短信验证码注册和登录。个人资料管理 &#xff1a;允许用户编辑和更新个人信息及其密码。站内信消息通知&#xff1a;通知公告。来访预约&#xff1a;提交来访预约支持车牌…

H3C MPLS跨域optionB

实验拓扑 实验需求 如图,VPN1 和 VPN2 分别通过运营商 MPLS VPN 连接各自分支机构按照图示配置 IP 地址,VPN1 和 VPN2 连接同一个 PE 设备的私网 IP 网段存在地址复用,使用多 VRF 技术来防止 IP 冲突AS 100 和 AS 200 内部的公共网络中各自运行 OSPF 使 AS 内各设备的 Loo…

【项目管理】根据业务流程进行函数结构设计和模块化设计

在开发一个复杂的系统时&#xff0c;根据业务流程进行函数结构设计和模块化设计是一个非常重要的步骤。通过这种方式&#xff0c;能够将复杂的业务逻辑拆分成多个功能模块和函数&#xff0c;使代码更清晰、易维护、易扩展。我们在写代码的时候需要基于对于业务的理解来编程&…

VMware虚拟机中CentOS系统/dev/mapper/centos-home分区扩容指南

要将VMware上新扩展的磁盘添加到CentOS虚拟机,并将其扩容到/dev/mapper/centos-home下,你可以按照以下步骤操作: 一、在VMware中扩展虚拟机磁盘 关闭CentOS虚拟机:确保在扩展磁盘之前,CentOS虚拟机已经关闭。 编辑虚拟机设置:在VMware中,右键点击CentOS虚拟机,选择“设…

GPUStack v0.4.1 单节点与多节点安装与部署指南 Docker PowerShell

Introduce GPUStack 是一个开源的 GPU 集群管理器&#xff0c;专为运行 AI 模型而设计。它以其广泛的硬件兼容性而闻名&#xff0c;支持多种品牌的 GPU&#xff0c;并能在 Apple MacBook、Windows PC 和 Linux 服务器上运行。 GPUStack支持各种AI模型&#xff0c;包括大型语言…

【23种设计模式·全精解析 | 行为型模式篇】11种行为型模式的结构概述、案例实现、优缺点、扩展对比、使用场景、源码解析

Hiヽ(゜▽゜ )&#xff0d;欢迎来到蓝染Aizen的CSDN博客~ &#x1f525; 博客主页&#xff1a; 【✨蓝染 の Blog&#x1f618;】 &#x1f496;感谢大家点赞&#x1f44d; 收藏⭐ 评论✍ 文章目录 行为型模式1、模板方法模式&#xff08;1&#xff09;概述&#xff08;2&…

【解决报错】AttributeError: ‘NoneType‘ object has no attribute ‘group‘

学习爬虫时&#xff0c;遇到如下报错&#xff1a; 报错原因&#xff1a; 正则表达式的 search 或 finditer 方法没有找到任何匹配项&#xff0c;可能是换行符处理不当等。 解决方法如下&#xff1a; 在正则表达式末尾加上re.S即可&#xff0c;re.S是一个编译标志&#xff0c…

一款5k star的 Redis 客户端!!简洁高效!

作为一名热爱编程的程序员&#xff0c;对于高效的工具总是格外追求。在日常的开发中&#xff0c;Redis 作为一款优秀的内存数据库&#xff0c;是我们不可或缺的利器之一。了不起之前也推荐过一些出色的 Redis 客户端&#xff0c;它们在提升我们的开发效率和便利性方面发挥了巨大…

关于科研中使用linux服务器的集锦

文章目录 常用的linux命令下载COCO2017数据集 常用的linux命令 一个文件移动到另一个目录下的命令是&#xff1a;mv -v ./old_name ./new_name 如果目标文件夹中已经有同名文件或文件夹&#xff0c;mv 会覆盖它们&#xff08;除非使用了 -i 选项来提示确认&#xff09;。 使用…

Vue开发环境搭建上篇:安装NVM和NPM(cpnm、pnpm)

文章目录 引言I 安装NVM1.1 Windows系统安装NVM,实现Node.js多版本管理1.2 配置下载镜像1.3 NVM常用操作命令II NPM永久使用淘宝源安装 cnpm安装pnpm【推荐】see also: vscode常用插件引言 淘宝镜像:http://npm.taobao.org 和 http://registry.npm.taobao.org 已在 2022.06.3…

x86_64 Ubuntu 编译安装英伟达GPU版本的OpenCV

手把手带你在Linux上安装带GPU加速的opencv库&#xff08;C版本&#xff09;_opencv linux-CSDN博客 cmake \-D CMAKE_BUILD_TYPERELEASE \-D OPENCV_GENERATE_PKGCONFIGON \-D CMAKE_INSTALL_PREFIX/usr/local \-D OPENCV_EXTRA_MODULES_PATH/home/hwj/opencv/opencv_contrib…

计算机毕业设计Python+卷积神经网络租房推荐系统 租房大屏可视化 租房爬虫 hadoop spark 58同城租房爬虫 房源推荐系统

温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 作者简介&#xff1a;Java领…