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

大厂常问iOS面试题–Runloop篇

大厂常问iOS面试题–Runloop篇

一.RunLoop概念

  • RunLoop顾名思义就是可以一直循环(loop)运行(run)的机制。这种机制通常称为“消息循环机制
    NSRunLoop和CFRunLoopRef就是实现“消息循环机制”的对象。其实NSRunLoop本质是由CFRunLoopRef封装的,提供了面向对象的API,而CFRunLoopRef是一些面向过程的C函数API。两者最主要的区别在于:NSRunLoop是非线程安全的,意味着你不能用非当前线程去调用当前线程的NSRunLoop,否则会出现意想不到的错误(You should never try to call the methods of an NSRunLoop object running in a different thread)。而CFRunLoopRef是线程安全的

  • RunLoop是通过内部维护的事件循环来对事件/消息进行管理的一个对象
    它的关键点在于:如何通过事件循环来管理事件/消息,从而让线程在没有处理消息时休眠以避免资源占用、在有消息到来时立刻被唤醒

基本作用

  • 保持程序的持续运行
  • 处理APP中的各种事件(触摸,定时器,GCD异步回到主线程,runloop中block回调的处理等)
  • 节省CPU资源,提供性能,该做事的时候做事,该休息的时候休息

Runloop 和线程的关系

  • 一个线程对应一个 Runloop
  • 主线程默认就有了 Runloop,而且默认是启动的
  • 子线程的 Runloop 以懒加载的形式创建;默认是没有启动的,如果你需要更多的线程交互则可以手动配置和启动,如果线程只是去执行一个长时间的已确定的任务则不需要
  • Runloop存储在一个全局的可变字典里,线程是 key ,Runloop 是 value。

二.RunLoop的运行模式

RunLoop的运行模式共有5种,RunLoop只会运行在一个模式下,要切换模式,就要暂停当前模式,重写启动一个运行模式。model 主要作用是用来指定事件在运行循环中的优先级的。

  • kCFRunLoopDefaultMode-默认,空闲状态: App的默认运行模式,通常主线程是在这个运行模式下运行
  • UITrackingRunLoopMode-ScrollView滑动时:, 跟踪用户交互事件(用于 ScrollView 追踪触摸滑动,保证界面滑动时不受其他Mode影响)
  • kCFRunLoopCommonModes-Mode集合, 伪模式,不是一种真正的运行模式
  • UIInitializationRunLoopMode-启动时:在刚启动App时第进入的第一个Mode,启动完成后就不再使用
  • GSEventReceiveRunLoopMode-:接受系统内部事件,通常用不到

三.Runloop内部逻辑

  • 实际上 RunLoop 就是这样一个函数,其内部是一个 do-while 循环。当你调用 CFRunLoopRun() 时,线程就会一直停留在这个循环里;直到超时或被手动停止,该函数才会返回。
    在这里插入图片描述在这里插入图片描述
  • 内部逻辑:
    1.通知观察者RunLoop已经启动
    2.通知观察者即将要开始的定时器
    3.通知观察者即将即将触发 Source0 (非port) 回调
    4.触发 Source0 (非port) 回调。
    5.如果有 Source1 (基于port) 处于 ready 状态,直接处理这个 Source1
    6.通知观察者线程进入休眠状态
    7.将线程置于休眠直到任一下面的事件发生:
    某一事件到达 Source1 (基于port)
    定时器启动
    RunLoop设置的时间已经超时
    RunLoop被显示唤醒(例如手动调用CFRunLoopWakeUp)
    8.通知观察者线程将被唤醒
    9.处理未处理的事件,之后再跳回2
    10.通知观察者RunLoop结束。

四.Runloop的使用场景

1.main.m中的autoreleasePool

iOS的应用程序里面,程序启动后main.m会有一个如下的main()函数,为什么执行了main函数后,app没有自动退出,反而能一直响应用户消息呢?

int main(int argc, char * argv[]) {@autoreleasepool {return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));}
}

