ANR系列之八:疑难ANR问题处理记录

前言:

本文仅是记录作者自身处理过的ANR问题,以及帮助他人解决过的ANR问题。本文中所介绍的ANR处理记录仅供参考,并不适用所有场景。并且最终结论和分析并不一定就是绝对正确的。

案例1.页面切换时前台应用焦点未获得

案例编号:略

案例描述:

自动化验证的时候,偶现ANR,ANR提示如下:

Subject: Input dispatching timed out (Waiting because no window has focus but there is a focused application that may eventually add a window when it finishes starting up.)

案例分析:

这个ANR错误代表应用切换到了前台,但是被切换到前台的应用并没有获取到焦点。仔细查看相关的log日志,如下:

//关闭返回
03-08 04:58:26.820 2588 2588 I XxxxLink_HU :  =>> close click.//AMS执行切换
03-08 04:58:26.830 1038 1101 W ActivityManager : Resuming top, waiting visible to hide: ActivityRecord{5480ff u0 com.yflink.client/com.xxxx.entrance.ui.CopyScreenMainActivity t40}
03-08 04:58:26.830 1038 1101 W ActivityManager : Resume running: ActivityRecord{8e973ce u0 com.xxxx.launcher/.passenger.PassMainActivity t27} stopped=true visible=false
03-08 04:58:26.831 1038 1101 I am_set_resumed_activity : [0,com.xxxx.launcher/.passenger.PassMainActivity,resumeTopActivityInnerLocked]//桌面响应
03-08 04:58:26.850 1460 1460 I am_on_resume_called : [0,com.xxxx.launcher.passenger.PassMainActivity,RESUME_ACTIVITY]
//切换完成
03-08 04:58:26.875 1038 2730 I WindowManager : finishDrawingWindow: Window{1632bf9 u0 com.xxxx.launcher/com.xxxx.launcher.passenger.PassMainActivity} mDrawState=DRAW_PENDING//再次启动CopyScreenMainActivity
03-08 04:58:27.823 1038 2431 I ActivityManager : START u0 {flg=0x10000000 cmp=com.yflink.client/com.xxxx.entrance.ui.CopyScreenMainActivity} from uid 1000 from pid 1460//执行newIntent流程
03-08 04:58:27.835 2588 2588 I am_on_resume_called : [0,com.xxxx.entrance.ui.CopyScreenMainActivity,performNewIntents]//AMS执行切换,这时候PassMainActivity被暂停,CopyScreenMainActivity切换到前台。
03-08 04:58:27.854 1460 1460 I am_on_paused_called : [0,com.xxxx.launcher.passenger.PassMainActivity,performPause]
03-08 04:58:27.854 1038 1101 W ActivityManager : Resuming top, waiting visible to hide: ActivityRecord{8e973ce u0 com.xxxx.launcher/.passenger.PassMainActivity t27}
03-08 04:58:27.854 1038 1101 W ActivityManager : Resume running: ActivityRecord{5480ff u0 com.yflink.client/com.xxxx.entrance.ui.CopyScreenMainActivity t40} stopped=false visible=false
03-08 04:58:27.854 1038 1101 I am_set_resumed_activity : [0,com.yflink.client/com.xxxx.entrance.ui.CopyScreenMainActivity,resumeTopActivityInnerLocked]
//APP响应
03-08 04:58:27.903 2588 2588 I am_on_resume_called : [0,com.xxxx.entrance.ui.CopyScreenMainActivity,RESUME_ACTIVITY]//这里缺少APP执行finishDrawingWindow的流程,说明window没有注册上。所以最大的可能性就是桌面没有释放
//桌面的Window响应注册
03-08 04:58:27.938 1038 7512 I WindowManager : finishDrawingWindow: Window{aba4e14 u0 com.xxxx.launcher} mDrawState=DRAW_PENDING03-08 04:58:28.219 1460 1460 W IPSurfaceView : surfaceDestroyed
03-08 04:58:28.219 1460 1460 W IPSurfaceView : pause 清空动画
03-08 04:58:28.219 1460 1460 W IPSurfaceView : destroyThread called
03-08 04:58:28.220 1460 29148 W System.err : java.lang.InterruptedException
03-08 04:58:28.220 1460 29148 W System.err :   at java.lang.Object.wait(Native Method)
03-08 04:58:28.220 1460 29148 W System.err :   at java.lang.Object.wait(Object.java:422)
03-08 04:58:28.220 1460 29148 W System.err :   at com.xxxx.ipservicesdk.widget.IPSurfaceView.drawLoop(IPSurfaceView.java:360)
03-08 04:58:28.220 1460 29148 W System.err :   at com.xxxx.ipservicesdk.widget.IPSurfaceView.updateView(IPSurfaceView.java:284)
03-08 04:58:28.220 1460 29148 W System.err :   at com.xxxx.ipservicesdk.widget.IPSurfaceView$1.run(IPSurfaceView.java:163)
03-08 04:58:28.220 1460 29148 W System.err :   at java.lang.Thread.run(Thread.java:764)
03-08 04:58:28.220 1460 29148 W IPSurfaceView : update thread finished com.xxxx.ipservicesdk.widget.IPSurfaceView$1@e78b18c//这里缺少CopyScreenMainActivity完成渲染的日志finishDrawingWindow,说明其没有正常注册窗口。
03-08 04:58:34.423 1038 2861 I WindowManager : finishDrawingWindow: Window{41c1228 u0 com.gameloft.android.BTCN.GloftA9BT/com.gameloft.android.BTCN.GloftA9BT.MainActivity} mDrawState=DRAW_PENDING
03-08 04:58:34.580 1038 7512 I WindowManager : finishDrawingWindow: Window{41c1228 u0 com.gameloft.android.BTCN.GloftA9BT/com.gameloft.android.BTCN.GloftA9BT.MainActivity} mDrawState=HAS_DRAWN

