Android中Matrix的简单使用

news2024/10/2 20:23:25

Android中Matrix的简单使用

1.简介:

Matrix 是一款微信研发并日常使用的应用性能接入框架,支持iOS, macOS和Android。 Matrix 通过接入各种性能监控方案,对性能监控项的异常数据进行采集和分析,输出相应的问题分析、定位与优化建议,从而帮助开发者开发出更高质量的应用。

2.使用说明:

​ Matrix-android 当前监控范围包括:应用安装包大小,帧率变化,启动耗时,卡顿,慢方法,SQLite 操作优化,文件读写,内存泄漏等等。

  • APK Checker: 针对 APK 安装包的分析检测工具,根据一系列设定好的规则,检测 APK 是否存在特定的问题,并输出较为详细的检测结果报告,用于分析排查问题以及版本追踪
  • Resource Canary: 基于 WeakReference 的特性和 Square Haha 库开发的 Activity 泄漏和 Bitmap 重复创建检测工具
  • Trace Canary: 监控ANR、界面流畅性、启动耗时、页面切换耗时、慢函数及卡顿等问题
  • SQLite Lint: 按官方最佳实践自动化检测 SQLite 语句的使用质量
  • IO Canary: 检测文件 IO 问题,包括:文件 IO 监控和 Closeable Leak 监控
  • Battery Canary: 监控 App 活跃线程(待机状态 & 前台 Loop 监控)、ASM 调用 (WakeLock/Alarm/Gps/Wifi/Bluetooth 等传感器)、 后台流量 (Wifi/移动网络)等 Battery Historian 统计 App 耗电的数据
  • MemGuard
  • 检测堆内存访问越界、使用释放后的内存、重复释放等问题

3.特性:

与常规的 APM 工具相比,Matrix 拥有以下特点:

APK Checker

  • 具有更好的可用性:JAR 包方式提供,更方便应用到持续集成系统中,从而追踪和对比每个 APK 版本之间的变化
  • 更多的检查分析功能:除具备 APKAnalyzer 的功能外,还支持统计 APK 中包含的 R 类、检查是否有多个动态库静态链接了 STL 、搜索 APK 中包含的无用资源,以及支持自定义检查规则等
  • 输出的检查结果更加详实:支持可视化的 HTML 格式,便于分析处理的 JSON ,自定义输出等等

Resource Canary

  • 分离了检测和分析部分,便于在不打断自动化测试的前提下持续输出分析后的检测结果
  • 对检测部分生成的 Hprof 文件进行了裁剪,移除了大部分无用数据,降低了传输 Hprof 文件的开销
  • 增加了重复 Bitmap 对象检测,方便通过减少冗余 Bitmap 数量,降低内存消耗

Trace Canary

  • 编译期动态修改字节码, 高性能记录执行耗时与调用堆栈
  • 准确的定位到发生卡顿的函数,提供执行堆栈、执行耗时、执行次数等信息,帮助快速解决卡顿问题
  • 自动涵盖卡顿、启动耗时、页面切换、慢函数检测等多个流畅性指标
  • 准确监控ANR,并且能够高兼容性和稳定性地保存系统产生的ANR Trace文件

SQLite Lint

  • 接入简单,代码无侵入
  • 数据量无关,开发、测试阶段即可发现SQLite性能隐患
  • 检测算法基于最佳实践,高标准把控SQLite质量*
  • 底层是 C++ 实现,支持多平台扩展

IO Canary

  • 接入简单,代码无侵入
  • 性能、泄漏全面监控,对 IO 质量心中有数
  • 兼容到 Android P

Battery Canary

  • 接入简单,开箱即用
  • 预留 Base 类和 Utility 工具以便扩展监控特性

Memory Hook

  • 一个检测 Android native 内存泄漏的工具
  • 无侵入,基于 PLT-hook(iqiyi/xHook),无需重编 native 库
  • 高性能,基于 Wechat-Backtrace 进行快速 unwind 堆栈,支持 aarch64 和 armeabi-v7a 架构

Pthread Hook

  • 一个检测 Android Java 和 native 线程泄漏及缩减 native 线程栈空间的工具
  • 无侵入,基于 PLT-hook(iqiyi/xHook),无需重编 native 库
  • 通过对 native 线程的默认栈大小进行减半降低线程带来的虚拟内存开销,在 32 位环境下可缓解虚拟内存不足导致的崩溃问题