这是因为UIApplicationMain()函数,这个方法会为main thread设置一个NSRunLoop对象,这样就可以达到:我们的应用在无人操作的时候休息,需要让它干活的时候立马响应。
代码逻辑通常是这样的:

function loop() {initialize();do {var message = get_next_message();process_message(message);} while (message != quit);
}或使用伪代码来展示下:
int main(int argc, char * argv[]) {//程序一直运行状态while (AppIsRunning) {//睡眠状态,等待唤醒事件id whoWakesMe = SleepForWakingUp();//得到唤醒事件id event = GetEvent(whoWakesMe);//开始处理事件HandleEvent(event);}return 0;
}

这种模型通常被称作Event Loop。Event Loop在很多系统和框架里都有实现,比如 Node.js 的事件处理,比如Windows程序的消息循环,再比如iOS里的 RunLoop

关于Runloop的事件循环

  • 维护的事件循环,可以用来不断的处理消息或者事件,对他们进行管理
  • 当没有消息进行处理时,会从用户态发生到内核态的切换,由此可以用来当前线程的休眠,避免资源占用
  • 当有消息需要处理时,会发生从内核态到用户态的切换,当前的用户线程会被唤醒

用户态和内核态

  • 用户态: 应用程序一般都是运行在用户态上,用户进程,包括我们开发所使用的绝大多数API,都是针对用户层面的
  • 内核态:在内核态往往有些陷阱指令,中断,以及一些开机关机的操作,并且内核态里面的一些内容,可以对用户态中的一些线程进行调度和管理,包括进程间的通信
    在用户态调用 mach_msg_trap() 时会触发陷阱机制,切换到内核态;内核态中内核实现的 mach_msg() 函数会完成实际的工作。RunLoop 的核心就是一个 mach_msg() ,RunLoop 调用这个函数去接收消息,如果没有别人发送 port 消息过来,内核会将线程置于等待状态。例如你在模拟器里跑起一个 iOS 的 App,然后在 App 静止时点击暂停,你会看到主线程调用栈是停留在 mach_msg_trap() 这个地方。
    在这里插入图片描述
    main函数为何能保持不退出?
  • 在UIApplicationMain函数内部会启动主线程的Runloop,可以不断的接收消息,比如点击屏幕事件,滑动列表以及处理网络请求的返回等
  • 接收消息后对事件进行处理,处理完之后,就会继续等待、休眠
  • Runloop是对事件循环的一种维护机制,可以做到在有事做的时候做事,没有事情的时候会通过用户态发生到内核态的切换,避免资源占用,当前线程处于休眠的状态。

autoreleasePool 在何时被释放?

  • App启动后,苹果在主线程 RunLoop 里注册了两个 Observer,其回调都是 _wrapRunLoopWithAutoreleasePoolHandler()。
  • 第一个 Observer 监视的事件是 Entry(即将进入Loop),其回调内会调用 _objc_autoreleasePoolPush() 创建自动释放池。其 order 是 -2147483647,优先级最高,保证创建释放池发生在其他所有回调之前
  • 第二个 Observer 监视了两个事件: BeforeWaiting(准备进入休眠) 时调用_objc_autoreleasePoolPop() 和 _objc_autoreleasePoolPush() 释放旧的池并创建新池;Exit(即将退出Loop) 时调用 _objc_autoreleasePoolPop() 来释放自动释放池。这个 Observer 的 order 是 2147483647,优先级最低,保证其释放池子发生在其他所有回调之后
  • 在主线程执行的代码,通常是写在诸如事件回调、Timer回调内的。这些回调会被 RunLoop 创建好的 AutoreleasePool 环绕着,所以不会出现内存泄漏,开发者也不必显示创建 Pool 了。

2.Runloop使用场景-GCD

  • Runloop的超时时间就是通过GCD timer来控制的。GCD启动子线程,内部其实用到了runloop。GCD从子线程返回到主线程,会触发runloop的Source1事件
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(5 * NSEC_PER_SEC)), dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{/// GCD往子线程丢一个延时操作,能够执行,说明GCD内部其实用到了runloop。NSLog(@"global after %@", [NSThread currentThread]);
});

