jbase仪器接口设计

news2024/9/28 21:25:10

jbase的计划有借助虚拟M来实现连仪器,之前陆续写了些TCP逻辑,今天终于整理完成了仪器设计。首先用java的cs程序测试TCP的服务和客户端。

javafx的示例加强

package sample;

import javafx.application.Application;
import javafx.event.EventHandler;
import javafx.fxml.FXMLLoader;
import javafx.geometry.Pos;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.FlowPane;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
import javafx.scene.control.Button;
import javafx.scene.control.TextArea;
import javafx.scene.control.ScrollPane;

import java.awt.*;
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.atomic.AtomicInteger;

public class Main extends Application {

    //数字
    static int num = 0;

    //场景
    Scene scene;

    //场景1
    Scene scene1;

    //定时发送
    Socket sendSocket = null;

    //自动发送次数
    int sendNum = 0;

    //通讯日志
    StringBuilder sbLog=new StringBuilder();

    //换行符
    String lineStr=System.getProperty("line.separator");


    @Override
    public void start(Stage stage) throws Exception {
        //舞台标题
        stage.setTitle("第一个java程序");
        // 流式布局:按照控件的添加次序按个摆放,按照从上到下、从左到右的次序摆放。
        FlowPane pane = new FlowPane(5, 5);
        // 居中显示
        pane.setAlignment(Pos.CENTER);
        // 场景
        scene = new Scene(pane, 800, 600);


        // 标签
        Label label = new Label("初始值:" + num);


        // 加1按钮
        Button addButton = new Button("加1");
        addButton.setOnMouseClicked(e -> {
            num++;
            label.setText("当前值:" + num);
        });

        //减1按钮
        Button subButton = new Button("减1");
        subButton.setOnMouseClicked(e -> {
            num--;
            label.setText("当前值:" + num);
        });

        //切换到场景1
        Button btnScene1 = new Button("场景1");
        btnScene1.setOnMouseClicked(e -> {
            stage.setScene(scene1);
        });

        //弹出一个子窗口
        Button btnShowChildForm = new Button("子窗口");
        btnShowChildForm.setOnMouseClicked(e -> {
            Child.ShowChild("子窗口", "传给子窗口的参数");
        });

        // 创建一个TextArea控件
        TextArea textArea = new TextArea();
        textArea.setWrapText(true); // 设置文本自动换行

        //定时器,主动上传时候用
        Timer timer = new Timer();
        TimerTask task = new TimerTask() {
            @Override
            public void run() {
                if (sendSocket != null) {
                    try {
                        sendNum++;
                        // 发送请求消息到服务端
                        OutputStream outputStream = sendSocket.getOutputStream();
                        PrintWriter out = new PrintWriter(new OutputStreamWriter(outputStream, "GBK"), true);
                        out.println("这是定时发送的第" + sendNum + "次数据");
                        out.flush();
                    } catch (Exception ex) {

                    }
                }
            }
        };
        // 设置定时器的执行策略,延迟0秒后开始执行,每隔1秒执行一次
        timer.schedule(task, 0, 5000);


        //启动tcp服务
        Button btnTcpServer = new Button("TCP服务");
        btnTcpServer.setOnMouseClicked(e -> {
            Thread clientThread = new Thread(new Runnable() {
                @Override
                public void run() {
                    try {
                        ServerSocket serverSocket = new ServerSocket(8888);
                        //增加一个无限循环
                        while (true) {
                            sbLog.append("服务启动"+lineStr);
                            System.out.println("服务启动");
                            //通知界面
                            javafx.application.Platform.runLater(()->{
                                textArea.setText(sbLog.toString());
                            });
                            //等待客户端连接,阻塞
                            Socket clientSocket = serverSocket.accept();
                            sendSocket = clientSocket;
                            //得到输出流
                            PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true);
                            System.out.println("客户端连接");
                            sbLog.append("客户端连接"+lineStr);
                            //通知界面
                            javafx.application.Platform.runLater(()->{
                                textArea.setText(sbLog.toString());
                            });
                            //得到输入流
                            InputStream inputStream = clientSocket.getInputStream();
                            //IO读取
                            byte[] buf = new byte[10240];
                            int readlen = 0;
                            //阻塞读取数据
                            while ((readlen = inputStream.read(buf)) != -1) {
                                System.out.println(new String(buf, 0, readlen, "GBK"));
                                sbLog.append(new String(buf, 0, readlen, "GBK")+lineStr);
                                //通知界面
                                javafx.application.Platform.runLater(()->{
                                    textArea.setText(sbLog.toString());
                                });
                            }
                            //关闭输入
                            inputStream.close();
                            //关闭输出
                            out.close();
                            clientSocket.close();
                        }
                    } catch (Exception e) {

                    }
                }
            });
            clientThread.start();
        });