WVPreAllocHook

  • 一个用于安全释放 WebView 预分配内存以在不加载 WebView 时节省虚拟内存的工具,在 32 位环境下可缓解虚拟内存不足导致的崩溃问题
  • 无侵入,基于 PLT-hook(iqiyi/xHook),无需重编 native 库
  • 使用该工具后 WebView 仍可正常工作

MemGuard

  • 一个基于 GWP-Asan 修改的堆内存问题检测工具
  • 无侵入,基于 PLT-hook(iqiyi/xHook),无需重编 native 库
  • 可根据正则表达式指定被检测的目标库
  • 可检测堆内存访问越界、使用释放后的内存和双重释放等问题

Backtrace Component

  • 基于 DWARF 以及 ARM 异常处理数据进行简化并生成全新的 quicken unwind tables 数据,用于实现可快速回溯 native 调用栈的 backtrace 组件。回溯速度约是 libunwindstack 的 15x ~ 30x 左右。

完整的说明查看官方文档:https://github.com/Tencent/matrix#matrix_android_cn

4.依赖导入:

4.1 配置Matrix版本:

在gradle.properties目录下配置Matrix版本

MATRIX_VERSION=2.1.0

4.2 AGP8.0.2导入依赖:

由于我是最新稳定版的Studio,AGP版本为8.0以上,所以这里有两种配置方式,后面讲解AGP8.0新的依赖配置方式和改变,这里就直接上代码.

dependencies {
    implementation 'androidx.appcompat:appcompat:1.6.1'
    implementation 'com.google.android.material:material:1.9.0'
    implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
    testImplementation 'junit:junit:4.13.2'
    androidTestImplementation 'androidx.test.ext:junit:1.1.5'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1'
    implementation group: "com.tencent.matrix", name: "matrix-android-lib", version: MATRIX_VERSION, changing: true
    implementation group: "com.tencent.matrix", name: "matrix-android-commons", version: MATRIX_VERSION, changing: true
    implementation group: "com.tencent.matrix", name: "matrix-trace-canary", version: MATRIX_VERSION, changing: true
    implementation group: "com.tencent.matrix", name: "matrix-io-canary", version: MATRIX_VERSION, changing: true
    implementation group: "com.tencent.matrix", name: "matrix-memory-canary", version: MATRIX_VERSION, changing: true
    implementation 'com.blankj:utilcodex:1.31.1'
}

4.3 AGP8.0以下导入依赖:

apply plugin: 'com.android.application'
apply plugin: 'com.tencent.matrix-plugin'

    matrix {
        trace {
            enable = true    //if you don't want to use trace canary, set false
            baseMethodMapFile = "${project.buildDir}/matrix_output/Debug.methodmap"
            blackListFile = "${project.projectDir}/matrixTrace/blackMethodList.txt"
        }
    }

dependencies {
    implementation 'androidx.appcompat:appcompat:1.6.1'
    implementation 'com.google.android.material:material:1.9.0'
    implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
    testImplementation 'junit:junit:4.13.2'
    androidTestImplementation 'androidx.test.ext:junit:1.1.5'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1'
    implementation group: "com.tencent.matrix", name: "matrix-android-lib", version: MATRIX_VERSION, changing: true
    implementation group: "com.tencent.matrix", name: "matrix-android-commons", version: MATRIX_VERSION, changing: true
    implementation group: "com.tencent.matrix", name: "matrix-trace-canary", version: MATRIX_VERSION, changing: true
    implementation group: "com.tencent.matrix", name: "matrix-io-canary", version: MATRIX_VERSION, changing: true
    implementation group: "com.tencent.matrix", name: "matrix-memory-canary", version: MATRIX_VERSION, changing: true
    implementation 'com.blankj:utilcodex:1.31.1'
}


在这里插入图片描述

4.4 项目的build.gradle配置:

buildscript {
    repositories {
        google()
        mavenCentral()
        maven { url 'https://maven.aliyun.com/nexus/content/groups/public/' }
        maven { url 'https://repo1.maven.org/maven2/' }
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:8.0.2'
        classpath ("com.tencent.matrix:matrix-gradle-plugin:${MATRIX_VERSION}") { changing = true }
    }
}
plugins {
    id 'com.android.application' version '8.0.2' apply false
    id 'com.android.library' version '8.0.2' apply false
}

在这里插入图片描述

4.5 完整的配置如下:

App目录下的build.gradle

