【JMX】JAVA监控的基石

news2024/11/26 2:38:31

目录

1.概述

2.MBean

2.1.Standard MBean

2.2.Dynamic MBean

2.3.Model Bean

2.4.Dynamic MBean和Model Bean的区别

2.5.MXBean

2.6.Open Bean

3.控制台


1.概述

什么是JMX,首先来看一段对话:

Java Management Extensions(JMX)是一种Java标准,用于管理和监控Java应用程序,特别是分布式系统。它提供了一种标准化的方式来管理应用程序的各种方面,包括性能监控、配置更改、事件通知等。目前JMX最常用的就是用来做JAVA程序的监控,市面上常见的Java 监控框架基本都是基于JMX来实现的。

JMX分为三部分:

  1. MBean:MBean是用来提供功能的,MBean是管理对象的标准接口,通过MBean可以获取和操作应用程序的各种属性和操作。Java提供了几种类型的MBean,包括标准MBean、动态MBean、模型MBean等,每种类型适用于不同的场景。

  2. MBean服务器:MBean服务器是用来管理MBean的,它是一个注册表,用于注册和管理MBean。应用程序通过MBean服务器暴露MBean,并且其他应用程序或工具可以连接到MBean服务器以检索和操作这些MBean。

  3. JMX代理:JMX代理是用来访问MBean服务器的,可以理解为CS架构中的client端,支持多种访问方式。JMX代理是一个位于应用程序和MBean服务器之间的中间层,用于管理远程应用程序。它允许远程管理工具连接到远程应用程序的MBean服务器,并执行各种管理操作,如监控、配置和诊断。

img

JMX标准的实现通常由Java虚拟机(JVM)提供支持。Java虚拟机会实现JMX标准,以便应用程序可以利用JMX的功能。JVM会提供一个MBean服务器,应用程序可以将MBean注册到该服务器中,使其可供其他应用程序或工具访问和操作。

Java虚拟机通过提供标准的MBean服务器和相关的API,为应用程序提供了一种标准化的方式来管理和监控应用程序的各个方面。这种标准化使得开发人员可以使用相同的接口和工具来管理不同的Java应用程序,从而提高了管理的效率和一致性。

2.MBean

MBean服务器由于是JVM实现的,所以对我们应用开发者来说,最核心的其实就是MBean了,因为MBean是用来实现功能的。JMX标准中将MBean分为以下几种:

  1. Standard MBean(标准 MBean):它是最简单的一种 MBean 类型。一个标准 MBean 由一个 Java 接口和一个对应的实现类组成。接口中定义了 MBean 的属性和操作,实现类则提供了对应的实现。标准 MBean 的命名约定为 YourInterfaceNameMBean

  2. Dynamic MBean(动态 MBean):与标准 MBean 不同,动态 MBean 可以在运行时动态地确定其属性和操作。动态 MBean 的属性和操作是在运行时通过方法调用来确定的,因此可以根据需要进行动态修改。

  3. Model MBean(模型 MBean):模型 MBean 是一种特殊的 MBean,它通过描述符来描述其管理接口,可以在运行时动态地配置其属性和操作。模型 MBean 可以通过 XML 或者通过程序动态地加载描述符。

  4. MXBean:MXBean 是一种专门用于 JMX 的 MBean 类型。它定义了一种简单的 Java 接口和实现约定,用于描述 MBean 的属性和操作,同时这些接口和实现类遵循 Java Bean 的命名约定。MXBean 在 JMX 中用于管理特定类型的对象,例如内存使用情况、线程信息等。

  5. Open MBean:开放 MBean 是一种通用的 MBean 类型,它可以包含各种类型的属性和操作。开放 MBean 不限制其属性和操作的类型,因此可以包含任意类型的数据。

2.1.Standard MBean

所谓的Standard MBean,就是说按照JMX的命名规范来定义接口然后注册到MBean Server中,MBean就能被JMX的client端访问到。具体该MBean提供了什么功能,在这个自定义的MBean中去定义属性和方法仔细实现即可。

代码示例:

// 定义一个接口,命名约定为 YourInterfaceNameMBean
public interface HelloMBean {
    String getName();
    void setName(String name);
    void sayHello();
}
​
// 实现上述接口的类
public class Hello implements HelloMBean {
    private String name;
​
    @Override
    public String getName() {
        return name;
    }
​
    @Override
    public void setName(String name) {
        this.name = name;
    }
​
    @Override
    public void sayHello() {
        System.out.println("Hello, " + name + "!");
    }
}
​
// 主程序
public class Main {
    public static void main(String[] args) throws Exception {
        // 创建标准 MBean 实例
        HelloMBean helloMBean = new Hello();
        
        // 创建 MBeanServer
        MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
        
        // 创建 ObjectName,用于标识 MBean
        ObjectName name = new ObjectName("com.example:type=Hello");
        
        // 注册 MBean 到 MBeanServer
        mbs.registerMBean(helloMBean, name);
        
        // 等待一段时间,使得可以通过 JConsole 或者其他 JMX 客户端来操作 MBean
        Thread.sleep(Long.MAX_VALUE);
    }
}

2.2.Dynamic MBean

动态 MBean 是 Java Management Extensions (JMX) 中的一种特殊类型的 MBean,它与标准 MBean 不同之处在于,动态 MBean 允许在运行时动态地确定其属性和操作,这使得动态 MBean 能够在运行时根据需要动态地调,而不是在编译时就确定了。

说人话就是很方便动态的去修改Dynamic MBean的属性,这非常适合拿来做一些动态的功能,比如:

  • 动态配置管理,从外部去加载配置文件,实现配置的动态变化。

  • 动态监控,从外部去获取监控信息,比如实时的CPU、内存的信息,实现对系统的动态监控。

动态 MBean 的核心是实现 DynamicMBean 接口,该接口定义了一组方法,用于动态地获取和设置 MBean 的属性,执行 MBean 的操作,以及获取 MBean 的元数据信息。以下是 DynamicMBean 接口的几个核心方法:

  • getAttribute(String attribute):根据属性名获取属性值。

  • setAttribute(Attribute attribute):设置指定属性的值。

  • getAttributes(String[] attributes):批量获取属性值。

  • setAttributes(AttributeList attributes):批量设置属性值。

  • invoke(String actionName, Object[] params, String[] signature):执行指定的操作。

  • getMBeanInfo():获取 MBean 的元数据信息,包括属性、操作和描述信息。

代码示例:

import javax.management.*;
import java.lang.management.ManagementFactory;
​
public class DynamicHello implements DynamicMBean {
    private String name;
​
    @Override
    public Object getAttribute(String attribute) throws AttributeNotFoundException, MBeanException, ReflectionException {
        if (attribute.equals("Name")) {
            return name;
        } else {
            throw new AttributeNotFoundException("Attribute '" + attribute + "' not found");
        }
    }
​
    @Override
    public void setAttribute(Attribute attribute) throws AttributeNotFoundException, InvalidAttributeValueException, MBeanException, ReflectionException {
        if (attribute.getName().equals("Name")) {
            name = (String) attribute.getValue();
        } else {
            throw new AttributeNotFoundException("Attribute '" + attribute.getName() + "' not found");
        }
    }
​
    @Override
    public AttributeList getAttributes(String[] attributes) {
        AttributeList attrs = new AttributeList();
        for (String attr : attributes) {
            try {
                Object value = getAttribute(attr);
                attrs.add(new Attribute(attr, value));
            } catch (Exception e) {
                // Ignore if attribute not found
            }
        }
        return attrs;
    }
​
    @Override
    public AttributeList setAttributes(AttributeList attributes) {
        AttributeList responseAttrs = new AttributeList();
        for (Attribute attr : attributes.asList()) {
            try {
                setAttribute(attr);
                responseAttrs.add(new Attribute(attr.getName(), getAttribute(attr.getName())));
            } catch (Exception e) {
                // Ignore if attribute not found or set failed
            }
        }
        return responseAttrs;
    }
​
    @Override
    public Object invoke(String actionName, Object[] params, String[] signature) throws MBeanException, ReflectionException {
        if (actionName.equals("sayHello")) {
            return "Hello, " + name + "!";
        } else {
            throw new UnsupportedOperationException("Operation '" + actionName + "' not supported");
        }
    }
​
    @Override
    public MBeanInfo getMBeanInfo() {
        MBeanAttributeInfo[] attributes = new MBeanAttributeInfo[]{
                new MBeanAttributeInfo("Name", "java.lang.String", "Name of the person", true, true, false)
        };
​
        MBeanOperationInfo[] operations = new MBeanOperationInfo[]{
                new MBeanOperationInfo("sayHello", "Say hello to the person", null, "java.lang.String", MBeanOperationInfo.ACTION)
        };
​
        return new MBeanInfo(this.getClass().getName(), "Dynamic Hello MBean", attributes, null, operations, null);
    }
​
    public static void main(String[] args) throws Exception {
        DynamicHello dynamicHello = new DynamicHello();
        MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
        ObjectName name = new ObjectName("com.example:type=DynamicHello");
        mbs.registerMBean(dynamicHello, name);
        Thread.sleep(Long.MAX_VALUE);
    }
}

