【操作系统】FCFS、SJF、HRRN、RR、EDF、LLF调度算法及python实现代码

文章目录

一、先来先服务调度算法(FCFS)

二、短作业优先调度算法(SJF)

三、高响应比优先调度算法(HRRN)

四、轮转调度算法(RR)

五、最早截至时间优先算法(EDF)

六、最低松弛度优先算法(LLF)

相关时间计算
周转时间 = 作业完成时刻 - 作业到达时刻
等待时间 = 周转时间 - 运行时间
带权周转时间 = 周转时间 / 服务时间
平均周转时间 = 作业周转时间之和 / 作业个数
平均带权周转时间 = 带权周转时间之和 / 作业个数
服务时间:作业的运行时间

一、先来先服务调度算法(FCFS)

如果早就绪的进程排在就绪队列的前面,迟就绪的进程排在就绪队列的后面,那么先来先服务(FCFS: first come first service)总是把当前处于就绪队列之首的那个进程调度到运行状态。也就说,它只考虑进程进入就绪队列的先后,而不考虑它的下一个CPU周期的长短及其他因素。

先来先服务的调度算法是最简单的调度算法,既可以用于作业调度 ,也可以用于程序调度,当作业调度中采用该算法时,系统将按照作业到达的先后次序来进行调度,优先从后备队列中,选择一个或多个位于队列头部的作业,把他们调入内存,分配所需资源、创建进程,然后放入“就绪队列”,直到该进程运行到完成或发生某事件堵塞后,进程调度程序才将处理机分配给其他进程。

实现代码:

avg_turnaround_time = 0.0
aqtt = 0.0

class Progress:
    def __init__(self):
        self.pro_name = ""
        self.arrive_time = 0
        self.service_time = 0
        self.finish_time = 0
        self.cycling_time = 0
        self.float_wi = 0.0

courses = [Progress() for _ in range(80)]

def health_examine(course_num):
    return

def progress_num(course_num):
    i = 0
    for i in range(course_num):
        print("Enter information for process %d" % (i + 1))
        courses[i].pro_name = input("Enter process name: ") #进程名
        courses[i].arrive_time = int(input("Enter arrival time: ")) #到达时间
        courses[i].service_time = int(input("Enter service time: ")) #服务时间
    return

def finish_time(course_num):
    i = 0
    if courses[0].arrive_time != 0:
        courses[0].finish_time = courses[0].arrive_time + courses[0].service_time
    courses[0].finish_time = courses[0].service_time
    for i in range(1, course_num):
        if courses[i - 1].finish_time >= courses[i].arrive_time:
            courses[i].finish_time = courses[i - 1].finish_time + courses[i].service_time
        else:
            courses[i].finish_time = courses[i].arrive_time + courses[i].service_time
    return

def cycling_time(course_num): #周转时间
    for i in range(course_num):
        courses[i].cycling_time = courses[i].finish_time - courses[i].arrive_time
    return

def float_wi(course_num): #带权周转时间
    for i in range(course_num):
        courses[i].float_wi = float(courses[i].cycling_time) / courses[i].service_time
    return

def avg_turnaround_time(course_num): #平均周转时间
    sum_turnaround_time = 0
    for i in range(course_num):
        sum_turnaround_time += courses[i].cycling_time
    global avg_turnaround_time
    avg_turnaround_time = sum_turnaround_time / course_num
    return

def aqtt(course_num): #平均带权周转时间
    sum_float_wi = 0
    for i in range(course_num):
        sum_float_wi += courses[i].float_wi
    global aqtt
    aqtt = sum_float_wi / course_num
    return

def print_fifo(course_num):
    print("Process information:")
    print("Process\tArrival Time\tService Time\tFinish Time\tTurnaround Time\tWeighted Turnaround")
    for i in range(course_num):
        print("%s\t%d\t%d\t%d\t%d\t%.2f" % (courses[i].pro_name, courses[i].arrive_time, courses[i].service_time, courses[i].finish_time, courses[i].cycling_time, courses[i].float_wi))
    print("Average Turnaround Time\tAverage Weighted Turnaround Time")
    print("%.2f\t%.2f" % (avg_turnaround_time, aqtt))
    return

def main():
    course_num = 5
    course_num = int(input("Enter the number of processes: "))
    progress_num(course_num)
    finish_time(course_num)
    cycling_time(course_num)
    float_wi(course_num)
    avg_turnaround_time(course_num)
    aqtt(course_num)
    print_fifo(course_num)