plugins {
    id 'com.android.application'
}
//apply plugin: 'com.android.application'
//apply plugin: 'com.tencent.matrix-plugin'
android {
    namespace 'com.example.matrixdemo'
    compileSdk 33
    defaultConfig {
        applicationId "com.example.matrixdemo"
        minSdk 23
        targetSdk 33
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }
 /*   matrix {
        trace {
            enable = true    //if you don't want to use trace canary, set false
            baseMethodMapFile = "${project.buildDir}/matrix_output/Debug.methodmap"
            blackListFile = "${project.projectDir}/matrixTrace/blackMethodList.txt"
        }
    }*/
}

dependencies {
    implementation 'androidx.appcompat:appcompat:1.6.1'
    implementation 'com.google.android.material:material:1.9.0'
    implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
    testImplementation 'junit:junit:4.13.2'
    androidTestImplementation 'androidx.test.ext:junit:1.1.5'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1'
    implementation group: "com.tencent.matrix", name: "matrix-android-lib", version: MATRIX_VERSION, changing: true
    implementation group: "com.tencent.matrix", name: "matrix-android-commons", version: MATRIX_VERSION, changing: true
    implementation group: "com.tencent.matrix", name: "matrix-trace-canary", version: MATRIX_VERSION, changing: true
    implementation group: "com.tencent.matrix", name: "matrix-io-canary", version: MATRIX_VERSION, changing: true
    implementation group: "com.tencent.matrix", name: "matrix-memory-canary", version: MATRIX_VERSION, changing: true
    implementation 'com.blankj:utilcodex:1.31.1'
}

项目的build.gradle:

// Top-level build file where you can add configuration options common to all sub-projects/modules.

buildscript {
    repositories {
        google()
        mavenCentral()
        maven { url 'https://maven.aliyun.com/nexus/content/groups/public/' }
        maven { url 'https://repo1.maven.org/maven2/' }
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:8.0.2'
        classpath ("com.tencent.matrix:matrix-gradle-plugin:${MATRIX_VERSION}") { changing = true }
    }
}
plugins {
    id 'com.android.application' version '8.0.2' apply false
    id 'com.android.library' version '8.0.2' apply false
}

5.MatrixUtils工具类:

package com.example.matrixdemo.utils;

import android.app.Application;

import com.blankj.utilcode.util.LogUtils;
import com.example.matrixdemo.impl.MatrixDynamicConfigImpl;
import com.example.matrixdemo.plugin.MatrixPluginListener;
import com.tencent.matrix.Matrix;
import com.tencent.matrix.iocanary.IOCanaryPlugin;
import com.tencent.matrix.iocanary.config.IOConfig;
import com.tencent.matrix.memory.canary.MemoryCanaryPlugin;
import com.tencent.matrix.trace.TracePlugin;
import com.tencent.matrix.trace.config.TraceConfig;

/**
 * @author: njb
 * @date: 2023/8/10 11:19
 * @desc:
 */
public class MatrixUtils {
    private static volatile MatrixUtils INSTANCE;
    private static final String TAG = "MatrixLog";

    private MatrixUtils() {
    }

    public static MatrixUtils getInstance() {
        if (INSTANCE == null) {
            synchronized (MatrixUtils.class) {
                if (INSTANCE == null) {
                    INSTANCE = new MatrixUtils();
                }
            }
        }
        return INSTANCE;
    }

    public void initPlugin(Application application, String splashActivity) {
        Matrix.Builder builder = new Matrix.Builder(application); // build matrix
        builder.pluginListener(new MatrixPluginListener(application)); // add general pluginListener
        MatrixDynamicConfigImpl matrixDynamicConfig = new MatrixDynamicConfigImpl(); // dynamic config
        boolean fpsEnable = matrixDynamicConfig.isFPSEnable();
        boolean traceEnable = matrixDynamicConfig.isTraceEnable();
        //Trace plugin
        TraceConfig traceConfig = new TraceConfig.Builder()
                .dynamicConfig(matrixDynamicConfig)
                .enableFPS(fpsEnable)//帧率
                .enableEvilMethodTrace(traceEnable)//慢方法
                .enableAnrTrace(traceEnable)//anr
                .enableStartup(traceEnable)//启动速度
                .splashActivities(splashActivity)//首页
                //debug模式
                .isDebug(true)
                //dev环境
                .isDevEnv(false)
                .build();

        TracePlugin tracePlugin = new TracePlugin(traceConfig);
        builder.plugin(tracePlugin);

        MemoryCanaryPlugin memoryCanaryPlugin = new MemoryCanaryPlugin();
        builder.plugin(memoryCanaryPlugin);

        // io plugin
        IOCanaryPlugin ioCanaryPlugin = new IOCanaryPlugin(new IOConfig.Builder()
                .dynamicConfig(matrixDynamicConfig)
                .build());
        builder.plugin(ioCanaryPlugin);

        //init matrix
        Matrix.init(builder.build());
        tracePlugin.start();
    }
}

