计算机操作系统—调度算法

# 有些计算会有问题谅解

经典进程的同步问题

1、吃水果

桌上有一只盘子,每次只能放入一只水果,爸爸专向盘子中放苹果(apple),妈妈专向盘子中放桔子(orange),一个儿子专等吃盘子中的桔子,一个女儿专等吃盘子中的苹果。只要盘子中空则爸爸或妈妈可向盘子中放一只水果,仅当盘中有自己需要的水果时,儿子或女儿可从中取出。把爸爸、妈妈、儿子、女儿看做四个进程,用wait、signal操作进行管理,使这4个进程能正确地并发执行。如图所示。

image-20211207210621113
.png)

1、定义信号量的含义与赋值

定义一个是否允许向盘子中存放水果的信号量S,其初值为“1” ;定义两个信号量SP和SO分别表示盘子中是否有苹果或桔子的消息,初值均为“0” ,一个互斥信号量

SP=SO=

2、写伪代码

begin:
	S,SP,SO:semaphere;	//设置信号量
    	S:=1;	SP:=0;	SO:=0;	//进行初始赋值
            Process 爸爸{
            Begin
                L1:准备一个苹果;
            	wait(S);	//申请空盘子的互斥信号量
                    将苹果放入盘子中
                    signal(SP);	//盘子中有苹果,返回SP
                    Goto L1;	//调用L1女儿取走盘子中的苹果
                       end;
       		 }
			Process 妈妈{
            Begin
                L2:准备一个桔子;
            	wait(S);	//申请空盘子的互斥信号量
                    将桔子放入盘子中
                    signal(SO);	//盘子中有桔子,返回SO
                    Goto L2;	//调用L2儿子取走盘子中的桔子
                       end;
       		 }
			Process 儿子{
            begin
                L3:.wait(SO);	//等待盘子中有桔子
                    从盘子中拿走桔子
                    signal(S);	//拿走桔子后,盘子为空;由SO向S转变
                    end;
            }
			Process 女儿{
            begin
                L4:.wait(SP);	//等待盘子中有苹果
                    从盘子中拿走苹果
                    signal(S);	//拿走苹果后,盘子为空;由SP向S转变
                    end;
            }
			end; 

2、共享打印机

现有四个进程R1R2W1W2,它们共享可以存放一个数的缓冲区。进程R1每次把来自键盘的一个数存入缓冲区中,供进程W1打印输出;进程R2每次从磁盘上读一个数存放到缓冲区中,供进程w2打印输出。为防止数据的丢失和重复打印,问怎样用waitsignal操作来协调这四个进程的并发执行。

1、定义变量

image

定义一个是否允许向缓冲区中存放数据的信号量S,其初值为“1” ;定义两个信号量SW1和SW2分别表示缓冲区中是否有数据R1与R2的消息,初值均为“0” ,一个互斥信号量

2、伪代码

begin:
	S,SW1,SW2:semaphere;	//设置信号量
    	S:=1;	SW1:=0;	SW2:=0;	//进行初始赋值
    	Process R1{
    	begin:
    	wait(S);	//R1申请缓冲区
    		R1向缓冲区存入数据
    		signal(SW1);
    		Goto W1;	//调用W1从缓冲区读数据并打印
    	end;
    	}
    	Process R2{
    	wait(S);	//R2申请缓冲区
    	R2向缓冲区存入数据;
    	signal(SW2);	
    	Goto W2;	//调用W2从缓冲区读数据并打印
    	end;
    	}
    	Process W1{
    	wait(SW1);	//申请SW1缓冲区
    	读取并打印SW1;
    	signal(S);	//释放缓冲区的数据
    	end;
    	}
    	Process W2{
    	wait(SW2);	//申请SW2缓冲区
    	读取并打印SW2;
    	signal(S);	//释放缓冲区的数据
    	end;
    	}
    	end

3、超市购物

某超市,可容纳100人同时购物,入口处备有篮子。每个购物者持一只篮子入内购物,出口处结帐,并归还篮子(出、入口仅容一人通过)。试用信号量和waitsignal操作写出购物同步算法。

1、分析:

超市最多可容纳100人同时购物,当超市人满时,其他购物者必须等待,而有人离开时,应允许等待者进入,因此需设一同步信号量来实现有限数目的购物者进入超市。另外因为出、入口仅容一人通过,所以多个购物者必须互斥通过出、入口,需设两个互斥信号量

2、定义信号量

S—表示是否可以进入超市,初值为100
互斥信号量:

  • mutex1—用于多个购物者互斥通过入口取篮子。初值为1。
  • mutex2—用于多个购物者互斥通过出口结账、还篮子。初值为1。

3、伪代码:

  begin 
    S, mutex1, mutex2 : semaphore; 
    S:=100;mutex1:=1; mutex2:=1; 
    cobegin 
    PROCESS	consumer.j;(j=1,2,,r) 
  begin 
    wait(S);	//超市人满时,购物者进程必须等待 
    wait(mutex1);			//进入入口临界区 
    {在入口处取篮子,进入超市}; 
  signal(mutex1);	//退出临界区 
    {在超市购物}wait(mutex2);	//进入出口临界区 
    {在出口处放篮子,结账}; 
  signal(mutex2);	//退出临界区 
  signal(S)//允许等待者进入 
end; coend; end; 

4、哲学家进餐

有五个哲学家,他们的生活方式是交替地进行思考和进餐。他们共用一张圆桌,分别坐在五张椅子上。在圆桌上有五个碗和五支筷子,平时一个哲学家进行思考,饥饿时便试图取用其左、右最靠近他的筷子,只有在他拿到两支筷子时才能进餐。进餐毕,放下筷子又继续思考。
哲学家进餐问题可看作是并发进程并发执行时,处理共享资源的一个有代表性的问题。

1、问题分析

放在桌上的每只筷子是临界资源,一段时间内只由一位哲学家使用。为了实现对筷子的互斥使用,需要用一个信号量表示一只筷子。5个信号量则构成信号量数组。