我们发现,页面切换的时候,理应被切换到前台的Activity执行了resume流程后,却没有执行finishDrawingWindow的流程,并且此时的CPU负载并不高。

详细查看页面切换后5S内的日志,发现有一个桌面悬浮框报错,并且是在渲染更新的时候,所以怀疑是这个悬浮框占据了焦点未释放。

在过去了6S之后,又跳转了下一个页面,这个页面是正常的流程。所以中间那5S的时间PassMainActivity并没有获取到焦点。

问题结论:

应用的Activity是复用的,切换到前台的时候,焦点被上一个应用的延时操作占据,所以导致注册了window之后并没有整的走dispatchDraw流程完成焦点的切换。

其实这个时候如果使用命令:adb shell dumpsys window 获取当前屏幕window的话,焦点应该在IPSurfaceView上面,不过因为是偶现,所以也只能推测。

解决方案是给IPSurfaceView的实现类添加Window的Flag:FLAG_NOT_FOCUSABLE。

案例2.跨进程通信的问题

案例编号:略

案例描述:

开机启动后不久,某些应用直接发生ANR,ANR提示如下:

Subject: Context.startForegroundService() did not then call Service.startForeground()

值得注意的是,此时的CPU负载是很高的。

问题分析:

首先看发生ANR时的负载,此时的CPU负载是很高的,总负载达到了70%以上。

CPU usage from 0ms to 20784ms later (2023-03-10 21:03:42.371 to 2023-03-10 21:04:03.155):
73% 514/surfaceflinger: 45% user + 28% kernel / faults: 5073 minor
51% 3075/com.xxxx.voice: 42% user + 9.4% kernel / faults: 202836 minor 131 major
30% 1483/com.xxxx.beanmap: 17% user + 13% kernel / faults: 49570 minor 12 major
24% 1167/system_server: 11% user + 12% kernel / faults: 20432 minor 2 major
23% 458/android.hardware.graphics.composer@2.2-service: 10% user + 12% kernel / faults: 36 minor
20% 1439/com.xxxx.adapterservice.server: 17% user + 3% kernel / faults: 26796 minor

接下来看ANR时的主线程堆栈,内容如下:

kernel: (couldn't read /proc/self/task/3582/stack)
native: #00 pc 000000000001f06c  /system/lib64/libc.so (syscall+28)
native: #01 pc 00000000000d724c  /system/lib64/libart.so (art::ConditionVariable::WaitHoldingLocks(art::Thread*)+148)
native: #02 pc 00000000005171b0  /system/lib64/libart.so (offset 449000) (_ZN3artL12GoToRunnableEPNS_6ThreadE.llvm.323061163+448)
native: #03 pc 0000000000516fac  /system/lib64/libart.so (offset 449000) (art::JniMethodEnd(unsigned int, art::Thread*)+28)
at android.os.BinderProxy.transactNative(Native method)
at android.os.BinderProxy.transact(Binder.java:1129)
at com.xxxx.accountstub.IAccountData$Stub$Proxy.isLogin(IAccountData.java:538)
at com.xxxx.accountstub.BeanAccountInfoManager.isLogin(BeanAccountInfoManager.java:250)
at com.xxxx.mediacenter.core_account.AccountInfoHub.isLogin(AccountInfoHub.java:231)
at com.xxxx.mediacenter.core_account.AccountInfoHub.getThirdAccountList(AccountInfoHub.java:156)
at com.xxxx.mediacenter.core_account.AccountInfoHub.access$600(AccountInfoHub.java:45)
at com.xxxx.mediacenter.core_account.AccountInfoHub$3.run(AccountInfoHub.java:142)

很明显,主线程中此时被阻塞了,阻塞的原因是正在通过binder进行跨进程通讯,但是作为binder的server端迟迟没有响应。

在仔细排查日志,发现作为server一方的那个进程,也正在执行初始化的流程中,所以没有办法响应。总结下来,其实就是开机启动后,有大量的进程执行自启动操作导致CPU被强占,并且由于相关之间还存在依赖关系,从而导致一些本来其实负载并不到的应用也产生了ANR问题。

案例结论:

这种问题,解决方案有两种,从技术上解决和从业务上解决。

从技术上解决:

1.binder通讯放到子线程处理,这样就不会阻塞主线程,但是这样治标不治本,用户仍然无法正常使用业务功能。

2.改为启动后台服务,后台服务的超时时间为200S。但是高版本对后台服务启动有很多限制,而且service未能按时启动仍然会影响业务。

所以从技术上解决,多是治标不治本的方案,并不是太好。

从业务逻辑上解决:

统一收口开机启动的应用,然后通过按需拉起和梯队拉起来解决。

1.取消各个应用的persistent属性,由一个三方应用应用来管控开机之后的拉起操作。至于为什么不放system_server,大家可以自行考虑下原因。

2.按需拉起。自然就是要看是否需要拉起,尤其是在开机阶段是否有必要拉起。

3.梯队拉起。则需要先梳理一下应用之间的相互依赖关系以及相关业务优先级,被依赖的应用以及业务优先级价值较高的被优先拉起。

我们选择的是后者,当然,这需要拉齐所有相关方,成本还是蛮高的,但是我们认为是值得的。

案例3.前台服务启动超时

案例编号:略

案例描述:

应用ANR,异常reason为:

Context.startForegroundService() did not then call Service.startForeground(): ServiceRecord{9c69e1d u0 com.xxxx.mediacenter.passenger/com.xxxx.mediacenter.mediacentermodel.BeanMediaStartService}

这个错误代表被第三方应用通过直接拉起service的方式启动前台服务,并且在service的onStartCommand被调用后的30秒内没有调用startForeground方法,此时系统会通知应用产生一个异常崩溃,但此时主线程卡顿超10S以上,就会出现这种类型的ANR。如果此时主线程不卡顿,那么就会产生一个崩溃。

案例分析:

这个仍然是启动前台服务导致的超时,但是分析下来,和问题2还是有区别的,因为此时整体负载并算很高。

查看ANR文件中的堆栈:

"main" prio=5 tid=1 Runnable| group="main" sCount=0 dsCount=0 flags=0 obj=0x7449cb08 self=0x71e9614c00| sysTid=3471 nice=0 cgrp=default sched=0/0 handle=0x726f25a550| state=R schedstat=( 2284943688 9496195780 2668 ) utm=174 stm=53 core=0 HZ=100| stack=0x7feac82000-0x7feac84000 stackSize=8MB| held mutexes= "mutator lock"(shared held)at java.lang.StringBuilder.append(StringBuilder.java:137)at java.util.Arrays.toString(Arrays.java:4511)at dalvik.system.DexPathList.toString(DexPathList.java:201)at java.lang.String.valueOf(String.java:2896)at java.lang.StringBuilder.append(StringBuilder.java:132)at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:134)at java.lang.ClassLoader.loadClass(ClassLoader.java:379)at java.lang.ClassLoader.loadClass(ClassLoader.java:312)at com.iqy.iv.plugin.server.core.PluginClassLoader.findClass(PluginClassLoader.java:37)at java.lang.ClassLoader.loadClass(ClassLoader.java:379)at java.lang.ClassLoader.loadClass(ClassLoader.java:312)at java.lang.Class.classForName(Native method)at java.lang.Class.forName(Class.java:453)at java.lang.Class.forName(Class.java:378)at com.qiyi.baselib.utils.device.DeviceUtil.isHarmonyOSByOsBrand(DeviceUtil.java:1089)at com.qiyi.baselib.utils.device.DeviceUtil.isHarmonyOs(DeviceUtil.java:1079)at org.qiyi.android.coreplayer.utils.CupidAdTool.setCupidSdkStatus(CupidAdTool.java:182)at org.qiyi.android.coreplayer.bigcore.BigCoreLibLoader.loadAndInitCup(BigCoreLibLoader.java:402)at org.qiyi.android.coreplayer.bigcore.BigCoreLibLoader.loadBigCoreSo(BigCoreLibLoader.java:114)at org.qiyi.android.coreplayer.bigcore.DLController.loadLib(DLController.java:533)at org.iqiyi.video.facade.LoadLibJob.doInitAndLoadLib(LoadLibJob.java:43)at org.iqiyi.video.facade.CarPlayerInit.initLibConfig(CarPlayerInit.java:69)at org.iqiyi.video.facade.CommonPlayerInit.initAppForQiyi(CommonPlayerInit.java:91)at org.iqiyi.video.facade.CarPlayerInit.initAppForQiyi(CarPlayerInit.java:48)at org.iqiyi.video.facede.QYAppFacede.init(QYAppFacede.java:142)at org.iqiyi.video.facede.QYAppFacede.initAppForQiyi(QYAppFacede.java:153)at com.qiyi.ivsdk.init.InitHelper.initNecessaryForPlayerSync(InitHelper.java:399)at com.qiyi.ivsdk.init.InitHelper.init(InitHelper.java:145)at com.iqy.iv.sdk.PlayerSdkImpl.initialize(unavailable:104)at com.iqy.iv.sdk.PlayerSdkProxy.initSDK(PlayerSdkProxy.java:159)at com.iqy.iv.sdk.PlayerSdkProxy$2.handleMessage(PlayerSdkProxy.java:78)at android.os.Handler.dispatchMessage(Handler.java:106)at android.os.Looper.loop(Looper.java:193)at android.app.ActivityThread.main(ActivityThread.java:6734)at java.lang.reflect.Method.invoke(Native method)at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:506)at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)