        //启动tcp客户端
        Button btnTcpClient = new Button("TCP客户端");
        btnTcpClient.setOnMouseClicked(e -> {
            Thread clientThread = new Thread(new Runnable() {
                @Override
                public void run() {
                    try {
                        try {
                            // 创建 Socket 对象并连接到服务端
                            Socket socket = new Socket("172.16.1.232", 1991);
                            sendSocket = socket;
                            // 发送请求消息到服务端
                            OutputStream outputStream = socket.getOutputStream();
                            PrintWriter out = new PrintWriter(new OutputStreamWriter(outputStream, "GBK"), true);
                            out.println("你好,我是客户端");
                            out.flush();
                            //得到输入流
                            InputStream inputStream = socket.getInputStream();
                            //IO读取
                            byte[] buf = new byte[10240];
                            int readlen = 0;
                            //阻塞读取数据
                            while ((readlen = inputStream.read(buf)) != -1) {
                                System.out.println(new String(buf, 0, readlen, "GBK"));
                                sbLog.append(new String(buf, 0, readlen, "GBK")+lineStr);
                                out.println("我已经收到数据");
                                //通知界面
                                javafx.application.Platform.runLater(()->{
                                    textArea.setText(sbLog.toString());
                                });
                            }
                            //关闭输入
                            inputStream.close();
                            //关闭输出
                            out.close();
                            // 关闭连接
                            socket.close();
                        } catch (IOException ex) {
                            ex.printStackTrace();
                        }
                    } catch (Exception e) {

                    }
                }
            });
            clientThread.start();
        });

        pane.getChildren().addAll(addButton, subButton, btnScene1, btnShowChildForm, label, textArea, btnTcpServer, btnTcpClient);


        // 场景1
        // 流式布局:按照控件的添加次序按个摆放,按照从上到下、从左到右的次序摆放。
        FlowPane pane1 = new FlowPane(10, 10);
        // 居中显示
        pane1.setAlignment(Pos.CENTER);
        scene1 = new Scene(pane1, 200, 150);

        //返回开始的场景
        Button btnReturn = new Button("返回");
        btnReturn.setOnMouseClicked(e -> {
            stage.setScene(scene);
        });
        pane1.getChildren().addAll(btnReturn);

        //默认场景和显示
        stage.setScene(scene);
        stage.show();
    }


    public static void main(String[] args) {
        launch(args);
    }
}

在这里插入图片描述

客户端测试成功后设计jbase仪器基础,这里首先要理解连设备的本质,连TCP设备的话,其实真正的业务只关心我当做客户端还是服务端、以什么编码、然后解析和发送数据,我并不想关系TCP的实现细节。所以可以把初始化TCP和处理数据及定时上传以接口形式抽取出来。

先抽取处理仪器数据接口IMachDealData,具体仪器只需要实现该接口即可,抽取变性很重要

package LIS.Core.Socket;

import java.io.PrintWriter;
import java.net.Socket;

/**
 * 仪器处理数据接口,具体的仪器接口实现此接口后初始化MachSocketBase对象
 */
public interface IMachDealData {
    /**
     * 处理上传定时器接口
     * @param sender Socket对象,用来发送比特用
     * @param writer 用来发布初始化指定的字符用
     */
    public void DealUpTimer(Socket sender, PrintWriter writer);

    /**
     * 处理数据接收
     * @param data 公共层处理成字符串的数据
     * @param buf 没处理的比特数组
     * @param sender Socket对象,用来发送比特用
     * @param writer 用来发布初始化指定的字符用
     */
    public void DealReceive(String data, byte[] buf, Socket sender, PrintWriter writer);

}

然后实现MachSocketBase类作为连接TCP仪器的基础类,里面实现了tcp的客户端和服务端和定时器,里面对数据处理都是调用接口操作