Var chopstick: array[0,, 4] of semaphore;
所有信号量均被初始化为1, 第i位哲学家的活动可描述为: 
repeat
	 wait(chopstick[i]);/*试图拿右边(编号为顺时针时)的筷子*/

    	wait(chopstick[(i+1) mod 5);/*试图拿左边的筷子*/
      		…
   	 eat;
                            ...
   	 signal(chopstick[i]);/放下右边的筷子*/

	 signal(chopstick[(i+1) mod 5); /*放下左边的筷子*/
     	            …
   	 think;
  until false; 

若五位哲学家同时饥饿而各自拿起了右边的筷子,这使五个信号量stick均为0,当他们试图去拿起左边的筷子时,都将因无筷子而无限期地等待下去,即可能会引起死锁。

Var chopsiick array [0,, 4] of semaphore∶   =(1,1,1,1,1);
 process i
        repea
     think;
     Swait(chopstick[(i+1) mod 5, chopstick [i]);
     eat;
 Ssignat(chopstick [(i+1) mod 5, chopstick [i]);
 until false;

5、读者—写者问题

在计算机系统中,有些文件是可以供若干进程共享的。假定有某个共享文件F,系统允许进程对文件F读或修改(写),但规定:

  1. 多个进程可以同时读文件F任一个进程在对文件F
  2. 进行修改(写)时不允许其他进程对文件进行读或修改当有进程在读文件时不允许任何进程去修改(写)文件。
  3. 一个文件可能被多个进程共享,为了保证读写的正确性和文件的一致性,系统要求,当有读者进程读文件时,不允许任何写者进程写,但允许多读者同时读当有写者进程写时,不允许任何其它写者进程写,也不允许任何读者进行读

单纯使用信号量不能解决读者写者问题,必须引入计数器readcount对读进程计数,rmutex是用于对计数器readcount操作的互斥信号量, wmutex表示是否允许写的信号量.

1、设置信号量

设置一个共享变量和两个信号量:

  1. 共享变量Readcount:记录当前正在读数据集的读进程数目,初值为0。
  2. 读互斥信号量rmutex :表示读进程互斥地访问共享变量readcount,初值为1.
  3. 写互斥信号量wmutex:表示写进程与其它进程(读、写)互斥地访问数据集,初值为1.

2、伪代码

begin:
rmutex, wmutex:semaphore:=1;	//设置信号量初始值

    Readcount:integer∶=0;	//初始化正在读当前文件的数量
    begin
    parbegin
     Reader:begin
        repeat
         wait(rmutex);{	//申请读的互斥信号量,表示当前文件正在被读
   if readcount=0 then wait(wmutex);;/*第一位读者阻止写者*/
   Readcount∶   =readcount+1;
         signal(rmutex);
           …
         perform read operation;
           …
	end;
     }
wait(rmutex);{		//申请读的信号量,表示文件准备开始写入数据
         readcount∶   =readcount-1;	//减少正在读该文件数量--1
     if readcount=0 then signal(wmutex);	 /*第末位读者允许写者进*/
         signal(rmutex);
        until false;	//没有人在读这份文件
       end
}

writer:begin
        repeat
         wait(wmutex);			//阻止其它进程(读、写)进/
         perform write operation
         signal(wmutex);	//允许其它进程(读、写)进/

        until false;
       end
    parend
  end

调度算法

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

基本思想:按作业(进程)到达时间的先后顺序依次使用处理机。可用于作业调度和进程调度。

特点:FCFS 调度算法有利于长作业(进程),不利于短作业(进程)

缺点:会使许多短作业等待很长的时间,从而引起许多短作业用户的不满。

进程名 到达时间 服务时间 开始执行时间 完成时间 周转时间 带权周转时间
A 0 1 0 1 1 1
B 1 100 1 101 100 1
C 2 1 101 102 100 100
D 3 100 102 202 199 1.99

=;=

短作业优先(SJF)调度算法(非抢占式)

基本思想:对短作业(短进程)优先调度的算法,可用于作业调度和进程调度。

特点:有利于短作业(进程),不利于长作业(进程)

优点:能有效降低作业的平均等待时间;提高吞吐量;能有效缩短进程的周转时间;

缺点:对长作业不利;不考虑作业的紧迫程度;作业执行时间仅为估计值;人机无法实现交互

进程名 到达时间 服务时间 完成时间 周转时间 带权周转时间
A 0 4 4 4 1
B 1 3 9 8 2.67
C 2 5 18 16 3.2
D 3 2 6 3 1.5
E 4 4 13 9 2.25

短作业优先(SJF)调度算法(抢占式)

进程名 到达时间 服务时间 周转时间 带权周转时间
A 0 1 1 1
B 1 100 101 1.01
D 2 100 200 2
C 3 1 1 1

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

=+=R

特点:同时照顾了长短作业(进程),增加了系统开销

例如有四个作业:

若采用响应比高者优先调度算法,求作业的调度顺序。

=CPU(CPU)+CPU(CPU)

作业 到达时间 所需CPU时间
1 8.2 2
2 9.4 1
3 9.5 0.8
4 9.8 0.2

若采用响应比高者优先作业调度算法,先将作业1投入运行,于10.2完成,此时:

作 业 到达时间 所需CPU时间 已等待时间 响应比
2 9.4 1 10.2-9.4=0.8 1.8
3 9.5 0.8 10.2-9.5=0.7 1.875
4 9.8 0.2 10.2-9.8=0.4 3

由于作业4有最高响应比,因此被调度投入运行,于10.4完成,此时

作 业 到达时间 所需CPU时间 已等待时间 响应比
2 9.4 1 10.4-9.4=1 2
3 9.5 0.8 10.4-9.5=0.9 2.125

轮转调度算法(RR)

基本思想:把CPU的处理时间分成固定大小的时间片,如果一个进程在调度中被选中后,用完系统规定的时间片任然没有完成任务,则让出处理机,并排到就绪队列末尾。同时进程调度程序又调度当前就绪队列对首的第一个进程投如运行。

特点:系统能在给定的时间内,响应所有用户的请求。

例如:假定在一台处理机上要运行以下作业1,2,3,4,5.且假定这些作业在时刻0到达,他们的执行时间分别是:10、1、2、1、5。用时间片轮转法,当q=1时,各作业的周转时间和带权周转时间各是多少?

作业 服务时间 进入时刻 完成时刻 周转时间 带权周转时间
1 10 0 19 19 1.9
2 1 0 2 2 2
3 2 0 7 7 3.5
4 1 0 4 4 4
5 5 0 14 14 2.8

轨迹如下:

运行时间(1S) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
作业顺序 1 2 3 4 5 1 3 5 1 5 1 5 1 5 1 1 1 1 1

银行家算法:

数据结构:

可用资源[Avaliable] 表示系统中可用的资源数目
最大需求矩阵[Max] 定义每一个进程对某种资源的最大需求
分配矩阵[Allocation] 每一个进程当前已经分配的某种资源数量
需求矩阵[Need] 表示一个进程还需要多少某种资源数量需求不能超出可用资源数量和最大需求资源

Requesti[j]Need[i,j]FTRequesti[j]Available[i,j]F()()Available[j]:=Available[j]Requesti[j];()Allocation[i,j]=Allocation[i,j]+Requesti[j];()Need[i,j]=Need[i,j]Requesti[j];()TF

假定系统中有五个进程{P0, P1, P2, P3, P4}和三类资源{A, B, C},各种资源的数量分别为10、5、7,在T0时刻的资源分配情况如图所示。

进行与资源数 MAX
A B C
Allocation
A B C
Need
A B C
Available
A B C
P0 7 5 3 0 1 0
0 3 0
7 4 3
7 2 3
3 3 2
2 3 0
2 1 0
P1 3 2 2 2 0 0
3 0 2
1 2 2
0 2 0
P2 9 0 2 3 0 2 6 0 0
P3 2 2 2 2 1 1 0 1 1
P4 4 3 3 0 0 2
1 0 3
4 3 1
3 3 0

求:系列问题

  1. T0时刻的安全性
  2. P1发出请求向量Request(1,0,2),系统能否将资源分配给它?
  3. 在问题2的基础上,P4发出请求向量Request(3,3,0),系统能否将资源分配给它?
  4. 在问题2与问题3的基础上,P0发出请求向量Request(0,2,0),系统能否将资源分配给它?

1、T0时刻的安全性

进行与资源数 work
A B C
Need
A B C
Allocation
A B C
work+Allocation
A B C
finsh
P1 3 3 2 1 2 2 2 0 0 5 3 2 ture
P3 5 3 2 0 1 1 2 1 1 7 4 3 ture
P4 7 4 3 4 3 1 0 0 2 7 4 5 ture
P2 7 4 5 6 0 0 3 0 2 10 4 7 ture
P0 10 4 7 7 4 3 0 1 0 10 5 7 ture

:P1P3P4P2P0

2、P1发出请求向量Request(1,0,2),系统能否将资源分配给它?

进行与资源数 work
A B C
Need
A B C
Allocation
A B C
work+Allocation
A B C
finsh
P1 3 3 2 1 2 2 2 0 0 5 3 2 ture
P3 5 3 2 0 1 1 2 1 1 7 4 3 ture
P4 7 4 3 4 3 1 0 0 2 7 4 5 ture
P0 7 4 5 7 4 3 0 1 0 7 5 5 ture
P2 7 5 5 6 0 0 3 0 2 10 5 7 ture

:P1P3P4P0P2

3、在问题2的基础上,P4发出请求向量Request(3,3,0),系统能否将资源分配给它?

P4Request3,3,0Available(2,3,0)

4、在问题2与问题3的基础上,P0发出请求向量Request(0,2,0),系统能否将资源分配给它?

进行试探性分配后,可用资源Available(2,1,0)已不能满足任何进程的需要。系统进入不安全状态,所以系统不能将资源给P0进程。

连续分配存储管理方式

基于顺序搜索的动态分区分配算法

首次适应算法(FF)

原理:要求空闲分区表/链以地址递增的次序链接空闲分区。从表/链首开始查找,直至第一个满足要求的空闲分区。按作业的大小,从该分区中划出一块空间,余下部分留在空闲表/链中。

特点:优先利用内存低地址部分的空闲分区,从而保留了高地址部分的大空闲区。但由于低地址部分不断被划分,致使低地址端留下许多难以利用的很小的空闲分区(内部碎片),而每次查找又都是从低地址部分开始, 增加了查找可用空闲分区的开销

例 :系统中的空闲分区表如下,现有三个作业分配申请内存空间100K、30K及7K。给出按首次适应算法的内存分配情况

空闲分区表

区号 大小 起址
1 32k 20k
2 8k 52k
3 120k 60k
4 331k 180k

解:按首次适应算法,

申请作业100k,分配3号分区,剩下分区为20k,起始地址160K ;

申请作业30k,分配1号分区,剩下分区为2k,起始地址50K ;

申请作业7k,分配2号分区,剩下分区为1k,起始地址59K ;

循环首次适应算法(CFF)

原理:要求空闲分区表/链以地址递增的次序链接空闲分区,从上次找到空闲分区的下一个空闲分区开始查找,直至找到一个能满足要求的空闲分区。按作业的大小,从该分区中划出一块空间,余下部分留在空闲表/链中。

算法特点:使存储空间的利用更加均衡,不致使小的空闲区集中在存储区的一端,但这会导致缺乏大的空闲分区

例 :系统中的空闲分区表如下,现有三个作业分配申请内存空间100K、30K及7K。给出按循环首次适应算法的内存分配情况

空闲分区表

区号 大小 起址
1 32k 20k
2 8k 52k
3 120k 60k
4 331k 180k

解:按循环首次适应算法,

申请作业100k,分配3号分区,剩下分区为20k,起始地址160K;

申请作业30k,分配4号分区,剩下分区为301k,起始地址210K ;

申请作业7k,分配1号分区,剩下分区为25k,起始地址27K ;

最佳适应算法(BF)

原理:要求空闲分区表/链以空闲分区容量以小到大的次序链接空闲分区从表/链首开始查找,直至找到一个能满足要求的空闲分区。按作业的大小,从该分区中划出一块空间,余下部分留在空闲表/链中。

算法特点:空闲区一般不可能正好和它申请的内存空间大小一样,因而将其分割成两部分时,往往使剩下的空闲区非常小,从而在存储器中留下许多难以利用的小空闲区(内部碎片)

例 :系统中的空闲分区表如下,现有三个作业分配申请内存空间100K、30K及7K。给出按最佳适应算法的内存分配情况

分配前的空闲分区表

区号 大小 起址
1 8k 52k
2 32k 20k
3 120k 60k
4 331k 180k

解:按最佳适应算法,分配前的空闲分区表如上表。

申请作业100k,分配3号分区,剩下分区为20k,起始地址160K;

申请作业30k,分配2号分区,剩下分区为2k,起始地址50K ;

申请作业7k,分配1号分区,剩下分区为1k,起始地址59K ;

最坏适应算法(WF)

原理:要求空闲分区表/链以空闲分区容量以大到小的次序链接空闲分区从表/链首开始查找,直至找到一个能满足要求的空闲分区。按作业的大小,从该分区中划出一块空间,余下部分留在空闲表/链中。

特点:总是挑选满足作业要求的最大的分区分配给作业。这样使分给作业后剩下的空闲分区也较大,可装下其它作业。但由于最大的空闲分区总是因首先分配而划分,当有大作业到来时,其存储空间的申请往往会得不到满足

例 :系统中的空闲分区表如下,现有三个作业分配申请内存空间100K、30K及7K。给出按最坏适应算法的内存分配情况

空闲分区表

区号 大小 起址
1 331k 180k
2 120k 60k
3 32k 20k
4 8k 52k

解:按最坏适应算法,分配前的空闲分区表如上表。

申请作业100k,分配1号分区,剩下分区为231k,起始地址280K;

申请作业30k,分配1号分区,剩下分区为201k,起始地址310K ;

申请作业7k,分配1号分区,剩下分区为194k,起始地址317K ;

基本分页存储管理方式

页面置换算法

缺页率:在进程运行过程中,访问页面成功(所访问的页面在内存中)的次数为S,访问页面失败(所访问的页面不在内存中,需要从外存调入)的次数为F,则该进程总的页面访问次数为A=S+F,该进程在其运行过程中的缺页率为 f=F/A

影响缺页率的因素:分配给进程的物理块数;页面本身的大小;程序的编制方法;页面置换算法

最佳(Optimal)置换算法(理想化算法)

算法思想: 选择将来不再被使用,或者最长时间不再被访问的页面将其淘汰。(往后看)

最佳置换算法产生的缺页中断次数最少,可获得最低的缺页中断率。但是由于无法预知哪个页面是未来最长时间内不被访问的,所以该算法只是一种理论上的算法,可用该算法评价其它算法的优劣。

假设系统为某进程分配了三个物理块,程序访问页面的顺序为7,0,1,2,0,3,0,4,2,3,0,3,2,1,2,0,1,7,0,1

7 0 1 2 0 3 0 4 2 3 0 3 2 1 2 0 1 7 0 1
7 7 7 2 2 2 2 2 7
0 0 0 0 4 0 0 0
1 1 3 3 3 1 1
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20

缺页次数6次;缺页率:6/20 应该是置换率吧

先进先出置换算法(FIFO)

算法思想:选择最先进入内存的页面将其淘汰。

先进先出(FIFO)置换算法实现简单,但与进程实际运行的规律不适应

7 0 1 2 0 3 0 4 2 3 0 3 2 1 2 0 1 7 0 1
7 7 7 2 2 2 4 4 4 0 0 0 7 7 7
0 0 0 3 3 3 2 2 2 1 1 1 0 0
1 1 1 0 0 0 3 3 3 2 2 2 1
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20

缺页次数12次;缺页率:12/20

最近最久未使用置换算法(LRU)

算法思想:选择最近最久没有使用的页面将其淘汰

最近最久未使用置换算法(LRU)的性能接近于最佳算法,但实现起来较困难。因为要快速找出最近最久未使用的页面,需要两类硬件之一的支持:寄存器或栈

7 0 1 2 0 3 0 4 2 3 0 3 2 1 2 0 1 7 0 1
7 7 7 2 2 4 4 4 0 1 1 7
0 0 0 0 0 0 3 3 3 0 0
1 1 3 3 2 2 2 2 2 1
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20

Clock置换算法

简单的Clock置换算法:每页设置一个访问位,并将内存中的所有页链接成一个循环队列。当某页被访问时,系统将其访问位设置为1。置换时采用一个指针,从当前指针位置开始按序检查各页,若访问位为0则选择该页换出,若访问位为1则将其设置为0,最后指针停留在被置换页的下一页上。

改进型Clock算法:访问位(A位)和修改位(M位)

A=0,M=0:未访问,未修改,为最佳淘汰页; A=0,M=1:未访问,已修改,并不是很好的淘汰页;

A=1,M=0:已访问,未修改,有可能再次被访问; A=1,M=1:已访问,已修改,有可能再次被访问;

磁盘调度算法

先来先服务FCFS

基本思想:根据进程请求访问磁盘的先后次序进行调度

特点:简单、公平,但平均寻道时间长。

image

(从100号磁道开始)
被访问的下一个磁道号 移动距离(磁道数)
55 45
58 3
39 19
18 21
90 72
160 70
150 10
38 112
184 146
平均寻道长度:55.3

最短寻道时间优先SSTF

基本思想:优先选择距当前磁头最近的访问请求进行服务

特点:改善了磁盘平均服务时间,但容易造成某些访问请求长期等待得不到服务

image

(从100号磁道开始)
被访问的下一个磁道号 移动距离(磁道数)
90 10
58 32
55 3
39 16
38 1
18 20
150 132
160 10
184 24
平均寻道长度:27.5

扫描算法SCAN(电梯算法)

基本思想:磁头从磁盘的一端开始向另一端移动,沿途响应访问请求,直到到达了磁盘的另一端,此时磁头反向移动并继续响应服务请求。

特点:寻道性能较好,避免了饥饿,但不利于远离磁头一端的访问请求。

image

(从100号磁道开始,向磁道号增加方向访问)
被访问的下一个磁道号 移动距离(磁道数)
150 50
160 10
184 24
90 94
58 32
55 3
39 16
38 1
18 20
平均寻道长度:27.8

循环扫描算法CSCAN

基本思想:类似于扫描算法,但磁头只能单向移动

特点:消除了对两端磁道请求的不公平。

image

(从100号磁道开始,向磁道号增加方向访问)
被访问的下一个磁道号 移动距离(磁道数)
150 50
160 10
184 24
18 166
38 20
39 1
55 16
58 3
90 32
平均寻道长度:35.8
posted @   这只小恐龙已经躺下了  阅读(1129)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探
点击右上角即可分享
微信分享提示