Android第十三次面试总结(四大 组件基础)

Activity生命周期和四大启动模式详解

一、Activity 生命周期

Activity 的生命周期由一系列回调方法组成,用于管理其创建、可见性、焦点和销毁过程。以下是核心方法及其调用时机:

  1. onCreate()​

    • 调用时机​:Activity 首次创建时调用。
    • 作用​:初始化布局(setContentView)、绑定数据、创建后台线程等。
    • 注意​:在此方法中应避免耗时操作。
  2. onStart()​

    • 调用时机​:Activity 可见但未获得焦点(例如被对话框覆盖)。
    • 作用​:恢复UI更新或资源加载。
  3. onResume()​

    • 调用时机​:Activity 进入前台并可与用户交互。
    • 作用​:启动动画、传感器监听、高频率更新UI等。
    • 关键点​:此时 Activity 位于栈顶。
  4. onPause()​

    • 调用时机​:Activity 失去焦点(如弹出对话框或跳转到其他 Activity)。
    • 作用​:保存临时数据、释放资源(如摄像头)。
    • 注意​:需快速执行,否则会影响新 Activity 的启动。
  5. onStop()​

    • 调用时机​:Activity 完全不可见(被其他 Activity 覆盖或退出)。
    • 作用​:停止动画、释放非必要资源。
  6. onDestroy()​

    • 调用时机​:Activity 被销毁(用户主动退出或系统回收资源)。
    • 作用​:清理内存、注销广播等。
  7. onRestart()​

    • 调用时机​:Activity 从停止状态重新回到前台(如按返回键返回)。
    • 流程​:onRestart()onStart()onResume()

场景应用

场景 1:打开新页面

流程​:

  1. 原 Activity 执行 onPause()(失去焦点)
  2. 新 Activity 依次执行:
    • onCreate()(初始化)
    • onStart()(可见)
    • onResume()(可交互)
  3. 原 Activity 执行 onStop()(完全不可见)

典型场景​:

  • 从主页跳转到详情页
  • 列表页打开新的商品页

场景 2:返回上一个页面

流程​:

  1. 当前 Activity 执行 onPause()
  2. 上一个 Activity 依次执行:
    • onRestart()(重新激活)
    • onStart()(可见)
    • onResume()(可交互)
  3. 当前 Activity 执行:
    • onStop()
    • onDestroy()(被销毁)

典型场景​:

  • 提交订单后返回购物车
  • 查看图片详情后返回相册

场景 3:屏幕旋转

流程​:

  1. onPause() → onSaveInstanceState()(保存数据)
  2. onStop() → onDestroy()(销毁实例)
  3. 重新创建:
    • onCreate()(携带保存的数据)
    • onStart()
    • onRestoreInstanceState()(恢复数据)
    • onResume()

开发重点​:

  • 在 onSaveInstanceState() 保存编辑框内容/滚动位置
  • 避免在旋转时中断网络请求

场景 4:被弹窗/来电中断
场景生命周期变化恢复顺序
普通对话框onPause()onResume()
全屏弹窗/来电onPause() → onStop()onRestart() → onResume()

关键区别​:

  • 是否完全遮挡决定是否触发 onStop()

二、四大启动模式(Launch Mode)

        Android 的四大启动模式核心基于任务栈管理机制实现。系统通过 ActivityManagerService(AMS)维护一个全局的任务栈结构,每个任务栈由 TaskRecord 对象表示,遵循后进先出的堆栈原则。当启动 Activity 时,AMS 会根据不同启动模式的预设规则,动态调整任务栈的组成。

        ​standard 模式是最基础的方式。它简单地无条件创建新 Activity 实例,并将其压入当前任务栈顶部。这种模式不涉及任何复用判断,因此可能在栈中积累多个相同 Activity 实例,对内存管理构成压力。系统在处理时直接调用 ActivityStarter 的强制压栈方法,整个过程没有任何条件检测。

适用场景​:

  • 常规页面跳转​(如商品详情页、新闻内容页)
  • 多实例并行需求​(如浏览器标签页、文档编辑页)
    典型案例​:
  • 电商应用浏览商品:主页 → 商品A页 → 商品B页,栈内存在多个不同商品页实例
  • 文档应用编辑文件:同时打开文档1文档2,返回时可逐个切换

