当前位置: 首页 > news >正文

Android Proguard混淆

关于作者:CSDN内容合伙人、技术专家, 从零开始做日活千万级APP。
专注于分享各领域原创系列文章 ,擅长java后端、移动开发、人工智能等,希望大家多多支持。

目录

  • 一、导读
  • 二、概览
  • 三、语法规则
    • 3.1 输入/输出选项
    • 3.2 保留选项
    • 3.3 缩小选项
    • 3.4 优化选项
    • 3.5 混淆选项
    • 3.6 预验证选项
    • 3.7 常规选项
  • 四、过滤器
    • 4.1 增量混淆
    • 4.2 寻找未使用的代码及方法等(废弃代码)
  • 五、混淆基本原则
    • 5.1 系统相关类不要混淆
    • 5.2 部分项目相关类不要混淆
    • 5.3、添加混淆字典
    • 5.4 r8 & proguard
  • 六、 推荐阅读

在这里插入图片描述

一、导读

我们继续总结学习基础知识,温故知新。
本文讲述Android Proguard 相关知识。

二、概览

Proguard 四部曲:
shrink(删减):删减无用代码,包括类、变量、方法和属性,缩减了APK包的大小

optimize(优化):优化方法字节码,并移除无用的构造方法

obfuscate(混淆):混淆现有代码,将有意义的命名替换为无意义的命名

preverify(预校验):给类添加预校验信息,这是J2ME和Java 6及以上要求的

proguard 文档

三、语法规则

3.1 输入/输出选项

 @ filename

“文件名”的缩写 ‘-include filename’.

 -include filename

从给定文件filename递归读取配置选项

 -basedirectory directoryname

指定这些配置参数或此配置文件中所有后续相对文件名的基目录

 -injars class_path

指定要处理的应用程序的输入 jar(或 apks、aabs、aars、wars、ears、jmods、zip 或目录)。
可以使用多个-injars选项指定类路径条目。

-outjars class_path

指定输出 jar 的名称(或 apks、aabs、aars、wars、ears、jmods、zips 或目录)。
为了更好的可读性,可以使用多个-outjars选项指定类路径条目。如果没有任何-outjars选项,则不会编写任何 jars

-libraryjars class_path

指定要处理的应用程序的库 jar(或 apks、aabs、aars、wars、ears、jmods、zips、目录)

-skipnonpubliclibraryclasses

指定在读取库 jar 时跳过非公共类,以加快处理速度并减少 ProGuard 的内存使用量

-dontskipnonpubliclibraryclasses

指定不忽略非公共库类。从版本 4.5 开始,这是默认设置

-dontskipnonpubliclibraryclassmembers

指定不忽略包可见的库类成员(字段和方法)

-keepdirectories [directory_filter]

指定要保留在输出 jar 中的目录(或 apks、aabs、aars、wars、ears、jmods、zips 或目录)

-target version

已弃用:此选项仅适用于 Java 类文件版本 <= 11

-forceprocessing

指定处理输入,即使输出看起来是最新的

3.2 保留选项


-keep [,modifier,...] class_specification
-keepnames class_specification
指定要保留为代码入口点的类和类成员(字段和方法)-keepclassmembers [,modifier,...] class_specification
-keepclassmembernames class_specification
指定要保留的类成员(如果它们的类也被保留)-keepclasseswithmembers [,modifier,...] class_specification
-keepclasseswithmembernames class_specification
指定要保留的类和类成员,前提是所有指定的类成员都存在
-if class_specification

指定必须present激活后续保留选项(-keep、-keepclassmembers、…)的类和类成员。
条件和后续的 keep 选项可以共享通配符和对通配符的引用。例如,您可以使用Dagger和Butterknife等框架保留类,前提是项目中存在具有相关名称的类。

-printseeds [filename]

指定详尽列出与各种-keep选项匹配的类和类成员。该列表将打印到标准输出或给定文件。该列表可用于验证是否确实找到了预期的类成员,
特别是在您使用通配符时。例如,您可能想要列出您保留的所有应用程序或所有小程序。

3.3 缩小选项

-dontshrink

指定不收缩输入。默认情况下,ProGuard 会缩小代码:它会删除所有未使用的类和类成员。它只保留各种-keep选项列出的选项以及它们直接或间接依赖的选项。
它还在每个优化步骤之后应用收缩步骤,因为某些优化可能会提供删除更多类和类成员的可能性。

-printusage [filename]

指定列出输入类文件的死代码。该列表将打印到标准输出或给定文件。例如,您可以列出应用程序未使用的代码。仅适用于收缩时。

-whyareyoukeeping class_specification

指定打印有关为何给定类和类成员保留在收缩步骤中的详细信息。如果您想知道为什么某些给定元素出现在输出中,这可能很有用。

3.4 优化选项

-dontoptimize

指定不优化输入类文件。默认情况下,ProGuard 会优化所有代码。它内联和合并类和类成员,并在字节码级别优化所有方法。

-optimizations optimization_filter

以更细粒度的级别指定要启用和禁用的优化。仅适用于优化时
例如:

# 指定混淆是采用的算法,后面的参数是一个过滤器
# 这个过滤器是谷歌推荐的算法,一般不做更改
-optimizations !code/simplification/arithmetic,!field/*,!class/merging/*
-optimizationpasses n

指定代码的压缩级别 0 - 7(指定代码进行迭代优化的次数,在Android里面默认是5,这条指令也只有在可以优化时起作用。)

-assumenosideeffects class_specification

指定除了可能返回值之外没有任何副作用的方法。例如,该方法System.currentTimeMillis()返回一个值,但它没有任何副作用。
在优化步骤中,如果 ProGuard 可以确定未使用返回值,则可以删除对此类方法的调用。ProGuard 会分析您的程序代码以自动查找此类方法。
它不会分析库代码,因此此选项很有用。例如,您可以指定 method System.currentTimeMillis(),以便删除对其的任何空闲调用。如果小心的话,
您还可以使用该选项来删除日志记录代码。请注意,ProGuard 将该选项应用于指定方法的整个层次结构。仅适用于优化时。一般来说,做出假设可能是危险的。
您可以轻松地破坏已处理的代码。仅当您知道自己在做什么时才使用此选项!

-assumenoexternalsideeffects class_specification
-assumenoescapingparameters class_specification
-assumenoexternalreturnvalues class_specification
-assumevalues class_specification
-allowaccessmodification
-mergeinterfacesaggressively
-optimizeaggressively

代码优化相关,用不好容易出问题。

3.5 混淆选项

-dontobfuscate

指定不混淆输入类文件。默认情况下,ProGuard 会混淆代码:它为类和类成员分配新的短随机名称。它删除了仅对调试有用的内部属性,例如源文件名、变量名和行号。

-printmapping [filename]

指定打印已重命名的类和类成员从旧名称到新名称的映射。映射被打印到标准输出或给定文件。例如,后续增量混淆需要它,或者如果您想再次理解混淆的堆栈跟踪。仅在混淆时适用。

-applymapping filename

指定重用在 ProGuard 的先前混淆运行中打印出的给定名称映射。映射文件中列出的类和类成员接收与其一起指定的名称。未提及的类和类成员将获得新名称。
该映射可以引用输入类以及库类。此选项对于增量混淆非常有用,即处理现有代码片段的附加组件或小补丁。如果代码结构发生根本性变化,ProGuard 可能会打印出应用映射导致冲突的警告。
您可以通过-useuniqueclassmembernames在两次混淆运行中指定该选项来降低这种风险。只允许使用单个映射文件。仅在混淆时适用。

-obfuscationdictionary          proguard-dic.txt  //指定一个字典文件作为混淆字典
-classobfuscationdictionary     proguard-dic.txt //类字典
-packageobfuscationdictionary   proguard-dic.txt //包字典
-overloadaggressively

指定在混淆时应用积极的重载。然后,多个字段和方法可以获得相同的名称,只要它们的参数和返回类型不同,如 Java 字节码所要求的(不仅仅是它们的参数,如 Java 语言所要求的)。
此选项可以使处理后的代码更小(并且更难以理解,大小,体积)。仅在混淆时适用。

但是可能存在问题,如Google 的 Dalvik VM 无法处理过载的静态字段。

-useuniqueclassmembernames

指定将相同的混淆名称分配给具有相同名称的类成员,并将不同的混淆名称分配给具有不同名称的类成员(对于每个给定的类成员签名)。如果没有该选项,更多的类成员可以映射到相同的短名称,如“a”、“b”等。因此,
该选项会稍微增加结果代码的大小,但它确保保存的混淆名称映射始终可以在后续增量混淆步骤中受到尊重

-dontusemixedcaseclassnames

指定在混淆时不生成大小写混合的类名。默认情况下,混淆的类名可以包含大写字符和小写字符的混合。

-keeppackagenames [package_filter]

指定不混淆给定的包名称。

-flattenpackagehierarchy [package_name]

指定通过将重命名的所有包移动到单个给定父包中来重新打包它们。如果不带参数或使用空字符串 (‘’),包将移至根包中。此选项是进一步混淆包名称的示例之一。它可以使处理后的代码更小且更难以理解(大小,体积)。仅在混淆时适用。

与 repackageclasses 冲突

-repackageclasses [package_name]

指定通过将重命名的所有类文件移动到单个给定包中来重新打包它们。如果没有参数或使用空字符串 (‘’),则包将被完全删除。该选项会覆盖该-flattenpackagehierarchy选项。这是进一步混淆包名称的另一个例子。
它可以使处理后的代码变得更小并且更难以理解(大小,体积)。它的已弃用名称是-defaultpackage. 仅在混淆时适用。

-keepattributes [attribute_filter]

指定要保留的任何可选属性。可以使用一个或多个指令来指定属性-keepattributes

# 抛出异常时保留代码行号
-keepattributes SourceFile,LineNumberTable
# 保护代码中的Annotation不被混淆
-keepattributes *Annotation*
# 避免混淆泛型, 这在JSON实体映射时非常重要
-keepattributes Signature
-keepparameternames

指定保留所保留方法的参数名称和类型。该选项实际上保留了调试属性LocalVariableTable和LocalVariableTypeTable

-renamesourcefileattribute [string]

指定要放入类文件的SourceFile属性(和属性)中的常量字符串。SourceDir请注意,该属性必须首先存在,因此还必须使用-keepattributes指令显式保留它。
例如,您可能希望让经过处理的库和应用程序生成有用的模糊堆栈跟踪。仅在混淆时适用。

-keepkotlinmetadata

已弃用:使用-keep class kotlin.Metadata替代。指定处理kotlin.Metadata注释(如果存在)。目前仅支持对其内容进行缩小和混淆。如果启用此选项,则应从优化中排除包含此类注释的类。

-adaptclassstrings [class_filter]

指定与类名相对应的字符串常量也应该被混淆。如果没有过滤器,所有与类名相对应的字符串常量都会被调整。

-adaptresourcefilenames [file_filter]

根据相应类文件(如果有)的混淆名称指定要重命名的资源文件。如果没有过滤器,则与类文件对应的所有资源文件都会被重命名。

-adaptresourcefilecontents [file_filter]

指定要更新内容的资源文件和本机库。资源文件中提到的任何类名都会根据相应类(如果有)的混淆名称进行重命名。

3.6 预验证选项

-dontpreverify

指定不对已处理的类文件进行预验证。

-microedition

指定处理的类文件针对 Java Micro Edition。

-android

指定处理的类文件是针对Android平台的

3.7 常规选项

-verbose

指定在处理过程中写出更多信息。如果程序因异常而终止,此选项将打印出整个堆栈跟踪,而不仅仅是异常消息。

-dontnote [class_filter]

指定不打印有关配置中潜在错误或遗漏的注释,例如类名称中的拼写错误或缺少可能有用的选项。可选的过滤器是正则表达式;ProGuard 不会打印有关具有匹配名称的类的注释。

-dontwarn [class_filter]

指定根本不警告未解决的引用和其他重要问题。可选的过滤器是正则表达式;ProGuard 不会打印有关具有匹配名称的类的警告。忽视警告可能会很危险。

-ignorewarnings

指定打印有关未解决的引用和其他重要问题的任何警告,但在任何情况下都继续处理。忽视警告可能会很危险。屏蔽警告

-printconfiguration [filename]

指定写出已解析的整个配置,包括包含的文件和替换的变量。该结构被打印到标准输出或给定文件。

-dump [filename]

指定在任何处理之后写出类文件的内部结构。该结构被打印到标准输出或给定文件。

-addconfigurationdebugging

指定使用调试语句来检测已处理的代码,这些调试语句会打印出缺少 ProGuard 配置的建议。

四、过滤器

?	匹配名称中的任何 单个 字符。  例如,“ com.example.Test?”匹配“ com.example.Test1”和“ com.example.Test2”,但不匹配“ com.example.Test12”。*	匹配名称中不包含包分隔符或目录分隔符的任何部分。 
例如,“ com.example.*Test*”匹配“ com.example.Test”和“ com.example.YourTestApplication”,但不匹配“ com.example.mysubpackage.MyTest”。
或者,更一般地说,“ com.example.*”匹配“ com.example”中的所有类,但不匹配其子包中的所有类。**	匹配名称的任何部分,可能包含任意数量的包分隔符或目录分隔符。<n>	匹配同一选项中第n个匹配的通配符。例如,“ com.example.*Foo<1>”匹配“ com.example.BarFooBar”。
例如,“ java/**.class,javax/**.class”匹配 和 中的所有类java文件javax。此外,文件名前面可以有感叹号“ ! ” '从进一步尝试与后续文件名匹配中排除该文件名。例如,“ !**.gif,images/**”匹配images目录中除 gif 文件之外的所有文件。忽略输入 jar 中的某些文件,images此配置会删除该目录及其子目录中的所有文件。
-injars  in.jar(!images/**)
-outjars out.jar仅保留第一个输入 jar 中的清单文件:
-injars  in1.jar
-injars  in2.jar(!META-INF/MANIFEST.MF)
-injars  in3.jar(!META-INF/MANIFEST.MF)
-outjars out.jar
例如,“ foo,*bar”匹配名称foo以及所有以 结尾的名称bar。
<init>	匹配任何构造函数。
<fields>	匹配任何字段。
<methods>	匹配任何方法。
*	匹配任何字段或方法。

通配符	意义
%	匹配任何原始类型(" boolean"、" int" 等)或 " void" 类型。
?	匹配类名中的任何单个字符。
*	匹配类名中不包含包分隔符的任何部分。
**	匹配类名的任何部分,可能包含任意数量的包分隔符。
***	匹配任何类型(原始或非原始、数组或非数组)。
...	匹配任意数量任意类型的参数。
<n>	匹配同一选项中第n个匹配的通配符。

请注意?,、 和通配符永远不会匹配原始类型。此外,只有通配符才能匹配任何维度的数组类型。例如,“ ** get*()”匹配“ java.lang.Object getObject()”,
但不匹配“ float getFloat()”,也不匹配“ java.lang.Object[] getObjects()”。

4.1 增量混淆

-injars       proguardgui.jar
-outjars      proguardgui_out.jar
-injars       proguard.jar
-outjars      proguard_out.jar
-libraryjars  <java.home>/jmods/java.base.jmod(!**.jar;!module-info.class)
-applymapping proguard.map-keep public class proguard.gui.ProGuardGUI {public static void main(java.lang.String[]);
}

4.2 寻找未使用的代码及方法等(废弃代码)


#不进行优化,建议使用此选项,
-dontoptimize
#指定不混淆输入类文件。默认情况下,ProGuard 会混淆代码:它为类和类成员分配新的短随机名称。它删除了仅对调试有用的内部属性,例如源文件名、变量名和行号。
-dontobfuscate# 不进行预校验,Android不需要,可加快混淆速度。
-dontpreverify
#指定列出输入类文件的死代码。该列表将打印到标准输出或给定文件。例如,您可以列出应用程序未使用的代码。仅适用于收缩时。
-printusage

点击build后,可以看到如下的输出,列出了几个没有使用到的类及方法


> Task :app:minifyReleaseWithR8
org.fmod.example.CallBack
org.fmod.example.CallBackManager
org.fmod.example.DeadClass
org.fmod.example.MemoryShakeActivity:public void dpOperate()public void testa()public void testb()
org.fmod.example.BuildConfig
org.fmod.example.R$color
org.fmod.example.R$drawable
org.fmod.example.R$id
org.fmod.example.R$layout
org.fmod.example.R$mipmap
org.fmod.example.R$string
org.fmod.example.R$style
org.fmod.example.R$xml
org.fmod.example.R
org.fmod.example.databinding.ActivityMemoryBinding:public final android.widget.Button btMemoryprivate void <init>(android.widget.FrameLayout,android.widget.Button)public static org.fmod.example.databinding.ActivityMemoryBinding bind(android.view.View)public static org.fmod.example.databinding.ActivityMemoryBinding inflate(android.view.LayoutInflater)public static org.fmod.example.databinding.ActivityMemoryBinding inflate(android.view.LayoutInflater,android.view.ViewGroup,boolean)
androidx.core.location.LocationManagerCompat$$InternalSyntheticLambda$1$196e0315f48caa68131c5d4d780ff53e9618a06658f902ea94f753d0df163305$1
androidx.core.location.LocationManagerCompat:public static synthetic java.lang.Boolean $r8$lambda$JLIcm4BkQpukCiUbhX4BKZUICt4(android.location.LocationManager,androidx.core.location.LocationManagerCompat$GpsStatusTransport)

#不进行优化,建议使用此选项,
-dontoptimize
#指定不混淆输入类文件。默认情况下,ProGuard 会混淆代码:它为类和类成员分配新的短随机名称。它删除了仅对调试有用的内部属性,例如源文件名、变量名和行号。
-dontobfuscate# 不进行预校验,Android不需要,可加快混淆速度。
-dontpreverify
#指定列出输入类文件的死代码。该列表将打印到标准输出或给定文件。例如,您可以列出应用程序未使用的代码。仅适用于收缩时。
-printusage-keep public class org.fmod.example.DeadClass {public static void main(java.lang.String[]);
}

如果我们将某一个未使用的class 进行keep,则结果如下


> Task :app:minifyReleaseWithR8
org.fmod.example.BuildConfig
org.fmod.example.CallBack
org.fmod.example.CallBackManager
org.fmod.example.DeadClass:public void testa()public void testb()public void testc()
org.fmod.example.MemoryShakeActivity:public void dpOperate()public void testa()public void testb()
org.fmod.example.R$color
org.fmod.example.R$drawable
org.fmod.example.R$id
org.fmod.example.R$layout
org.fmod.example.R$mipmap
org.fmod.example.R$string
org.fmod.example.R$style
org.fmod.example.R$xml
org.fmod.example.R
org.fmod.example.databinding.ActivityMemoryBinding:public final android.widget.Button btMemoryprivate void <init>(android.widget.FrameLayout,android.widget.Button)public static org.fmod.example.databinding.ActivityMemoryBinding bind(android.view.View)public static org.fmod.example.databinding.ActivityMemoryBinding inflate(android.view.LayoutInflater)public static org.fmod.example.databinding.ActivityMemoryBinding inflate(android.view.LayoutInflater,android.view.ViewGroup,boolean)
androidx.core.location.LocationManagerCompat$$InternalSyntheticLambda$1$196e0315f48caa68131c5d4d780ff53e9618a06658f902ea94f753d0df163305$1
androidx.core.location.LocationManagerCompat:public static synthetic java.lang.Boolean $r8$lambda$JLIcm4BkQpukCiUbhX4BKZUICt4(android.location.LocationManager,androidx.core.location.LocationManagerCompat$GpsStatusTransport)

五、混淆基本原则

项目中以下类不应该混淆

5.1 系统相关类不要混淆

  • 四大组件:如 Activity、Service、Provider、Broadcast及其Fragment等系统相关类
#继承activity,application,service,broadcastReceiver,contentprovider....不进行混淆
-keep public class * extends android.app.Activity
-keep public class * extends android.app.Application
-keep public class * extends android.support.multidex.MultiDexApplication
-keep public class * extends android.app.Service
-keep public class * extends android.content.BroadcastReceiver
-keep public class * extends android.app.backup.BackupAgentHelper
-keep public class * extends android.preference.Preference
-keep public class * extends android.view.View-keep public class * extends android.support.v4.app.Fragment
-keep public class * extends androidx.fragment.app.Fragment
-keep public class * extends android.content.ContentProvider
  • view(WebView)相关类
-keepclassmembers class * extends android.app.Activity{public void *(android.view.View);
}
#不混淆任何一个View中的setXxx()getXxx()方法,
#因为属性动画需要有相应的setter和getter的方法实现
-keep public class * extends android.view.View{*** get*();void set*(***);public <init>(android.content.Context);public <init>(android.content.Context, android.util.AttributeSet);public <init>(android.content.Context, android.util.AttributeSet, int);
}
-keepclasseswithmembers class * {public <init>(android.content.Context, android.util.AttributeSet);public <init>(android.content.Context, android.util.AttributeSet, int);
}
  • 枚举类
#不混淆枚举中的values()valueOf()方法
-keepclassmembers enum * {public static **[] values();public static ** valueOf(java.lang.String);
}
  • 注解
  • support下的所有类及其内部类

-keep class android.support.** {*;}## 保留support下的所有类及其内部类
-keep public class * extends android.support.v4.**
-keep public class * extends android.support.v7.**
-keep public class * extends android.support.annotation.**
  • Serializable
# 继承Serizalizable的类的如下成员不被移除混淆
-keepclassmembers class * implements java.io.Serializable {java.lang.Object writeReplace();java.lang.Object readResolve();static final long serialVersionUID;private static final java.io.ObjectStreamField[] serialPersistentFields;private void writeObject(java.io.ObjectOutputStream);private void readObject(java.io.ObjectInputStream);
}
  • Parcelable的子类和Creator静态成员变量

#不混淆Parcelable实现类中的CREATOR字段,
-keep class * implements android.os.Parcelable {public static final android.os.Parcelable$Creator *;
}

5.2 部分项目相关类不要混淆

  • 数据模型(各种数据模型类,GSON、fastjson等框架解析服务端数据时,混淆后解析不了)
-keep class com.xxx.entity.** {*;}
  • Jni接口和java的native方法 (这个方法需要和native方法保持一致,混淆后找不到会报错)
-keepclasseswithmembernames class * {native <methods>;
}
  • Java接口 (主要针对对外开放的接口)

  • 调用反射的地方 ()

  • 抽象内部类
    比如Animal的内部类不混淆

-keep class com.xxx.demo.Animal{*;}
-keep class com.xxx.demo.Animal$*{*;}
  • 使用到的第三方开源库或者引用其他第三方的SDK包
# 微信支付 
-keep class com.tencent.mm.opensdk.** {*; }
  • AOP或者读取路径等的地方

整理了一个基础混淆文件:
Android通用混淆文件

5.3、添加混淆字典

为了是混淆更混乱,可以添加自定义的混淆字典
-classobfuscationdictionary proguard-dic.txt //类字典
-obfuscationdictionary proguard-dic.txt //混淆字典
-packageobfuscationdictionary proguard-dic.txt //包字典

混淆字典下载地址

5.4 r8 & proguard

如果不想用R8,想用回ProGuard的话,可以在gradle.properties文件中添加下述配置禁用R8:

android.enableR8=falseandroid.enableR8.libraries=false

Android在打包后,一般会有以下几个文件:
mapping.txt、usage.txt 等

mapping.txt→ 原始与混淆过的类、方法、字段名称间的转换关系;seeds.txt→ 未进行混淆的类与成员;usage.txt→ APK中移除的代码;即废弃代码configuration.txt→ missing_rules.txtresources.txt→ 资源优化记录文件,哪些资源引用了其他资源,哪些资源在使用,哪些资源被移除;

参考

proguard 文档

六、 推荐阅读

Java 专栏

SQL 专栏

数据结构与算法

Android学习专栏

未经允许不得转载
ddd

相关文章:

Android Proguard混淆

关于作者&#xff1a;CSDN内容合伙人、技术专家&#xff0c; 从零开始做日活千万级APP。 专注于分享各领域原创系列文章 &#xff0c;擅长java后端、移动开发、人工智能等&#xff0c;希望大家多多支持。 目录 一、导读二、概览三、语法规则3.1 输入/输出选项3.2 保留选项3.3 缩…...

MySQL 1、初识数据库

一、什么是数据库&#xff1f; 以特定的格式保存好的文件&#xff0c;我们就叫做数据库。 提供较为便捷的数据的存取服务的软件集合、解决方案&#xff0c;我们就叫它数据库。 存储数据用文件就可以了&#xff0c;为什么还要弄个数据库。 文件或数据库都可以存储数据&#…...

H5ke11--3介绍本地,会话存储

代码顺序: 1.设置input,捕获input如果有多个用属性选择符例如 input[typefile]点击事件.向我们的本地存储设置键值对 2.在点击事件外面设置本地存储表示初始化的值.点击上面的事件才能修改我们想修改的值 会话(session)浏览a数据可以写到本地硬盘,关闭页面数据就没了 本地(…...

技术分享 | 如何写好测试用例?

对于软件测试工程师来说&#xff0c;设计测试用例和提交缺陷报告是最基本的职业技能。是非常重要的部分。一个好的测试用例能够指示测试人员如何对软件进行测试。在这篇文章中&#xff0c;我们将介绍测试用例设计常用的几种方法&#xff0c;以及如何编写高效的测试用例。 ## 一…...

quarkus的一些注解1

path 用于指定一个类或者方法的URL路径前缀。 Inject 将一个依赖注入到一个类或方法中 Get 用于指定一个处理HTTP GET请求 Produce 注解用于指定一个方法返回的内容类型。例如&#xff0c;Produces(MediaType.TEXT_PLAIN) 表示该方法返回一个纯文本类型的内容 QuarkusIn…...

初学Redis(Redis的启动以及字符串String)

首先使用在Windows PowerShell中输入指令来启动Redis&#xff1a; redis-server.exe 然后通过指令连接Redis&#xff1a; redis-cli 上图的127.0.0.1是计算机的回送地址 &#xff0c;6379是默认端口 上述代码中创建了两个键&#xff0c;注意Redis中严格区分大小写&#xff0…...

C++ opencv基本用法【学习笔记(九)】

这篇博客为修改过后的转载&#xff0c;因为没有转载链接&#xff0c;所以选了原创 文章目录 一、vs code 结合Cmake debug1.1 配置tasks.json1.2 配置launch.json 二、图片、视频、摄像头读取显示2.1 读取图片并显示2.2 读取视频文件并显示2.3 读取摄像头并写入文件 三、图片基…...

理财和银保区别

理财和银保在以下六个方面存在区别&#xff1a; 产品性质&#xff1a;银行理财是银行发行的理财产品&#xff0c;属于金融投资&#xff0c;主要投向债券、票据等固定收益类资产。银保产品是保险公司发行的保险产品&#xff0c;属于保障投资&#xff0c;除了固定收益类资产外&am…...

一文浅入Springboot+mybatis-plus+actuator+Prometheus+Grafana+Swagger2.9.2开发运维一体化

Swagger是一个规范和完整的框架,用于生成、描述、调用和可视化 RESTFUL风格的Web服务,是非常流行的API表达工具。 Swagger能够自动生成完善的 RESTFUL AP文档,,同时并根据后台代码的修改同步更新,同时提供完整的测试页面来调试API。 Prometheus 是一个开源的服务监控系统和时…...

【日常】爬虫技巧进阶:textarea的value修改与提交问题(以智谱清言为例)

序言 记录一个近期困扰了一些时间的问题。 我很喜欢在爬虫中遇到问题&#xff0c;因为这意味着在这个看似简单的事情里还是有很多值得去探索的新东西。其实本身爬虫也是随着前后端技术的不断更新在进步的。 文章目录 序言Preliminary1 问题缘起1.1 Selenium长文本输入阻塞1.2…...

C++知识点总结(6):高精度乘法真题代码

一、高精度数 低精度数 #include <iostream> #include <cstring> using namespace std;int main() {// 存储并输入两个数字 char a_str[1005] {};long long b;cin >> a_str >> b;// 特例先行&#xff1a;结果是0的情况if (a 0 || b 0){cout <&…...

Polygon zkEVM的Dragon Fruit和Inca Berry升级

1. Polygon zkEVM的Dragon Fruit升级 2023年8月31日&#xff0c;Polygon zkEVM团队宣称启动了其Mainnet Beta的Dragon Fruit升级的10天timelock&#xff0c;预计将于2023年9月11日激活。 Dragon Fruit升级点有&#xff1a; 改进了网络支持了最新的以太坊opcode——PUSH0 1.…...

【计算机网络学习之路】网络基础1

文章目录 前言一. 计算机网络发展局域网和广域网 二. 网络协议三. OSI七层模型四. TCP/IP四层&#xff08;五层&#xff09;模型五. 计算机体系结构与网络协议栈六. 协议形式及局域网通信数据包封装与分用 七. 跨网络通信八. MAC地址与网络通信的理解结束语 前言 本系列文章是…...

HTTP/2.0协议详解

前言 HTTP/2.0&#xff1a;互联网通信的革新标准 随着互联网技术的飞速发展&#xff0c;HTTP协议作为互联网应用最广泛的通信协议&#xff0c;也在不断演进和优化。HTTP/2.0是HTTP协议的最新版本&#xff0c;它旨在提供更高效、更安全、更快速的互联网连接。 一、HTTP/2.0的优…...

Python中的Random模块详解:生成随机数与高级应用

在Python编程中&#xff0c;随机数生成是许多应用的基础之一。random模块为我们提供了生成伪随机数的丰富工具&#xff0c;从简单的随机数生成到复杂的应用场景&#xff0c;都有很多功能可以探索。本文将深入介绍random模块的各个方面&#xff0c;通过详实的示例代码&#xff0…...

(论文阅读32/100)Flowing convnets for human pose estimation in videos

32.文献阅读笔记 简介 题目 Flowing convnets for human pose estimation in videos 作者 Tomas Pfister, James Charles, and Andrew Zisserman, ICCV, 2015. 原文链接 https://arxiv.org/pdf/1506.02897.pdf 关键词 Human Pose Estimation in Videos 研究问题 视频…...

【设计一个缓存--针对各种类型的缓存】

设计一个缓存--针对各种类型的缓存 1. 设计顶层接口2. 设计抽象类 -- AbstractCacheManager3. 具体子类3.1 -- AlertRuleItemExpCacheManager3.2 -- AlertRuleItemSrcCacheManager 4. 类图关系 1. 设计顶层接口 // 定义为一个泛型接口,提供给抽象类使用 public interface Cach…...

Django部署时静态文件配置的坑

Django部署时静态文件配置配置的坑 近期有个需求是用django进行开发部署&#xff0c;结果发现静态文件配置的坑是真的多&#xff0c;另外网上很多的内容也讲不清楚原理&#xff0c;就是这样这样&#xff0c;又那样那样&#xff0c;进了不少坑&#xff0c;这里记录一下关于css,…...

Android---网络编程优化

网络请求操作是一个 App 的重要组成部分&#xff0c;程序大多数问题都是和网络请求有关。使用 OkHttp 框架后&#xff0c;可以通过 EventListener 来查看一次网络请求的详细情况。一次完整的网络请求会包含以下几个步骤。 也就是说&#xff0c;一次网络请求的操作是从 DNS 解析…...

《算法通关村——不简单的字符串转换问题》

《算法通关村——不简单的字符串转换问题》 8. 字符串转换整数 (atoi) 请你来实现一个 myAtoi(string s) 函数&#xff0c;使其能将字符串转换成一个 32 位有符号整数&#xff08;类似 C/C 中的 atoi 函数&#xff09;。 函数 myAtoi(string s) 的算法如下&#xff1a; 读入…...

给VSCode插上一双AI的翅膀

#AI编程助手哪家好&#xff1f;DevChat“真”好用# 文章目录 前言一、安装DevChat1.1、访问地址1.2、注册1.3、在VSCode里安装DevChat插件1.3.1、未安装状态1.3.2、已安装状态 二、设置Access Key2.1. 点击左下角管理&#xff08;“齿轮”图标&#xff09;—命令面板&#xff…...

2023年亚太杯数学建模思路 - 案例:异常检测

文章目录 赛题思路一、简介 -- 关于异常检测异常检测监督学习 二、异常检测算法2. 箱线图分析3. 基于距离/密度4. 基于划分思想 建模资料 赛题思路 &#xff08;赛题出来以后第一时间在CSDN分享&#xff09; https://blog.csdn.net/dc_sinor?typeblog 一、简介 – 关于异常…...

机器学习的医疗乳腺癌数据的乳腺癌疾病预测

项目视频讲解:基于机器学习的医疗乳腺癌数据的乳腺癌疾病预测 完整代码数据分享_哔哩哔哩_bilibili 效果演示: 代码: #第一步!导入我们需要的工具 import numpy as np import pandas as pd import matplotlib.pyplot as plt import seaborn as sns %matplotlib inlin…...

解析:什么是生成式AI?与其他类型的AI有何不同?

原创 | 文 BFT机器人 快速浏览一下头条新闻&#xff0c;你会发现生成式AI似乎无处不在。事实上&#xff0c;一些新闻标题甚至可能是通过生成式AI编写的&#xff0c;例如OpenAI旗下的ChatGPT&#xff0c;这个聊天机器人已经展现出了生成看起来像人类所写文本的惊人能力。 当人们…...

国产化项目改造:使用达梦数据库和东方通组件部署,前后端分离框架

前提&#xff1a;前后端分离前后端包都要用war包。 1、springboot后端改变war包 pom文件添加 <packaging>war</packaging>添加依赖&#xff0c;并且支持tomcat<!-- war包 --><dependency><groupId>org.springframework.boot</groupId><…...

Nginx实现负载均衡

Nginx实现负载均衡 负载均衡的作用 1、解决单点故障&#xff0c;让web服务器构成一个集群 2、将请求平均下发给后端的web服务器 负载均衡的软硬件介绍 负载均衡软件&#xff1a; # nginx 四层负载均衡&#xff1a;stream&#xff08;nginx 1.9版本以后有stream模块&#x…...

SpringCloud 2022有哪些变化

目录 前提条件 AOT支持 Spring Native支持 前提条件 Spring Cloud 2022.0.0是构建在Spring Framework 6.0和Spring Boot 3.0 之上的一S个主要版本。 JDK要求最低需要是Java 17J2EE要求最低需要Jakarta EE 9 AOT支持 Spring cloud 2022支持AOT编译&#xff0c;它是将程序源…...

如何快速本地搭建悟空CRM结合内网穿透工具高效远程办公

&#x1f308;个人主页&#xff1a;聆风吟 &#x1f525;系列专栏&#xff1a;数据结构、Cpolar杂谈 &#x1f516;少年有梦不应止于心动&#xff0c;更要付诸行动。 文章目录 &#x1f4cb;前言一. 无需公网IP&#xff0c;使用cpolar实现悟空CRM远程访问二. 通过公网来访问公司…...

Docker打包Python项目

1. 简介 Docker是一种开源的容器化平台&#xff0c;可以将应用程序及其依赖项打包到一个轻量级、可移植的容器中。通过使用Docker&#xff0c;可以简化Python项目的部署和运行&#xff0c;提高开发效率和应用程序的可移植性。 本文将介绍如何使用Docker来打包Python项目。我们…...

【Java并发编程一】并发与并行

为什么引入并发 摩尔定理逐渐失效&#xff0c;单核性能很难提升&#xff0c;通过组合多核性能来进一步满足实际需要&#xff0c;从而引入并发编程。在大部分场景下&#xff0c;并行是由于串行的&#xff0c;并行可以优化非关键节点的时间消耗。 并发的三大特性 原子性  某个…...

MFC/QT 一些快忘记的细节:

1&#xff1a;企业应用中&#xff0c;MFC平台除了用常见的对话框模式还有一种常用的就是单文档模式&#xff0c; 维护别人的代码&#xff0c;不容易区分,看它与程预序认同名cpp&#xff0c;就知道了&#xff0c;比如项目名称为 DoCMFCDemo&#xff0c;那么就看BOOL CDocMFCDe…...

在服务器上部署MVC 6应用程序

在服务器上成功部署MVC 6应用程序&#xff08;现在更为称为ASP.NET Core MVC&#xff09;涉及一系列步骤。以下是一般的指导步骤&#xff1a; 1. 准备服务器环境&#xff1a; - 确保服务器上安装了.NET Core Runtime和.NET Core SDK。可以从[.NET下载页面](https://dotnet.mi…...

golang学习笔记——斐波纳契数列

斐波纳契数列 编写一个程序来计算某个数字的斐波纳契数列。 斐波那契数列是一个数字列表&#xff0c;其中每个数字是前两个斐波那契数字之和。 例如&#xff0c;数字 6 的序列是 1,1,2,3,5,8&#xff0c;数字 7 的序列是 1,1,2,3,5,8,13&#xff0c;数字 8 的序列是 1,1,2,3,5…...

学习raft协议(1)

CAP C: 一致性 强调数据的正确性&#xff0c;每次读操作&#xff0c;要么读到最新&#xff0c;要么读失败 A:可用性 不发生错误&#xff0c;也不能出现过长的等待时间. P:分区容错性 在网络环境不可靠的背景下&#xff0c;整个系统仍然是正常运作的两种流派 &#xff08;1&am…...

SpringSecurity+jwt使用

参考文章链接 自定义SpringSecurity用户 package com.daben.springsecurityjwt.vo;import com.daben.springsecurityjwt.entity.SysUser; import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.userdetails.User; import j…...

html-网站菜单-点击显示导航栏

一、效果图 1.点击显示菜单栏&#xff0c;点击x号关闭&#xff1b; 2.点击一级菜单&#xff0c;展开显示二级&#xff0c;并且加号变为减号&#xff1b; 3.点击其他一级导航&#xff0c;自动收起展开的导航。 二、代码实现 <!DOCTYPE html> <html><head>&…...

【C++函数的进化】函数指针,模板,仿函数,lambda表达式

/*** poject * author jUicE_g2R(qq:3406291309)* file C函数的进化* * language C* EDA Base on VS2022* editor Obsidian&#xff08;黑曜石笔记软件&#xff09;* * copyright 2023* COPYRIGHT 原创学习笔记&#xff1a;转载需获得博…...

云服务器windows service2022 部署git服务器

1 安装 下载地址gitblit 解压到你的一个目录,我这里给的是C:\gitblit 根据官网提示要下载jre or jdk7.0,这里建议使用下载jre (jdk 有时候运行出问题,或者2个都安装),自行安装java,这里不做环境配置的说明 进入c:\gitblit\data 目录里面找到,defaults.properties 文件,编辑主…...

Linux_Docker修改Docker Root Dir

今天遇到需求&#xff0c;要修改一下docker容器和镜像的存储位置&#xff0c;默认位置为/var/lib/docker目录下&#xff0c;要修改到/new/dockerFile目录下。 停止docker服务 sudo service docker stop 备份docker容器镜像 移动/var/lib/docker目录下的文件到/dockerFile目录…...

解决requests 2.28.x版本SSL错误:证书验证失败

1、问题背景 在使用requests 2.28.1版本时&#xff0c;我进行HTTP post传输报告负载时&#xff0c;由于SSL验证设置为True&#xff0c;请求失败&#xff0c;错误如下&#xff1a;(Caused by SSLError(SSLCertVerificationError(1, ‘[SSL: CERTIFICATE_VERIFY_FAILED] certifi…...

【开源】基于Vue.js的开放实验室管理系统的设计和实现

项目编号&#xff1a; S 013 &#xff0c;文末获取源码。 \color{red}{项目编号&#xff1a;S013&#xff0c;文末获取源码。} 项目编号&#xff1a;S013&#xff0c;文末获取源码。 目录 一、摘要1.1 项目介绍1.2 项目录屏 二、研究内容2.1 实验室类型模块2.2 实验室模块2.3 实…...

使用composer安装ffmpeg的步骤

以下是使用composer安装ffmpeg的步骤&#xff1a; 1.在laravel根目录下执行以下命令安装ffmpeg&#xff1a; composer require php-ffmpeg/php-ffmpeg 2.如果不指定版本号&#xff0c;则默认使用0.14版本。 3.执行以上命令后&#xff0c;composer会自动下载并安装ffmpeg。 …...

RT-DETR优化策略:轻量级Backbone改进 | 高效模型 (Efficient MOdel, EMO),现代倒残差移动模块设计|ICCV2023

🚀🚀🚀本文改进:面向移动端的轻量化网络模型——EMO,它能够以相对较低的参数和 FLOPs 超越了基于 CNN/Transformer 的 SOTA 模型,支持四个版本EMO_1M, EMO_2M, EMO_5M, EMO_6M,参数量如下,相对于自带的rtdetr-l、rtdetr-x有很大提升 layersparametersgradientsEMO_1…...

一些nginx命令

1.停止nginx nginx -s quit systemctl stop nginx.service 立即停止 nginx-s stop 杀死nginx进程 killall nginx 2.启动命令 nginx systemctl start nginx.service 3.查看nginx进程 ps aux | grep nginx 4.重启nginx服务 systemctl restart nginx.service 5.重载…...

WPF自定义控件介绍

在WPF中&#xff0c;自定义控件通常是指从头开始创建一个新控件或从现有控件继承并扩展其功能。自定义控件与用户控件&#xff08;User Control&#xff09;不同&#xff0c;用户控件是通过组合其他控件来构建的&#xff0c;而自定义控件通常涉及对控件的更底层的渲染和行为进行…...

JUNIT使用和注意、以及断言的介绍使用、SpringBoot Test测试类的使用、maven配置使用junit详细介绍

参考文章&#xff1a; https://www.cnblogs.com/zhukaile/p/14514238.html&#xff0c;https://blog.csdn.net/qq_36448800/article/details/126438339 一、什么是单元测试 在平时的开发当中&#xff0c;一个项目往往包含了大量的方法&#xff0c;可能有成千上万个。如何去保…...

强化学习在文生图中的应用:Training Diffusion Models with Reinforcement Learning

论文链接:Training Diffusion Models with Reinforcement Learning项目地址:Training Diffusion Models with Reinforcement Learning官方代码:https://github.com/kvablack/ddpo-pytorch/tree/maintrl实现:https://huggingface.co/docs/trl/ddpo_trainer🤗关注公众号 fu…...

【C语言】数组下标为啥从0开始?下标越界访问一定报错吗?

本篇文章目录 0. 相关文章1. 下标从0开始问题2. 数组下标越界不报错问题 0. 相关文章 指针与指针变量数组名不是首元素地址的的2个例外拨开指针和数组名之间的迷雾 1. 下标从0开始问题 原因是&#xff1a;数组下标访问本质是“指针解引用操作”&#xff0c;而指针又是地址&am…...

机器学习-搜索技术:从技术发展到应用实战的全面指南

在本文中&#xff0c;我们全面探讨了人工智能中搜索技术的发展&#xff0c;从基础算法如DFS和BFS&#xff0c;到高级搜索技术如CSP和优化问题的解决方案&#xff0c;进而探索了机器学习与搜索的融合&#xff0c;最后展望了未来的趋势和挑战&#xff0c;提供了对AI搜索技术深刻的…...

Axelar、J.P.Morgan Onyx、Apollo 完成概念验证,向跨区块链自动化投资领域探索

J.P.Morgan Onyx、Apollo、Axelar、Oasis Pro 以及 Provenance Block Chain 展开合作&#xff0c;共同进行互操作性概念验证&#xff08;Proof-of-Concept&#xff0c;PoC)。 新加坡 — Axelar Inc.、Oasis Pro 、Provenance Blockchain 与 J.P.Morgan Onyx 以及 Apollo 通过新…...