Java小型操作系统模拟(采用策略模式结合反射进行搭建,支持一些简单的命令)

Java小型操作系统模拟

    • 项目说明
    • 第一阶段:反射结合策略模式搭建基本的命令结构
    • 第二阶段:注解结合反射与策略模式,将结构进一步规范
    • 第三阶段:开启新的窗口,将控制台输入切换到新窗口中,同时创建右键菜单,使效果贴近命令行
    • 第四阶段,发现IDEA的编译与命令行编译不一致且导致类装载出错的情况进行处理--重新编写初始化的装载方法
    • 第五阶段,解决打包为jar后的装载问题及采用脚本自动编译
    • 项目下载

项目说明

主要是为了学习Java反射的知识,以及对操作系统的一些概念进行回顾,搭建了一个小型的操作系统,包括基本的一些命令,如:clear、help、cd、mkdir、ls等;同时支持用户及角色创建,密码登录等,相关文件采用加密存储在本地;同时采用资源分配的形式设计了磁盘资源和内存资源,采用首次适应、循环首次适应、最佳适应、最坏适应等策略;采用Java的Socket通信设计了简单的socket通信模式

第一阶段:反射结合策略模式搭建基本的命令结构

采用配置文件的形式指定命令的名称、描述与对应类的全路径,采用反射的形式创建对象并装载到容器中;策略模式结合HashMap的形式,可以较为方便的获取到命令对象,并执行对应的策略方法。

策略模式的体现,采用Map进行命令策略的管理

package os.strategy;import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;/*** @author bbyh* @date 2023-07-27 21:19* @description*/
public abstract class BaseStrategy {private static final Map<String, BaseStrategy> STRATEGY_FACTORY = new HashMap<>(4);private static final Map<String, String> STRATEGY_DOC = new HashMap<>(4);private final String name;private final String doc;public BaseStrategy(String name, String doc) {this.name = name;this.doc = doc;}protected final void register() {STRATEGY_FACTORY.put(name, this);STRATEGY_DOC.put(name, doc);}public abstract void execute();public static BaseStrategy getStrategy(String name) {if (!STRATEGY_FACTORY.containsKey(name)) {throw new UnsupportedOperationException("该策略还不支持");}return STRATEGY_FACTORY.get(name);}public static Set<String> getCommandNameSet() {return new HashSet<>(STRATEGY_FACTORY.keySet());}public static Map<String, String> getCommandDoc() {return new HashMap<>(STRATEGY_DOC);}
}

采用配置文件结合反射装载对象;分为只装载指定目录,或装载指定目录及其子目录,要求都是基础策略类的子类

package os.util;import os.strategy.BaseStrategy;import java.io.*;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.HashSet;
import java.util.Properties;/*** @author bbyh* @date 2023/7/28 12:19*/
public class OsApplication {private static final String PACKAGE_PREFIX = "src/";private static final String DEFAULT_STRATEGY_PACKAGE = "strategy.impl";private static final String OS_COMMAND_PROPERTIES = "os-command-config.properties";private static final HashSet<Class<?>> CLASS_SET = new HashSet<>(4);private static void load() {for (Class<?> instance : CLASS_SET) {if (instance.getSuperclass() == BaseStrategy.class) {try (InputStream inputStream = Files.newInputStream(Paths.get(OS_COMMAND_PROPERTIES))) {Properties properties = new Properties();properties.load(inputStream);if (properties.containsKey(instance.getName())) {String[] split = properties.getProperty(instance.getName()).split(",");try {Constructor<?> constructor = instance.getConstructor(String.class, String.class);Object newInstance = constructor.newInstance(split[0], split[1]);Method register = newInstance.getClass().getSuperclass().getDeclaredMethod("register");register.setAccessible(true);register.invoke(newInstance);} catch (NoSuchMethodException | InvocationTargetException |IllegalAccessException | InstantiationException e) {throw new RuntimeException(e);}}} catch (IOException e) {throw new RuntimeException(e);}}}}public static void runWithSpecifiedDirectory(Class<?> application) {initSpecifiedDirectory(application.getPackage().getName() + "." + DEFAULT_STRATEGY_PACKAGE);load();}private static void initSpecifiedDirectory(String scanPackage) {File basePackage = new File(PACKAGE_PREFIX + scanPackage.replace(".", "/"));File[] files = basePackage.listFiles(file -> file.getName().endsWith(".java"));loadClasses(scanPackage, files);}private static void loadClasses(String scanPackage, File[] files) {if (files != null) {for (File file : files) {try {Class<?> instance = Class.forName(scanPackage + "." + file.getName().replace(".java", ""));CLASS_SET.add(instance);} catch (ClassNotFoundException e) {throw new RuntimeException(e);}}}}public static void runWithRecursiveDirectory(Class<?> application) {initRecursiveDirectory(application.getPackage().getName());load();}private static void initRecursiveDirectory(String scanPackage) {File basePackage = new File(PACKAGE_PREFIX + scanPackage.replace(".", "/"));File[] files = basePackage.listFiles(file -> {if (file.isDirectory()) {initRecursiveDirectory(scanPackage + "." + file.getName());}return file.getName().endsWith(".java");});loadClasses(scanPackage, files);}
}