dispatch_async(main_queue, block)时,libdispatch会向主线程的runloop发送消息唤醒runloop,runloop被唤醒后会从消息中获取block,在callout函数 CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE 中执行该block任务。仅限主线程,子线程的dispatch block操作全部由libdispatch完成的。

runloopMode
dispatch_async(dispatch_get_main_queue(), …)会将block放到commonModes中执行,而CFRunLoopPerformBlock允许指定runloopMode来执行block。

能否唤醒runloop
dispatch_async(dispatch_get_main_queue(), …)会唤醒主线程的runloop,而CFRunLoopPerformBlock不会主动唤醒runloop。如runloop休眠,则CFRunLoopPerformBlock的block不能执行。可以使用CFRunLoopWakeUp来唤醒runloop。

GCD的main queue是一个串形队列
GCD的main queue是一个串形队列,这样的结果就是dispatch_async(dispatch_get_main_queue(), …)传入的block会作为一个整体,在runloop的下一次循环时执行。
请看如下代码,输出 1,3,2是我们再也熟悉不过的代码了,而后半部分为什么会 输出 4,5,6呢?且等待的1s间隔时机也不一样,分别为1…32和45…6。这里的…表示间隔

- (void)testGCDMainQueue {dispatch_async(dispatch_get_main_queue(), ^{NSLog(@"main queue task 1");dispatch_async(dispatch_get_main_queue(), ^{NSLog(@"main queue task 2");});[[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:1]];NSLog(@"main queue task 3");});/// 输出 1,3,2CFRunLoopPerformBlock(CFRunLoopGetCurrent(), kCFRunLoopCommonModes, ^{NSLog(@"main queue task 4");CFRunLoopPerformBlock(CFRunLoopGetCurrent(), kCFRunLoopCommonModes, ^{NSLog(@"main queue task 5");});[[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:1]];NSLog(@"main queue task 6");});/// 输出 4,5,6
}

3.AFNetworking 中如何运用 Runloop

  • AFURLConnectionOperation 这个类是基于 NSURLConnection 构建的,其希望能在后台线程接收 Delegate 回调。为此 AFNetworking 单独创建了一个线程,并在这个线程中启动了一个 RunLoop:
 + (void)networkRequestThreadEntryPoint:(id)__unused object {@autoreleasepool {[[NSThread currentThread] setName:@"AFNetworking"];NSRunLoop *runLoop = [NSRunLoop currentRunLoop];[runLoop addPort:[NSMachPort port] forMode:NSDefaultRunLoopMode];[runLoop run];}
}+ (NSThread *)networkRequestThread {static NSThread *_networkRequestThread = nil;static dispatch_once_t oncePredicate;dispatch_once(&oncePredicate, ^{_networkRequestThread = [[NSThread alloc] initWithTarget:self selector:@selector(networkRequestThreadEntryPoint:) object:nil];[_networkRequestThread start];});return _networkRequestThread;
}
  • RunLoop 启动前内部必须要有至少一个 Timer/Observer/Source,所以 AFNetworking 在 [runLoop run] 之前先创建了一个新的 NSMachPort 添加进去了。通常情况下,调用者需要持有这个 NSMachPort (mach_port) 并在外部线程通过这个 port 发送消息到 loop 内;但此处添加 port 只是为了让 RunLoop 不至于退出,并没有用于实际的发送消息。
 + (void)start {[self.lock lock];if ([self isCancelled]) {[self performSelector:@selector(cancelConnection) onThread:[[self class] networkRequestThread] withObject:nil waitUntilDone:NO modes:[self.runLoopModes allObjects]];} else if ([self isReady]) {self.state = AFOperationExecutingState;[self performSelector:@selector(operationDidStart) onThread:[[self class] networkRequestThread] withObject:nil waitUntilDone:NO modes:[self.runLoopModes allObjects]];}[self.lock unlock];
}
  • 当需要这个后台线程执行任务时,AFNetworking 通过调用 [NSObject performSelector:onThread:…] 将这个任务扔到了后台线程的 RunLoop 中。

