ANR实战案例 - 通用方法总结

news2024/11/28 6:43:50

系列文章目录

提示:这里可以添加系列文章的所有文章的目录,目录需要自己手动添加
例如:第一章 Python 机器学习入门之pandas的使用


文章目录

  • 系列文章目录
  • 前言
  • 一、业务耗时
    • 1.登录Dialog优化
    • 2.子线程更新通知栏
  • 二、频繁调用
    • 1.底部Tab资源初始化
  • 三、Binder资源不足
    • 1.运行时权限判断优化
    • 2.Intent复用
  • 总结


前言


一、业务耗时

1.登录Dialog优化

"main" prio=5 tid=1 Native
  | group="main" sCount=1 dsCount=0 flags=1 obj=0x72cc6fb8 self=0xa2c84610
  | sysTid=28496 nice=0 cgrp=default sched=1073741825/1 handle=0xaff39470
  | state=S schedstat=( 217838418253 2300050047 386660 ) utm=18046 stm=3737 core=1 HZ=100
  | stack=0xbe0f4000-0xbe0f6000 stackSize=8192KB
  | held mutexes=
  native: #00 pc 00034038  /apex/com.android.runtime/lib/bionic/libc.so (syscall+28)
  native: #01 pc 00039149  /apex/com.android.runtime/lib/bionic/libc.so (__futex_wait_ex(void volatile*, bool, int, bool, timespec const*)+92)
  native: #02 pc 0007ffe3  /apex/com.android.runtime/lib/bionic/libc.so (pthread_cond_wait+32)
  native: #03 pc 0003d155  /system/lib/libc++.so (std::__1::condition_variable::wait(std::__1::unique_lock<std::__1::mutex>&)+8)
  native: #04 pc 0003f019  /system/lib/libc++.so (std::__1::__assoc_sub_state::__sub_wait(std::__1::unique_lock<std::__1::mutex>&)+24)
  native: #05 pc 0021b00d  /system/lib/libhwui.so (android::uirenderer::renderthread::RenderProxy::RenderProxy(bool, android::uirenderer::RenderNode*, android::uirenderer::IContextFactory*)+452)
  native: #06 pc 0020126f  /system/lib/libhwui.so (android::android_view_ThreadedRenderer_createProxy(_JNIEnv*, _jobject*, unsigned char, unsigned char, long long)+58)
  at android.graphics.HardwareRenderer.nCreateProxy(Native method)
  at android.graphics.HardwareRenderer.<init>(HardwareRenderer.java:160)
  at android.view.ThreadedRenderer.<init>(ThreadedRenderer.java:289)
  at android.view.ThreadedRenderer.create(ThreadedRenderer.java:255)
  at android.view.ViewRootImpl.enableHardwareAcceleration(ViewRootImpl.java:1398)
  at android.view.ViewRootImpl.setView(ViewRootImpl.java:1009)
  - locked <0x0c5a9a6b> (a android.view.ViewRootImpl)
  at android.view.WindowManagerGlobal.addView(WindowManagerGlobal.java:409)
  - locked <0x039fca61> (a java.lang.Object)
  at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:109)
  at android.app.Dialog.show(Dialog.java:384)
  at com.xxx.util.SignupLoginDialog.buildDialog(:3)
  at com.xxx.util.SignupLoginDialog.openRegisterLoginDialog(:5)
  at com.xxx.kit.function.CustomCommentDialog.showLoginOrSignUp(:2)
  at com.xxx.kit.function.CustomCommentDialog.showLoginOrSignUp(:1)
  at com.xxx.ui.xx.room.VoiceRoomFragment.onClickVoiceRoomSeatsByViewer(:6)
  at com.xxx.ui.xx.room.VoiceRoomFragment.onClickVoiceRoomSeats(:4)
  at com.xxx.ui.xx.room.VoiceRoomFragment.lambda$init$9(:1)
  at com.xxx.ui.xx.room.VoiceRoomFragment.lambda$init$9$VoiceRoomFragment(:-1)
  at com.xxx.ui.xx.room.-$$Lambda$VoiceRoomFragment$ZS2IAg70OkVevpXcQJjytmKz_3w.clickVoiceRoomSeats(:-1)
  at com.xxx.ui.xx.adapter.VoiceRoomSeatsAdapter.lambda$onBindViewHolder$1(:1)
  at com.xxx.ui.xx.adapter.VoiceRoomSeatsAdapter.lambda$onBindViewHolder$1$VoiceRoomSeatsAdapter(:-1)
  at com.xxx.ui.xx.adapter.-$$Lambda$VoiceRoomSeatsAdapter$-hYnXO7y6oji9WzyVYN0Z6bdivg.onClick(:-1)
  at android.view.View.performClick(View.java:7465)
  at android.view.View.performClickInternal(View.java:7438)
  at android.view.View.access$3600(View.java:813)
  at android.view.View$PerformClick.run(View.java:28505)
  at android.os.Handler.handleCallback(Handler.java:938)
  at android.os.Handler.dispatchMessage(Handler.java:99)
  at android.os.Looper.loop(Looper.java:268)
  at android.app.ActivityThread.main(ActivityThread.java:7963)
  at java.lang.reflect.Method.invoke(Native method)
  at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:627)
  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:997)