配置文件

os.strategy.impl.ClearStrategy=clear,清屏命令,清空屏幕
os.strategy.impl.HelpStrategy=help,帮助命令,查看当前系统支持的命令

项目结构
在这里插入图片描述

第二阶段:注解结合反射与策略模式,将结构进一步规范

采用类似SpringBoot的启动方式,自动装载指定目录下的命令类,采用注解的形式设置命令的名称与描述

采用注解设置启动装载包目录名,以及各个策略类的目录名称与相关说明

package os.annotation;import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;/*** @author bbyh* @date 2023/7/2 15:29*/
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface StrategyScan {String value() default "strategy.impl";
}

help命令,简单输出系统支持的命令和说明

package os.strategy.impl;import os.annotation.StrategyAnnotation;
import os.annotation.StrategyDocAnnotation;
import os.strategy.BaseStrategy;import java.util.Map;
import java.util.Set;/*** @author bbyh* @date 2023-07-27 21:26* @description*/
@StrategyAnnotation(commandName = "help")
@StrategyDocAnnotation(commandDoc = "帮助命令,查看当前系统支持的命令")
public class HelpStrategy extends BaseStrategy {public HelpStrategy(String name, String doc) {super(name, doc);}@Overridepublic void execute() {System.out.println("系统支持的命令");Set<String> commandNameSet = BaseStrategy.getCommandNameSet();Map<String, String> commandDoc = BaseStrategy.getCommandDoc();for (String commandName : commandNameSet) {System.out.println(commandName + ":" + commandDoc.get(commandName));}}
}

同样加载指定目录下携带注解的策略子类,或者加载目录及其子目录的所有符合条件的类

package os.util;import os.annotation.StrategyAnnotation;
import os.annotation.StrategyDocAnnotation;
import os.annotation.StrategyScan;
import os.strategy.BaseStrategy;import java.io.File;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashSet;/*** @author bbyh* @date 2023/7/28 12:19*/
public class OsApplication {private static final String PACKAGE_PREFIX = "src/";private static final HashSet<Class<?>> CLASS_SET = new HashSet<>(4);private static void load() {for (Class<?> instance : CLASS_SET) {if (instance.getSuperclass() == BaseStrategy.class) {try {StrategyAnnotation nameAnnotation = instance.getAnnotation(StrategyAnnotation.class);StrategyDocAnnotation docAnnotation = instance.getAnnotation(StrategyDocAnnotation.class);if (nameAnnotation != null && docAnnotation != null) {Constructor<?> constructor = instance.getConstructor(String.class, String.class);Object newInstance = constructor.newInstance(nameAnnotation.commandName(), docAnnotation.commandDoc());Method register = newInstance.getClass().getSuperclass().getDeclaredMethod("register");register.setAccessible(true);register.invoke(newInstance);}} catch (NoSuchMethodException | InvocationTargetException |IllegalAccessException | InstantiationException e) {throw new RuntimeException(e);}}}}/*** 加载配置目录下的添加了StrategyAnnotation注解的类** @param application 启动类*/public static void runWithSpecifiedDirectory(Class<?> application) {StrategyScan strategyScan = application.getAnnotation(StrategyScan.class);initSpecifiedDirectory(application.getPackage().getName() + "." + strategyScan.value());load();}private static void initSpecifiedDirectory(String scanPackage) {File basePackage = new File(PACKAGE_PREFIX + scanPackage.replace(".", "/"));File[] files = basePackage.listFiles(file -> file.getName().endsWith(".java"));loadClasses(scanPackage, files);}private static void loadClasses(String scanPackage, File[] files) {if (files != null) {for (File file : files) {try {Class<?> instance = Class.forName(scanPackage + "." + file.getName().replace(".java", ""));CLASS_SET.add(instance);} catch (ClassNotFoundException e) {throw new RuntimeException(e);}}}}/*** 加载配置目录及其子目录下的添加了StrategyAnnotation注解的类** @param application 启动类*/public static void runWithRecursiveDirectory(Class<?> application) {initRecursiveDirectory(application.getPackage().getName());load();}private static void initRecursiveDirectory(String scanPackage) {File basePackage = new File(PACKAGE_PREFIX + scanPackage.replace(".", "/"));File[] files = basePackage.listFiles(file -> {if (file.isDirectory()) {initRecursiveDirectory(scanPackage + "." + file.getName());}return file.getName().endsWith(".java");});loadClasses(scanPackage, files);}
}