在进行爱奇艺SDK的初始化,并且在主线程,但是调用堆栈并不是在application或者service的onCreate方法,说明应该是通过handler.post等方法进行过切换。

上面说到,这种ANR,是30S内service中没有调用startForeground方法,并且30S后主线程处于阻塞状态无法处理系统传递过来的崩溃。出现了这种ANR,如果主线程不阻塞,那么就会Crash。

所以推测应该是下面两种场景之一导致的:

  1. onCreate方法并不耗时,onStartCommand中有调用startForeground的方法但是并未执行,推测执行onStartCommand方法前,有耗时操作。大概率应该是onCreate中post了耗时操作,并且阻塞了超过(30+10=40)秒。

  2. onStartCommand中没有调用startForeground方法,前30S主线程有可能并不阻塞,30S后主线程被阻塞住,从而产生了ANR。

最终通过查看相关日志,确定属于上面的场景1,并且通过分析确定,单单PlayerSdkProxy.initSDK方法耗时并不是很多,但是onCreate中通过post添加了很多耗时任务,导致累计超时。

案例结论:

解决方案很简单,按需加载,没有必要在service启动的时候一下子初始化那么多的SDK。改成懒加载机制,等service走完生命周期创建后在初始化。

问题4.隐藏的动画导致ANR

案例编号:76621

案例描述:

仍然是自动化验证,发现进入某个应用之后,很容易发生ANR问题,并且该应用ANR之后,进入其它应用也极易发生ANR问题。

发生ANR的堆栈,指向系统注册窗口的时机。