if __name__ == "__main__":
    main()

输出信息:

Enter the number of processes: 3
Enter information for process 1
Enter process name: p1
Enter arrival time: 0
Enter service time: 5
Enter information for process 2
Enter process name: p2
Enter arrival time: 2
Enter service time: 1
Enter information for process 3
Enter process name: p3
Enter arrival time: 3
Enter service time: 4
Process information:
Process	Arrival Time	Service Time	Finish Time	Turnaround Time	Weighted Turnaround
p1	0	5	5	5	1.00
p2	2	1	6	4	4.00
p3	3	4	10	7	1.75
Average Turnaround Time	Average Weighted Turnaround Time
5.33	2.25

进程已结束,退出代码0

二、短作业优先调度算法(SJF)

算法思想是追求更少的平均时间,最少的平均周转时间,最少的平均平均带权周转时间算法规则是最短的作业/进程优先得到服务(所谓“最短”,是指要求服务时间最短)。即可用于作业调度,也可用于进程调度。用于进程调度时称为“短进程优先(SPF,Shortest Process First)算法”。 SJF和SPF都是非抢占式的算法。但是也有抢占式的版本----最短剩余时间优先算法。(SRTN,Shortest Remaining Time Next)

  • 优点: "最短的"平均等待时间、平均周转时间
  • 缺点: 不公平。对短作业有利,对长作业不利。可能产生==饥饿现象。==另外,进程/作业的运行时间都是由用户提供的,并不一定真实,不一定能做到真正的短作业优先。
  • 饥饿: 会导致饥饿

实现代码(非抢占式):


N = 5
class PCB:
    def __init__(self):
        self.process_name = ""
        self.arrive_time = 0
        self.service_time = 0
        self.complete_time = 0


PCB_list = [PCB() for _ in range(N + 1)]

def sjf(n):

    for i in range(1, n + 1):
        print("请输入第", i, "进程名字: ", end="")
        PCB_list[i].process_name = input()
        print("请输入到达时间: ", end="")
        PCB_list[i].arrive_time = int(input())
        print("请输入服务时间: ", end="")
        PCB_list[i].service_time = int(input())

    temp = 1
    for i in range(2, n + 1):
        if PCB_list[temp].arrive_time > PCB_list[i].arrive_time or (
                PCB_list[temp].arrive_time == PCB_list[i].arrive_time and PCB_list[temp].service_time > PCB_list[
            i].service_time):
            temp = i

    PCB_list[0] = PCB_list[temp]
    PCB_list[temp] = PCB_list[1]
    PCB_list[1] = PCB_list[0]

    sum = 1
    PCB_list[1].complete_time = PCB_list[1].arrive_time + PCB_list[1].service_time
    time = PCB_list[1].complete_time
    print("\n第1次进程调度运行的进程为 :   ", PCB_list[1].process_name)

    nextprocess = 0
    while True:
        if sum >= n:
            break

        nextprocess = i = sum + 1

        while i <= n:
            if time >= PCB_list[i].arrive_time and PCB_list[i].service_time < PCB_list[nextprocess].service_time:
                nextprocess = i
            i += 1

        PCB_list[0] = PCB_list[nextprocess]
        PCB_list[nextprocess] = PCB_list[sum + 1]
        PCB_list[sum + 1] = PCB_list[0]
        nextprocess = sum + 1

        if PCB_list[nextprocess].arrive_time > time:
            time = PCB_list[nextprocess].arrive_time

        time += PCB_list[nextprocess].service_time
        PCB_list[nextprocess].complete_time = time
        sum += 1
        print("第", sum, "次进程调度运行的进程为 :   ", PCB_list[nextprocess].process_name)

    return 0


def print_info():
    i = 1
    round_time = [0] * (N + 1)
    force_round_time = [0] * (N + 1)
    sum_time = 0

    print("\n 进程   到达时间    服务时间     完成时间     周转时间   带权周转时间")

    while i < N + 1:
        round_time[i] = PCB_list[i].complete_time - PCB_list[i].arrive_time
        force_round_time[i] = round_time[i] / PCB_list[i].service_time
        print(PCB_list[i].process_name, "\t  ", PCB_list[i].arrive_time, "\t    ", PCB_list[i].service_time, "\t\t ",
              PCB_list[i].complete_time, "\t        ", round_time[i], "\t     ", force_round_time[i])
        sum_time += force_round_time[i]
        i += 1

    print("\n\n系统平均带权周转时间: ", (sum_time / (i - 1)))