package LIS.Core.Socket;

import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;

import LIS.Core.Socket.IMachDealData;
import LIS.Core.Util.LogUtils;

/**
 * 通过Socket连接的仪器操作基类,由该类提供TCP客户端和服务端的公共逻辑,并且调用处理数据接口处理数据,从而分离TCP主体和业务处理逻辑,达到简化连设备目的
 */
public class MachSocketBase {
    /**
     * 发送数据的操作对象
     */
    public Socket Sender = null;

    /**
     * 写操作对象
     */
    public PrintWriter Writer = null;

    /**
     * 主动上传定时器
     */
    public Timer UpTimer = null;

    /**
     * 处理接口对象
     */
    public IMachDealData DealObj;

    /**
     * 编码
     */
    public String Encode;

    /**
     * 要关闭的客户端端口
     */
    private Socket closeSocket = null;

    /**
     * 要关闭的服务端口
     */
    private ServerSocket closeServerSocket = null;

    /**
     * 存IP和端口的唯一标识串
     */
    public String ID;

    /**
     * 处理类的全面
     */
    public String DealClassName;

    /**
     * 主处理进程
     */
    Thread MainThread = null;

    /**
     * 定时器任务
     */
    TimerTask timerTask = null;

    /**
     * 上传间隔
     */
    Long UpPeriod = null;

    /**
     * 存启动和停止的错误串
     */
    public String Err="";

    /**
     * 停止负载
     *
     * @return 有错误就返回错误
     */
    public String Stop() {
        try {
            if (MainThread != null) {
                MainThread.interrupt();
            }
            if (UpTimer != null) {
                UpTimer.cancel();
            }
            if (closeSocket != null) {
                closeSocket.close();
                ;
            }
            if (closeServerSocket != null) {
                closeServerSocket.close();
                ;
            }
        } catch (Exception ex) {
            Err=ex.getCause().getMessage();
            LogUtils.WriteExceptionLog("停止仪器TCP异常", ex);
            return ex.getCause().getMessage();
        }
        return "";
    }


    /**
     * 启动连接和定时器
     * @return 有错误就返回错误
     */
    public String Start() {
        try {
            if (UpTimer != null) {
                // 设置定时器的执行策略,延迟0秒后开始执行,每隔1秒执行一次
                UpTimer.schedule(timerTask, 0, UpPeriod);
            }
            if (MainThread != null) {
                MainThread.start();
            }
        } catch (Exception ex) {
            Err=ex.getCause().getMessage();
            LogUtils.WriteExceptionLog("启动仪器TCP异常", ex);
            return ex.getCause().getMessage();
        }
        return "";

    }