项目结构
在这里插入图片描述

第三阶段:开启新的窗口,将控制台输入切换到新窗口中,同时创建右键菜单,使效果贴近命令行

经过测试发现,上面两个系统在初始化加载类时有一些小问题,因为在实际使用时都是执行class文件,而在IDEA里面的执行是以Java文件为路径的,需要进行一些简单的小修改,当前这个阶段主要以IDEA里面的运行为主,后面再对路径和初始化逻辑进行一些调整,来保证兼容性

主窗体

package os.util;import os.strategy.BaseStrategy;import javax.swing.*;
import java.awt.*;
import java.awt.datatransfer.Clipboard;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable;
import java.awt.datatransfer.UnsupportedFlavorException;
import java.awt.event.*;
import java.io.IOException;/*** @author bbyh* @date 2023-07-29 15:51* @description*/
public class MainFrame extends JFrame {public static final JLabel DISPLAY = new JLabel();private static final String DEFAULT_WORD_DIR = "C:\\root>";public MainFrame() {setTitle("BBYH OS System");setSize(1000, 600);setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);setLocationRelativeTo(null);JScrollPane scrollPane = new JScrollPane(DISPLAY);DISPLAY.setOpaque(true);DISPLAY.setBackground(Color.WHITE);setLayout(new GridLayout(1, 1));add(scrollPane);setVisible(true);Font font = new Font("Consolos", Font.PLAIN, 24);DISPLAY.setFont(font);DISPLAY.setVerticalAlignment(SwingConstants.TOP);DISPLAY.setFocusable(true);init();// 右键菜单JPopupMenu rightMenu = new JPopupMenu();JMenuItem backgroundItem = new JMenuItem();JMenuItem fontItem = new JMenuItem();JMenuItem copyItem = new JMenuItem();backgroundItem.setFont(font);fontItem.setFont(font);copyItem.setFont(font);backgroundItem.setText("设置背景颜色");fontItem.setText("设置字体颜色");copyItem.setText("复制剪切版内容");rightMenu.add(backgroundItem);rightMenu.add(fontItem);rightMenu.add(copyItem);backgroundItem.addActionListener(evt -> {Color color = JColorChooser.showDialog(null, "设置背景颜色", Color.WHITE);if (color != null) {DISPLAY.setBackground(color);}});fontItem.addActionListener(evt -> {Color color = JColorChooser.showDialog(null, "设置字体颜色", Color.BLACK);if (color != null) {DISPLAY.setForeground(color);}});copyItem.addActionListener(evt -> {Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();Transferable transferable = clipboard.getContents(null);if (transferable != null) {if (transferable.isDataFlavorSupported(DataFlavor.stringFlavor)) {try {String data = (String) clipboard.getData(DataFlavor.stringFlavor);appendDisplay(data);} catch (UnsupportedFlavorException | IOException e) {throw new RuntimeException(e);}}}});DISPLAY.addKeyListener(new KeyAdapter() {@Overridepublic void keyPressed(KeyEvent e) {char keyChar = e.getKeyChar();if (keyChar == KeyEvent.VK_BACK_SPACE && !"".equals(getContent())) {DISPLAY.setText(getContent().substring(0, getContent().length() - 1));appendDisplay("");} else if (keyChar == KeyEvent.VK_ENTER) {appendDisplay("<br />");try {BaseStrategy.getStrategy(Context.getNextCommand()).execute();} catch (Exception ex) {appendDisplay(ex.getMessage() + "<br />");}appendDisplay(Context.getWorkDir());} else if (Character.isLetterOrDigit(keyChar)) {appendDisplay(String.valueOf(keyChar));}}});DISPLAY.addMouseListener(new MouseAdapter() {@Overridepublic void mouseClicked(MouseEvent e) {if (e.getButton() == MouseEvent.BUTTON3) {rightMenu.show(DISPLAY, e.getX(), e.getY() - 10);}}});}private static void init() {Context.setWorkDir(DEFAULT_WORD_DIR);appendDisplay(DEFAULT_WORD_DIR);}public static void appendDisplay(String content) {DISPLAY.setText("<html><body style='padding: 20px 10px'>" + getContent() + content + "</body></html>");}private static String getContent() {return DISPLAY.getText().replace("<html><body style='padding: 20px 10px'>", "").replace("</body></html>", "");}
}