日志可看出是SignupLoginDialog的问题,结合业务代码查看:

public SignupLoginDialog(Activity context, int sourceFrom, LocalLoginParams params) {
		...
        initFaceBookAuth(activity, findViewById(R.id.ivFacebook));
        initGoogleAuth(activity, findViewById(R.id.llGoogle));
        initTwitterAuth(activity, findViewById(R.id.ivTiwtter));
        ...
}

可以看到FaceBook/Google/Twitter等三方账号在Dialog初始化的时候同时进行了初始化,较为耗时。
修改:抽取出各个三方登录平台初始化,用到时再进行初始化。

2.子线程更新通知栏

"main" tid=1 Runnable
  at android.os.Bundle.<init> (Bundle.java:67)
  at androidx.core.app.NotificationCompatBuilder.<init> (NotificationCompatBuilder.java:61)
  at androidx.core.app.NotificationCompat$Builder.build (NotificationCompat.java:2346)
  at com.xxx.biz.remote.XxNotification.innerDisplayNotifcation (XxNotification.java:498)
  at com.xxx.biz.remote.XxNotification.displayNotifcation (XxNotification.java:262)
  at com.xxx.biz.remote.XxNotification.displayNotifcation (XxNotification.java:268)
  at com.xxx.xxx.service.XxService$10.onNext (XxService.java:925)
  at com.xxx.xxx.service.XxService$10.onNext (XxService.java:913)
  at io.reactivex.internal.operators.observable.ObservableObserveOn$ObserveOnObserver.drainNormal (ObservableObserveOn.java:201)
  at io.reactivex.internal.operators.observable.ObservableObserveOn$ObserveOnObserver.run (ObservableObserveOn.java:255)
  at io.reactivex.android.schedulers.HandlerScheduler$ScheduledRunnable.run (HandlerScheduler.java:124)
  at android.os.Handler.handleCallback (Handler.java:873)
  at android.os.Handler.dispatchMessage (Handler.java:99)
  at android.os.Looper.loop (Looper.java:193)
  at android.app.ActivityThread.main (ActivityThread.java:6758)
  at java.lang.reflect.Method.invoke (Native method)
  at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run (RuntimeInit.java:497)
  at com.android.internal.os.ZygoteInit.main (ZygoteInit.java:912)

通过日志定位,查看innerDisplayNotifcation方法,内部有大量Notification相关的设置,大小图标适配等,且与业务高度耦合。

尝试了以下方案:
1.innerDisplayNotifcation方法拆分。
2.方法调用频率降低,监听通知栏下滑时候再去更新–>onWindowFocusChanged(无法准确获取通知栏下拉监听)
3.子线程更新通知栏
最终将innerDisplayNotifcation方法放入子线程执行,进行通知栏更新,可以彻底解决该ANR问题。

二、频繁调用

1.底部Tab资源初始化