    /**
     * 构造一个Socket基础并且启动Socket
     *
     * @param ip       IP地址,当服务端传空串
     * @param port     端口
     * @param upPeriod 上传毫秒间隔,不是主动上传的传null
     * @param dealObj  处理接口实现类
     * @param encode   编码格式,传null或空串默认为GBK
     */
    public MachSocketBase(String ip, int port, Long upPeriod, IMachDealData dealObj, String encode) {
        //处理对象
        DealObj = dealObj;
        //编码
        if (encode == null || encode.isEmpty()) {
            encode = "GBK";
        }
        Encode = encode;
        UpPeriod = upPeriod;
        ID = ip + ":" + port;
        if(dealObj!=null)
        {
            DealClassName=dealObj.getClass().getName();
        }
        //上传定时器
        if (upPeriod != null) {
            UpTimer = new Timer();
            timerTask = new TimerTask() {
                @Override
                public void run() {
                    try {
                        //初始化写对象
                        if (Sender != null && Writer == null) {
                            Writer = new PrintWriter(new OutputStreamWriter(Sender.getOutputStream(), Encode), false);
                        }
                        DealObj.DealUpTimer(Sender, Writer);
                    } catch (Exception ex) {
                        LogUtils.WriteExceptionLog("仪器上传定时器异常", ex);
                    }
                }
            };

        }
        //当客户端
        if (!ip.isEmpty()) {
            MainThread = new Thread(new Runnable() {
                @Override
                public void run() {
                    //得到输入流
                    InputStream inputStream = null;
                    //创建Socket对象并连接到服务端
                    Socket socket = null;
                    try {
                        //创建Socket对象并连接到服务端
                        socket = new Socket(ip, port);
                        Sender = socket;
                        closeSocket = socket;
                        Writer = new PrintWriter(new OutputStreamWriter(Sender.getOutputStream(), Encode), false);
                        //得到输入流
                        inputStream = socket.getInputStream();
                        //IO读取
                        byte[] buf = new byte[102400];
                        int readlen = 0;
                        //阻塞读取数据
                        while ((readlen = inputStream.read(buf)) != -1) {
                            String res = new String(buf, 0, readlen, Encode);
                            byte[] targetArray = new byte[readlen];
                            System.arraycopy(buf, 0, targetArray, 0, readlen);
                            //处理接收数据
                            DealObj.DealReceive(res, targetArray, Sender, Writer);
                        }
                    } catch (IOException ex) {
                        LogUtils.WriteExceptionLog("侦听仪器TCP异常", ex);
                    } finally {
                        try {
                            if (inputStream != null) {
                                //关闭输入
                                inputStream.close();
                            }
                            if (Writer != null) {
                                Writer.flush();
                                //关闭输出
                                Writer.close();
                            }
                            if (socket != null) {
                                // 关闭连接
                                socket.close();
                            }
                        } catch (Exception ex) {
                            LogUtils.WriteExceptionLog("释放TCP资源异常", ex);
                        }

                    }
                }
            });

        }
        //当服务端
        else {
            MainThread = new Thread(new Runnable() {
                @Override
                public void run() {
                    //得到输入流
                    InputStream inputStream = null;
                    //创建Socket对象并连接到服务端
                    Socket socket = null;
                    try {
                        ServerSocket serverSocket = new ServerSocket(port);
                        closeServerSocket = serverSocket;
                        //增加一个无限循环
                        while (true) {
                            //等待客户端连接,阻塞
                            socket = serverSocket.accept();
                            Sender = socket;
                            //得到输出流
                            Writer = new PrintWriter(new OutputStreamWriter(Sender.getOutputStream(), Encode), false);
                            //得到输入流
                            inputStream = socket.getInputStream();
                            //IO读取
                            byte[] buf = new byte[102400];
                            int readlen = 0;
                            //阻塞读取数据
                            while ((readlen = inputStream.read(buf)) != -1) {
                                String res = new String(buf, 0, readlen, Encode);
                                byte[] targetArray = new byte[readlen];
                                System.arraycopy(buf, 0, targetArray, 0, readlen);
                                //处理接收数据
                                DealObj.DealReceive(res, targetArray, Sender, Writer);
                            }
                        }
                    } catch (IOException ex) {
                        LogUtils.WriteExceptionLog("侦听仪器TCP异常", ex);
                    } finally {
                        try {
                            if (inputStream != null) {
                                //关闭输入
                                inputStream.close();
                            }
                            if (Writer != null) {
                                Writer.flush();
                                //关闭输出
                                Writer.close();
                            }
                            if (socket != null) {
                                // 关闭连接
                                socket.close();
                            }
                        } catch (Exception ex) {
                            LogUtils.WriteExceptionLog("释放TCP资源异常", ex);
                        }

                    }
                }
            });
        }

    }
}

然后为了统一管理所有TCP仪器提供MachManager,接口开发者之需要关心GetMachSocketBase方法

package LIS.Core.Socket;

import java.util.Iterator;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import LIS.Core.Socket.MachSocketBase;
import LIS.Core.Socket.IMachDealData;

/**
 * 统一管理所有仪器的MachSocketBase对象
 */
public class MachManager {
    /**
     * 存所有仪器连接
     */
    public static ConcurrentHashMap<String, MachSocketBase> AllMach = new ConcurrentHashMap<>();

    /**
     * 更新处理接口对象
     * @param dealClass
     * @throws Exception
     */
    public static void UpdateDeal(Class dealClass) throws Exception
    {
        String dealClsName=dealClass.getName();
        for (Map.Entry<String, MachSocketBase> entry : AllMach.entrySet()) {
            String key = entry.getKey();
            MachSocketBase value = entry.getValue();
            if(value.DealClassName.equals(dealClsName))
            {
                //创建对象
                Object o = dealClass.getConstructor().newInstance();
                value.DealObj=(IMachDealData)o;
                System.out.println("更新:"+value.ID+"的数据处理类");
            }
        }
    }