在这个示例中,我们实现了 DynamicMBean 接口,并重写了它的方法来提供 MBean 的属性和操作。动态 MBean 允许在运行时确定其属性和操作,因此我们需要在实现中动态地处理属性的获取、设置和操作的调用。

getMBeanInfo() 方法中,我们定义了 MBean 的元数据信息,包括属性、操作和描述信息。在 main() 方法中,我们创建了 DynamicHello 的实例,并将其注册到 MBeanServer 中。然后通过 Thread.sleep(Long.MAX_VALUE) 使程序保持运行,以便通过 JConsole 或其他 JMX 客户端来操作该动态 MBean。

2.3.Model Bean

Model MBean 的核心是实现 ModelMBean 接口,该接口继承自 DynamicMBean 接口,因此具有动态 MBean 的所有特性,同时还添加了一些额外的方法用于管理描述符。以下是 ModelMBean 接口的一些重要方法:

  • setModelMBeanInfo(ModelMBeanInfo mbi):设置 Model MBean 的元数据信息,包括属性、操作和描述符。

  • setManagedResource(Object mr, String mr_type):指定 Model MBean 管理的资源对象及其类型。

  • sendNotification(Notification ntfyObj):发送通知给注册的监听器。

  • setAttribute(Attribute attribute)getAttribute(String attribute):获取和设置属性,这些属性可以通过描述符来配置。

代码示例:

import javax.management.*;
import javax.management.modelmbean.*;
import java.lang.management.ManagementFactory;
​
public class SimpleModelMBeanExample {
    public static void main(String[] args) throws Exception {
        // 创建 ModelMBeanInfo 对象
        ModelMBeanInfo modelMBeanInfo = createModelMBeanInfo();
​
        // 创建 ModelMBean 实例
        ModelMBean modelMBean = createModelMBean(modelMBeanInfo);
​
        // 创建 MBeanServer
        MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
​
        // 创建 ObjectName,用于标识 MBean
        ObjectName name = new ObjectName("com.example:type=SimpleModelMBean");
​
        // 注册 ModelMBean 到 MBeanServer
        mbs.registerMBean(modelMBean, name);
​
        // 等待一段时间,使得可以通过 JConsole 或者其他 JMX 客户端来操作 MBean
        Thread.sleep(Long.MAX_VALUE);
    }
​
    private static ModelMBeanInfo createModelMBeanInfo() throws Exception {
        // 创建属性描述符
        Descriptor nameDesc = new DescriptorSupport();
        nameDesc.setField("name", "Name");
        nameDesc.setField("descriptorType", "attribute");
​
        // 创建操作描述符
        Descriptor sayHelloDesc = new DescriptorSupport();
        sayHelloDesc.setField("name", "sayHello");
        sayHelloDesc.setField("descriptorType", "operation");
​
        // 创建属性列表
        MBeanAttributeInfo[] attributes = new MBeanAttributeInfo[]{
                new MBeanAttributeInfo("Name", "java.lang.String", "Name of the person", true, true, false, nameDesc)
        };
​
        // 创建操作列表
        MBeanOperationInfo[] operations = new MBeanOperationInfo[]{
                new MBeanOperationInfo("sayHello", "Say hello to the person", null, "java.lang.String", MBeanOperationInfo.ACTION, sayHelloDesc)
        };
​
        // 创建 ModelMBeanInfo
        ModelMBeanInfo modelMBeanInfo = new ModelMBeanInfoSupport(
                SimpleModelMBeanExample.class.getName(),
                "Simple Model MBean Example",
                attributes,
                null,
                operations,
                null
        );
​
        return modelMBeanInfo;
    }
​
    private static ModelMBean createModelMBean(ModelMBeanInfo modelMBeanInfo) throws Exception {
        // 创建 ModelMBean 实例
        RequiredModelMBean modelMBean = new RequiredModelMBean();
        modelMBean.setModelMBeanInfo(modelMBeanInfo);
​
        // 创建 MBean 实例
        ObjectName name = new ObjectName("com.example:type=SimpleModelMBean");
        SimpleModelMBean example = new SimpleModelMBean();
​
        // 设置 MBean 实例
        modelMBean.setManagedResource(example, "ObjectReference");
​
        return modelMBean;
    }
}

在这个示例中,我们首先创建了一个 ModelMBeanInfo 对象,该对象描述了 Model MBean 的元数据信息,包括属性和操作。然后,我们创建了一个 ModelMBean 实例,并将 ModelMBeanInfo 设置到该实例中。接着,我们创建了一个 ObjectName 对象,用于标识 MBean,然后将 ModelMBean 实例注册到了 MBeanServer 中。

同时,我们还定义了一个 SimpleModelMBean 类,该类实现了 Model MBean 管理的资源对象。在这个类中,我们可以定义属性和操作的具体实现逻辑。

2.4.Dynamic MBean和Model Bean的区别

其实Model Bean本来就是继承自Dynamic MBean的,所以后者有的特点,前者也有,其二者本质的区别在于使用场景上:

  1. 动态性质

    • Dynamic MBean:Dynamic MBean 的设计理念是允许在运行时动态地确定其属性和操作。它适用于那些在编译时无法确定其管理接口的场景,例如,那些需要根据外部配置文件或运行时状态来确定其管理接口的应用程序。

    • Model MBean:Model MBean 的设计理念是通过描述符来描述其管理接口,使得可以在运行时动态地加载和配置 MBean 的属性和操作。它适用于需要动态加载和配置管理接口的场景,例如,根据不同的环境或条件来动态地调整管理接口。

  2. 自描述性

    • Dynamic MBean:Dynamic MBean 不提供自描述性,开发人员需要手动实现属性和操作的获取和设置逻辑。它主要关注于动态性和灵活性,适用于那些需要在运行时动态确定管理接口的场景。

    • Model MBean:Model MBean 提供了详细的元数据信息,包括属性和操作的描述信息,使得管理客户端可以动态地了解 MBean 的结构和功能。它适用于那些需要自描述性和灵活性的场景,例如,需要通过管理客户端来动态地了解和操作 MBean 的情况。

  3. 适应性

    • Dynamic MBean:Dynamic MBean 具有较高的适应性,可以根据外部条件或运行时状态动态地调整其管理接口。它适用于那些需要根据外部条件或运行时状态来动态调整管理接口的场景。

    • Model MBean:Model MBean 具有较高的适应性,可以根据不同的环境或条件动态地调整管理接口。它适用于那些需要根据不同的部署环境或运行时条件来动态地配置 MBean 的属性和操作的场景。

2.5.MXBean

在 Java 中,一切都被视为对象,而 JMX 则提供了一种标准化的方式来监控和管理 Java 程序的运行时状态、性能指标以及运行环境。而MXBean其实就是专门用于管理和监控这其中一些标准化类型的对象的。什么叫标准化的类型对象?其实就是一些定量的指标,例如内存使用情况、线程信息、操作系统属性等。这些MBean是拿来即用的。