"main" tid=1 Native
  #00  pc 0x0000000000019d1c  /system/lib/libc.so (syscall+28)
  #01  pc 0x00000000000a6b63  /system/lib/libart.so (art::ConditionVariable::WaitHoldingLocks(art::Thread*)+78)
  #02  pc 0x00000000003d490f  /system/lib/libart.so (art::GoToRunnable(art::Thread*) (.llvm.<US_SOCIAL_SECURITY_NUMBER>)+314)
  #03  pc 0x00000000003d47ad  /system/lib/libart.so (art::JniMethodEnd(unsigned int, art::Thread*)+8)
  at android.content.res.AssetManager.nativeOpenNonAsset (Native method)
  at android.content.res.AssetManager.openNonAsset (AssetManager.java:878)
  at android.content.res.ResourcesImpl.loadDrawableForCookie (ResourcesImpl.java:858)
  at android.content.res.ResourcesImpl.loadDrawable (ResourcesImpl.java:648)
  at android.content.res.Resources.getDrawableForDensity (Resources.java:888)
  at android.content.res.Resources.getDrawable (Resources.java:827)
  at android.content.res.Resources.getDrawable (Resources.java:802)
  at com.xxx.kit.widget.HomeBottomTabLayout.setDefaultValue (HomeBottomTabLayout.java:60)
  at com.xxx.ui.home.fragment.HomeTabFragment.onCreateView (HomeTabFragment.java:91)
  at androidx.fragment.app.Fragment.performCreateView (Fragment.java:2963)
  at androidx.fragment.app.FragmentStateManager.createView (FragmentStateManager.java:518)
  at androidx.fragment.app.FragmentStateManager.moveToExpectedState (FragmentStateManager.java:282)
  at androidx.fragment.app.FragmentManager.executeOpsTogether (FragmentManager.java:2189)
  at androidx.fragment.app.FragmentManager.removeRedundantOperationsAndExecute (FragmentManager.java:2100)
  at androidx.fragment.app.FragmentManager.execPendingActions (FragmentManager.java:2002)
  at androidx.fragment.app.FragmentManager.executePendingTransactions (FragmentManager.java:600)
  at com.xxx.ui.main.MainActivity.replaceFragment (MainActivity.java:1289)
  at com.xxx.ui.main.MainActivity.replaceMainActivityFragment (MainActivity.java:716)
  at com.xxx.ui.main.MainActivity.access$000 (MainActivity.java:256)
  at com.xxx.ui.main.MainActivity$ReleaseFragmentRunnable.run (MainActivity.java:704)
  at android.os.Handler.handleCallback (Handler.java:873)
  at android.os.Handler.dispatchMessage (Handler.java:99)
  at android.os.Looper.loop (Looper.java:193)
  at android.app.ActivityThread.main (ActivityThread.java:6710)
  at java.lang.reflect.Method.invoke (Native method)
  at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run (RuntimeInit.java:497)
  at com.android.internal.os.ZygoteInit.main (ZygoteInit.java:911)

HomeBottomTabLayout.setDefaultValue这个方法在onresume调用,频率高。在view的构造方法把getResources().getDrawable先取出来,setDefaultValue 方法直接给数组设置drawable。
修改:
在这里插入图片描述

三、Binder资源不足

1.运行时权限判断优化