    /**
     * 得到仪器连接的Socket管理类,直接就启动了控制了
     * @param ip IP地址,当服务端传空串
     * @param port 端口
     * @param upPeriod 上传毫秒间隔,不是主动上传的传null
     * @param dealObj 处理接口实现类
     * @param encode 编码格式,传null或空串默认为GBK
     * @return
     */
    public static MachSocketBase GetMachSocketBase(String ip, int port, Long upPeriod, IMachDealData dealObj, String encode)
    {
        MachSocketBase base=new MachSocketBase(ip,port,upPeriod,dealObj,encode);
        //注册到管理
        RegisterMachSocketBase(base);
        return base;
    }

    /**
     * 注册到管理
     * @param base
     */
    public static void RegisterMachSocketBase(MachSocketBase base)
    {
        //先停止老的接口
        if(AllMach.containsKey(base.ID))
        {
            AllMach.get(base.ID).Stop();
            AllMach.remove(base.ID);
        }
        //加入管理
        AllMach.put(base.ID,base);
        base.Start();
    }
}

然后为了解决修改仪器接口脚本后实时生效实现仪器注解,接口修改后会自动调用MachManager.UpdateDeal更新处理类,这样不用频繁重启仪器控制

//特性,申明此特性的仪器接口在修改后自动调用启动
package LIS.Core.CustomAttributes;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * 申明此特性的仪器接口在修改后自动调用启动
 */
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface  Mach {

}

在这里插入图片描述

然后实现一个实例仪器接口
在这里插入图片描述

import LIS.Core.CustomAttributes.Mach;
import LIS.Core.Socket.IMachDealData;
import LIS.Core.Socket.MachSocketBase;
import appcode.BaseHttpHandlerNoSession;
import appcode.Helper;

import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.Socket;

/**
 *连仪器示例代码
 */
@Mach
public class MachDemo extends BaseHttpHandlerNoSession implements IMachDealData {
    /**
     * 缓存数据
     */
    private static StringBuilder dataCache=new StringBuilder();

    //换行符
    private static String lineStr=System.getProperty("line.separator");

    /**
     * 显示日志
     * http://localhost:8080/ankilis/mi/MachDemo.ashx?Method=ShowLog
     * @return
     */
    public String ShowLog()
    {
        return dataCache.toString();
    }

    /**
     * 启动控制
     * http://localhost:8080/ankilis/mi/MachDemo.ashx?Method=Start
     * @return
     * @throws Exception
     */
    public String Start() throws Exception
    {
        //ip地址
        String ip=Helper.ValidParam(LIS.Core.MultiPlatform.LISContext.GetRequest(Request, "ip"), "");
        //端口
        int port=Helper.ValidParam(LIS.Core.MultiPlatform.LISContext.GetRequest(Request, "port"), 8888);
        MachSocketBase base=LIS.Core.Socket.MachManager.GetMachSocketBase(ip,port,Long.valueOf(5000),this,"GBK");
        if(base.Err.isEmpty())
        {
            return Helper.Success();
        }
        else
        {
            return Helper.Error(base.Err);
        }
    }

    /**
     * 处理上传定时器接口
     * @param sender Socket对象,用来发送比特用
     * @param writer 用来发布初始化指定的字符用
     */
    public void DealUpTimer(Socket sender, PrintWriter writer)
    {
        String sendStr="H->M:我主动定时给你推送的数据</br>";
        //返回数据
        writer.print(sendStr);
        writer.flush();
        dataCache.append(sendStr+lineStr);
    }

    /**
     * 处理数据接收
     * @param data 公共层处理成字符串的数据
     * @param buf 没处理的比特数组
     * @param sender Socket对象,用来发送比特用
     * @param writer 用来发布初始化指定的字符用
     */
    public void DealReceive(String data, byte[] buf, Socket sender, PrintWriter writer)
    {
        //缓存数据
        dataCache.append("M->H:"+data+lineStr);
        String sendStr="H->M:我收到你发给我的:"+data+"</br>";
        //返回数据
        writer.print(sendStr);
        writer.flush();
        dataCache.append(sendStr+lineStr);
    }
}

