JVM学习(二):JVM监控及诊断工具-命令行篇

news2024/11/20 22:40:44

一、概述

性能诊断是软件工程师在日常工作中需要经常面对和解决的问题,在用户体验至上的今天,解决好应用的性能问题能带来非常大的收益。

Java 作为最流行的编程语言之一,其应用性能诊断一直受到业界广泛关注。可能造成Java应用出现性能问题的因素非常多,例如线程控制、磁盘读写、数据库访问、网络I/o、垃圾收集等。想要定位这些问题,一款优秀的性能诊断工具必不可少。

接下来就给大家介绍Oracle自带的命令行诊断工具。

二、jps:查看正在运行的Java进程

jps(ava Process Status) 显示指定系统内所有的HotSpot虚拟机进程(查看虚拟机进程信息),可用于查询正在运行的虚拟机进程。对于本地虚拟机进程来说,进程的本地虚拟机ID与操作系统的进程ID是一致的,是唯一的。

2.1基本语法

打开命令行,输入jps,如果没有显示,需要以管理员身份运行命令行

然后我们启动一个java程序,因为jps是查看正在运行的java程序,所以我们需要让程序一直在运行。于是我让程序等待键入,这样就阻塞住了。

public class ScannerTest {
    public static void main(String[] args) {
        Scanner scan = new Scanner(System.in);
        String info = scan.next();
    }
}

再次使用jps查看

可以看到我们的ScannerTest就在上面了

我们可以使用jps -help来查看jps的使用语法。

可以看到,jps的基本使用语法为:

jps [potions] [hostid]

我们可以通过追加参数,来打印额外的信息

2.2 options参数

-q:仅仅显示LVMID (local virtual machine id),即本地虚拟机唯一id。不显示主类的名称等

-1:输出应用程序主类的全类名或如果进程执行的是jar包,则输出jar完整路径

-m:输出虚拟机进程启动时传递给主类main()的参数

-v:列出虚拟机进程启动时的JVM参数。比如: -Xms20m -Xmx5em是启动程序指定的jvm参数。

说明:以上参数可以综合使用。

例如,我们综合使用-l 和 -v,可以写成jps -l -v 或者 jps -lv

补充:如果某Java进程关闭了默认开启的UsePerfData参数(即使用参数

-XX :-UsePerfData),那么jps命令(以及下面介绍的jstat)将无法探知该Java进程。

2.3 hostid参数

RMI注册表中注册的主机名。

如果想要远程监控主机上的java程序,需要安装jstatd。

对于具有更严格的安全实践的网络场所而言,可能使用一个自定义的策略文件来显示对特定的可信主机或网络的访问,尽管这种技术容易受到IP地址欺诈攻击

如果安全问题无法使用一个定制的策略文件来处理,那么最安全的操作是不运行jstatd服务器,而是在本地使用jstat和jps工具。

三、jstat:查看JVM统计信息

jstat(VM Statistics Monitoring Tool):用于监视虚拟机各种运行状态信息的命令行工具。它可以显示本地或者远程虚拟机进程中的类装载、内存、垃圾收集、IT编译等运行数据。

在没有GUI图形界面,只提供了纯文本控制台环境的服务器上,它将是运行期定位虚拟机性能问题的首选工具。常用于检测垃圾回收问题以及内存泄漏问题。

3.1 基本语法

可以使用 jstat -h或 jstat -help 查看相关参数

可以看到,jstat的基本使用语法为:

jstat -<option> [-t] [-h<lines>] <vmid> [<interval> [<count>]]

其中vmid是进程id号,也就是我们使用jps查看到的号码

3.2 option参数

3.2.1 类装载相关参数

  • -class:显示ClassLoader的相关信息:类的装载、卸载数量、总空间、类装载所消耗的时间等

我们先使用jps查看一下进程id

然后使用jstat -class 20384,即jstat -<option> <vmid>

Loaded:加载的类的个数 Bytes:加载的类的字节数

Unloaded:卸载的类的个数 Bytes:卸载的类的字节数 Time:响应时间

3.2.2 垃圾回收相关参数

我们利用一个会发生OOM(java.lang.OutOfMemoryError,即内存溢出) 的程序来进行演示:

/**
 * -Xms60m -Xmx60m -XX:SurvivorRatio=8
 */
public class GCTest {
    public static void main(String[] args) {
        ArrayList<byte[]> list = new ArrayList<>();

        for (int i = 0; i < 1000; i++) {
            byte[] arr = new byte[1024 * 100];//100KB
            list.add(arr);
            try {
                Thread.sleep(120);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

然后配一下GC参数:-Xms60m -Xmx60m -XX:SurvivorRatio=8(最大可用内存60M,初试内存60M,Eden区与Survivor区比例为8:1:1)

这里我用的idea是2021.3,配置好GC参数之后就可以启动程序了

  • -gc:显示与GC相关的堆信息。包括Eden区、两个survivor区、老年代、永久代等的容量、己用空间、GC时间合计等信息。

首先我们先看一下-gc会显示哪些参数,先启动ScannerTest,利用jps查看一下进程id,

然后使用命令jstat -gc 20384

参数解释:

  1. 新生代相关:

  • S0C是第一个幸存者区的大小(字节)

  • S1C是第二个幸存者区的大小(字节)

  • S0U是第一个幸存者区已使用的大小(字节)

  • S1U是第二个幸存者区已使用的大小(字节)

  • EC是Eden空间的大小(字节)

  • EU是Eden空间已使用大小(字节)

  1. 老年代相关:

  • OC是老年代的大小(字节)

  • OU是老年代已使用的大小(字节)

  1. 方法区(元空间)相关:

  • MC是方法区的大小

  • MU是方法区已使用的大小

  • CCSC是压缩类空间的大小

  • CCSU是压缩类空间已使用的大小

  1. 其他:

  • YGC是从应用程序启动到采样时young gc的次数

  • YGCT是指从应用程序启动到采样时young gc消耗时间(秒)

  • FGC是从应用程序启动到采样时full gc的次数

  • FGCT是从应用程序启动到采样时的full gc的消耗时间(秒)

  • GCT是从应用程序启动到采样时gc的总时间

其次咱们启动一下GCTest,用jps命令查看一下进程id:

使用命令jstat -gc 10824 1000 10,每秒打印1次结果,一共打印10次

  • -gccapacity:显示内容与-gc基本相同,但输出主要关注Java堆各个区域使用到的最大、最小空间。

使用命令 jstat gccapatity 进程号

其中S0C代表幸存者0区的容量,S1C代表幸存者1区的容量,EC代表伊甸园区的容量,CCSC代表压缩类的容量,YGC代表年轻代垃圾回收的时间,FGC代表Full GC垃圾回收的时间

  • -gcutil:显示内容与-gc基本相同,但输出主要关注已使用空间占总空间的百分比。

启动GCTest,使用jps查看进程id

使用命令jstat -gcutil 1984 2000

  • -gccause:与-gcutil功能一样,但是会额外输出导致最后一次或当前正在发生的GC产生的原因。

使用命令 jstat -gccause 18288 1000 10

后面的参数就不一一演示了。

  • -gcnew:显示新生代GC状况

  • -gcnewcapacity:显示内容与-gcnew基本相同,输出主要关注使用到的

最大、最小空间

  • -geold:显示老年代Gc状况

  • -gcoldcapacity:显示内容与-gcold基本相同,输出主要关注使用到的最大、最小空间

  • -gcpermcapacity:显示永久代使用到的最大、最小空间。

3.2.3 JIT相关参数

  • -compiler:显示JIT编译器编译过的方法、耗时等信息

例如:jstat -compiler 20384

  • -printcompilation:输出已经被JIT编译的方法

例如:jstat -printcompilation 20384

3.3 interval参数

用于指定输出统计数据的周期,单位为毫秒。即:查询间隔

例如:jstat -class 20384 1000,即jstat -<option> <vmid> <interver>,表示将结果每隔1秒打印一次。

会一直打印下去,所以通常配合count参数使用

3.4 count参数

用于指定查询的总次数。

例如:jstat -class 20384 1000 10,即jstat -<option> <vmid> <interver> <count>表示将结果每隔1秒打印一次,共打印10次

3.5 -t参数

可以在输出信息前加上一个Timestamp列,显示程序的运行时间。单位:秒

例如:使用jstat -class -t 20384,就会在结果前面加上一个Timestamp列,显示程序的运行时间。因为我们的程序在我写博客期间一直是阻塞住的,从启动到现在花了1382.9秒。

这里有一个小经验

我们可以比较Java进程的启动时间以及总 GC时间(GCT列),或者两次测量的间隔时间以及总GC时间的增量,来得出GC时间占运行时间的比例。

如果该比例超过20%,则说明目前堆的压力较大;如果该比例超过90%,则说明堆里几乎没有可用空间,随时都可能抛出OOM异常。

3.6 -h参数

可以在周期性数据输出时,输出多少行数据后输出一个表头信息。

例如:jstat -class -t -h3 20384 1000 10

可以看到效果,会每输出3行后打印一次Timestamp

3.3 如何利用jstat排查OOM和内存泄漏

这里可以参考我的博客:利用jstat命令排查OOM和内存泄漏

四、jinfo:实时查看和修改JVM配置参数

jinfo(Configuration Info for Java)用来查看虚拟机配置参数信息,也可用于调整虚拟机的配置参数。

在很多情况下,Java应用程序不会指定所有的Java虚拟机参数。而此时,开发人员可能不知道某一个具体的Java虚拟机参数的默认值。在这种情况下,可能需要通过查找文档获取某个参数的默认值。这个查找过程可能是非常艰难的。但有了jinfo工具,开发人员可以很方便地找到ava虚拟机参数的当前值。

官方文档: https://docs.oracle.com/en/java/javase/11/tools/jinfo.html

4.1 基本语法

使用命令jinfo -help查看:

可以看到,它的基本使用语法为:jinfo [options] pid

option属性:

选项

选项说明

no option

输出全部的参数和系统属性

-flag name

输出对应名称的参数

-flag [+-]name

开启或者关闭对应名称的参数,只有被标记为manageable的参数才可以被动态修改

-flag name=value

设定对应名称的参数

-flags

输出全部的参数

-sysprops

输出系统属性

4.2 查看JVM配置参数

  • jinfo -sysprops 进程id

可以查看由System.getProperties()取得的参数

可以看到很多的属性信息,这些都是可以由System.getProperties()取得的参数。

  • jinfo -flags 进程id 查看曾经赋过值的一些参数

  • jinfo -flag 参数名称 进程id 查看某个java进程的具体参数信息

4.3 修改JVM配置参数

jinfo不仅可以查看运行时某一个Java虚拟机参数的实际取值,甚至可以在运行时修改部分参数,并使之立即生效

但是,并非所有参数都支持动态修改。参数只有被标记为manageable的flag可以被实时修改。其实,这个修改能力是极其有限的。

我们可以在Linux下使用以下命令查看哪些参数可以被实时修改

java -XX:+PrintFlagsFinal -version | grep manageable

可以看出,其实也就是bool类型和数值类型。

4.3.1 针对bool类型参数的修改

使用命令:jinfo -flag [+|-]参数名称 进程id

本身查看是没有PrintGCDetails这个参数的,然后我们将它加上

4.3.2 针对非bool类型参数的修改

使用命令:jinfo -flag 参数名称=参数值 进程id

可以看出,本来MaxHeapFreeRatio的数值是100,我们将它改为了90

4.4 拓展

  • java -XX:+PrintFlagsInitial

查看所有JVM参数启动的初始值

  • java -XX:+PrintFlagsFinal

查看所有JVM参数的最终值

  • java -参数名称:+PrintCommandLineFlags

查看那些已经被用户或者JVM设置过的详细的XX参数的名称和值

五、jmap:导出内存映像文件&内存使用情况

jmap(JVM Memory Map):作用一方面是获取dump文件(堆转储快照文件,二进制文件),它还可以获取目标Java进程的内存相关信息,包括Java堆各区域的使用情况、堆中对象的统计信息、类加载信息等。

5.1 基本语法

使用jmap -help查看使用方法:

可以看出,它的基本使用语法为:

  • jmap [option] <pid>

  • jmap [option] <executable <core>

  • jmap [option] [server_id@]<remote server IP or hostname>

5.2 导出内存映像文件

5.2.1手动方式

一般用于需要立刻生成映像文件的情况。

  • jmap -dump:format=b, file=<filename.hprof> <pid> 生成所有的对象的快照

  • jmap -dump:live, format=b, file=<filename.hprof> <pid> 仅生成存活的对象的快照

<filename.hprof>中的filename是文件名称,而.hprof是后缀名;<>代表该值可以省略,后面的<pid>是进程id,需要通过jps查询出来;format=b表示生成的是标准的dump文件,用来进行格式限定。

一般使用的是第二种方式,也就是生成堆中存活对象的快照,因为我们遇到GC问题时,往往是因为某些存活的对象无法回收导致的,这种方式生成的dump文件更小,我们传输处理都更方便。

5.2.2 自动方式

一般用于发生OOM之后立刻生成镜像文件的情况。

当程序发生OOM退出系统时,一些瞬时信息都随着程序的终止而消失,而重现OOM问题往往比较困难或者耗时。此时若能在OOM时,自动导出dump文件就显得非常迫切。

这里介绍一种比较常用的取得堆快照文件的方法,即使用:

  • -XX:+HeapDumpOnOutOfMemoryError 在程序发生OOM时,导出应用程序的当前堆快照

  • -XX:HeapDumpPath=<filename.hprof> 可以指定堆快照的保存位置

例如,我们使用上面的GCTest代码,配好GC启动参数:

-Xms60m -Xmx60m -XX:SurvivorRatio=8 -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=D:\1.hprof

启动程序,等待发生OOM后,即可在d盘找到生成的镜像文件:

5.3 显示堆内存相关信息

  • jmap -heap 进程id

jmap -heap 进程id只是时间点上的堆信息,这其实没有jstat强大,jstat后面可以添加参数,可以指定时间动态观察数据改变情况,而jstat又比不上图形化界面工具,例如jvisualvm等,它们可以用图表的方式动态展示出相关信息,更加直观明了。

  • jmap -histo 进程id

输出堆中对象的同级信息,包括类、实例数量和合计容量,也是这一时刻的内存中的对象信息

5.4 其他作用

  • jmap -permstat 进程id 查看系统的ClassLoader信息

  • jmap -finalizerinfo 查看堆积在finalizer队列中的对象

这两个参数不常用,且只能在linux/solaris平台有效,就不再演示了

5.5 小结

由于jmap将访问堆中的所有对象,为了保证在此过程中不被应用线程干扰,jmap需要借助安全点机制,让所有线程停留在不改变堆中数据的状态。也就是说,由jmap导出的堆快照必定是安全点位置的。这可能导致基于该堆快照的分析结果存在偏差。

举个例子,假设在编译生成的机器码中,某些对象的生命周期在两个安全点之间,那么: live选项将无法探知到这些对象,这就是存在偏差的地方。

另外,如果某个线程长时间无法跑到安全点,jmap将一直等下去。

前面讲的jstat则不同,垃圾回收器会主动将jstat所需要的摘要数据保存至固定位置之中,jstat只需直接读取即可。

六、jhat:JDK自带堆分析工具

jhat( VM Heap Analysis Tool)是Sun JDK提供的,jhat命令与jmap命令搭配使用,用于分析jmap生成的heap dump文件(堆转储快照)。jhat内置了一个微型的HTTP/HTML服务器,生成dump文件的分析结果后,用户可以在浏览器中查看分析结果(分析虚拟机转储快照信息)。使用jhat命令就启动了一个http服务,端口是7000,即http://localhost:7000/,就可以在浏览器里分析。

说明:jhat命令在JDK9、JDK10中已经被删除,官方建议用VisualVM代替。所以该指令只需简单了解一下即可。

6.1 基本语法

可以看出,它的基本使用语法为: jhat [option] [ dumpfile]

其中dumpfile代表dump文件的地址以及名称。

例如:jhat d:\1.hprof

6.2 option参数

  • -stack false|true 关闭|打开对象分配调用栈跟踪

  • -refs false|true 关闭|打开对象引用跟踪

  • -port port-number 设置jhat HTTP Server的端口号,默认7000

  • -exclude exclude-file 执行对象查询时需要排除的数据成员

  • -baseline exclude-file 指定一个基准堆转储

  • -debug int 设置debug级别

  • -version 启动后显示版本信息就退出

  • -J<flag> 传入启动参数,比如-J-Xmx512m

6.3 使用

咱们就分析一下刚刚演示jmap时生成的1.hprof文件,命令行键入

jhat d:\1.hprof

打开浏览器,访问http://localhost:7000/

七、jstack:打印JVM中线程快照

jstack(JVM Stack Trace):用于生成虚拟机指定进程当前时刻的线程快照(虚拟机堆栈跟踪)。线程快照就是当前虚拟机内指定进程的每一条线程正在执行的方法堆栈的集合。

生成线程快照的作用:可用于定位线程出现长时间停顿的原因,如线程间死锁、死循环、请求外部资源导致的长时间等待等问题。这些都是导致线程长时间停顿的常见原因。当线程出现停顿时,就可以用jstack显示各个线程调用的堆栈情况。

在thread dump中,要留意下面几种状态:

  • 死锁,Deadlock(重点关注)

  • 等待资源,waiting on condition(重点关注)

  • 等待获取监视器,waiting on monitor entry(重点关注)

  • 阻塞,Blocked(重点关注)

  • 执行中,Runnable

  • 暂停,Suspended

  • 对象等待中,object.wait()或TIMED_WAITING

  • 停止,Parked

7.1 基本语法

可以看出,它的基本使用语法为:jstack option pid

7.2 option参数

咱们先使用一段造成线程死锁的代码,便于看到工具的使用效果:

/**
 * 演示线程的死锁问题
 */
public class ThreadDeadLock {

    public static void main(String[] args) {

        StringBuilder s1 = new StringBuilder();
        StringBuilder s2 = new StringBuilder();

        new Thread(){
            @Override
            public void run() {

                synchronized (s1){

                    s1.append("a");
                    s2.append("1");

                    try {
                        Thread.sleep(100);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }

                    synchronized (s2){
                        s1.append("b");
                        s2.append("2");

                        System.out.println(s1);
                        System.out.println(s2);
                    }

                }

            }
        }.start();


        new Thread(new Runnable() {
            @Override
            public void run() {
                synchronized (s2){

                    s1.append("c");
                    s2.append("3");

                    try {
                        Thread.sleep(100);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }

                    synchronized (s1){
                        s1.append("d");
                        s2.append("4");

                        System.out.println(s1);
                        System.out.println(s2);
                    }
                }
            }
        }).start();

        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        new Thread(new Runnable() {
            @Override
            public void run() {
                Map<Thread, StackTraceElement[]> all = Thread.getAllStackTraces();//追踪当前进程中的所有的线程
                Set<Map.Entry<Thread, StackTraceElement[]>> entries = all.entrySet();
                for(Map.Entry<Thread, StackTraceElement[]> en : entries){
                    Thread t = en.getKey();
                    StackTraceElement[] v = en.getValue();
                    System.out.println("【Thread name is :" + t.getName() + "】");
                    for(StackTraceElement s : v){
                        System.out.println("\t" + s.toString());
                    }
                }
            }
        }).start();
    }
}
  • -F 当正常输出的请求不被响应时,强制输出线程堆栈

  • -l 除堆栈外,显示关于锁的附加信息

  • -m 如果调用本地方法的话,可以显示C/C++的堆栈

  • -h 帮助操作

八、jcmd:多功能命令行

在JDK 1.7以后,新增了一个命令行工具jcmd,它是一个多功能的工具,可以用来实现前面除了jstat之外所有命令的功能。比如:用它来导出堆、内存使用、查看Java进程、导出线程信息、执行Gc、JVM运行时间等。

jcmd拥有jmap的大部分功能,并且在Oracle的官方网站上也推荐使用jcmd命令代jmap命令。

8.1 基本语法

8.2 使用

  • jcmd -l 列出所有的JVM进程(可用于代替jps)

  • jcmd 进程号 help 针对指定的进程,列出支持的所有具体命令

  • jcmd 进程号 具体命令 显示指定进程的指令命令的数据

九、jstatd:远程主机信息收集

之前的指令只涉及到监控本机的Java应用程序,而在这些工具中,一些监控工具也支持对远程计算机的监控(如jps、jstat)。为了启用远程监控,则需要配合使用jstatd 工具。

命令jstatd是一个RMI服务端程序,它的作用相当于代理服务器,建立本地计算机与远程监控工具的通信。jstatd服务器将本机的Java应用程序信息传递到远程计算机。

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

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

相关文章

十二.自定义类型:结构体、联合、枚举

目录 一.结构体 1.结构体类型的基础知识 &#xff08;1&#xff09;结构的声明 &#xff08;2&#xff09;匿名结构体 &#xff08;3&#xff09;结构体变量的定义和初始化 &#xff08;4&#xff09;结构的自引用 &#xff08;5&#xff09;结构体传参 2.结构体内存对齐…

227. 基本计算器 II

227. 基本计算器 II题目算法设计&#xff1a;栈扩展&#xff1a;后缀表达式题目 传送门&#xff1a;https://leetcode.cn/problems/basic-calculator-ii/submissions/ 算法设计&#xff1a;栈 一个功能完备的计算器功能&#xff0c;有很多功能&#xff0c;我们需要从最简单的…

【CAD .NET】第一课 开发自己的CAD软件

开发自己的CAD软件(解析库私信我buy) 介绍 CAD .NET 为在 .NET 环境下开发解决方案的库。它支持 AutoCAD DWG、DXF、PLT 和其他 CAD 格式。它支持 AutoCAD DWG, DXF, PLT 和其他 CAD 格式。 该库可用于广泛领域: 处理所有项目阶段的工业图纸 监测和远程控制程序 数控(C…

ReactNative0.71正式版发布,Ts作为首要开发语言

时隔近4个月的时间&#xff0c;ReactNative带来了0.71版本的更新&#xff0c;这速度对比隔壁Flutter不得不说是真的有的慢。 这个版本的更新的内容还是比较重磅和突破性的&#xff0c;主要体现在如下几点&#xff1a; 编程语法默认改为TypeScript使用Flexbox Gap使布局更加简…

AlmaLinux 9部署JumpServer

JumpServer简介 JumpServer 是广受欢迎的开源堡垒机&#xff0c;是符合 4A 规范的专业运维安全审计系统。 JumpServer 使用 Python 开发&#xff0c;配备了业界领先的 Web Terminal 方案&#xff0c;交互界面美观、用户体验好。 JumpServer 采纳分布式架构&#xff0c;支持多…

【C++11】—— 类的新功能

目录 一、移动构造和移动赋值的特点 二、类成员变量初始化 三、强制生成默认函数的关键字default 四、禁止生成默认函数的关键字delete 五、继承和多态中的fifinal与override关键字 一、移动构造和移动赋值的特点 默认成员函数 原来C类中&#xff0c;有6个默认成员函数&a…

Yolov8实例分割Tensorrt部署实战

目录 0 引言 1 生成onnx模型 2 onnx转为tensorrt的engine模型 3 Tensorrt推理 3.1 yolov8n-seg分割结果 3.2 yolov8s-seg分割结果 3.3 yolov8m-seg分割结果 3.4 yolov8l-seg分割结果 3.5 yolov8x-seg分割结果 0 引言 ultralytics在github发布了yolov8模型&#xff0c;…

C语言 atoi 函数解析

文章目录前言atoi函数的介绍atoi函数的使用atoi函数的自我实现写在最后前言 对于atoi函数大家可能会有些陌生&#xff0c;不过当你选择并阅读到这里时&#xff0c;请往下阅读&#xff0c;我相信你能对atoi函数熟悉该函数的头文件为 <stdlib.h> 或 <cstdlib> atoi函…

Android Studio Electric Eel | 2022.1.1 发布,快来看看有什么大更新吧

原文链接&#xff1a;https://developer.android.com/studio/releases 本次 Android Studio 又发布了大量的内容更新&#xff0c;按照惯例推荐是等两个小版本后再更新会比较稳&#xff0c;当然也鼓励大家尝尝鲜&#xff0c;本次更新推出了大量实用的功能。 另外由于国内对更新…

大学生在校和校外可以开展的兼职,你肯定不知道

大学生的空闲时间比较多&#xff0c;适合大学生的兼职也有很多&#xff0c;因为大学生逻辑思维更强、大脑灵活、接受新事物能力强&#xff0c;而且大多都有电脑手机&#xff0c;可以做一点网上的兼职。如果你在学校有一定条件的话&#xff0c;还可以开展在学校里另类的兼职&…

1580_AURIX_TC275_SMU模块初步

全部学习汇总&#xff1a; GreyZhang/g_TC275: happy hacking for TC275! (github.com) SMU集中了所有软硬件的Alarm信息&#xff0c;这个在之前的很多模块的描述中看得出来的。默认情况下&#xff0c;其实只有看门狗的Alarm是开的&#xff0c;其他的都是关的。这个描述跟我之前…

[ 问题解决篇 ] 设置windows密码策略并且更改用户密码 -- 解决windwos密码无法设置为1的问题

&#x1f36c; 博主介绍 &#x1f468;‍&#x1f393; 博主介绍&#xff1a;大家好&#xff0c;我是 _PowerShell &#xff0c;很高兴认识大家~ ✨主攻领域&#xff1a;【渗透领域】【数据通信】 【通讯安全】 【web安全】【面试分析】 &#x1f389;点赞➕评论➕收藏 养成习…

P3654 First Step (ファーストステップ)

P3654 First Step (ファーストステップ) 题目背景 知らないことばかりなにもかもが&#xff08;どうしたらいいの&#xff1f;&#xff09; 一切的一切 尽是充满了未知数&#xff08;该如何是好&#xff09; それでも期待で足が軽いよ&#xff08;ジャンプだ&#xff01;&…

C语言 全排列(包含错误代码及分析,memset简单介绍及举例)

正确代码&#xff1a;#include <stdio.h> #include <math.h> #include <string.h>int n;//表示位数 int a[10]; int hash_tabel[10];void print() {for(int in;i>0;i--)printf("%d",a[i]);printf("\n"); } void core(int d) {if(d0)/…

Linux使用ACL控制对文件的访问

文章目录1. 查看文件ACL2. 解释文件ACL3. 更改ACL文件权限setfacl命令1) 以递归方式更新现有 cases 目录及其内容。2) 以递归方式更新现有cases 目录及其内容。3) 为contractors 组成员更新默认权限。默认权限为读取、写入和执行3.1.4) 为contractor3用户更新默认权限。默认权限…

ssm权限管理系统2

PageHelper 直接使用maven在pom.xml中添加依赖就行 在我们这个ssm管理项目中&#xff0c;已经添加了依赖包 在Springp配置文件中配置拦截器插件 正式使用 我们只需要在调用dao的方法之前插入如下语句就行&#xff0c;也就是说在service层里面进行插入 当然了上面的pageNum与pag…

ssh公钥配置,使用git从github上拉取、上传项目

一、ssh公钥配置若在以下某个步骤出现问题&#xff1a;Please make sure you have the correct access rights and the repository exists 则按本节方法重新配置ssh。删除C:\Users\Administrator\.ssh下的所有文件在桌面右击&#xff0c;选择Git Bash Here# 1.设置用户名 git c…

万字讲解Linux常用指令

目录 前言&#xff1a; 一、Linux界面问题 二、什么是操作系统 三、为什么学习Linux基本指令 四、Linux基础指令 pwd命令 ls指令 认识一下ls -a&#xff1a; 认识一下ls -d&#xff1a; 理解文件 cd指令 4.touch指令 5.mkdir指令 6.rmdir指令和rm指令 7.man指令 8.cp指令 9.mv指…

自动驾驶中3D目标检测综述

1 背 景 1.1 3D目标检测 3D目标检测是通过输入传感器数据&#xff0c;预测3D目标的属性信息的任务。如何表示3D目标的属性信息是关键&#xff0c;因为后续的预测和规划需要这些信息。在大部分情况下&#xff0c;3D目标被定义为一个立方体&#xff0c;(x,y,z)是立方体的中心坐…

stm32mp1 uboot启动流程分析

stm32mp1 uboot启动流程分析 本节主要关注uboot启动linux的流程&#xff0c;首先关注下uboot的环境变量 uboot环境变量 进入uboot以后回车输入print即可看到uboot的所有环境变量&#xff1a; 这里很多变量嵌套了一些流程&#xff0c;整理一下格式&#xff1a; altbootcmdru…