"main" tid=1 Native
  #00  pc 0x000000000005ddec  /apex/com.android.runtime/lib/bionic/libc.so (syscall+28)
  #01  pc 0x0000000000130dc9  /apex/com.android.art/lib/libart.so (art::ConditionVariable::WaitHoldingLocks(art::Thread*)+88)
  #02  pc 0x00000000004d8c23  /apex/com.android.art/lib/libart.so (art::GoToRunnable(art::Thread*)+342)
  #03  pc 0x00000000004d8aa5  /apex/com.android.art/lib/libart.so (art::JniMethodEnd(unsigned int, art::Thread*)+8)
  at android.os.BinderProxy.transactNative (BinderProxy.java)
  at android.os.BinderProxy.transact (BinderProxy.java:540)
  at android.os.storage.IStorageManager$Stub$Proxy.getVolumeList (IStorageManager.java:1610)
  at android.os.storage.StorageManager.getVolumeList (StorageManager.java:1381)
  at android.os.Environment$UserEnvironment.getExternalDirs (Environment.java:160)
  at android.os.Environment.isExternalStorageLegacy (Environment.java:1262)
  at com.xxx.storage.cache.ScopeStorageUtils.isScopeStorageEnabled (ScopeStorageUtils.java:31)
  at com.xxx.util.PermissionUtil.getExternalStoragePermissionStr (PermissionUtil.java:22)
  at com.xxx.common.base.XxxApplicationInitor.checkPermission (MusicApplicationInitor.java:688)
  at com.xxx.ui.main.MainActivity.onResume (MainActivity.java:2196)
  at android.app.Instrumentation.callActivityOnResume (Instrumentation.java:1456)
  at android.app.Activity.performResume (Activity.java:8135)
  at android.app.ActivityThread.performResumeActivity (ActivityThread.java:4481)
  at android.app.ActivityThread.handleResumeActivity (ActivityThread.java:4523)
  at android.app.servertransaction.ResumeActivityItem.execute (ResumeActivityItem.java:52)
  at android.app.servertransaction.TransactionExecutor.executeLifecycleState (TransactionExecutor.java:176)
  at android.app.servertransaction.TransactionExecutor.execute (TransactionExecutor.java:97)
  at android.app.ActivityThread$H.handleMessage (ActivityThread.java:2116)
  at android.os.Handler.dispatchMessage (Handler.java:106)
  at android.os.Looper.loop (Looper.java:223)
  at android.app.ActivityThread.main (ActivityThread.java:7723)
  at java.lang.reflect.Method.invoke (Method.java)
  at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run (RuntimeInit.java:612)
  at com.android.internal.os.ZygoteInit.main (ZygoteInit.java:997)

运行时权限频繁判定频繁获取,Binder资源不足导致,通过存储权限数组为全局变量以减少通讯。修改:
在这里插入图片描述
XxxApplicationInitor.checkPermission

public static List<String> checkPermission() {
    List<String> strs = new ArrayList<>(2);
    if (XxApplication.getApplication() == null) {
        return strs;
    }
    if (ContextCompat.checkSelfPermission(context,
            PermissionUtil.getExternalStoragePermissionStr()) != PackageManager.PERMISSION_GRANTED) {
        strs.add(PermissionUtil.getExternalStoragePermissionStr());
    }
    if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) {
        if (ContextCompat.checkSelfPermission(context,
                Manifest.permission.READ_PHONE_STATE) != PackageManager.PERMISSION_GRANTED) {
            strs.add(Manifest.permission.READ_PHONE_STATE);
        }
    }
    return strs;
}

2.Intent复用