if __name__ == "__main__":
    print("\t\t短作业优先调度算法")
    sjf(N)
    print_info()

输出信息:

请输入第 1 进程名字: p1
请输入到达时间: 0
请输入服务时间: 5
请输入第 2 进程名字: p2
请输入到达时间: 2
请输入服务时间: 1
请输入第 3 进程名字: p3
请输入到达时间: 3
请输入服务时间: 4
请输入第 4 进程名字: p4
请输入到达时间: 5
请输入服务时间: 6
请输入第 5 进程名字: p5
请输入到达时间: 7
请输入服务时间: 8

第1次进程调度运行的进程为 :    p1
第 2 次进程调度运行的进程为 :    p2
第 3 次进程调度运行的进程为 :    p3
第 4 次进程调度运行的进程为 :    p4
第 5 次进程调度运行的进程为 :    p5

 进程   到达时间    服务时间     完成时间     周转时间   带权周转时间
p1 	   0 	     5 		  5 	         5 	      1.0
p2 	   2 	     1 		  6 	         4 	      4.0
p3 	   3 	     4 		  10 	         7 	      1.75
p4 	   5 	     6 		  16 	         11 	      1.8333333333333333
p5 	   7 	     8 		  24 	         17 	      2.125


系统平均带权周转时间:  2.1416666666666666

进程已结束,退出代码0

三、高响应比优先调度算法(HRRN)

高响应比优先算法考虑了作业的等待时间,又考虑了作业运行时间的调度算法,因此照顾了短作业,又不致使长作业等待时间过长,从而改善了处理机的调度的性能。这个算法相当于给与每个作业一个动态的优先级,这个优先级是随着时间变化的变化的,等待时间不断地增加,这将让长作业的优先级在等待期间不断地增大,等待足够的时间,必然会得到处理机。

1、该优先级的变化规则可以描述为:

2、规律:

  • 作业的等待时间相同,则要求服务的越短,优先级越高,类似于SJF算法。
  • 当要求服务的时间相同时,等得越久优先级越高,类似于FCFS算法。
  • 对于长作业来说,该算法实现了较好的折中。

3、优点:算法折中,长短作业兼顾,时间分配较为均匀。

4、缺点:每次计算响应比都会花费一定时间,即时间开销,其性能比SJF算法略差。

实现代码:

class JobControl:
    def __init__(self, Id, arr_time, ser_time):
        self.Id = Id  # 序号
        self.arr_time = arr_time  # 到达时间
        self.ser_time = ser_time  # 服务时间
        self.Rp = 0
        self.state = False


jobs = []
n = 0  # 进程个数
new_time = 0

if __name__ == "__main__":
    print("请输入进程总数:")
    n = int(input())
    min_arr_time = float('inf')

    for i in range(n):
        print(f"请输入{i+1}号进程的到达时间和服务时间:")
        Id = i
        arr_time, ser_time = map(float, input().split())
        jobs.append(JobControl(Id, arr_time, ser_time))

        if arr_time < min_arr_time:
            min_arr_time = arr_time

    new_time = min_arr_time
    print("进程执行的顺序:")
    m = 0

    while m != n:
        max_Rp = -1
        max_id = 0

        for i in range(n):
            if not jobs[i].state and jobs[i].arr_time <= new_time:
                jobs[i].Rp = ((new_time - jobs[i].arr_time) + jobs[i].ser_time) / jobs[i].ser_time
                if max_Rp < jobs[i].Rp:
                    max_Rp = jobs[i].Rp
                    max_id = i

        jobs[max_id].state = True
        new_time += jobs[max_id].ser_time
        print(max_id+1, end=" ")
        m += 1

    print("\n进程的完成时间:", new_time)

输出信息:

请输入进程总数:
4
请输入1号进程的到达时间和服务时间:
0 20
请输入2号进程的到达时间和服务时间:
5 15
请输入3号进程的到达时间和服务时间:
1 5
请输入4号进程的到达时间和服务时间:
15 10
进程执行的顺序:
1 3 2 4 
进程的完成时间: 50.0

进程已结束,退出代码0