Java 平台中有一些预定义的 MXBean,例如 MemoryMXBeanThreadMXBeanOperatingSystemMXBean 等,用于管理和监控 JVM 的内存、线程、操作系统属性等。

代码示例:

import java.lang.management.ManagementFactory;
import java.lang.management.MemoryMXBean;
import java.lang.management.MemoryUsage;
​
public class MXBeanExample {
    public static void main(String[] args) {
        // 获取 MemoryMXBean 实例
        MemoryMXBean memoryMXBean = ManagementFactory.getMemoryMXBean();
​
        // 获取堆内存使用情况
        MemoryUsage heapMemoryUsage = memoryMXBean.getHeapMemoryUsage();
        System.out.println("Heap Memory Usage:");
        System.out.println("    Init: " + heapMemoryUsage.getInit() / (1024 * 1024) + " MB");
        System.out.println("    Used: " + heapMemoryUsage.getUsed() / (1024 * 1024) + " MB");
        System.out.println("    Committed: " + heapMemoryUsage.getCommitted() / (1024 * 1024) + " MB");
        System.out.println("    Max: " + heapMemoryUsage.getMax() / (1024 * 1024) + " MB");
​
        // 获取非堆内存使用情况
        MemoryUsage nonHeapMemoryUsage = memoryMXBean.getNonHeapMemoryUsage();
        System.out.println("Non-Heap Memory Usage:");
        System.out.println("    Init: " + nonHeapMemoryUsage.getInit() / (1024 * 1024) + " MB");
        System.out.println("    Used: " + nonHeapMemoryUsage.getUsed() / (1024 * 1024) + " MB");
        System.out.println("    Committed: " + nonHeapMemoryUsage.getCommitted() / (1024 * 1024) + " MB");
        System.out.println("    Max: " + nonHeapMemoryUsage.getMax() / (1024 * 1024) + " MB");
    }
}

可以自定义MXBean吗?当然可以。

自定义 MXBean 主要包括两个步骤:

  1. 定义接口:首先,需要定义一个 Java 接口来描述 MXBean 的管理接口。这个接口中定义了一组属性和操作,用于描述被管理的对象的状态和行为。

  2. 实现类:然后,需要编写一个实现类来实现定义的接口。在实现类中,需要提供属性和操作的具体实现逻辑,以及可能需要的管理逻辑。

代码示例:

// 定义 MXBean 接口
public interface MyMXBean {
    // 属性:名称
    String getName();
    void setName(String name);
    
    // 操作:打印消息
    void printMessage(String message);
}
​
// 实现类
public class MyMXBeanImpl implements MyMXBean {
    private String name;
    
    // 实现属性的 getter 和 setter 方法
    @Override
    public String getName() {
        return name;
    }
    
    @Override
    public void setName(String name) {
        this.name = name;
    }
    
    // 实现操作的方法
    @Override
    public void printMessage(String message) {
        System.out.println(message);
    }
}
​
// 在管理应用程序中注册和使用自定义的 MXBean
public class MyMXBeanRegistration {
    public static void main(String[] args) throws Exception {
        // 创建 MXBean 实例
        MyMXBean mxBean = new MyMXBeanImpl();
        
        // 注册 MXBean 到 MBeanServer
        MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
        ObjectName name = new ObjectName("com.example:type=MyMXBean");
        mbs.registerMBean(mxBean, name);
        
        // 等待一段时间,使得可以通过 JConsole 或者其他 JMX 客户端来操作 MXBean
        Thread.sleep(Long.MAX_VALUE);
    }
}

在这个示例中,我们定义了一个名为 MyMXBean 的接口,包含了一个属性 name 和一个操作 printMessage。然后,我们编写了一个实现类 MyMXBeanImpl,实现了这个接口,并提供了属性和操作的具体实现逻辑。最后,我们在管理应用程序中注册和使用了这个自定义的 MXBean。