6.自定义Matrix动态配置接口

package com.example.matrixdemo.impl;

import com.tencent.mrs.plugin.IDynamicConfig;

/**
 * @author: njb
 * @date: 2023/8/10 11:24
 * @desc:
 */
public class MatrixDynamicConfigImpl implements IDynamicConfig {
    public MatrixDynamicConfigImpl() {}

    public boolean isFPSEnable() { return true;}
    public boolean isTraceEnable() { return true; }
    public boolean isMatrixEnable() { return true; }
    public boolean isDumpHprof() {  return false;}

    @Override
    public String get(String key, String defStr) {
        return defStr;
    }

    @Override
    public int get(String key, int defInt) {
        return defInt;
    }

    @Override
    public long get(String key, long defLong) {
        return defLong;
    }

    @Override
    public boolean get(String key, boolean defBool) {
        return defBool;
    }

    @Override
    public float get(String key, float defFloat) {
        return defFloat;
    }
}

7.自定义插件事件监听:

package com.example.matrixdemo.plugin;

import android.content.Context;

import com.blankj.utilcode.util.LogUtils;
import com.tencent.matrix.plugin.DefaultPluginListener;
import com.tencent.matrix.report.Issue;
import com.tencent.matrix.util.MatrixLog;

/**
 * @author: njb
 * @date: 2023/8/10 11:21
 * @desc:
 */
public class MatrixPluginListener extends DefaultPluginListener {
    public static final String TAG = "MatrixPluginListener";

    public MatrixPluginListener(Context context) {
        super(context);
    }

    @Override
    public void onReportIssue(Issue issue) {
        super.onReportIssue(issue);
        //todo 处理性能监控数据
        MatrixLog.e(TAG, issue.toString());
        LogUtils.e(TAG, issue.toString());
    }
}

8.Matrix初始化:

package com.example.matrixdemo.app;

import android.app.Application;

import com.example.matrixdemo.utils.MatrixUtils;


/**
 * @author: njb
 * @date: 2023/8/10 11:31
 * @desc:
 */
public class App extends Application {

    @Override
    public void onCreate() {
        super.onCreate();
        initMatrix();
    }

    private void initMatrix() {
        MatrixUtils.getInstance().initPlugin(this,"com.example.matrixdemo.MainActivity;");
    }
}

9.简单使用:

private void testThreadAnr() {
    try {
        int number = 0;
        while (number++ < 5) {
            LogUtils.e(TAG, "主线程睡眠导致的ANR:次数" + number + "/5");
            try {
                Thread.sleep(5000L);
            } catch (InterruptedException e) {
                e.printStackTrace();
                LogUtils.e(TAG, "异常信息为:" + e.getMessage());
            }
        }
    } catch (Throwable e) {
        e.printStackTrace();
        LogUtils.e(TAG, "异常信息为:" + e.getMessage());
    }
}

10.完整测试代码:

这里是模拟主线程睡眠导致的ANR,只是为了简单测试.

package com.example.matrixdemo;

import android.os.Bundle;
import android.widget.TextView;

import androidx.appcompat.app.AppCompatActivity;

import com.blankj.utilcode.util.LogUtils;

public class MainActivity extends AppCompatActivity {
    public TextView textView;
    private static final String TAG = "MatrixLog";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initView();
    }

    private void initView() {
        textView = findViewById(R.id.tv_test);
        textView.setOnClickListener(v -> testThreadAnr());
    }

    private void testThreadAnr() {
        try {
            int number = 0;
            while (number++ < 5) {
                LogUtils.e(TAG, "主线程睡眠导致的ANR:次数" + number + "/5");
                try {
                    Thread.sleep(5000L);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                    LogUtils.e(TAG, "异常信息为:" + e.getMessage());
                }
            }
        } catch (Throwable e) {
            e.printStackTrace();
            LogUtils.e(TAG, "异常信息为:" + e.getMessage());
        }
    }
}

11.布局代码:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <TextView
        android:id="@+id/tv_test"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello World!"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>

12.日志打印:

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