at android.os.BinderProxy.transactNative(Native method)
at android.os.BinderProxy.transact(Binder.java:1129)
at android.view.IWindowSession$Stub$Proxy.addToDisplay(IWindowSession.java:825)
at android.view.ViewRootImpl.setView(ViewRootImpl.java:757)
locked <0x06fcde80> (a android.view.ViewRootImpl)
at android.view.WindowManagerGlobal.addView(WindowManagerGlobal.java:356)
locked <0x0c75ecb9> (a java.lang.Object)
at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:95)

案例分析:

乍一看,既然阻塞到向系统注册的时候,那么应该是系统问题。但是这里有一个疑点,那就是为什么每次这个应用甲ANR之后(我们暂且称之为应用甲),都会影响到其它的,理论上应用之间是相互独立的才对。所以,就把方向放到应用甲和系统窗口交互之间的原因上,怀疑有可能应用甲和系统过分的交互导致系统侧过载,从而间接的影响了其他的应用。

我们观察当时的日志,发现多次ANR都是发生在从MainActivity跳转WebViewActivity的时候。

//1. MainActivity pasue,准备跳转
09-30 01:39:27.803 1112 2086 I am_pause_activity : [0,111178572,com.xxxx.scenemanage/.MainActivity,userLeaving=true]
09-30 01:39:27.808 8046 8046 I am_on_paused_called : [0,com.xxxx.scenemanage.MainActivity,performPause]
//2. 进入WebViewActivity
09-30 01:39:27.857 8046 8046 I am_on_create_called : [0,com.xxxx.scenemanage.webkit.WebViewActivity,performCreate]
09-30 01:39:30.505 8046 8046 I am_on_resume_called : [0,com.xxxx.scenemanage.webkit.WebViewActivity,RESUME_ACTIVITY]
//3. 发生ANR了
09-30 01:39:33.799 1112 1198 I InputDispatcher : Application is not responding: Window
{91f7011 u0 com.xxxx.scenemanage/com.xxxx.scenemanage.WebViewActivity}

所以,缩小范围,应该是MainActivity页面WebViewActivity的onResume之前,有大量和系统侧的交互。

虽然我们不能复现当时的ANR场景,但是我们按照这个流程走一遍,并且通过top命令和systemtrace进行观察,还是能发现一些端倪的。我们发现进入到MainActivity,并且切换到FragmentB之后,TOP中SF和应用甲的负载会持续维持在高位,这是很不正常的,因为此时页面是静止的。

600%cpu  67%user   2%nice  51%sys 511%idle   0%iow   7%irq   2%sirq   0%host    PID USER         PR  NI VIRT  RES  SHR S[%CPU] %MEM     TIME+ ARGS            500 system       -2  -8 2.0G  34M  26M S 44.6   0.3 679:20.26 surfaceflinger20461 system       -3  -3  57M  17M  13M S  29.3   0.1 269:44.60 com.xxxx.scenemanage
...

结合systemtrace的线程分析,发现即使页面处于静止状态,RenderThread仍持续在跑,说明应用甲的代码中有地方在持续请求刷新的操作。最简单的方案,自然是断点打到ThreadedRender的draw方法中,看看到底谁在调用,但是发现,静止状态下,这里并没有被执行,所以说明是另外的地方直接请求native的方法进行请求刷新操作。

所以怀疑方向有两个:1.代码中是否有调用SO的地方;2.是否有执行相关的动画。

查完代码后,发现方向1不存在这种可能性。于是查看动画相关的代码,这时候,终于发现了根因。

<LinearLayout><com.xxxx.widget.loading.XxxxLoadingandroid:id="@+id/loading"android:layout_alignBottom="@+id/xxx"android:layout_marginEnd="16dp"android:layout_toStartOf="@+id/xxxx" />
</LinearLayout>

切换到FragmentB后,XxxxLoading处于visible状态,但是由于不再屏幕范围内,所以对用户是无感的。但是其一直有执行相关的动作操作,从而导致不断的请求执行绘制流程,从而导致了系统侧SF处于高负载状态,最终从而导致了ANR的发生。

public void onAnimationUpdate(@Nullable PAGView view) {this.tryCover();
}private final void tryCover() {if (XxxxLoading.this.willDraw) {XxxxLoading.this.setWillNotDraw(true);XxxxLoading.this.postInvalidate();}
}