四、轮转调度算法(RR)

在轮转(RR)法中,系统将所有的就绪进程按FCFS策略排成一个就绪队列。系统可设置每隔一定时间(如30 ms)便产生一次中断,去激活进程调度程序进行调度,把CPU分配给队首进程,并令其执行一个时间片。当它运行完毕后,又把处理机分配给就绪队列中新的队首进程,也让它执行一个时间片。

在RR调度算法中,应在何时进行进程的切换,可分为两种情况:
① 若一个时间片尚未用完,正在运行的进程便已经完成,就立即激活调度程序,将它从就绪队列中删除,再调度就绪队列中队首的进程运行,并启动一个新的时间片。
② 在一个时间片用完时,计时器中断处理程序被激活。如果进程尚未运行完毕,调度程序将把它送往就绪队列的末尾。

基于时间片为1的进程运行情况:

实现代码:

class JC:
    def __init__(self):
        self.Id = 0
        self.arr_time = 0.0
        self.ser_time = 0.0
        self.state = False
        self.arr_s = False


jc = [JC() for _ in range(10)]
n = 0
new_time = 0.0
rr = 0.0

if __name__ == "__main__":
    min_val = 0xFFF
    print("请输入进程的总数:")
    n = int(input())
    print("请依次输入各进程的信息,按到达时间排列:")
    for i in range(n):
        print(f"请输入{i+1}号进程的到达时间和服务时间:")
        jc[i].Id = i
        jc[i].arr_time, jc[i].ser_time = map(float, input().split())

    print("请输入时间片:")
    rr = float(input())

    m = 0
    print("进程完成执行的顺序:")
    jc[0].arr_s = True
    arr_sum = 1
    ary = [-1] * 100
    ary[0] = 0
    k = 1
    q = 0

    while True:
        if jc[ary[q]].arr_s and not jc[ary[q]].state:
            if jc[ary[q]].ser_time <= rr:
                new_time += jc[ary[q]].ser_time
                jc[ary[q]].state = True
                jc[ary[q]].ser_time = 0
                print(jc[ary[q]].Id+1, end=' ')
                m += 1
                q += 1
                if arr_sum < n:
                    for i in range(arr_sum, n):
                        if jc[i].arr_time <= new_time and not jc[i].arr_s:
                            jc[i].arr_s = True
                            ary[k] = i
                            k += 1

            else:
                new_time += rr
                jc[ary[q]].ser_time -= rr
                if arr_sum < n:
                    for i in range(arr_sum, n):
                        if jc[i].arr_time <= new_time and not jc[i].arr_s:
                            jc[i].arr_s = True
                            ary[k] = i
                            k += 1
                ary[k] = ary[q]
                k += 1
                q += 1

        if m == n:
            break

    print(f"进程的完成时间: {new_time}")

输出信息:

请输入进程的总数:
5
请依次输入各进程的信息,按到达时间排列:
请输入1号进程的到达时间和服务时间:
0 4
请输入2号进程的到达时间和服务时间:
1 3
请输入3号进程的到达时间和服务时间:
2 4
请输入4号进程的到达时间和服务时间:
3 2
请输入5号进程的到达时间和服务时间:
4 4
请输入时间片:
1
进程完成执行的顺序:
2 4 1 3 5 进程的完成时间: 17.0

五、最早截至时间优先算法(EDF)

最早截止期限优先(EDF)调度根据截止期限动态分配优先级。截止期限越早,优先级越高;截止期限越晚,优先级越低。根据 EDF 策略,当一个进程可运行时,它应向系统公布截止期限要求。优先级可能需要进行调整,以便反映新可运行进程的截止期限。注意单调速率调度与 EDF 调度的不同,前者的优先级是固定的。 

在每一个新的就绪状态,调度器都是从那些已就绪但还没有完全处理完毕的任务中选择最早截止时间的任务,并将执行该任务所需的资源分配给它。在有新任务到来时,调度器必须立即计算EDF,排出新的定序,即正在运行的任务被剥夺,并且按照新任务的截止时间决定是否调度该新任务。如果新任务的最后期限早于被中断的当前任务,就立即处理新任务。按照EDF算法,被中断任务的处理将在稍后继续进行。
该算法的思想是从两个任务中选择截至时间最早的任务,把它暂作为当前处理任务,再判断该任务是否在当前周期内,若不在当前周期内,就让另一任务暂作当前处理任务,若该任务也不在当前周期内,就让CPU空跑到最靠近的下一个截至时间的开始,若有任务在该周期内,就判断该任务的剩余时间是否小于当前截至时间与当前时间的差,若小于,则让该任务运行到结束,否则,就让该任务运行到该周期的截止时间,就立即抢回处理器,再判断紧接着的最早截至时间,并把处理器给它,做法同上,如此反复执行。