​        singleTop 模式的核心在于栈顶检查机制。启动时,AMS 会立即判断目标 Activity 是否恰好位于当前栈顶。如果匹配成功,则直接触发该实例的 onNewIntent() 进行数据刷新,完全跳过创建流程;若不在栈顶,则回退到 standard 模式创建新实例。这种设计特别适合通知栏点击等高频重复启动的场景。

适用场景​:

  • 避免重复通知​(通知栏多次点击跳转同一页)
  • 高频操作入口​(如刷新按钮、重复提交页面)
    典型案例​:
  • 微信消息页面:当停留在聊天页A时收到新消息,点击通知直接刷新当前页面
  • 支付倒计时页:用户多次点击“重新支付”按钮,复用当前页面更新倒计时
    特殊场景​:
  • 扫二维码页面:已打开扫码页时再次触发扫码,直接复用而非新建

        ​singleTask 模式采用任务栈重构策略。系统会优先搜索与目标 Activity 的 taskAffinity 匹配的任务栈,检测是否存在已有实例。如果找到,AMS 会先清除该实例之上的所有 Activity(触发它们的 onDestroy),将目标实例置于栈顶并调用 onNewIntent();若未找到,则新建独立任务栈。这种清除机制有效保障了栈内实例唯一性,但处理成本较高。

适用场景​:

  • 应用主页​(如微信主界面、设置首页)
  • 登录/授权中转站​(确保返回时跳过登录页)
    典型案例​:
  • 支付流程结束:商品页 → 收银台 → 支付成功页,点击“返回首页”清空整个支付栈,直达主页
  • 社交应用登录:若已登录过,再次打开APP直接进入主页面而非登录页

        ​singleInstance 模式具有全局隔离特性。该模式强制目标 Activity 独占整个任务栈,且栈内不允许其他 Activity 存在。启动时,AMS 先全局搜索专属栈:若存在则直接提至前台复用;若不存在则创建带唯一 ID 的新栈。这种模式实现了跨应用级的隔离,在系统低内存回收时可能被独立保留,常用于相机、拨号等系统组件。

适用场景​:

  • 系统级共享组件​(相机、通讯录选择器)
  • 独立功能模块​(如浮窗通话界面)
    典型案例​:
  • 系统相机调用:应用中启动相机拍照,返回时直接回到原应用
  • 第三方分享面板:微信分享时调起系统分享栈,完成后自动销毁
    特殊注意​:
  • 银行应用安全键盘:通过独立进程防止密码输入被截屏
场景需求推荐模式
常规页面跳转(允许多实例)standard
避免栈顶重复(如通知点击)singleTop
应用入口/核心页(需清栈)singleTask
独立系统组件(跨进程调用)singleInstance

        通过 AndroidManifest.xml 或 Intent 标志(如 FLAG_ACTIVITY_NEW_TASK)指定,控制 Activity 实例与任务栈(Task)的关系。

        onNewIntent() 是 Activity 被复用时的数据刷新入口,用于处理同一个 Activity 实例被再次启动时的新意图(Intent),而无需重建页面。

核心作用​(3个关键点):

  1. 复用已有页面

    • 避免重复创建相同 Activity(节省内存)
    • 保持当前页面状态(如滚动位置、输入内容)
  2. 更新数据

    protected void onNewIntent(Intent intent) {setIntent(intent); // 必须更新!否则getIntent()拿旧数据refreshUI(intent); // 根据新数据刷新界面
    }
  3. 特定场景触发

    • singleTop​:当 Activity 位于栈顶时
    • singleTask/singleInstance​:当 Activity 已存在于栈中时

典型场景​:

  • 点击通知栏多次打开同一聊天页(直接刷新消息)
  • 从支付结果页返回后再次支付(复用页面更新订单)
  • 全局搜索框重复搜索(保留搜索历史记录)

记住一个原则​:
只要看到 singleTop/singleTask,就要考虑是否需要重写 onNewIntent() 处理数据刷新!


启动模式在后台运行时的关键行为解析