案例结论:

解决方案很简单,默认隐藏XxxxLoading即可,XxxxLoading中设置为gone就不会走invalidate流程。

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

无代码的未来

随着无代码技术越来越成熟&#xff0c;很多web应用已经可以基于无代码平台进行开发。本文分析了4个最流行的无代码平台&#xff0c;并梳理了无代码行业今后可能的发展方向。原文: The future of NoCode 所有无代码编辑器都需要回答的问题 当需要选择无代码解决方案时&#xff0…

Vue基础语法核心指令过滤器计算属性监听属性

目录 1. 模板语法 1.1 插值 1.1.1 文本 1.1.2 html 1.1.3 属性 1.1.4 表达式 1.2 指令 1.2.1 核心指令 1.2.1.1 v-if |v-else-if|v-else 1.2.1.2 v-show 1.2.1.3 v-for 1.2.1.4 v-on|v-model|v-for 1.2.1.5 参数 v-bind:href,v-on:click 1.2.1.6 简写 2. 过滤器…

[AUTOSAR][网络管理] 什么是BusOff? 如何实现它?

文章目录 一、BusOff检测机制(1)简介(2)目录介绍(3)软件实现逻辑代码运行流程如下:二、测试方法(1)物理测试三、示例代码(1) busoff_recovery.c(2) busoff_recovery.h一、BusOff检测机制 (1)简介 CAN控制器可以判断出错误的类型是总线上暂时的数据错误(如外部干扰等…

Python中的内存管理:深入分析垃圾回收机制

python中有一个名为refchian的环状双向链表&#xff0c;python运行时创建的所有对象都会添加到refchain中。在refchain中的对象PyObject里都有一个ob_refcnt用来保存当前对象的引用计数器&#xff0c;就是该对象被引用的次数&#xff0c;当对象有新引用时ob_refcnt就会增加&…

西门子博途软件加密保护方法

一、程序块的专有技术保护 程序块的专有技术保护主要是对项目中的程序块&#xff08;OB、FB、FC、DB&#xff09;进行访问保护&#xff0c;如果没有专有技术保护密码则无法看到程序块中的具体内容&#xff0c;对于专有技术保护的 DB 块&#xff0c;如果没有密码只能读不能写。…

eNSP-OSPF协议其他区域不与骨干区域相连解决方法3

virtual-link技术 AR1 [ar1]int g0/0/0 [ar1-GigabitEthernet0/0/0]ip add 192.168.1.1 24 [ar1-GigabitEthernet0/0/0]quit [ar1]ospf [ar1-ospf-1]area 0 [ar1-ospf-1-area-0.0.0.0]net 192.168.1.0 0.0.0.255 [ar1-ospf-1-area-0.0.0.0]quit AR2 [ar2]int g0/0/0 [ar2-Gig…

skiaSharp linux 生成验码字体显示不出来

一、拷贝windows下的字体如&#xff1a;C:\Windows\Fonts 设置字体的地方&#xff1a; var fontPath Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Fonts", "TAHOMA.TTF");最终效果&#xff1a;

d3dx9_43.dll丢失怎么解决,四个解决方法帮你解决d3dx9_43.dll丢失

随着科技的不断发展&#xff0c;我们越来越依赖各种软件和硬件设备来提高生活和工作效率。然而&#xff0c;有时候我们可能会遇到一些技术问题&#xff0c;如“d3dx9_43.dll丢失”的问题。这个问题可能导致某些程序无法正常运行&#xff0c;给我们的生活带来诸多不便。因此&…

C++初阶--类与对象(1)

文章目录 类的引入类的定义访问限定符类成员的注意事项变量名的冲突 类的实例化类成员的声明与定义类的大小this指针特性 总结 类的引入 在c语言中&#xff0c;我们会这样写一个栈&#xff1a; struct Stack {int* a;int top;int capacity; };void StackInit(struct Stack* p…

线性代数2:梯队矩阵形式

图片来自 Europeana on Unsplash 一、前言 欢迎阅读的系列文章的第二篇文章&#xff0c;内容是线性代数的基础知识&#xff0c;线性代数是机器学习背后的基础数学。在我之前的文章中&#xff0c;我介绍了线性方程和系统、矩阵符号和行缩减运算。本文将介绍梯队矩阵形式&#xf…

Android 如何在Service中使用ViewModel

需求&#xff1a;最近有反馈说&#xff0c;需要在service中使用网络请求&#xff0c;而我网络请求就是封装的ViewModel。然后我就发现&#xff0c;原来service不支持&#xff0c;懵了呀&#xff01;哈哈 还是去看看ViewModel的源码了解下吧。下面有几个介绍的。就不多做赘述了。…

微信小程序开发之后台数据交互及wxs应用

目录 一、后端准备 1. 应用配置 2. 数据源配置 二、数据库 1. 创建 2. 数据表 3. 数据测试 三、前端 1. 请求方法整合 2. 数据请求 3. WXS的使用 4. 样式美化 5. 页面 一、后端准备 通过SpringMVC及mybatis的技术学习&#xff0c;还有前后端分离的技术应用&…

Mycat2 分布式数据库中间件

一.安装部署 Mycat2目前还不支持直接获取Docker镜像&#xff0c;需要自己通过Dockerfile打包镜像&#xff0c;其实这也是为了开发者考虑&#xff0c;比如一些个性化功能&#xff0c;如自定义分片等 Dockerfile FROM docker.io/adoptopenjdk/openjdk8:latestENV AUTO_RUN_DIR…

RemObjects Elements 12.0 Crack

Elements 是一个现代多功能软件开发工具链。 它支持六种流行的编程语言&#xff1a;Oxygene (Object Pascal)、C#、Java、Mercury (Visual Basic.NET™)、Go 和 Swift&#xff0c;适用于所有现代平台。 使用 Elements&#xff0c;您可以为您喜欢的任何平台进行编程- 无论是单…

想要精通算法和SQL的成长之路 - 找到最终的安全状态

想要精通算法和SQL的成长之路 - 找到最终的安全状态 前言一. 找到最终的安全状态1.1 初始化邻接图1.2 构建反向邻接图1.3 BFS遍历1.4 完整代码 前言 想要精通算法和SQL的成长之路 - 系列导航 一. 找到最终的安全状态 原题链接 我们从题目中可以看出来&#xff1a; 出度为0的…

面试官:如何理解CDN?说说实现原理?

一、是什么 CDN (全称 Content Delivery Network)&#xff0c;即内容分发网络 构建在现有网络基础之上的智能虚拟网络&#xff0c;依靠部署在各地的边缘服务器&#xff0c;通过中心平台的负载均衡、内容分发、调度等功能模块&#xff0c;使用户就近获取所需内容&#xff0c;降…

大模型技术实践(五)|支持千亿参数模型训练的分布式并行框架

在上一期的大模型技术实践中&#xff0c;我们介绍了增加式方法、选择式方法和重新参数化式方法三种主流的参数高效微调技术&#xff08;PEFT&#xff09;。微调模型可以让模型更适合于我们当前的下游任务&#xff0c;但当模型过大或数据集规模很大时&#xff0c;单个加速器&…

OpenCV中world模块介绍

OpenCV中有很多模块&#xff0c;模块间保持最小的依赖关系&#xff0c;用户可以根据自己的实际需要链接相关的库&#xff0c;而不需链接所有的库&#xff0c;这样在最终交付应用程序时可以减少总库的大小。但如果需要依赖OpenCV的库太多,有时会带来不方便&#xff0c;此时可以使…

忆联分布式数据库存储解决方案,助力MySQL实现高性能、低时延

据艾瑞咨询研究院《2022 年中国数据库研究报告》显示&#xff0c;截止2021年&#xff0c;中国分布式数据库占比达到 20%左右&#xff0c;主要以 MySQL 和 PostgreSQL 为代表的开源数据库为主。MySQL 作为备受欢迎的开源数据库&#xff0c;当前已广泛应用于互联网、金融、交通、…

【C++初阶】类和对象(上)

个人主页点击直达&#xff1a;小白不是程序媛 我的代码仓库&#xff1a;Gitee C系列专栏&#xff1a;C头疼记 目录 前言 面向过程和面向对象的初步认识 类的引入 类的定义 类的两种定义方式&#xff1a; 类的访问限定符及封装 封装 类的作用域 类的实例化 类对象模型…