启动控制
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

这样就可以在这个基础上轻松连接TCP的仪器了,还是脚本化、还不用来回重启控制

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

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

相关文章

如何给shopify motion主题的产品系列添加description

一、Description是什么 Description是一种HTML标签类型&#xff0c;通过指定Description的内容&#xff0c;可以帮助搜索引擎以及用户更好的理解当前网页包含的主要了内容。 二、Description有什么作用 1、基本作用&#xff0c;对于网站和网页做一个简单的说明。 2、吸引点击&…

部署单仓库多目录项目

部署单仓库多目录项目 文章目录 部署单仓库多目录项目1.部署单仓库多目录项目2.Shell脚本进行部署单仓库多目录项目2.1 编写Shell脚本2.2 Demo推送代码及测试 3.小结 1.部署单仓库多目录项目 #部署单仓库多目录项目 在开发过程中,研发团队往往会将一个大型项目拆分成几个子目录…

Python 安装win32com失败

今天进行服务器迁移&#xff0c; 中间有用的python调用win32com组件让docx转换成pdf。不出意外的话出意外了&#xff0c;pip安装win32com的时候各种安装不上&#xff0c; 今天处理完问题之后&#xff0c;记录一下&#xff0c;与人方便与己方便。 在cmd上面&#xff0c;一开始…

opencv-图像平滑

高斯平滑 高斯平滑即采用高斯卷积核对图像矩阵进行卷积操作。高斯卷积核是一个近似服从高斯分布的矩阵&#xff0c;随着距离中心点的距离增加&#xff0c;其值变小。这样进行平滑处理时&#xff0c;图像矩阵中锚点处像素值权重大&#xff0c;边缘处像素值权重小。 import cv2 …

C语言入门——第十七课

一、二分查询 1.概念 二分查询又被称为二分查找&#xff0c;是一种在有序数组或序列中快速查找到对应元素的一种方法。每次查找范围缩小至原来的一半。 ①前提条件 数组和列表必须有序&#xff0c;否则无法进行二分查找。 ②初始化 确定查找数组和列表的左边界&#xff0…

js ::after简单实战

::after的作用是在元素后面再加个XXX样式 工作中遇到了一个表格&#xff0c;鼠标指到单元格要有个整行编辑态的效果&#xff0c;下面写个简单的demo 有人可能会说了&#xff0c;直接修改某个单元格的hover样式不就行了嘛&#xff0c;问题是如果鼠标指到单元格和单元格直接的…

自己动手打包构建编译cri-dockerd

1.背景 本机是 armv7l架构cpu&#xff0c;发现官方文档中竟然没有&#xff0c;因此需要自己编译下&#xff1b; [rootcontainer0 ~]# uname -a Linux container0 5.4.206-v7l.1.el7 #1 SMP Mon Jul 25 14:13:29 UTC 2022 armv7l armv7l armv7l GNU/Linux2.打包/构建/编译 gi…

Linux—简介安装常用命令系统中软件安装项目部署

目录 1. 前言1.1 什么是Linux1.2 为什么要学Linux1.3 学完Linux能干什么 2. Linux简介2.1 主流操作系统2.2 Linux发展历史2.3 Linux系统版本 3. Linux安装3.1 安装方式介绍3.2 安装VMware3.3 安装Linux3.4 网卡设置3.5 安装SSH连接工具3.5.1 SSH连接工具介绍3.5.2 FinalShell安…

北醒携全球首款256线车规量产激光雷达亮相广州国际车展

11月17日&#xff0c;北醒携全球首款256线车规量产激光雷达亮相广州国际车展。在车展期间&#xff0c;北醒还公布了与广州花都区人民政府达成投资合作&#xff0c;获滴滴自动驾驶投资以及与捷普联合打造的全球首条量产256线级别车规激光雷达的生产线即将贯通的等多条利好信息&a…

如何提高图片转excel的效果?(软件选择篇)

在日常的工作中&#xff0c;我们常常会遇到一些财务报表类的图片需要转换成可编辑的excel&#xff0c;但是&#xff0c;受各种条件的限制&#xff0c;常常只能通过手工录入这种原始的方式来实现&#xff0c;随着人工智能、深度学习以及网络技术的发展&#xff0c;这种原始的录入…