"main" tid=1 Native
  #00  pc 0x00000000000d7b74  /apex/com.android.runtime/lib64/bionic/libc.so (__ioctl+4)
  #01  pc 0x0000000000093f70  /apex/com.android.runtime/lib64/bionic/libc.so (ioctl+160)
  #02  pc 0x0000000000051c7c  /system/lib64/libbinder.so (android::IPCThreadState::talkWithDriver(bool)+300)
  #03  pc 0x0000000000052c8c  /system/lib64/libbinder.so (android::IPCThreadState::waitForResponse(android::Parcel*, int*)+60)
  #04  pc 0x00000000000529f4  /system/lib64/libbinder.so (android::IPCThreadState::transact(int, unsigned int, android::Parcel const&, android::Parcel*, unsigned int)+188)
  #05  pc 0x000000000004b0b0  /system/lib64/libbinder.so (android::BpBinder::transact(unsigned int, android::Parcel const&, android::Parcel*, unsigned int)+152)
  #06  pc 0x00000000001270c0  /system/lib64/libandroid_runtime.so (android_os_BinderProxy_transact(_JNIEnv*, _jobject*, int, _jobject*, _jobject*, int)+152)
  at android.os.BinderProxy.transactNative (Native method)
  at android.os.BinderProxy.transact (BinderProxy.java:565)
  at android.app.IActivityManager$Stub$Proxy.getIntentSenderWithFeature (IActivityManager.java:7555)
  at android.app.PendingIntent.getBroadcastAsUser (PendingIntent.java:578)
  at android.app.PendingIntent.getBroadcast (PendingIntent.java:561)
  at com.xxx.util.Utils.getBroadcast (Utils.java:1126)
  at com.xxx.biz.download.utils.DownloadNotification.updateDownloadingNotification (DownloadNotification.java:168)
  at com.xxx.biz.download.utils.DownloadController$DownloadCallback.onProgress (DownloadController.java:824)
  at com.xxx.common.network.download.Downloader$1$1.accept (Downloader.java:99)
  at com.xxx.common.network.download.Downloader$1$1.accept (Downloader.java:94)
  at io.reactivex.internal.observers.LambdaObserver.onNext (LambdaObserver.java:63)
  at io.reactivex.observers.SerializedObserver.onNext (SerializedObserver.java:111)
  at io.reactivex.internal.operators.observable.ObservableDebounceTimed$DebounceTimedObserver.emit (ObservableDebounceTimed.java:143)
  at io.reactivex.internal.operators.observable.ObservableDebounceTimed$DebounceEmitter.run (ObservableDebounceTimed.java:168)
  at io.reactivex.internal.operators.observable.ObservableDebounceTimed$DebounceTimedObserver.onComplete (ObservableDebounceTimed.java:124)
  at io.reactivex.internal.operators.observable.ObservableObserveOn$ObserveOnObserver.checkTerminated (ObservableObserveOn.java:287)
  at io.reactivex.internal.operators.observable.ObservableObserveOn$ObserveOnObserver.drainNormal (ObservableObserveOn.java:193)
  at io.reactivex.internal.operators.observable.ObservableObserveOn$ObserveOnObserver.run (ObservableObserveOn.java:255)
  at io.reactivex.android.schedulers.HandlerScheduler$ScheduledRunnable.run (HandlerScheduler.java:124)
  at android.os.Handler.handleCallback (Handler.java:938)
  at android.os.Handler.dispatchMessage (Handler.java:99)
  at android.os.Looper.loop (Looper.java:257)
  at android.app.ActivityThread.main (ActivityThread.java:8220)
  at java.lang.reflect.Method.invoke (Native method)
  at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run (RuntimeInit.java:626)
  at com.android.internal.os.ZygoteInit.main (ZygoteInit.java:1015)

DownloadController$DownloadCallback.onProgress


class DownloadCallback implements DownloadListener {
        public void onProgress(long downloadedSize, long totalSize) {
            ...
            DownloadNotification.updateDownloadingNotification(downloadFile.getName(), (int) downloadedSize, (int) totalSize);
        }

}

DownloadNotification.updateDownloadingNotification

    public static void updateDownloadingNotification(String name, int progress, int total) {
        Intent intent = new Intent(ConstantUtil.notification_broadcast_action_to_download);
        intent.putExtra(IntentHandler.INTENT_TO_ACTIVITY, CommentString.DOWNLOAD_QUEUE_ACTIVITY);
        PendingIntent pendingIntent = Utils.getBroadcast(MusicApplication.getInstance(), 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
        updateDownloading(name, progress, total, pendingIntent);
    }

Utils.getBroadcast

    public static PendingIntent getBroadcast(Context context, int requestCode, Intent intent, int flags){
        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.S) {
            //适配 Android S
            return PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_IMMUTABLE);
        } else {
            return PendingIntent.getBroadcast(context, requestCode, intent, flags);
        }
    }