2.6.Open Bean

与传统的 Standard MBean 和 Dynamic MBean 不同,Open MBean 不需要预先定义接口,而是使用开放式的数据类型和操作来描述 MBean 的管理接口,使得可以更灵活地适应各种场景和需求。

代码示例:

import javax.management.*;
import javax.management.openmbean.*;
​
public class OpenMBeanExample {
    public static void main(String[] args) throws Exception {
        // 创建 OpenType
        OpenType<String> stringType = SimpleType.STRING;
        OpenType<Integer> integerType = SimpleType.INTEGER;
​
        // 创建 OpenMBeanAttributeInfo
        OpenMBeanAttributeInfoSupport nameAttrInfo = new OpenMBeanAttributeInfoSupport(
                "Name",
                "Name of the person",
                stringType,
                true,
                false,
                false
        );
        OpenMBeanAttributeInfoSupport ageAttrInfo = new OpenMBeanAttributeInfoSupport(
                "Age",
                "Age of the person",
                integerType,
                true,
                false,
                false
        );
​
        // 创建 OpenMBeanOperationInfo
        OpenMBeanParameterInfo[] params = new OpenMBeanParameterInfo[]{};
        OpenMBeanOperationInfoSupport sayHelloOpInfo = new OpenMBeanOperationInfoSupport(
                "sayHello",
                "Say hello to the person",
                params,
                stringType,
                OpenMBeanOperationInfo.ACTION
        );
​
        // 创建 OpenMBeanInfo
        OpenMBeanInfoSupport mbeanInfo = new OpenMBeanInfoSupport(
                SimpleOpenMBean.class.getName(),
                "Simple Open MBean Example",
                new OpenMBeanAttributeInfo[]{nameAttrInfo, ageAttrInfo},
                null,
                new OpenMBeanOperationInfo[]{sayHelloOpInfo},
                null
        );
​
        // 创建 OpenMBean 实例
        SimpleOpenMBean mbean = new SimpleOpenMBean("John", 30);
​
        // 创建 MBeanServer
        MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
​
        // 创建 ObjectName,用于标识 MBean
        ObjectName name = new ObjectName("com.example:type=SimpleOpenMBean");
​
        // 注册 OpenMBean 到 MBeanServer
        mbs.registerMBean(mbean, name);
​
        // 等待一段时间,使得可以通过 JConsole 或者其他 JMX 客户端来操作 MBean
        Thread.sleep(Long.MAX_VALUE);
    }
}
​
// 实现 OpenMBean
public class SimpleOpenMBean implements OpenMBean {
    private String name;
    private int age;
​
    public SimpleOpenMBean(String name, int age) {
        this.name = name;
        this.age = age;
    }
​
    @Override
    public Object getAttribute(String attribute) throws AttributeNotFoundException, MBeanException, ReflectionException {
        if (attribute.equals("Name")) {
            return name;
        } else if (attribute.equals("Age")) {
            return age;
        } else {
            throw new AttributeNotFoundException("Attribute " + attribute + " not found");
        }
    }
​
    @Override
    public void setAttribute(Attribute attribute) throws AttributeNotFoundException, InvalidAttributeValueException, MBeanException, ReflectionException {
        throw new UnsupportedOperationException("setAttribute not supported");
    }
​
    @Override
    public Object invoke(String actionName, Object[] params, String[] signature) throws MBeanException, ReflectionException {
        if (actionName.equals("sayHello")) {
            return "Hello, " + name + "!";
        } else {
            throw new UnsupportedOperationException("Operation " + actionName + " not supported");
        }
    }
​
    @Override
    public MBeanInfo getMBeanInfo() {
        // 实现 OpenMBean 接口的 getMBeanInfo 方法,返回 MBean 的元数据信息
        return null;
    }
}

3.控制台

JDK自带了一个JMX的控制台JConsole,启动后选择进程,就能看到相应程序中的MBean。

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

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

相关文章

猫头虎分享已解决Bug || 日志文件过大(Log File Oversize):LogFileOverflow, ExcessiveLoggingError