13.源码地址:

https://gitee.com/jackning_admin/matrixdemo

14.总结:

以上就是微信性能监控框架Matrix的简单封装,可以说非常好用,各种信息也非常全面,后面会尝试所有的性能监控插件的使用,这里只是简单介绍一下使用,在新版本的配置!!!

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

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

相关文章

08-3_Qt 5.9 C++开发指南_Graphics View绘图架构

文章目录 1. 场景、视图与图形项1.1 场景1.2 视图1.3 图形项 2. Graphics View 的坐标系统2.1 图形项坐标2.2 视图坐标2.3 场景坐标2.4 坐标映射 3. Graphics View 相关的类3.1 QGraphicsView 类的主要接口函数3.2 QGraphicsScene 类的主要接口函数3.3 图形项 4. 实例介绍 1. 场…

CI+JUnit5并发单测机制创新实践

目录 一. 现状问题 二. 分析原因 三. 采取措施 四. 实践步骤 五. 效能提升 资料获取方法 一. 现状问题 针对现如今高并发场景的业务系统&#xff0c;“并发问题” 终归是必不可少的一类&#xff08;占比接近10%&#xff09;&#xff0c;每次出现问题和事故后&#xff0c…

【C++】const_cast基本用法(详细讲解)

&#x1f449;博__主&#x1f448;&#xff1a;米码收割机 &#x1f449;技__能&#x1f448;&#xff1a;C/Python语言 &#x1f449;公众号&#x1f448;&#xff1a;测试开发自动化【获取源码商业合作】 &#x1f449;荣__誉&#x1f448;&#xff1a;阿里云博客专家博主、5…

华熙生物肌活:2023年版Bio-MESO肌活油性皮肤科学护肤指南

关于报告的所有内容&#xff0c;公众【营销人星球】获取下载查看 核心观点 以悦己和尝鲜为消费动机的他们&#xff0c;已迅速崛起成为护肤行业的焦点人群。而在新生代护肤议题中&#xff0c;“油性皮肤护理”已经成为一个至关重要的子集。今天&#xff0c;中国新生代人口数量…

通讯协议036——全网独有的OPC HDA知识一之聚合(五)计数

本文简单介绍OPC HDA规范的基本概念&#xff0c;更多通信资源请登录网信智汇(wangxinzhihui.com)。 本节旨在详细说明HDA聚合的要求和性能。其目的是使HDA聚合标准化&#xff0c;以便HDA客户端能够可靠地预测聚合计算的结果并理解其含义。如果用户需要聚合中的自定义功能&…

NZ系列工具NZ01:64位系统VBA二维码应用技术

【分享成果&#xff0c;随喜正能量】汗水能浇出成功的鲜花&#xff0c;拼搏能赢来胜利的喜悦&#xff0c;人生不易&#xff0c;累也过&#xff0c;闲也过&#xff0c;只要能充实就是最好过&#xff0c;有也过&#xff0c;没也过&#xff0c;为什么你不看看众生怎么过&#xff0…

从零到精通:学习这些R语言必学包成为数据分析高手!

一、操作数据 ❝ tidyverse ❞ tidyverse是一个强大的R语言数据分析工具集&#xff0c;包含了多个核心包。其中包括ggplot2用于数据可视化、dplyr用于数据处理和转换、tidyr用于数据整理和重塑、readr用于数据导入和读取、purrr用于函数式编程、stringr用于字符串处理等。 ❝ d…

同步_异步请求和Ajax并利用axios框架简化

目录 同步和异步 原生的Ajax 创建XMLHttpRequest对象 常用方法 常用属性 axios框架 同步和异步 同步请求&#xff1a;发送请求后&#xff0c;会做出回应&#xff0c;回应的内容会覆盖浏览器中的内容&#xff0c;这样会打断其他正常的操作&#xff0c;显得不太友好&#…

造个轮子-任务调度执行小框架-任务执行器代理实现

文章目录 前言执行器代理代理对象任务清单代理对象任务清单执项对象处理handler对象状态对象代理工厂任务清单代理工厂清单任务项代理工厂总结前言 不知道为啥,今天好像学不进去,没办法,那就继续编码吧。那么今天的话,加更一篇文章,那就是咱们这个任务执行器的实现。先前…

ESP-IDF插件去除红色波浪线