Context上下文操作类

package os.util;/*** @author bbyh* @date 2023-07-27 22:23* @description*/
public class Context {private static String workDir;public static String getWorkDir() {return workDir;}public static void setWorkDir(String workDir) {Context.workDir = workDir;}public static String getNextCommand() {String text = MainFrame.DISPLAY.getText();return text.substring(text.lastIndexOf(getWorkDir()) + getWorkDir().length(), text.lastIndexOf("<br /></body></html>"));}
}

主程序

package os;import os.annotation.StrategyScan;
import os.util.MainFrame;
import os.util.OsApplication;/*** @author bbyh* @date 2023-07-27 21:18* @description*/
@StrategyScan
public class Main {public static void main(String[] args) {OsApplication.runWithRecursiveDirectory(Main.class);new MainFrame();}
}

测试运行效果展示
在这里插入图片描述

第四阶段,发现IDEA的编译与命令行编译不一致且导致类装载出错的情况进行处理–重新编写初始化的装载方法

采用getResource方法获取类路径,来装在class文件,同时采用脚本来解决javac命令行执行时无法编译不被别的文件依赖的策略实现类

重新编写的装载方法,采用递归装载,装载启动类目录下及其子目录中带有注解的策略实现类

package os.util;import os.annotation.StrategyAnnotation;
import os.annotation.StrategyDocAnnotation;
import os.strategy.BaseStrategy;import java.io.File;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashSet;
import java.util.Objects;/*** @author bbyh* @date 2023/7/28 12:19*/
public class OsApplication {private static final HashSet<Class<?>> CLASS_SET = new HashSet<>(4);private static String BASE_PATH;/*** 加载配置目录及其子目录下的添加了StrategyAnnotation注解的类** @param application 启动类*/public static void runWithRecursiveDirectory(Class<?> application) {BASE_PATH = Objects.requireNonNull(application.getResource("/")).getPath();initRecursiveDirectory(application.getPackage().getName());load();}private static void initRecursiveDirectory(String packageName) {File[] files = new File(BASE_PATH + packageName.replace(".", System.getProperty("file.separator"))).listFiles(file -> {if (file.isDirectory()) {initRecursiveDirectory(packageName + "." + file.getName());}return file.getName().endsWith(".class");});loadClasses(packageName, files);}private static void load() {for (Class<?> instance : CLASS_SET) {if (instance.getSuperclass() == BaseStrategy.class) {try {StrategyAnnotation nameAnnotation = instance.getAnnotation(StrategyAnnotation.class);StrategyDocAnnotation docAnnotation = instance.getAnnotation(StrategyDocAnnotation.class);if (nameAnnotation != null && docAnnotation != null) {Constructor<?> constructor = instance.getConstructor(String.class, String.class);Object newInstance = constructor.newInstance(nameAnnotation.commandName(), docAnnotation.commandDoc());Method register = newInstance.getClass().getSuperclass().getDeclaredMethod("register");register.setAccessible(true);register.invoke(newInstance);}} catch (NoSuchMethodException | InvocationTargetException |IllegalAccessException | InstantiationException e) {throw new RuntimeException(e);}}}}private static void loadClasses(String packageName, File[] files) {if (files != null) {for (File file : files) {try {Class<?> instance = Class.forName(packageName + "." + file.getName().replace(".class", ""));CLASS_SET.add(instance);} catch (ClassNotFoundException e) {throw new RuntimeException(e);}}}}
}

需要注意的一点是,目前采用getResource方法对于打包为jar包时则会报空指针错误,后续将考虑采用新方法装载来解决该问题