博主猫头虎的技术世界 &#x1f31f; 欢迎来到猫头虎的博客 — 探索技术的无限可能&#xff01; 专栏链接&#xff1a; &#x1f517; 精选专栏&#xff1a; 《面试题大全》 — 面试准备的宝典&#xff01;《IDEA开发秘籍》 — 提升你的IDEA技能&#xff01;《100天精通鸿蒙》 …

C++构造和折构函数详解,超详细!

个人主页&#xff1a;PingdiGuo_guo 收录专栏&#xff1a;C干货专栏 大家龙年好呀&#xff0c;今天我们来学习一下C构造函数和折构函数。 文章目录 1.构造函数 1.1构造函数的概念 1.2构造函数的思想 1.3构造函数的特点 1.4构造函数的作用 1.5构造函数的操作 1.6构造函数…

电子电器架构 —— 对车载软件开发新阶段的愿景

电子电器架构 —— 对车载软件开发新阶段的愿景 我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师(Wechat:gongkenan2013)。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 本就是小人物,输了就是输了,不要在意别人怎么看自己。江湖一碗茶,喝…

使用C++从零开始,自己写一个MiniWeb

第一步&#xff1a;新建项目 1、打开VS点击创建新项目 2、选择空项目并点下一步&#xff08;切记不能选错项目类型&#xff09; 3、填写项目名称和路径&#xff0c;点击创建即可 新建好后项目是这样的比较干净 4、右击源文件&#xff0c;点击添加&#xff0c;新建http.cpp文件…

【华为云】容灾方案两地三中心实践理论

应用上云之后&#xff0c;如何进行数据可靠性以及业务连续性的保障是非常关键的&#xff0c;通过华为云云上两地三中心方案了解相关方案认证地址&#xff1a;https://connect.huaweicloud.com/courses/learn/course-v1:HuaweiXCBUCNXI057Self-paced/about当前内容为灾备常见理论…

代码随想录 Leetcode55. 跳跃游戏

题目&#xff1a; 代码(首刷自解 2024年2月9日&#xff09;&#xff1a; class Solution { public:bool canJump(vector<int>& nums) {int noz 0;for (int i nums.size() - 2; i > 0; --i) {if (nums[i] 0) {noz;continue;} else {if (nums[i] > noz) noz …

【Java八股面试系列】JVM-class文件结构

Class文件结构总结 根据 Java 虚拟机规范&#xff0c;Class 文件通过 ClassFile 定义&#xff0c;有点类似 C 语言的结构体。我们之前都是使用javap命令来对字节码文件进行反编译查看的&#xff0c;我们可以使用WinHex软件&#xff08;Mac平台可以使用010 Editor&#xff09;来…

假期day7

设计qq界面 代码 ui->lab1->setPixmap(QPixmap(":/pictrue/denglu.webp"));ui->lab1->setScaledContents(true);ui->lab2->setPixmap(QPixmap(":/pictrue/passwd.jpg"));ui->lab2->setScaledContents(true);ui->lab3->setP…

Elasticsearch:使用查询规则(query rules)进行搜索

在之前的文章 “Elasticsearch 8.10 中引入查询规则 - query rules”&#xff0c;我们详述了如何使用 query rules 来进行搜索。这个交互式笔记本将向你介绍如何使用官方 Elasticsearch Python 客户端来使用查询规则。 你将使用 query rules API 将查询规则存储在 Elasticsearc…

Java奠基】对象数组练习

目录 商品对象信息获取 商品对象信息输入 商品对象信息计算 商品对象信息统计 学生数据管理实现 商品对象信息获取 题目要求是这样的&#xff1a; 定义数组存储3个商品对象。 商品的属性&#xff1a;商品的id&#xff0c;名字&#xff0c;价格&#xff0c;库存。 创建三个…

Pytorch卷积层原理和示例 nn.Conv1d卷积 nn.Conv2d卷积