4.PerformSelector 的实现原理?

  • 当调用 NSObject 的 performSelecter:afterDelay: 后,实际上其内部会创建一个 Timer 并添加到当前线程的 RunLoop 中。所以如果当前线程没有 RunLoop,则这个方法会失效。
  • 当调用 performSelector:onThread: 时,实际上其会创建一个 Timer 加到对应的线程去,同样的,如果对应线程没有 RunLoop 该方法也会失效。

5.PerformSelector:afterDelay:这个方法在子线程中是否起作用?

  • 不起作用,子线程默认没有 Runloop,也就没有 Timer。可以使用 GCD的dispatch_after来实现

6.以+ scheduledTimerWithTimeInterval…的方式触发的timer,在滑动页面上的列表时,timer会暂停回调,为什么?如何解决?
RunLoop只能运行在一种mode下,如果要换mode,当前的loop也需要停下重启成新的。利用这个机制,ScrollView滚动过程中NSDefaultRunLoopMode(kCFRunLoopDefaultMode)的mode会切换到UITrackingRunLoopMode来保证ScrollView的流畅滑动:在NSDefaultRunLoopMode模式下处理的事件会影响ScrollView的滑动。

如果我们把一个NSTimer对象以NSDefaultRunLoopMode(kCFRunLoopDefaultMode)添加到主运行循环中的时候, ScrollView滚动过程中会因为mode的切换,而导致NSTimer将不再被调度。

//1.创建Timer
//2.自动添加到当前Runloop中,默认mode为kCFRunLoopDefaultMode
//mode 为kCFRunLoopDefaultMode导致的问题:当Scrollview滑动时,会停止计时,滑动结束后继续计时。
//原因:当滑动Scrollview时。mode改变成为UITrackingRunLoopMode,而timer添加到了默认模式下 NSDefaultRunLoopMode
_timer1 = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(handle:) userInfo:_timer1 repeats:YES];

同时因为mode还是可定制的,所以:
Timer计时会被scrollView的滑动影响的问题可以通过将timer添加到NSRunLoopCommonModes(kCFRunLoopCommonModes)来解决。代码如下:

//将timer添加到NSDefaultRunLoopMode中
[NSTimer scheduledTimerWithTimeInterval:1.0target:selfselector:@selector(timerTick:)userInfo:nilrepeats:YES];
//然后再添加到NSRunLoopCommonModes里
NSTimer *timer = [NSTimer timerWithTimeInterval:1.0target:selfselector:@selector(timerTick:)userInfo:nilrepeats:YES];
[[NSRunLoop currentRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];

6.事件响应的过程?

  • 苹果注册了一个 Source1 (基于 mach port 的) 用来接收系统事件,其回调函数为 __IOHIDEventSystemClientQueueCallback()。
  • 当一个硬件事件(触摸/锁屏/摇晃等)发生后,首先由 IOKit.framework 生成一个 IOHIDEvent 事件并由 SpringBoard 接收。这个过程的详细情况可以参考这里。SpringBoard 只接收按键(锁屏/静音等),触摸,加速,接近传感器等几种 Event,随后用 mach port 转发给需要的 App 进程。随后苹果注册的那个 Source1 就会触发回调,并调用 _UIApplicationHandleEventQueue() 进行应用内部的分发。
  • _UIApplicationHandleEventQueue() 会把 IOHIDEvent 处理并包装成 UIEvent 进行处理或分发,其中包括识别 UIGesture/处理屏幕旋转/发送给 UIWindow 等。通常事件比如 UIButton 点击、touchesBegin/Move/End/Cancel 事件都是在这个回调中完成的。

7.手势识别的过程?

  • 当 _UIApplicationHandleEventQueue() 识别了一个手势时,其首先会调用 Cancel 将当前的 touchesBegin/Move/End 系列回调打断。随后系统将对应的 UIGestureRecognizer 标记为待处理。
  • 苹果注册了一个 Observer 监测 BeforeWaiting (Loop即将进入休眠) 事件,这个 Observer 的回调函数是 _UIGestureRecognizerUpdateObserver(),其内部会获取所有刚被标记为待处理的 GestureRecognizer,并执行GestureRecognizer 的回调。
  • 当有 UIGestureRecognizer 的变化(创建/销毁/状态改变)时,这个回调都会进行相应处理。

8.CADispalyTimer和Timer哪个更精确
CADisplayLink 更精确

  • iOS设备的屏幕刷新频率是固定的,CADisplayLink在正常情况下会在每次刷新结束都被调用,精确度相当高。
  • NSTimer的精确度就显得低了点,比如NSTimer的触发时间到的时候,runloop如果在阻塞状态,触发时间就会推迟到下一个runloop周期。并且 NSTimer新增了tolerance属性,让用户可以设置可以容忍的触发的时间的延迟范围。
  • CADisplayLink使用场合相对专一,适合做UI的不停重绘,比如自定义动画引擎或者视频播放的渲染。NSTimer的使用范围要广泛的多,各种需要单次或者循环定时处理的任务都可以使用。在UI相关的动画或者显示内容使用 CADisplayLink比起用NSTimer的好处就是我们不需要在格外关心屏幕的刷新频率了,因为它本身就是跟屏幕刷新同步的。

相关文章:

大厂常问iOS面试题–Runloop篇

大厂常问iOS面试题–Runloop篇 一.RunLoop概念 RunLoop顾名思义就是可以一直循环(loop)运行(run)的机制。这种机制通常称为“消息循环机制” NSRunLoop和CFRunLoopRef就是实现“消息循环机制”的对象。其实NSRunLoop本质是由CFRunLoopRef封装的,提供了面向对象的AP…...

【解决】mac报错“zsh: command not found: nvm”

问题描述: 安装nodejs时要先安装nvm,按照网上教程安装之后出现以下异常情况: 1.终端运行npm -v能查到版本,idea运行同样命令提示没找到,像是没安装一样 2.终端关闭重新打开之后,也像是没安装一样,需要重…...

MySQL同步到ES的方案选型

文章目录 1. 同步双写优点缺点实现方式 2. 异步双写优点缺点实现方式 3. 另起应用 SQL 查询写入优点缺点实现方式 4. Binlog 实时同步优点缺点实现方式 5. 应用场景 本文参考: https://www.bilibili.com/video/BV13hvZeaErr/?vd_sourceb7e4d17fd13ffa91c4da6d37c08a6c7c 最近在…...

Transformer 与 CNN的对比

Transformer 相比于 CNN 的优点主要体现在以下几个方面: Transformer 相比 CNN 的优点: 全局依赖建模能力:Transformer 的核心机制是 自注意力机制,它可以直接建模输入序列中任意两个位置之间的依赖关系,无论它们之间的距离有多远。 相比之下,CNN 更擅长处理局部信息,它…...

Maven入门到进阶:构建、依赖与插件管理详解

文章目录 一、Maven介绍1、什么是Maven2、Maven的核心功能 二、Maven核心概念1、坐标GAVP1.1、GroupId1.2、ArtifactId1.3、Version1.3.1、版本号的组成 1.4、Packaging 2、POM、父POM和超级POM2.1、POM (Project Object Model)2.1、父POM(Parent POM)2.…...

炒股VS炒游戏装备,哪个更好做

这个项目,赚个10%都是要被嫌弃的 虽然天天都在抒发自己对股市的看法,但自己自始至终也没有买进任何一支股票。之所以对这个话题感兴趣,着实是因为手上的游戏搬砖项目也是国际性买卖,跟国际形势,国际汇率挂钩&#xff0…...

AI图像处理工具:开发者高阶用法与最佳实践

引言 随着人工智能技术的迅猛发展,AI图像处理工具正日益成为开发者工作流程中不可或缺的一部分。这些工具不仅能有效处理图像,还能通过深度学习模型实现复杂的图像理解和生成任务。本文将深入探讨开发者在使用AI图像处理工具时的高阶用法,提…...

Spring Boot 2.6=>2.7 升级整理

版本变更: 1、SpringBootTest 属性源优先级:使用 SpringBootTest 注解的测试现在将命令行属性源置于测试属性源之上 在 Spring Boot 2.7 及更高版本中,对 SpringBootTest 的属性源优先级进行了调整,使得通过命令行传递的属性&am…...

Race Track Generator Ultimate:Race Track Generator(赛车场赛道看台场景创建工具)

下载:​​Unity资源商店链接资源下载链接 效果图:...

数据结构7——二叉树的顺序结构以及堆的实现

在上篇文章数据结构6——树与二叉树中,我们了解了树和二叉树的概念,接着上篇文章,在本篇文章中我们学习二叉树顺序结构的实现。 目录 1. 二叉树的顺序存储结构 2. 堆的概念及结构 1. 堆的概念 2. 堆的结构 3. 堆的实现 1. 堆节点 2. 交…...

leetcode hot100 之【LeetCode 21. 合并两个有序链表】 java实现

LeetCode 21. 合并两个有序链表 题目描述 将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接两个链表的节点组成的。 示例 1: 输入:l1 [1,2,4], l2 [1,3,4] 输出:[1,1,2,3,4,4]示例 2: 输入:l1 …...

Android Camera系列(五):Camera2

Life was like a box of chocolates, you never know what you’re gonna get. 生命就像一盒巧克力,你永远无法知道下一个是什么味道的。 Android Camera系列(一):SurfaceViewCamera Android Camera系列(二&#xff0…...

从DexMV、VideoDex、MimicPlay到SeeDo:从人类视频中学习:机器人的主流训练方法之一

前言 在此文《UMI——斯坦福刷盘机器人:从手持夹持器到动作预测Diffusion Policy(含代码解读)》的1.1节开头有提到 机器人收集训练数据一般有多种方式,比如来自人类视频的视觉演示 有的工作致力于从视频数据——例如YouTube视频中进行策略学习 即最常见…...

如何在Docker中运行Squid

测试环境 VMware Rocky Linux 9.4 实现步骤 过程:写一个Dockerfile构建Squid镜像; 再写一个启动脚本start_squid.sh,在启动脚本中配置并运行Squid。 编写Dockerfile 以rockylinux9.3做基础镜像,通过yum安装Squid, 拷贝squid.conf FROM …...

Ubuntu22.04 加入AD域

Ubuntu22.04 加入AD域 要在Ubuntu 22.04上加入Active Directory (AD) 域,你可以使用realmd和sssd服务。以下是加入AD域的步骤和示例配置: 更新系统软件包列表: sudo apt update 下载安装必要的软件包: sudo apt install realm…...

Docker 构建 Miniconda3 Python 运行环境实战指南

Docker 构建 Miniconda3 Python 运行环境实战指南 文章目录 Docker 构建 Miniconda3 Python 运行环境实战指南一 准备 environment.yml二 获取项目 pip 信息三 Dockerfile 编写四 构建多平台镜像1 准备组件2 构建镜像3 导出镜像4 导入镜像 五 注意事项 本文详细介绍了如何通过 …...

029 elasticsearch文档管理(ElasticsearchRepository、ElasticsearchRestTemplate)

文章目录 BlogRepository.javaBlogRepositoryTest.javaBulkTest.java 文档的管理 ElasticSearchRepository接口 使用方法: 创建一个接口,继承于ElasticSearchRepository,指定使用的Entity类及对应主键数据类型 Springboot自动扫描接口并创建代…...

【Flutter】Dart:Isolate

在 Dart 和 Flutter 中,所有的代码默认都运行在单一的线程(即主线程)上,这个线程也叫做 UI 线程。当进行耗时操作(如复杂计算或网络请求)时,如果不使用多线程处理,主线程会被阻塞&am…...

​微信小程序 页面间传递数据

在小程序中,给页面传递参数通常有以下几种方法: 通过URL传递参数: 在小程序中,可以在页面的路径后面添加参数,然后在页面的 onLoad 函数中获取这些参数。 // 在app.json中配置页面路径 "pages": [{"pat…...

前端_005_Nodejs

文章目录 npm包管理器cjs和mjsYarn包管理器 1.Node.js 是js的一个运行环境,从nodejs诞生后js代码不局限于只在浏览器中执行,此外还能再nodejs里写服务端,用js可以前后端全栈开发 2.Node.js不跟浏览器一样默认含有document,window对象&#xf…...

SpringCache缓存介绍

1.为什么需要缓存 ​ 前台请求,后台先从缓存中取数据,取到直接返回结果,取不到时从数据库中取,数据库取到更新缓存,并返回结果,数据库也没取到,那直接返回空结果: 使用缓存是一个很…...

python实战(一)——iris鸢尾花数据集分类

一、任务背景 本文是python实战系列专栏的第一篇文章,我们将从分类开始由浅入深逐步学习如何使用python完成常规的机器学习/深度学习任务。iris数据集是经典的机器学习入门数据集,许多分类任务教程都会以这个数据集作为示例,它的数据量是150条…...

k8s-对命名空间资源配额

对k8s命名空间限制的方法有很多种,今天来演示一下很常用的一种 用的k8s对象就是ResourceQuota 一:创建命名空间 kubectl create ns test #namespace命名空间可以简写成ns 二: 对命名空间进行限制 创建resourcequota vim resourcequ…...

Failed to connect to github.com port 443

git push无法连接443端口 **问题1****方法一:取消代理设置**git命令 其他解决方案1. **设置 Git 使用 HTTP 而不是 HTTPS**2. **检查证书**3. **配置 Git 忽略 SSL 验证(不推荐)**4. **检查代理设置** 问题1 Failed to connect to github.com…...

【设计模式系列】简单工厂模式

一、什么是简单工厂模式 简单工厂模式(Simple Factory Pattern)是一种设计模式,其中包含一个工厂类,根据传入的参数不同,返回不同类的实例。这个工厂类封装了对象的创建逻辑,使得客户端代码可以从直接创建…...

给定一个正整数n随机生成n个字节即生成2n个十六进制数将其组成字符串返回secrets.token_hex(n)

【小白从小学Python、C、Java】 【考研初试复试毕业设计】 【Python基础AI数据分析】 给定一个正整数n 随机生成n个字节 即生成2n个十六进制数 将其组成字符串返回 secrets.token_hex(n) [太阳]选择题 根据题目代码,执行的结果错误的是? import secrets …...

[Gtk] 工程

MediaPlayer 可执行文件工程 结构 . ├── BUILD ├── ButtonHelper.cpp ├── ButtonHelper.h ├── CMakeLists.txt ├── DrawingAreaHelper.cpp ├── DrawingAreaHelper.h ├── layout.ui └── main.cpp CMakeLists.txt # 1) cmake basic cmake_minimum_r…...

基于Multisim的汽车尾灯控制电路设计与仿真

假设汽车尾部左右量测各有3个指示灯(用发光二极管模拟)1. 汽车正常运行时指示灯全灭;2.右转弯时,右侧3个指示灯按右循环顺序点亮;.3. 左转弯时,左侧3个指示灯按左循环顺序点亮;4.临时刹车时所有…...

Leetcode 3326. Minimum Division Operations to Make Array Non Decreasing

Leetcode 3326. Minimum Division Operations to Make Array Non Decreasing 1. 解题思路2. 代码实现 题目链接:3326. Minimum Division Operations to Make Array Non Decreasing 1. 解题思路 这一题的话就是要看出来题中给出的operation的本质事实上就是将任意…...

redo文件误删除后通过逻辑备份进行恢复

问题描述 开发同事让在一个服务器上查找下先前库的备份文件是否存在,如果存在进行下恢复。翻了服务器发现备份文件存在,多愁了一眼竟翻到了该备份文件于2024.6.17日恢复过的日志,赶紧和开发沟通说2024.6.17号已经恢复过了为啥还要恢复&#x…...