onProgress为下载进度回调,调用比较频繁,导致低端机Binder资源不足,可以修改复用updateDownloadingNotification方法中的intent:

    private static PendingIntent mNotificationContentIntent = getContentPendingIntent();

    public static PendingIntent getContentPendingIntent() {
        Intent intent = new Intent(ConstantUtil.notification_broadcast_action_to_download);
        intent.putExtra(IntentHandler.INTENT_TO_ACTIVITY, CommentString.DOWNLOAD_QUEUE_ACTIVITY);
        PendingIntent pendingIntent = Utils.getBroadcast(MusicApplication.getInstance(), 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
        return pendingIntent;
    }

    public static void updateDownloadingNotification(String name, int progress, int total) {
        Intent intent = new Intent(ConstantUtil.notification_broadcast_action_to_download);
        intent.putExtra(IntentHandler.INTENT_TO_ACTIVITY, CommentString.DOWNLOAD_QUEUE_ACTIVITY);
        updateDownloading(name, progress, total, mNotificationContentIntent);//意图复用
    }

总结

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

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

相关文章

【LLM系列之LLaMA】LLaMA: Open and Efficient Foundation Language Models

论文题目&#xff1a;《LLaMA: Open and Efficient Foundation Language Models》 论文链接&#xff1a;https://arxiv.org/pdf/2302.13971.pdf github链接&#xff1a;https://github.com/facebookresearch/llama/tree/main huggingface链接&#xff1a;https://huggingface.c…

[离散数学] 函数

文章目录 函数判断函数的条件复合函数复合函数的性质 逆函数 函数 判断函数的条件 dom F A ⇔ \Leftrightarrow ⇔所有x 都有 F&#xff08;x&#xff09;与之对应 有唯一的与其对应 < x , y > ∈ f ∧ < y , z > ∈ f ⇒ y z <x,y>\in f \land <y,z…

【C++】2. 进入面向对象 - 类和对象的初步认识

专栏导读 &#x1f341;作者简介&#xff1a;余悸&#xff0c;在读本科生一枚&#xff0c;致力于 C 方向学习。 &#x1f341;收录于 C专栏&#xff0c;本专栏主要内容为 C 初阶、C 进阶、STL 详解等&#xff0c;持续更新中&#xff01; &#x1f341;相关专栏推荐&#xff1a;…

TikTok新手做什么账号,Tiktok类目怎么选

有很多刚入驻TikTok的小白不知道要选择什么类目才比较容易起量。看完这篇后&#xff0c;相信你们的疑惑就会烟消云散。选择对了类目对以后的产品带货有很大的促进作用&#xff0c;今天我给你们分享6种适合TikTok小店运营的账号类型&#xff0c;以及一些比较推荐的类目。 TikTok…

测试和调试之Python高级篇

测试和调试 在软件开发过程中&#xff0c;测试和调试是非常重要的环节。测试用于验证代码的正确性和可靠性&#xff0c;而调试则是为了找到并解决代码中存在的问题。下面将会详细介绍单元测试、集成测试、断言、测试框架、调试工具和技巧。 单元测试 单元测试是指对软件中的…

linux环境安装使用redis详解

Redis 1. NoSQL的引言 NoSQL ( Not Only SQL )&#xff0c;意即 不仅仅是SQL , 泛指非关系型的数据库。Nosql这个技术门类,早期就有人提出,发展至2009年趋势越发高涨。 2. 为什么是NoSQL 随着互联网网站的兴起&#xff0c;传统的关系数据库在应付动态网站&#xff0c;特别是超大…

OpenPCDet系列 | 5.1 PointPillars算法——PillarVFE特征构建与编码模块

文章目录 PillarVFE模块1. PillarVFE初始化2. PillarVFE数据处理2.1 特征构造2.2 掩码构造2.3 特征编码 OpenPCDet的整个结构图&#xff1a; PillarVFE模块属于VFE结构的其中一种&#xff0c;所以可以在PCDet中的backbone_3d目录下&#xff0c;可以找到vfe目录结构。在OpenPCDe…

【JOSEF约瑟 JL-8GA/12端子排电流继电器 整定范围宽、功耗低】

JL-8GA/12端子排电流继电器名称:端子排电流继电器型号:JL-8GA/12品牌:JOSEF约瑟功率消耗:≤5W触点容量:250V5A额定电压:58,100,110,220V 系列型号&#xff1a; JL-8GA/11端子排电流继电器&#xff1b; JL-8GA/12端子排电流继电器&#xff1b; JL-8GA/13端子排电流继电器&am…

MySQL(1) ---- 数据库介绍与MySQL概述

介绍 1、什么是数据库&#xff1f; 数据库&#xff1a;DateBase&#xff08;DB&#xff09;&#xff0c;是存储和管理数据的仓库。数据库管理系统&#xff1a;DataBase Management System&#xff08;DBMS&#xff09;&#xff0c;操纵和管理数据库的大型软件。SQL&#xff1…

【C语言】手把手教你文件操作

文章目录 一、前言二、文件的打开和关闭1. fopen函数2. fclose函数 三、文件的顺序读写四、文件的随机读写1. fseek函数2. ftell函数3. fwind函数 一、前言 程序运行时&#xff0c;数据存放在内存中&#xff0c;而当程序退出后&#xff0c;数据也就不复存在。 想做到数据持久化…

数据库管理-第七十五期 手把手教你搭19c RAC(20230516)

数据库管理 2023-05-16 第七十五期 手把手教你搭19c RAC1 基础环境2 操作系统配置2.1 /etc/hosts2.2 配置系统挂载2.3 配置本地yum源2.4 操作系统配置2.5 安装预安装RPM包并配置&#xff1a;2.6 创建对应目录2.7 配置时间同步 3 存储挂载3.1 存储环境3.2 存储识别3.3 多路径聚合…

生成一个手绘图为底图的导游图

1 前言 上一篇演示了制作一个简版导游图。简版导游图的优点是制作简单、快速&#xff0c;不需要第三方软件&#xff0c;缺点是略显简陋、不够专业。 本编介绍制作专业导游图的步骤&#xff0c;用手绘图为地图&#xff0c;用图形展现景区信息&#xff0c;能表现出丰富的景区细…

ChatGPT:使用Edge浏览器获取ChatGPT以及如何使用ChatGPT帮你制作PPT

一&#xff1a;前言 ChatGPT&#xff1a;智能AI助你畅聊天地 在现代人日益忙碌的生活中&#xff0c;难免需要一些轻松愉快的聊天来放松身心。而现在&#xff0c;有了 ChatGPT&#xff0c;轻松愉快的聊天变得更加智能、有趣且不受时间、地点限制&#xff01; 什么是 ChatGPT&…

NSSCTF-[深育杯 2021]Press

下载链接&#xff1a;下载 载入IDA&#xff0c;查看内容 首先进入一个函数进行初始化&#xff0c;进入查看 unsigned __int64 sub_4007B6() {int v1; // [rsp8h] [rbp-48h]int i; // [rspCh] [rbp-44h]char src[56]; // [rsp10h] [rbp-40h] BYREFunsigned __int64 v4; // [r…

【可乐荐书】有趣的矩阵:看得懂又好看的线性代数

本栏目将推荐一些经典的、有趣的、有启发性的书籍&#xff0c;这些书籍涵盖了各个领域&#xff0c;包括文学、历史、哲学、科学、技术等等。相信这些书籍不仅可以让你获得知识&#xff0c;还可以让你感受到阅读的乐趣和魅力。 今天给大家推荐的书籍是&#xff1a;《有趣的矩阵…

【简单DP】CF1420 C1

昨天的CF心态又打崩了 好久没写DP了这道题一发过了 但是大家都会qwq 烦死 Problem - C1 - Codeforces 题意&#xff1a; 给定一个序列&#xff0c;让你找出一个子序列 使得 这个最大&#xff0c;a是子序列 思路&#xff1a; 首先子序列&#xff0c;自然就是DP 然后每个…

品牌活动如何策划,更利于传播?(吸引媒体报道)

传媒如春雨&#xff0c;润物细无声&#xff0c;大家好&#xff0c;我是51媒体网胡老师。 之前做媒体的时候&#xff0c;参加过无数的媒体活动&#xff0c;现在做媒体传播也给了许多品牌一些建议&#xff0c;有的活动设计的很有趣&#xff0c;有的活动设计的很巧妙&#xff0c;…

响应式设计 MediaQuery和flex

一、MediaQuery(媒体查询)的概念 为不同尺寸的屏幕设定不同的css样式 示例 二、media常用参数 三、媒体查询代码示例 MediaQuery在浏览器中的显示示例 MediaQuery综合案例 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8…

Go语言笔记:使用ssh包作为客户端与SSH服务器交互

文章目录 目的基础说明使用演示单次通讯连续通讯&#xff08;远程终端&#xff09; 总结 目的 Golang中可以使用 golang.org/x/crypto/ssh 包作为SSH客户端或者SSH服务使用。这篇文章将简单记录下作为客户端使用的一些内容。 Package ssh implements an SSH client and server…

QT自定义控件折线图、趋势图。

这里提供两种实现方式&#xff0c;一直自绘的自定义控件&#xff0c;一直三方SDK&#xff08;qcustomplot&#xff09;。 这里主要介绍自绘的&#xff0c;它的优点是结构简单&#xff0c;代码逻辑好修改&#xff0c;容易定制&#xff0c;缺点是功能相对单一。三方的qcustomplot…