如图&#xff0c;新装的ESP-IDF打开别人的工程有好多红色波浪线。 把这里的第一个文件夹删除&#xff0c;就是那个.vscode&#xff0c;接下来按ctrlshiftP&#xff0c;输入vscode&#xff0c; 选第一个&#xff0c;添加配置文件夹。 问题解决。 之后记得重新配置板子信息和串…

【C++】static_cast基本用法(详细讲解)

&#x1f449;博__主&#x1f448;&#xff1a;米码收割机 &#x1f449;技__能&#x1f448;&#xff1a;C/Python语言 &#x1f449;公众号&#x1f448;&#xff1a;测试开发自动化【获取源码商业合作】 &#x1f449;荣__誉&#x1f448;&#xff1a;阿里云博客专家博主、5…

ffmepg滤镜

视频按顺时针方向旋转90度 ffplay -vf transpose1 -i juren-30s.mp4 ffplay -f lavfi -i testsrc -vf transpose1 -f lavfi -i testsrc这个滤镜是ffmpeg给用户的一个测试使用的视频 视频水平翻转(左右翻转) -vf hflip 实现慢速播放&#xff0c;声音速度是原始速度的50% ffpla…

pycharm,VSCode 几个好用的插件

pycharm Tabnine AI Code 可以在编写程序的时候为你提供一些快捷方式&#xff0c;增加编程速度 Chinese 对英文不好的程序员来说是个不错的选择&#xff0c;可以将英文状态下的pycharm变为中文版的 ChatGPT 可以跟ai聊天&#xff0c;ai可以解决你80%的问题 &#xff0c;也可以帮…

10个AI绘图生成器让绘画更简单

AI不仅影响商业和医疗保健等行业&#xff0c;还在创意产业中发挥着越来越大的作用&#xff0c;开创了AI绘画生成器新时代。在绘画领域当然也是如此&#xff0c;与传统的绘画工具不同&#xff0c;AI人工智能时代的绘画工具是全自动的、智能的&#xff0c;甚至可以说是“傻瓜式”…

nginx负载均衡的几种配置方式介绍

一.负载均衡含义简介 二.nginx负载均衡配置方式 准备三台设备&#xff1a; 2.190均衡服务器&#xff0c;2.191web服务器1&#xff0c;2.160web服务器2&#xff0c;三台设备均安装nginx&#xff0c;两台web服务器均有网页内容 1.一般轮询负载均衡 &#xff08;1&#xff09…

CMake: 检测并使用OpenMP的并行环境

CMake: 检测OpenMP的并行环境 导言OpenMP简介项目结构CMakeLists.txt相关源码输出结果 导言 目前&#xff0c;市面上的计算机几乎都是多核机器&#xff0c;对于性能敏感的程序&#xff0c;我们必须关注这些多核处理器&#xff0c;并在编程模型中使用并发。OpenMP是多核处理器上…

重零搭建SpringSecurity +JWT

1、前期工作&#xff08;创建父工程&#xff0c;导入依赖&#xff09; 2、创建启动类 3、测试项目&#xff0c;启动后访问8080端口、hello看有没有页面 4、引入springSecurity依赖&#xff08;重新启动&#xff0c;再访问/hello,会跳转到登录页面&#xff0c;用户名是 user,密码…

系统集成项目管理工程师好考吗?不报班能考过吗?

即使不参加培训班&#xff0c;只要自我控制能力还不错&#xff0c;也可以通过考试。中级集成考试难度不大&#xff0c;主要是要理解47个过程的输入输出和工具的使用&#xff0c;很多题目都是按照这个逻辑出的。建议可以在网上或者刷题APP上找一些资料和真题来练习&#xff0c;因…

Ajax 笔记(二)—— Ajax 案例

笔记目录 2. Ajax 综合案例2.1 案例一-图书管理2.1.1 渲染列表2.1.2 新增图书2.1.3 删除图书2.1.4 编辑图书 2.2 案例二-背景图的上传和更换2.2.1 上传2.2.2 更换 2.3 案例三-个人信息设置2.3.1 信息渲染2.3.2 头像修改2.2.3 信息修改2.3.4 提示框 Ajax 笔记&#xff1a; Ajax…

全新 – Amazon EC2 M1 Mac 实例

去年&#xff0c;在 re: Invent 2021 大会期间&#xff0c;我写了一篇博客文章&#xff0c;宣布推出 EC2 M1 Mac 实例的预览版。我知道你们当中许多人请求访问预览版&#xff0c;我们尽了最大努力&#xff0c;却无法让所有人满意。不过&#xff0c;大家现在已经无需等待了。我很…