内容列表 一&#xff0c;前提 二&#xff0c;卷积层原理 1.概念 2.作用 3. 卷积过程 三&#xff0c;nn.conv1d 1&#xff0c;函数定义&#xff1a; 2, 参数说明: 3,代码: 4, 分析计算过程 四&#xff0c;nn.conv2d 1, 函数定义 2, 参数&#xff1a; 3, 代码 4, 分析计算过程 …

Netty应用(七) 之 Handler Netty服务端编程总结

目录 15.Handler 15.1 handler的分类 15.1.1 按照方向划分 15.1.2 handler的结构 15.2 输入方向ChannelInboundHandlerAdapter 15.2.1 输出方向Handler的顺序 15.2.2 多个输入方向Handler之间的数据传递 15.2.2.1 handler消失了 15.2.2.2 手动编写netty提供的new Strin…

一个查看armv8系统寄存器-值-含义的方式

找到解压后的SysReg_xml_v86A-2019-12目录 wget https://developer.arm.com/-/media/developer/products/architecture/armv8-a-architecture/2019-12/SysReg_xml_v86A-2019-12.tar.gz wget https://developer.arm.com/-/media/developer/products/architecture/armv8-a-archi…

(已解决)将overleaf上的文章paper上传到arxiv上遇到的问题。

文章目录 前言初级问题后续问题 前言 首先说一点&#xff0c;将paper的pdf文件直接上传arxiv是不行的&#xff0c;arxiv要求我们要上传源文件&#xff0c;所以才这么麻烦。 初级问题 首先上传文件之后有可能会在下面这个界面出现问题&#xff0c;这里一般都比较常见的问题&a…

『运维备忘录』之 HTTP 响应状态码速查

运维人员不仅要熟悉操作系统、服务器、网络等只是&#xff0c;甚至对于开发相关的也要有所了解。很多运维工作者可能一时半会记不住那么多命令、代码、方法、原理或者用法等等。这里我将结合自身工作&#xff0c;持续给大家更新运维工作所需要接触到的知识点&#xff0c;希望大…

java学习07---综合练习

飞机票 1.需求: 机票价格按照淡季旺季、头等舱和经济舱收费、输入机票原价、月份和头等舱或经济舱。 按照如下规则计算机票价格&#xff1a;旺季&#xff08;5-10月&#xff09;头等舱9折&#xff0c;经济舱8.5折&#xff0c;淡季&#xff08;11月到来年4月&#xff09;头等舱7…

[C#] 如何使用ScottPlot.WPF在WPF桌面程序中绘制图表

什么是ScottPlot.WPF&#xff1f; ScottPlot.WPF 是一个开源的数据可视化库&#xff0c;用于在 WPF 应用程序中创建高品质的绘图和图表。它是基于 ScottPlot 库的 WPF 版本&#xff0c;提供了简单易用的 API&#xff0c;使开发人员能够通过简单的代码创建各种类型的图表&#…

【项目技术点总结之三】使用Java生成复杂好看的word或pdf报告的解决方案

前言 项目中往往会遇到需要生成报告的场景&#xff0c;不管是简单报告还是复杂报告&#xff0c;其实都需要找很多资料去尝试&#xff0c;本文会提出几种个人完美解决报告生成的解决方案&#xff0c;而且会提出几个失败但是能生成报告的设想&#xff0c;当然都是踩过坑的&#…

Peter算法小课堂—背包问题

我们已经学过好久好久的动态规划了&#xff0c;动态规划_Peter Pan was right的博客-CSDN博客 那么&#xff0c;我用一张图片来概括一下背包问题。 大家有可能比较疑惑&#xff0c;优化决策怎么优化呢&#xff1f;答案是&#xff0c;滚动数组&#xff0c;一个神秘而简单的东西…

java nio零拷贝

零拷贝是一种计算机执行IO操作的优化技术&#xff0c;其核心目标是减少数据拷贝次数&#xff0c;从而提高系统性能。它主要体现在以下几个方面&#xff1a; 1. **定义与原理**&#xff1a;零拷贝字面上的意思包括“零”和“拷贝”。其中&#xff0c;“拷贝”是指数据从一个存储…