一、后台启动 Activity 的通用规则
  1. 基本行为​:

    • 当应用在后台时启动新 Activity,系统会先将应用带回前台
    • 新 Activity 会被添加到当前任务栈中
    • 用户按返回键时会回到上一个 Activity
  2. 核心影响​:

    • 应用进程优先级提升到前台进程
    • 可能触发系统回收机制(低内存时后台进程优先被杀)

二、后台启动的注意事项

1. Android 8.0+ 限制
  • 后台启动限制​:应用在后台时无法随意启动 Activity
  • 解决方案​:
    // 必须使用全屏通知
    NotificationCompat.Builder builder = new NotificationCompat.Builder(this, CHANNEL_ID).setContentIntent(pendingIntent) // 用户点击才启动.setFullScreenIntent(pendingIntent, true); // 紧急通知
2. 内存回收策略
启动模式回收优先级恢复难度
standard难(多实例)
singleTop中等
singleTask易(单实例)
singleInstance最低最易
3. 最佳实践
  1. 后台启动 singleTask 主页​:

    // 清理所有历史栈
    Intent intent = new Intent(context, MainActivity.class);
    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
  2. 避免后台 standard 启动​:

    • 易导致 OOM(内存溢出)
    • 返回栈混乱
  3. 跨进程通信​:

    // 启动独立进程的Activity
    <activity android:process=":camera_process"/>

三、各模式后台表现对比表

启动模式后台启动特点内存效率适用场景
standard持续堆叠新实例需多实例的普通页面
singleTop栈顶复用省资源通知/消息更新
singleTask清理栈内多余页面应用主页/核心入口
singleInstance独立进程不受主应用影响最高相机/电话等系统级功能
模式实例数量栈位置典型场景
standard多个当前栈普通页面
singleTop栈顶唯一当前栈防重复启动(通知栏)
singleTask栈内唯一可指定新栈应用主界面
singleInstance全局唯一独占新栈独立功能(如相机)

微信小游戏双图标背后的启动模式解析

场景重现:

  1. 点击微信图标启动微信主界面

  2. 在微信内点击进入小游戏

  3. 后台出现两个独立图标​:

    • 微信主应用图标

    • 小游戏独立图标

核心启动模式:singleInstance

实现原理​:

<!-- 小游戏Activity声明示例 -->
<activityandroid:name=".GameActivity"android:launchMode="singleInstance"android:taskAffinity="com.tencent.game"android:process=":game_process" />

三大关键机制​:

  1. 独立进程

    android:process=":game_process"
    • 小游戏运行在独立的 com.tencent.mm:game_process 进程

    • 与微信主进程 com.tencent.mm 完全隔离

    • 效果​:系统显示两个独立进程图标

  2. 独立任务栈

    android:taskAffinity="com.tencent.game"
    android:launchMode="singleInstance"
    • 创建专属任务栈(与微信主栈隔离)

    • 效果​:

      • 最近任务显示两个独立任务项

      • 游戏退出时直接回到手机桌面,不经过微信

  3. 跨进程通信

    // 微信启动游戏的关键代码
    Intent intent = new Intent();
    intent.setComponent(new ComponentName("com.tencent.mm", "com.tencent.mm.plugin.game.GameActivity"));
    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_MULTIPLE_TASK);
    startActivity(intent);
    • 使用 FLAG_ACTIVITY_MULTIPLE_TASK 允许多实例

完整启动流程:

  1. 用户点击小游戏入口

  2. 微信创建子进程​:

    • 通过 startActivity() 跨进程启动

    • 指定 singleInstance + NEW_TASK 标志

  3. 系统创建资源隔离区​:

    • 独立内存空间(分配专属内存)

    • 独立渲染线程(避免微信主线程卡顿)

    • 独立任务栈(系统记录为独立应用)

  4. 游戏结束后​:

    • 游戏进程销毁

    • 微信主进程不受影响

    • 返回路径​:游戏 → 桌面 (不返回微信)