非抢占式调度任务用于非周期实时任务:

抢占式调度任务用于周期性实时任务: 

 

实现代码(抢占式):

class JobControl:
    def __init__(self, Id, arr_time, ser_time, end_time):
        self.Id = Id
        self.arr_time = arr_time
        self.ser_time = ser_time
        self.end_time = end_time
        self.edf = -1
        self.state = False

n = 7
jc = [JobControl(0, 0, 0, 0) for _ in range(10)]
new_time = 0

print("进程总数为:" + str(n))

for i in range(5):
    jc[i].Id = i
    jc[i].arr_time = i * 20
    jc[i].ser_time = 10
    jc[i].end_time = (i + 1) * 20

for i in range(5, 7):
    jc[i].Id = i
    jc[i].arr_time = (i - 5) * 50
    jc[i].ser_time = 25
    jc[i].end_time = (i - 5 + 1) * 50

m = 0
min_val = 0xFFF
min_id = 0

print("进程完成执行的顺序:")
while True:
    for i in range(7):
        if jc[i].arr_time <= new_time and not jc[i].state and jc[i].edf == -1:
            if jc[i].end_time < min_val:
                min_val = jc[i].end_time
                min_id = jc[i].Id
                jc[i].edf = 0

    jc[min_id].ser_time -= 5
    new_time += 5

    if jc[min_id].ser_time == 0:
        jc[min_id].state = True
        print(min_id+1, end=" ")
        m += 1
        min_val = 0xFFF

    for i in range(7):
        if jc[i].arr_time <= new_time and not jc[i].state:
            if jc[i].end_time < min_val:
                min_val = jc[i].end_time
                min_id = jc[i].Id

    if m == n:
        break

print()
print("进程的完成执行时间:" + str(new_time))

输出信息:

进程总数为:7
进程完成执行的顺序:
1 2 6 3 4 7 5 
进程的完成执行时间:100

六、最低松弛度优先算法(LLF)

最低松弛度优先算法(Lowest Slack Time First,简称LLF)是一种动态优先级调度算法,它根据进程的剩余处理时间和截止时间来确定优先级,以确保系统能够尽可能快地完成最紧急的任务。在LLF算法中,每个进程都有一个松弛度(Slack Time),表示当前时间到达截止时间的剩余时间。

LLF算法的核心思想是选择具有最低松弛度的进程作为下一个执行的任务,以最大限度地降低任务的响应时间和延迟。根据任务的紧急(或松弛)度,来确定任务的优先级,紧急度越高,优先级越高。要求系统中有一个按松弛度排序的实时任务就绪队列,松弛度最低的任务排在任务最前面。

  • 主要用于可抢占调度方式中
  • 松弛度=必须完成的时间 - 其本身的运行时间 - 当前时间
  • 抢占时机:松弛度为零时。
  • 最小响应时间: LLF算法优先执行剩余处理时间最短、截止时间最近的任务,因此能够最小化任务的响应时间。
  • 高实时性: LLF算法适用于对任务响应时间有严格要求的实时系统,能够确保紧急任务及时完成。
  • 负载均衡: LLF算法能够在各个任务之间实现相对均衡的负载分配,提高系统整体性能。

实现代码:

class Job:
    def __init__(self):
        self.Id = 0
        self.arr_time = 0.0
        self.ser_time = 0.0
        self.end_time = 0.0
        self.llf = -1
        self.state = False

n = 6
jc = [Job() for _ in range(10)]
new_time = 0


print("进程总数:", n)

for i in range(4):
    jc[i].Id = i
    jc[i].arr_time = i * 20
    jc[i].ser_time = 10
    jc[i].end_time = (i + 1) * 20

for i in range(4, 6):
    jc[i].Id = i
    jc[i].arr_time = (i - 4) * 50
    jc[i].ser_time = 25
    jc[i].end_time = (i - 4 + 1) * 50

m = 0
min_val = float('inf')
min_id = 0