【C++】泛型编程 ⑩ ( 类模板的运算符重载 - 函数实现 写在类外部的同一个 cpp 代码中 | 类模板 的 外部友元函数二次编译问题 )

文章目录 一、类模板 - 函数声明与函数实现分离1、类模板 外部 实现 构造函数2、类模板 外部 实现 普通函数3、类模板 外部 实现 友元函数( 1 ) 错误示例及分析 - 类模板 的 外部友元函数 二次编译 问题( 2 ) 正确写法 二、代码示例 - 函数声明与函数实现分离1、代码示例2、执行…

深度学习之基于Pytorch的昆虫分类识别系统

欢迎大家点赞、收藏、关注、评论啦 &#xff0c;由于篇幅有限&#xff0c;只展示了部分核心代码。 文章目录 一项目简介系统架构技术亮点 二、功能三、系统四. 总结 一项目简介 # 深度学习基于 Pytorch 的昆虫分类识别系统介绍 深度学习在图像分类领域取得了显著的成就&#…

logic-flow 使用过程中遇到的bug - 拖动节点到画布的时候,鼠标松开,节点不落在画布,仍旧跟着鼠标走

背景&#xff1a; 插件&#xff1a;logicFlow 用途&#xff1a;画流程图 bug表现&#xff1a; 初始化的样子&#xff1a; bug的样子&#xff1a; 拖动第一个节点的时候&#xff0c;一切正常&#xff08;无论哪个节点作为第一个节点&#xff0c;都是正常的&#xff0c;但是拖动…

C语言回文数(1106:回文数(函数专题))

题目描述 一个正整数&#xff0c;如果从左向 右读&#xff08;称之为正序数&#xff09;和从右向左读&#xff08;称之为倒序数&#xff09;是一样的&#xff0c;这样的数就叫回文数。输入两个整数m和n&#xff08;m<n)&#xff0c;输出区间[m&#xff0c;n]之间的回文数。 …

Flowable工作流高级篇

文章目录 一、任务分配和流程变量1.任务分配1.1 固定分配1.2 表达式分配1.2.1 值表达式1.2.2 方法表达式 1.3 监听器分配 2.流程变量2.1 全局变量2.2 局部变量2.3 案例讲解 二、候选人和候选人组1.候选人1.1 定义流程图1.2 部署和启动流程实例1.3 任务的查询1.4 任务的拾取1.5 …

转录组学习第四弹-数据质控

数据质控 将SRR转为fastq之后&#xff0c;我们需要对fastq进行质量检查&#xff0c;排除质量不好的数据 1.质量检查&#xff0c;生成报告文件 ls *fastq.gz|while read id;do fastqc $id;done并行处理 ls *fastq.gz|xargs fastqc -t 102.生成 html 报告文件和对应的 zip 压缩…

2 Advanced Learning Algorithms

文章目录 Week1Neurons and brainNeural network layerForward propagationBuild a netural network ------codeAGIMatrix multiplication ------code Week2Tensorflow--- training detailsactivation functionsMultclass and SoftmaxClassification with multiple outputsAdam…

Android DatePicker(日期选择器)、TimePicker(时间选择器)、CalendarView(日历视图)- 简单应用

示意图&#xff1a; layout布局文件&#xff1a;xml <?xml version"1.0" encoding"utf-8"?> <ScrollView xmlns:android"http://schemas.android.com/apk/res/android"xmlns:app"http://schemas.android.com/apk/res-auto"…

【C/PTA】函数专项练习(一)

本文结合PTA专项练习带领读者掌握函数&#xff0c;刷题为主注释为辅&#xff0c;在代码中理解思路&#xff0c;其它不做过多叙述。 目录 6-1 输出星期名6-2 三整数最大值6-3 数据排序6-4 多项式求值 6-1 输出星期名 请编写函数&#xff0c;根据星期数输出对应的星期名。 函数原…

Redis 5 种基本数据类型详解

Redis 共有 5 种基本数据类型&#xff1a;String&#xff08;字符串&#xff09;、List&#xff08;列表&#xff09;、Set&#xff08;集合&#xff09;、Hash&#xff08;散列&#xff09;、Zset&#xff08;有序集合&#xff09;。 这 5 种数据类型是直接提供给用户使用的&…