技术优势:

  1. 性能隔离​:

    • 游戏占500MB内存不影响微信聊天

    • 游戏崩溃不会导致微信闪退

    # 进程内存占用示例
    com.tencent.mm: 300MB   # 微信主进程
    com.tencent.mm:game: 500MB # 游戏进程
  2. 独立生命周期​:

    操作

    微信主进程

    游戏进程

    进入游戏

    onPause()

    onCreate()

    游戏切后台

    -

    onPause->onStop

    关闭游戏

    onResume()

    onDestroy()

    游戏崩溃

    无影响

    自动重启

  3. 用户体验优化​:

    • 游戏可独立操作(微信后台保持运行)

    • 小窗口模式双向互动(微信浮窗+游戏)

对比其他启动模式:

启动模式

是否分进程

是否独立图标

适用场景

standard

普通页面跳转

singleTask

微信钱包

singleTop

公众号文章

singleInstance

​**✅**​

小游戏/视频通话

典型应用场景:

  1. 微信/QQ内置小游戏

  2. 直播平台连麦功能

  3. 银行App的安全键盘

  4. AR扫描模块

ContentProvider应用场景

        ​ContentProvider 是 Android 实现应用间安全数据共享(基于 URI 和 Binder)的核心组件,同时通过空实现 Provider 的 onCreate() 机制实现库的自动初始化。​

ContentProvider 的主要应用场景

a) 应用间共享数据(最常见目的)​
*   **系统功能:** Android系统自身提供了大量ContentProvider让应用访问系统数据:*   `ContactsContract.Contacts` (通讯录联系人)*   `MediaStore.Images.Media` (相册图片)*   `MediaStore.Audio.Media` (音频文件)*   `CalendarContract.Events` (日历事件)*   `CallLog.Calls` (通话记录)*   `Settings.System` (系统设置)
*   **第三方应用:** 当你的应用需要向其他应用**提供数据**时(如提供用户配置、自定义数据库内容),你需要实现自己的ContentProvider,并定义相应的authority和URI结构。
 ​b) 同一个应用内的结构化数据访问
*   即使只在应用内部使用,ContentProvider也提供了一种**标准化**的方式来访问应用本身的数据库或结构化文件。这有利于统一数据访问逻辑、解耦UI和数据层(符合MVC/MVP/MVVM架构思想)、并便于以后扩展成跨应用共享(仅需添加权限和可能的URI结构调整)。
 ​c) 跨进程回调/协调
*   一些复杂的跨应用协作可以通过ContentProvider的`query()`、`insert()`等操作来触发。例如,应用A通过调用应用B的ContentProvider插入一条特定数据,可以作为一种信号通知应用B执行某项操作(不过Intent广播和Service是更直接的IPC方式)。
 ​d) 应用初始化 - Auto-initialization Providers
*   **这是非常关键且容易被问到的点!** 你在开发中可能会遇到一些第三方库(或Android Jetpack库),需要在应用启动(`Application.onCreate()`之前)就立即执行初始化。**ContentProvider 是实现这种“自动初始化”的核心机制。**
*   **原理:** 系统会在应用进程启动时,**早于**创建 `Application` 实例并调用其 `onCreate()` 方法之前,先**实例化**并**初始化**(调用 `onCreate()` 方法)清单文件中所有在`<application>`标签里声明的ContentProvider。
*   **库的做法:** 一个需要预初始化的库可以在其 SDK 中包含一个**不暴露任何实际数据 URI 的“空” ContentProvider**。1.  这个 Provider 在清单文件中声明。2.  它的唯一目的是在其 `onCreate()` 方法中执行库所需的初始化代码(如初始化单例、设置全局配置、数据库设置等)。3.  由于其 `onCreate()` 调用时机非常早(在 `Application.onCreate()` 之前),库就能确保在应用的任何代码运行前完成初始化。
*   **常见例子:***   **WorkManager (>= v2.1):** 使用 `WorkManagerInitializer` Provider 来自动初始化。*   **Firebase:** `FirebaseApp`的初始化通常通过Provider(如`FirebaseInitProvider`)完成。*   **Google Play Services SDKs:** 某些服务可能使用此机制。*   **Mockito / Robolectric 等测试框架:** 有时用于注入测试依赖。
*   **优势:** 开发者只需引入库依赖并配置清单文件(通常是自动合并的),无需在 `Application.onCreate()` 中显式调用 `initialize()` 方法,减少了初始化配置遗漏的可能性。
*   **注意:** 过度使用会略微增加启动时间,因为系统需要加载和初始化这些 Provider。应仅用于必要的库初始化。