print("进程完成执行的顺序:")
while True:
    for i in range(6):
        if jc[i].arr_time <= new_time and not jc[i].state and jc[i].llf == -1:
            jc[i].llf = jc[i].end_time - jc[i].ser_time - new_time
            if jc[i].llf < min_val:
                min_val = jc[i].llf
                min_id = jc[i].Id

    jc[min_id].ser_time -= 5
    new_time += 5

    if jc[min_id].ser_time == 0:
        jc[min_id].state = True
        print(min_id+1, end=" ")
        m += 1
        min_val = float('inf')

    for i in range(6):
        if jc[i].arr_time <= new_time and not jc[i].state:
            jc[i].llf = jc[i].end_time - jc[i].ser_time - new_time
            if jc[i].llf < min_val:
                min_val = jc[i].llf
                min_id = jc[i].Id

    if m == n:
        break

print("\n")
print("进程的完成执行时间:", new_time)

输出信息:

进程总数: 6
进程完成执行的顺序:
1 2 5 3 4 6 

进程的完成执行时间: 90

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

单V及多V感知在自动驾驶在恶劣环境条件下的感知提升方案

单V及多V感知在自动驾驶在恶劣环境条件下的感知提升方案 附赠自动驾驶学习资料和量产经验&#xff1a;链接 自动驾驶中的视觉感知是车辆在不同交通条件下安全、可持续地行驶的关键部分。然而&#xff0c;在大雨和雾霾等恶劣天气下&#xff0c;视觉感知性能受到多种降级效应的极…

EasyCVR视频汇聚平台海康Ehome2.0与5.0设备接入时的配置区别

安防视频监控/视频集中存储/云存储/磁盘阵列EasyCVR平台可拓展性强、视频能力灵活、部署轻快&#xff0c;可支持的主流标准协议有国标GB28181、RTSP/Onvif、RTMP等&#xff0c;以及支持厂家私有协议与SDK接入&#xff0c;包括海康Ehome、海大宇等设备的SDK等。平台既具备传统安…

excel中文本列显示e+17这样的科学计数法如何处理

我的excel中文本列显示e17这样的科学计数法 然后右键&#xff0c;设置单元格格式&#xff0c;为特殊&#xff0c;邮政编码&#xff0c;点确定即可 最后效果如下

JavaScript_与html结合方式

JavaScript_语法 ECMAScript&#xff1a;客户端脚本语言的标准 1.基本语法 1.1 与html结合方式&#xff08;2种&#xff09; 1. 内部JS 定义<script>,标签体内容就是js代码 2. 外部JS 定义<script>,通过src属性引入外部的 js文件 注意&#xff1a; 1.<script>…

Html提高——视频标签音频标签及其相关属性

HTML5 在不使用插件的情况下&#xff0c;也可以原生的支持音视频格式文件的播放&#xff0c;当然&#xff0c;支持的格式是有限的。 1、video标签 1.1、video标签的语法 <video src"文件地址" controls"controls"></video> video标签的内部…

maven-下载慢问题

1、使用统一的maven组件&#xff0c;将maven安装到系统中&#xff0c;maven安装请自行百度 2、idea中配置如图 3、编辑settings.xml&#xff0c;直接将下面代码粘贴进去即可&#xff0c;原理是换到阿里服务器 <?xml version"1.0" encoding"UTF-8"?&…

C++取经之路(其三)——内联函数,auto关键字

目录 内联函数&#xff1a; 内联函数注意点&#xff1a; auto&#xff1a; atto注意点&#xff1a; 内联函数&#xff1a; 概念&#xff1a; 以inline修饰的函数叫做内联函数&#xff0c;编译时C编译器会在调用内联函数的地方展开&#xff0c;没有函数调 用建立栈帧的开销…

【单片机 5.3开关检测】

文章目录 前言一、5.3开关检测1.1没按键按下的1.2有按键按下的 二、改进1.改进 三、独立键盘3.1为什么要取反3.2 实用的按键 总结 前言 提示&#xff1a;这里可以添加本文要记录的大概内容&#xff1a; 课程需要&#xff1a; 提示&#xff1a;以下是本篇文章正文内容&#xf…

【C语言】【Leetcode】409. 最长回文串