第五阶段,解决打包为jar后的装载问题及采用脚本自动编译

自动编译的脚本,Windows

mkdir out
cd src
javac -d ../out os/Main.java os/strategy/impl/*.java -encoding UTF-8cd ../outjava os.Main

自动编译的脚本,Linux

#!/bin/bash
mkdir out
cd src
javac -d ../out os/Main.java os/strategy/impl/*.java -encoding UTF-8
cd ../out
java os.Main

需要注意几点小问题,脚本.sh需要在Linux下创建使用,同时需要给它赋予x执行权限(chmod +x javac_os_java.sh);然后在执行时还需要对XShell安装一下图形服务x11,参考文章:xshell-linux 启动 jmeter 报 No X11 DISPLAY variable was set, but this program performed …;不过这个Xming对中文的显示有问题,有点难办

主函数(根据启动不一样采用不一样的装载策略)

package os;import os.annotation.StrategyScan;
import os.util.MainFrame;
import os.util.OsApplication;import java.util.Objects;/*** @author bbyh* @date 2023-07-27 21:18* @description*/
@StrategyScan
public class Main {public static boolean applicationRunning = true;private static final String FILE_PROTOCOL = "file";private static final String JAR_PROTOCOL = "jar";public static void main(String[] args) {String protocol = Objects.requireNonNull(OsApplication.class.getResource("")).getProtocol();if (Objects.equals(protocol, FILE_PROTOCOL)) {OsApplication.runWithRecursiveDirectory(Main.class);} else if (Objects.equals(protocol, JAR_PROTOCOL)) {OsApplication.runWithRecursiveJar(Main.class);}new MainFrame();}
}

装载工具类

package os.util;import os.annotation.StrategyAnnotation;
import os.annotation.StrategyDocAnnotation;
import os.strategy.BaseStrategy;import java.io.File;
import java.io.IOException;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.Objects;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;/*** @author bbyh* @date 2023/7/28 12:19*/
public class OsApplication {private static final HashSet<Class<?>> CLASS_SET = new HashSet<>(4);private static String BASE_PATH;public static final String FILE_SEPARATOR = "/";private static final String PREFIX_FILE = "file:";private static final String PREFIX_JAR = "jar:file:";private static final String SUFFIX_CLASS = ".class";/*** 加载配置目录及其子目录下的添加了StrategyAnnotation注解的类** @param application 启动类*/public static void runWithRecursiveDirectory(Class<?> application) {BASE_PATH = Objects.requireNonNull(application.getResource("")).toString().replace(PREFIX_FILE, "");String packageName = application.getPackage().getName();BASE_PATH = BASE_PATH.substring(0, BASE_PATH.lastIndexOf("/" + packageName + "/")) + FILE_SEPARATOR;initRecursiveDirectory(packageName);load();}private static void initRecursiveDirectory(String packageName) {File[] files = new File(BASE_PATH + packageName.replace(".", FILE_SEPARATOR)).listFiles(file -> {if (file.isDirectory()) {initRecursiveDirectory(packageName + "." + file.getName());}return file.getName().endsWith(SUFFIX_CLASS);});loadFileClasses(packageName, files);}private static void loadFileClasses(String packageName, File[] files) {if (files != null) {for (File file : files) {try {Class<?> instance = Class.forName(packageName + "." + file.getName().replace(SUFFIX_CLASS, ""));CLASS_SET.add(instance);} catch (ClassNotFoundException e) {throw new RuntimeException(e);}}}}private static void load() {for (Class<?> instance : CLASS_SET) {if (instance.getSuperclass() == BaseStrategy.class) {try {StrategyAnnotation nameAnnotation = instance.getAnnotation(StrategyAnnotation.class);StrategyDocAnnotation docAnnotation = instance.getAnnotation(StrategyDocAnnotation.class);if (nameAnnotation != null && docAnnotation != null) {Constructor<?> constructor = instance.getConstructor(String.class, String.class);Object newInstance = constructor.newInstance(nameAnnotation.commandName().split(" ")[0], docAnnotation.commandDoc());Method register = newInstance.getClass().getSuperclass().getDeclaredMethod("register");register.setAccessible(true);register.invoke(newInstance);}} catch (NoSuchMethodException | InvocationTargetException |IllegalAccessException | InstantiationException e) {throw new RuntimeException(e);}}}}public static void runWithRecursiveJar(Class<?> application) {BASE_PATH = Objects.requireNonNull(application.getResource("")).toString().replace(PREFIX_JAR, "");BASE_PATH = BASE_PATH.substring(0, BASE_PATH.lastIndexOf("!/" + application.getPackage().getName() + "/")) + FILE_SEPARATOR;initRecursiveJar();load();}private static void initRecursiveJar() {try (JarFile jarFile = new JarFile(BASE_PATH)) {Enumeration<JarEntry> jarEntryEnumeration = jarFile.entries();while (jarEntryEnumeration.hasMoreElements()) {JarEntry jarEntry = jarEntryEnumeration.nextElement();if (jarEntry.getName().endsWith(SUFFIX_CLASS)) {Class<?> instance = Class.forName(jarEntry.getName().replace(SUFFIX_CLASS, "").replace("/", "."));CLASS_SET.add(instance);}}} catch (IOException | ClassNotFoundException e) {throw new RuntimeException(e);}}}