代码示例: 

利用 ContentProvider 实现应用初始化

 自定义初始化 Provider 实现 (空内容提供者)
public class AppInitProvider extends ContentProvider {@Overridepublic boolean onCreate() {// 系统在 Application.onCreate() 前调用initializeApp();return true; // 初始化成功}private void initializeApp() {// 1. 初始化单例配置AppConfig.initialize(getContext());// 2. 设置全局异常处理Thread.setDefaultUncaughtExceptionHandler(new AppCrashHandler());// 3. 初始化网络请求库OkHttpClient client = new OkHttpClient.Builder().connectTimeout(10, TimeUnit.SECONDS).build();RetrofitManager.init(client);// 4. 初始化数据库框架Room.databaseBuilder(getContext(), AppDatabase.class, "app-db").fallbackToDestructiveMigration().build();// 5. 三方库初始化 (示例)FirebaseApp.initializeApp(getContext());}// 空方法 - 此 Provider 不提供实际数据@Nullable @Override public Cursor query(...) { return null; }@Nullable @Override public Uri insert(...) { return null; }@Override public int delete(...) { return 0; }@Override public int update(...) { return 0; }@Nullable @Override public String getType(Uri uri) { return null; }
}
 AndroidManifest.xml 配置
<application><!-- 系统将优先初始化此 Provider --><providerandroid:name=".init.AppInitProvider"android:authorities="${applicationId}.appinit"  <!-- 唯一标识符 -->android:exported="false"  <!-- 不对外暴露 -->android:initOrder="100"   <!-- 多个 Provider 时指定初始化顺序 -->tools:ignore="ExportedContentProvider"/> <!-- 常规 Application 类 --><activityandroid:name=".MainActivity".../>
</application>
 Application 类中的后续初始化
public class MyApplication extends Application {@Overridepublic void onCreate() {super.onCreate();// 此时 AppInitProvider 已完成初始化// 1. 初始化必须依赖前序操作的组件initializePushNotifications();// 2. 验证初始化状态if(!AppConfig.isInitialized()) {throw new RuntimeException("初始化失败! 请检查AppInitProvider");}}private void initializePushNotifications() {// 依赖 AppInitProvider 中初始化的网络库PushService.setHttpClient(RetrofitManager.getClient());}
}

使用此模式后,开发者只需添加依赖库,​零代码初始化三方库​ - 特别适合SDK开发者。如 Firebase 通过此机制实现完全自动初始化,无需在 Application 中调用 FirebaseApp.initializeApp()。 

Service 启动方式与实战场景详解

        Service是Android执行后台长时操作(如音乐播放、网络下载)或跨进程通信(通过AIDL)的核心组件,其生命周期由系统管理,分为启动状态(startService())和绑定状态(bindService()),8.0+系统需结合前台服务或JobScheduler规避后台限制。​

一、两种核心启动方式
1. startService() 启动方式

本质特点​:

  • 启动后服务与组件完全解耦
  • 生命周期独立运行
  • 必须显式停止​(调用 stopSelf() 或 stopService())

完整生命周期流程​:

  1. 首次启动:onCreate() → onStartCommand()
  2. 后续启动:直接触发 onStartCommand()
  3. 停止服务:onDestroy()

场景适用​:

  • 后台长期任务​:如音乐播放、定位追踪
  • 无交互任务​:如日志上传、数据同步
  • 跨应用操作​:如推送消息处理

实战代码​:

// 启动下载服务
Intent downloadIntent = new Intent(this, DownloadService.class);
downloadIntent.putExtra("file_url", "https://example.com/file.zip");
startService(downloadIntent);// 服务内部停止
public class DownloadService extends Service {@Overridepublic int onStartCommand(Intent intent, int flags, int startId) {new Thread(() -> {downloadFile(intent.getStringExtra("file_url"));stopSelf();  // 下载完成后自动停止}).start();return START_NOT_STICKY;}
}
2. bindService() 启动方式

本质特点​:

  • 建立组件与服务的绑定关系
  • 通过 IBinder 接口实现双向通信
  • 绑定解绑自动管理生命周期

完整生命周期流程​:

  1. 首次绑定:onCreate() → onBind()
  2. 通信期间:通过 Binder 接口交互
  3. 所有绑定解除:onUnbind() → onDestroy()

场景适用​:

  • 实时交互场景​:如音乐控制(播放/暂停/进度)
  • 功能模块解耦​:如支付模块服务
  • 跨进程通信(IPC)​​:不同应用间的数据交换

实战代码​:

// 绑定音乐服务
ServiceConnection conn = new ServiceConnection() {@Overridepublic void onServiceConnected(ComponentName name, IBinder binder) {MusicService.MusicBinder musicBinder = (MusicService.MusicBinder) binder;musicBinder.play();  // 直接调用服务方法}
};
bindService(new Intent(this, MusicService.class), conn, BIND_AUTO_CREATE);// 解绑服务
unbindService(conn);

Service使用场景

音乐/视频播放服务

核心实现方案​:

public class MediaPlaybackService extends Service implements MediaPlayer.OnPreparedListener, MediaPlayer.OnCompletionListener {private MediaPlayer mediaPlayer;private MediaSession mediaSession;private static final int NOTIFICATION_ID = 101;@Overridepublic void onCreate() {// 初始化媒体播放器mediaPlayer = new MediaPlayer();mediaPlayer.setAudioAttributes(new AudioAttributes.Builder().setUsage(AudioAttributes.USAGE_MEDIA).setContentType(AudioAttributes.CONTENT_TYPE_MUSIC).build());// 创建媒体会话(支持锁屏控制)mediaSession = new MediaSession(this, "MediaPlaybackService");mediaSession.setCallback(new MediaSessionCallback());mediaSession.setFlags(MediaSession.FLAG_HANDLES_MEDIA_BUTTONS | MediaSession.FLAG_HANDLES_TRANSPORT_CONTROLS);// 设置通知通道(Android 8.0+必须)createNotificationChannel();}@Overridepublic int onStartCommand(Intent intent, int flags, int startId) {String action = intent.getStringExtra("action");if("PLAY".equals(action)) {String mediaUrl = intent.getStringExtra("media_url");playMedia(mediaUrl);} else if("PAUSE".equals(action)) {pausePlayback();}return START_NOT_STICKY;}private void playMedia(String mediaUrl) {try {// 停止当前播放if (mediaPlayer.isPlaying()) {mediaPlayer.stop();}mediaPlayer.reset();mediaPlayer.setDataSource(mediaUrl);mediaPlayer.prepareAsync(); // 异步准备播放mediaPlayer.setOnPreparedListener(this);// 转换为前台服务Notification notification = buildMediaNotification("正在播放");startForeground(NOTIFICATION_ID, notification);} catch (IOException e) {Log.e("MediaService", "播放初始化失败", e);}}@Overridepublic void onPrepared(MediaPlayer mp) {mediaPlayer.start();mediaSession.setActive(true);// 更新通知显示播放状态Notification notification = buildMediaNotification("正在播放");NotificationManager nm = getSystemService(NotificationManager.class);nm.notify(NOTIFICATION_ID, notification);}// 构建媒体通知(含播放控制按钮)private Notification buildMediaNotification(String status) {// 构建通知内容(包含播放控制按钮)// ...}
}

关键技术与注意事项​:

  1. 音频焦点管理​:
AudioManager audioManager = (AudioManager) getSystemService(AUDIO_SERVICE);
int result = audioManager.requestAudioFocus(focusChangeListener, AudioManager.STREAM_MUSIC, AudioManager.AUDIOFOCUS_GAIN_TRANSIENT);
  1. 耳机事件处理​:
// 注册耳机拔出广播
IntentFilter intentFilter = new IntentFilter(AudioManager.ACTION_AUDIO_BECOMING_NOISY);
registerReceiver(noisyReceiver, intentFilter);BroadcastReceiver noisyReceiver = new BroadcastReceiver() {@Overridepublic void onReceive(Context context, Intent intent) {if(AudioManager.ACTION_AUDIO_BECOMING_NOISY.equals(intent.getAction())) {pausePlayback(); // 耳机拔出时暂停播放}}
};
  1. 通知栏控制​:
  • 通过 MediaStyle 通知样式添加播放控制按钮
  • 更新播放进度(Android 12+支持直接显示播放进度条)
  1. 播放状态持久化​:
  • 在 onDestroy() 中保存当前播放位置
  • 在 onCreate() 中恢复最后播放位置

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

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

相关文章

讲讲JVM的垃圾回收机制

垃圾回收就是对内存堆中已经死亡或者长时间没有使用的对象进行清楚或回收。 JVM 在做 GC 之前&#xff0c;会先搞清楚什么是垃圾&#xff0c;什么不是垃圾&#xff0c;通常会通过可达性分析算法来判断对象是否存活。 在确定了那些垃圾可以被回收后&#xff0c;垃圾回收器&…

QT软件外包开发费用

国内QT软件外包开发费用是一个非常复杂的问题&#xff0c;没有一个固定的价格&#xff0c;它受到多种因素的影响。以下将详细阐述影响QT软件外包开发费用的主要因素&#xff0c;并提供大致的价格区间供参考&#xff08;请注意&#xff0c;这些价格仅为估算&#xff0c;实际报价…

iOS 16 SwiftUI 优雅跳转实践:用枚举路由和 NavigationStack 实现多页面导航

引言&#xff1a;跳转的混乱与优雅的必要性 SwiftUI 给我们带来了声明式界面的全新开发体验&#xff0c;但当涉及到页面跳转时&#xff0c;许多开发者仍然面临一些“旧痛”。最初的 NavigationLink(destination:isActive:) 或 sheet(isPresented:) 等方式虽然能用&#xff0c;…

TikTok矩阵养号实战:住宅IP纯净度与设备指纹联动方案

在TikTok矩阵运营中&#xff0c;住宅IP纯净度和设备指纹管理是规避风控的核心。以下方案整合多平台风控逻辑与实战数据&#xff0c;覆盖环境隔离、行为模拟到风险防控全流程。 &#x1f527; 一、住宅IP纯净度维持策略 IP筛选与验证 静态住宅IP优选&#xff1a;核心账号绑定目标…

Elasticsearch增删改查语句

创建索引库&#xff1a;不带映射的 PUT /索引名称 {"settings": {"number_of_shards": 3, // 主分片数"number_of_replicas": 1 // 每个主分片的副本数} } 创建带映射的索引库&#xff1a; PUT /products {"settings": {"…

树莓派4B, ubuntu20.04, 安装Ros Noetic[踩坑记录]

一、安装过程 1. 硬件要求 树莓派4B (建议4GB或8GB内存版本) 至少16GB的microSD卡 2. 下载并安装Ubuntu 20.04 Ubuntu 20.04 LTS (Focal Fossa) for Raspberry Pi 使用Raspberry Pi Imager或BalenaEtcher将镜像写入microSD卡 3. 安装ROS Noetic ​# 设置sources.list s…

视觉slam--框架

视觉里程计的框架 传感器 VO--front end VO的缺点 后端--back end 后端对什么数据进行优化 利用什么数据进行优化的 后端是怎么进行优化的 回环检测 建图 建图是指构建地图的过程。 构建的地图是点云地图还是什么信息的地图&#xff1f; 建图并没有一个固定的形式和算法…

每日算法 -【Swift 算法】删除链表的倒数第 N 个结点

🧩 Swift | 删除链表的倒数第 N 个结点(含详细注释) 在刷算法题时,我们经常会遇到关于链表的题目,而「删除链表的倒数第 N 个节点」是其中一个非常经典的题。今天我们就用 Swift 来实现它,并梳理清楚整个思路。 🧠 一、题目描述 给你一个链表,删除链表的倒数第 n 个…

Truffle 和 Ganache 使用指南

Truffle 和 Ganache 使用指南 Truffle 命令详解 Truffle 是一个流行的以太坊开发框架,提供了许多有用的命令来简化智能合约的开发、测试和部署。 常用 Truffle 命令 初始化项目 truffle init 创建一个新的 Truffle 项目结构。 编译合约 truffle compile 编译项目中的 Solid…

docker进阶之架构

一、OCI 名为OCI&#xff0c;全称 Open Container Initiative/开放容器倡议,其目的主要是为了制定容器技术的通用技术标准。目前主要有两种标准&#xff1a; 1、容器运行时标准 &#xff08;runtime spec&#xff09; 2、容器镜像标准&#xff08;image spec&#xff09; …

企业产品网络安全日志6月10日-WAF资费消耗排查

发生了什么事&#xff1f; 上个的费用账单出来了&#xff0c;WAF费用有点飙升。比平时多了50%到100%。 周五的时候就已经知道这个事情了&#xff0c;但当时考虑肯定是拦截了一些恶意请求&#xff0c;所以。 反正也是上个月的事情了&#xff0c;所以周一过来复盘一下 数了下&a…

vue3+el-table 利用插槽自定义数据样式

<el-table-column label"匹配度" prop"baseMatchingLevel"><template #default"scope"><div :style"{ color: scope.row.baseMatchingLevel > 0.8 ? #00B578 : #FA5151 }">{{ scope.row.baseMatchingLevel }}&l…

[密码学实战]C语言使用SDF库构建国密算法RESTful服务(五)

[密码学实战]C语言使用SDF库构建国密算法RESTful服务(五) 引言 在现代信息安全领域,国密算法(SM系列算法)作为中国自主研发的密码算法标准,在金融、政务等领域得到广泛应用。本文将详细介绍如何使用C语言结合SDF(Security Device Function)库,构建一个提供国密算法服…

ubuntu 22.04搭建SOC开发环境

目录 AArch64位编译器命名规则 安装交叉工具链编译 安装aarch64-none-elf工具链 安装aarch64-none-linux-gnu工具链 启动板载系统 板卡启动方式 硬件连接 准备阶段 硬件连接 udev规则配置 启动流程 开发板外观图 硬件准备清单 硬件连接 SSH登录系统 设置Windows为…

push [特殊字符] present

push &#x1f19a; present 前言present和dismiss特点代码演示 push和pop特点代码演示 前言 在 iOS 开发中&#xff0c;push 和 present 是两种不同的视图控制器切换方式&#xff0c;它们有着显著的区别。 present和dismiss 特点 在当前控制器上方新建视图层级需要手动调用…

Java项目中常用的中间件及其高频问题避坑

Java项目中常用的中间件及其高频问题避坑如下: 一、常用中间件分类及作用 1. ​​消息队列中间件​​ ​​作用​​:解耦系统、异步通信、削峰填谷。​​代表产品​​: ​​Kafka​​:高吞吐量流处理,适合日志收集、实时分析。​​RocketMQ​​:金融级可靠性,支持事务消…

发布一个angular的npm包(包含多个模块)

为什么要发布npm包 根本原因时为了能够在更广泛的区域复用代码&#xff0c;比如公司不支持一般的外部网络&#xff0c;但是支持npm包的下载&#xff0c;那么就可以发布npm包&#xff0c;然后在公司内使用。 angular的npm不同吗 angular library angular 目前已经到angular20…

Web后端基础:Maven基础

课程内容&#xff1a; 初始MavenMaven概述 Maven模型Maven仓库介绍Maven安装与配置 IDEA集成Maven依赖管理单元测试 1.初始Maven 1.1介绍 Maven 是一款用于管理和构建Java项目的工具&#xff0c;是Apache旗下的一个开源项目 。 Apache 软件基金会&#xff0c;成立于1999年7月…

http协议同时传输文本和数据的新理解

首先&#xff0c;承认本人对于http协议认知确实不够&#xff0c;从来没有仔细研究这一块。 其次&#xff0c;这回确实要把自己十几年的理解更新一下了&#xff0c;主要还是自己过去没有认真研究过http协议。 这一次是这么回事&#xff0c;碰到一个情况&#xff0c;要在一次消…

《安富莱嵌入式周报》第354期: 开源36通道16bit同步数据采集卡,开源PoE以太网GPIB,分体式键盘DIY,微软WSL开源,USB转车载以太网

周报汇总地址&#xff1a;嵌入式周报 - uCOS & uCGUI & emWin & embOS & TouchGFX & ThreadX - 硬汉嵌入式论坛 - Powered by Discuz! 视频版&#xff1a; https://www.bilibili.com/video/BV1kJThzxETY/ 《安富莱嵌入式周报》第354期: 开源36通道16bit同…