文章目录 题目思路代码呈现 题目 链接: link 思路 关于这道题&#xff0c;比起一般的回文数题&#xff0c;这题的区别的在给定的字符中任意排序直至形成一个最长的回文数&#xff0c;而且题目中跟我们提到&#xff0c;这里的字符串中只会出现字母&#xff0c;我们只需区分大…

EPO平台:赋能离散型制造,实现智慧化管理

在离散型制造行业&#xff0c;如电梯、汽车配件、轴承制造、家电制造等领域&#xff0c;随着市场竞争的加剧和企业规模的不断扩大&#xff0c;传统的管理方式已经逐渐无法满足企业的需求。数据采集复杂、库存积压、工艺配置混乱、订单交付困难等问题成为制约企业发展的瓶颈。为…

前端-css-03

1.盒子模型 <!DOCTYPE html> <html lang"zh-CN"> <head><meta charset"UTF-8"><meta http-equiv"X-UA-Compatible" content"IEedge"><meta name"viewport" content"widthdevice-wid…

Spire.PDF for .NET【文档操作】演示:合并 PDF 文件并添加页码

搜索了这么多有关 PDF 合并的信息后&#xff0c;很容易发现&#xff0c;无论您在线合并 PDF 文件还是使用 C#/VB.NET 来实现此任务&#xff0c;您都无法逃避对 PDF 文件安全等一些重要问题的担忧&#xff0c;因此需要花费多少时间或者合并后的文件是否支持打印页码等等。不过&a…

【机器学习300问】60、图像分类任务中,训练数据不足会带来什么问题?如何缓解图像数据不足带来的问题?

在机器学习中&#xff0c;绝大部分模型都需要大量的数据进行训练和学习&#xff08;包括有监督学习和无监督学习&#xff09;&#xff0c;然而在实际应用中经常会遇到训练数据不足的问题。就比如图像分类这样的计算机视觉任务&#xff0c;确实依赖于大规模且多样化的训练数据以…

Reversing Linked List

Given a constant K and a singly linked list L, you are supposed to reverse the links of every K elements on L. For example, given L being 1→2→3→4→5→6, if K3, then you must output 3→2→1→6→5→4; if K4, you must output 4→3→2→1→5→6. Input Specifi…

数据可视化高级技术(Echarts)

目录 &#xff08;一&#xff09;数据可视化概念及Echarts基础知识 数据可视化的好处&#xff1a; 数据可视化的目标 数据可视化的基本流程 &#xff08;二&#xff09;数据图表 类别比较图表&#xff1a; 数据关系图表&#xff1a; 数据分布图表&#xff1a; 时间序列…

VScode使用Prettier格式化代码

1、安装Prettier插件 2、扩展设置 3、设置.prettierrc.json配置文件路径 4、.prettierrc 配置文件 .prettierrc.json 是 Prettier 格式化工具的配置文件&#xff0c;用于指定代码格式化的规则和风格。下面是一些可能的配置选项&#xff0c;请自行选择&#xff1a; {"prin…

vim copilot插件安装使用

copilot简介 在使用不熟悉的开发语言或函数库进行开发工作时&#xff0c;虽然可以通过阅读开发文档或示例代码的方式学习开发&#xff0c;但这种方式学习成本较高、效率较低&#xff0c;且后续不一定会用上。 GitHub Copilot是一个由GitHub开发的机器学习工具&#xff0c;可以…

HarmonyOS 应用开发之通过关系型数据库实现数据持久化

场景介绍 关系型数据库基于SQLite组件&#xff0c;适用于存储包含复杂关系数据的场景&#xff0c;比如一个班级的学生信息&#xff0c;需要包括姓名、学号、各科成绩等&#xff0c;又或者公司的雇员信息&#xff0c;需要包括姓名、工号、职位等&#xff0c;由于数据之间有较强…

xshell7连接ubuntu18.04

&#x1f3a1;导航小助手&#x1f3a1; 1.查看ubuntu IP2.开启openssh-server3.静态IP设置4.Xshell连接 1.查看ubuntu IP 输入下面命令查看IP ifconfig -a可以看到网卡是ens33&#xff0c;IP为192.168.3.180。 2.开启openssh-server 1、执行下句&#xff0c;下载SSH服务 s…

标定系列——预备知识-OpenCV中相机标定相关函数(十一)

标定系列——预备知识-OpenCV中相机标定相关函数&#xff08;十一&#xff09; 说明记录 说明 对相机标定过程中使用的函数进行记录 记录