运行效果
在这里插入图片描述

项目下载

Gitee链接–Java模拟操作系统

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

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

相关文章

【雕爷学编程】MicroPython动手做(27)——物联网之掌控板小程序3

知识点&#xff1a;什么是掌控板&#xff1f; 掌控板是一块普及STEAM创客教育、人工智能教育、机器人编程教育的开源智能硬件。它集成ESP-32高性能双核芯片&#xff0c;支持WiFi和蓝牙双模通信&#xff0c;可作为物联网节点&#xff0c;实现物联网应用。同时掌控板上集成了OLED…

Web服务器实验案例

目录 关闭或放行防火墙和selinux 1 搭建静态网站 2 建立两个基于ip地址访问的网站 思路&#xff1a; 简单配置 编写httpd额外文件 3 建立两个基于不同端口访问的网站 思路 创建文件&#xff08;与之前一致&#xff09; 额外文件配置 4 基于虚拟目录和用户控制的web网…

Stable Diffusion AI绘画学习指南【本地环境搭建win+mac】

一、硬件配配置要求 系统&#xff1a;windows 10 / Mac os 硬盘&#xff1a;C 盘预留 15GB 以上&#xff0c;其他盘 50GB 以上,Stable Ddiffusion的很多大模型都是以 GB 起步。 显卡&#xff1a;4GB 以上&#xff0c;建议 8GB, 效率高&#xff0c;能玩大尺寸的图 CPU&…

Jenkins常用命令(Linux篇)

查看jenkins是否运行&#xff1a; systemctl status jenkins.service 查看运行日志&#xff1a; journalctl -xe 启动命令&#xff1a; systemctl start jenkins 查看状态&#xff1a; systemctl status jenkins 修改文件后重新加载&#xff1a;systemctl daemon-reload 修改端…

微信小程序(van-tabs) 去除横向滚动条样式(附加源码解决方案+报错图)

问题描述 今天第一次接触vant组件库。 ant官网地址适用于Vue3 支持Vue2、Vue3、微信小程序等 我在使用van-tabs组件时遇到了一个问题&#xff0c;如下图所示&#xff1a; 从图片上可以看到有个灰色的横向滚动条&#xff0c;一开始领导给我说这个问题&#xff0c;我反反复复都…

C++ xmake构建

文章目录 一、xmake.lua二、xmake常用语句 一、xmake.lua --xmake.luaset_project("XXX")add_rules("mode.debug", "mode.release") set_config("arch", "x64")if is_plat("windows") then -- the release modei…

C++ ——stack、queue容器模拟实现及deque容器底层介绍

deque文档 stack文档 deque文档 文章目录 &#x1f345;1. deque容器&#x1f352;deque底层&#x1f352;deque的优势&#x1f352;deque的劣势 &#x1fad0;2. stack模拟实现&#x1f95d;3. queue模拟实现 &#x1f345;1. deque容器 查看文档可发现&#xff0c;栈和队列都…

linux防火墙

一、前言 防火墙&#xff0c;其实说白了讲&#xff0c;就是用于实现Linux下访问控制的功能的&#xff0c;它分为硬件的或者软件的防火墙两种。无论是在哪个网络中&#xff0c;防火墙工作的地方一定是在网络的边缘。而我们的任务就是需要去定义到底防火墙如何工作&#xff0c;这…

Netty自定义消息协议的实现逻辑处理粘包拆包、心跳机制

Netty 自定义消息协议的实现逻辑自定义编码器 心跳机制实现客户端发送心跳包 自定义消息协议的实现逻辑 消息协议&#xff1a;这一次消息需要包含两个部分&#xff0c;即消息长度和消息内容本身。 自定义消息编码器︰消息编码器将客户端发送的消息转换成遵守消息协议的消息&…

pandas调整文件列顺序

使用loc索引器&#xff0c;可以传入一个列序列表给loc索引器来重新排列列顺序。例如&#xff1a;dfdf[[col3,col2,col1]]&#xff0c;这将col3列置于第一列&#xff0c;col2列置于第二列&#xff0c;col1列置于第三列。使用loc整数位置选择器&#xff0c;dfdf.iloc[:,[2,1,0]]使…

spring boot 拦截器例子

在Spring Boot中&#xff0c;拦截器是通过实现HandlerInterceptor接口来实现的。它允许你在请求到达控制器方法之前和之后执行自定义的逻辑。下面我将为你提供一个简单的Spring Boot拦截器的例子。 假设我们有一个简单的控制器类UserController&#xff0c;其中有两个请求处理…

Linux第一个小程序-进度条(缓冲区概念)

1.\r和\n C语言中有很多字符 a.可显字符 b.控制字符 对于回车其实有两个动作&#xff0c;首先换行&#xff0c;在将光标指向最左侧 \r &#xff1a;回车 \n&#xff1a;换行 下面举个例子&#xff1a; 把\n去掉会怎样 什么都没输出。为什么&#xff1f; 2.缓冲区概念 观察下两个…

微信小程序性能优化

一、提高小程序速度 优化小程序的速度是最基本的需求之一&#xff0c;因为流畅的使用体验对于用户来说非常重要。可以采取以下措施来提高小程序的速度&#xff1a; 压缩代码 编写高效的代码是提高小程序速度的关键之一&#xff0c;开发者可以使用一些工具来对代码进行压缩&…

网工内推 | 网络安全工程师,最高15K,有高温补贴

01 超圣信华 招聘岗位&#xff1a;网络安全工程师 职责描述&#xff1a; 1. 负责网络安全产品的售前沟通交流、现状调研、方案设计、产品测试、产品选型和招投标等工作。 2. 负责网络安全集成项目的实施管理、项目交付文档编制以及项目验收等工作。 3. 负责网络安全产品的售后…

Vue中对对象内容调用的Demo

目录 1.对象作为数据&#xff1a; 2.对象数组 在Vue中&#xff0c;你可以通过对象的键来调用对象中的各个部分的内容。下面是一些使用Vue调用对象各部分内容的示例&#xff1a; 1.对象作为数据&#xff1a; 如果你在Vue实例的数据中有一个对象&#xff0c;你可以使用点语法来…

C#中i++和++i的底层原理

一&#xff1a;前言 我们都知道&#xff0c;i是先取值&#xff0c;后计算。i是先计算&#xff0c;后取值。下面说下它的底层原理 运算符优先级与运算顺序&#xff1a; 运算符的优先级只是影响了表达式中的结合顺序&#xff0c;不会影响运算顺序&#xff0c;运算顺序永远都是从…

在云服务器上,clone github时报Connection timed outexit code: 128

文章目录 问题解决方案 问题 在执行pip install安装依赖时&#xff0c;需要clone github代码&#xff0c;此时报了Connection timed out&exit code: 128错误&#xff0c;原因是访问超时了&#xff0c;此时需要使用代理 fatal: unable to access https://github.com/hugg…

【MATLAB第62期】基于MATLAB的PSO-NN、BBO-NN、前馈神经网络NN回归预测对比

【MATLAB第62期】基于MATLAB的PSO-NN、BBO-NN、前馈神经网络NN回归预测对比 一、数据设置 1、7输入1输出 2、103行样本 3、80个训练样本&#xff0c;23个测试样本 二、效果展示 NN训练集数据的R2为&#xff1a;0.73013 NN测试集数据的R2为&#xff1a;0.23848 NN训练集数据的…

Python tqdm的两种用法【教程】

Python tqdm的两种用法 本文记录一下在学习深度强化学习过程中遇到tqdm库显示进度条的用法&#xff0c;以供大家交流。 注意本文使用的tqdm均是使用的tqdm库中的同名tqdm方法&#xff0c;应该按照如下方式导入 from tqdm import tqdmCatologue Python tqdm的两种用法1. 基于可…