9-22 面试总结

1-浏览器中输入www.baidu.com后发生了什么
第一步 浏览器查找该域名的 IP 地址

第二步 浏览器根据解析得到的IP地址向 web 服务器发送一个 HTTP 请求

第三步 服务器收到请求并进行处理

第四步 服务器返回一个响应

第五步 浏览器对该响应进行解码,渲染显示。

第六步 页面显示完成后,浏览器发送异步请求。

1)域名解析,其实就是根据用户输入的网址去寻找它对应的IP地址,比如输入www.baidu.com的网址就会经历以下过程:浏览器把域名发送给系统默认DNS服务器。如果该服务器本地有缓存,且缓存未过期,则直接返回结果;否则向上一级DNS服务器查询,直到DNS根服务器。DNS协议最终会返回A记录(IPv4)或者AAAA记录(IPv6)或者Alias(别名)等。如果DNS失败,浏览器会提示域名找不到或者DNS错误。

2)到此为止,浏览器知道了网址的对应服务器IP地址和端口,然后就通过TCP协议发起网络请求。
通过DNS获取到IP后,目标IP和本机IP分别与子网掩码相与的结果相同,那么它们在一个子网,那么通过ARP协议可以查到目标主机的MAC地址,否则的话,需要通过网关转发,也就是目标MAC是网关的MAC。
请求需要进行编码,生成一个HTTP数据包,依次打上TCP、IP、以太网协议的头部。其中TCP头部主要信息是本机端口和目标端口号等信息,用于标识同一个主机的不同进程,对于HTTP协议,服务器端的默认端口号是80,本机浏览器的话生成一个1024到65535之间的端口号。IP头部主要包含本地IP和目标IP等信息。以太网协议头部主要是双方的MAC地址,目标MAC可以由第一条所诉方法得到。以太网数据包的数据部分,最大长度为1500字节,所以如果IP包太大的话还要拆包,比如IP包5000字节,要分为4包,每一包都包含一个IP头部。

3)终于到达处理HTTP协议的软件了。这类软件叫做Web Server。主流的包括Windows系统上的IIS,开源的Apache,Nginx等
HTTP协议处理
Web Server最重要的角色就是处理HTTP协议,给浏览器规范的应答。处理网络请求和相关连接。因此吞吐量和性能是一个重要的指标。开源软件中Nginx是高性能Web服务器的主流选择,IIS是Windows上的标准软件。
HTTPS协议处理
HTTPS协议相关的证书、加解密、签名等也需要Web服务器处理。但是开源软件中,一般选择调用OpenSSL处理,而IIS是微软自行实现的加密库。

4)静态文件
Web Server能够直接处理的只有静态文件。比如请求http://upload.jianshu.io/admin_banners/web_images/2870/48782c3773b1132ee6c594e56211f64499669099.jpg,那么Web服务器根据网址在服务器磁盘上找到这个路径的文件,返回文件内容。
动态内容接口
但是现在的网站除了css、js和图片等资源外,大量的内容都是动态内容。Web服务器需要一个标准接口与不同语言的代码配合,来动态生成网页内容。这个接口包括CGI、FastCGI、ISAPI等。其中ISAPI属于IIS,开源服务器一般支持CGI和FastCGI等。
应用服务器
请求到达应用服务器之后,就开始网站自己的活了。应用服务器通过CGI、FastCGI、ISAPI等接口与Web服务器通信,获得HTTP请求,返回HTTP应答。主流应用服务器根据语言和平台分:
Windows和.NET:IIS。IIS放在这里是因为ASP.NET深度集成,无法分出。
Java:Jetty,JBoss,Tomcat,WebLogic等
PHP:php-cgi
应用服务器可以作为dll运行在Web服务器中(比如IIS,但是IIS也支持FastCGI),或者作为独立进程,通过IPC与Web服务器通信。
接下来就是程序内部的事情了。省略。
数据库服务器
应用服务器在生成网站内容的过程中一般需要连接数据库存取数据。目前主流数据库包括:
MySQL:开源软件,SUN公司被收购后由Oracle负责
MariaDB:SUN被收购后,因为社区与Oracle的纠纷,从MySQL分支出来的版本。
SQL Server:微软开发的商用数据库。其中Express Edtion免费。
Oracle:Oracle公司开发的商用数据库。
PostgreSQL:开源软件,号称开源中功能最强。
DB2:IBM公司开发的商用数据库。
Redis: NoSQL,支持多种数据结构
MongoDB: NoSQL

5)HTML和CSS解析
最终应用服务器生成了HTML,然后给Web Server。Web Server生成HTTP应答,然后通过复杂的网络线路回到用户电脑中。用户电脑的操作系统把应答给浏览器。浏览器开始渲染。
开始从头到尾解析HTML,并生成DOM树。其中如果有外链资源,需要再次通过网络层以此下载。如果是"script"标签,则需要调用JS引擎执行脚本。如果是css,则开始解析CSS,得到一系列样式规则。DOM树生成之后,与样式规则拼接,得到渲染树。
渲染树经过排版引擎得到最终的渲染位置和样式,然后调用操作系统的绘图API绘制页面(部分内容会调用显卡进行硬件加速)。

6)页面显示完成后客户端仍与服务器端保持着联系。
它会持续与服务器保持联系来及时更新一些页面信息。在浏览器中执行的 JavaScript代码会给服务器发送异步请求。这个异步请求发送给特定的地址,它是一个按照程式构造的获取或发送请求。

2- 浅析HTTP与HTTPS的区别
一、两者的基本概念
HTTP:全称是HyperText Transfer Protocol,超文本传输协议,为互联网中使用最为广泛的协议。

HTTPS:全称是Hyper Text Transfer Protocol over Secure Socket Layer,安全套接字层超文本传输协议。简单来讲就是就是安全的HTTP,即HTTPS=HTTP+SSL。

二、两者的主要区别
【1】端口
(1)HTTP协议默认采用80端口

(2)HTTPS采用443端口

【2】安全性
(1)HTTP协议以明文发送数据,不提供任何方式的加密。因此HTTP协议安全性较差

(2)HTTPS协议使用额外的SSL协议,依靠服务器端发送来的证书来验证服务器身份,并为此次传输加密。即SSL的作用就是身份验证与加密传输。由于HTTPS协议的安全性较高,很多银行网站都采用这种方式进行数据的传输。

【3】连接效率
HTTP与HTTPS建立连接都需要与服务器进行握手,但HTTPS协议在握手阶段的需要做更多的事情,HTTPS需要比HTTP多发SSL的数据包。因此耗时较为严重,页面加载更加慢,耗能增加。

【4】使用成本
SSL证书需要进行申请,功能越强大的证书,费用越高。当然也可以自己制作证书,唯一的区别就是自己制作的证书在首次连接的过程中需要用户确认,用户体验降低。而申请到的证书不需要用户进行确认,由第三方进行担保。

3-数据库索引:
什么是索引?
在关系数据库中,索引是一种单独的、物理的对数据库表中一列或多列的值进行排序的一种存储结构,它是某个表中一列或若干列值的集合和相应的指向表中物理标识这些值的数据页的逻辑指针清单。

索引的作用相当于图书的目录,可以根据目录中的页码快速找到所需的内容。

当表中有大量记录时,若要对表进行查询:

第一种搜索信息方式是全表搜索,是将所有记录一一取出,和查询条件进行一一对比,然后返回满足条件的记录,这样做会消耗大量数据库系统时间,并造成大量磁盘 I/O 操作。
第二种就是在表中建立索引,然后在索引中找到符合查询条件的索引值,最后通过保存在索引中的 ROWID(相当于页码)快速找到表中对应的记录。
MySQL 5.5 以后 InnoDB 储引擎使用的索引数据结构主要用:B+Tree;本篇文章带大家以 B+Tree 前世今生为主线来聊一聊。
二叉排序树 → 二叉平衡树 → B-Tree(B树) → B+Tree(B+树)
①二叉排序树

理解 B+树之前,简单说一下二叉排序树,对于一个节点,它的左子树的孩子节点值都要小于它本身,它的右子树的孩子节点值都要大于它本身。

如果所有节点都满足这个条件,那么它就是二叉排序树。(此处可以串一下二分查找的知识点)
上图是一颗二叉排序树,你可以尝试利用它的特点,体验查找 9 的过程:
在这里插入图片描述
9 比 10 小,去它的左子树(节点 3)查找。
9 比 3 大,去节点 3 的右子树(节点 4)查找。
9 比 4 大,去节点 4 的右子树(节点 9)查找。
节点 9 与 9 相等,查找成功。
一共比较了 4 次,那你有没有想过上述结构的优化方式?

②AVL 树(自平衡二叉查找树)
在这里插入图片描述
上图是 AVL 树,节点个数和值均和二叉排序树一摸一样。
再来看一下查找 9 的过程:

9 比 4 大,去它的右子树查找。
9 比 10 小,去它的左子树查找。
节点 9 与 9 相等,查找成功。
一共比较了 3 次,同样的数据量比二叉排序树少了一次,为什么呢?因为 AVL 树高度要比二叉排序树小,高度越高意味着比较的次数越多;不要小看优化的这一次,假如是 200w 条数据,比较次数会明显地不同。

你可以想象一下一棵 100 万节点的平衡二叉树,树高 20。一次查询可能需要访问 20 个数据块。在机械硬盘时代,从磁盘随机读一个数据块需要 10 ms 左右的寻址时间。

也就是说,对于一个 100 万行的表,如果使用二叉树来存储,单独访问一个行可能需要 20 个 10 ms 的时间,这个查询可真够慢的!

③B 树(Balanced Tree)多路平衡查找树,多叉的

在这里插入图片描述
B 树的特点如下:
所有键值分布在整个树中。
任何关键字出现且只出现在一个节点中。
搜索有可能在非叶子节点结束。
在关键字全集内做一次查找,性能逼近二分查找算法。
为了提升效率,要尽量减少磁盘 I/O 的次数。实际过程中,磁盘并不是每次严格按需读取,而是每次都会预读。MySQL(默认使用 InnoDB 引擎),将记录按照页的方式进行管理,每页大小默认为 16K(可以修改)。
④B+Tree (B+树是 B 树的变体,也是一种多路搜索树)
在这里插入图片描述
从图中也可以看到,B+树与 B 树的不同在于:

所有关键字存储在叶子节点,非叶子节点不存储真正的 data,从而可以快速定位到叶子结点。
为所有叶子节点增加了一个链指针,意味着所有的值都是按顺序存储的,并且每一个叶子页到根的距离相同,很适合查找范围数据。
因此,B+Tree 可以对 <,<=,=,>,>=,BETWEEN,IN,以及不以通配符开始的 LIKE 使用索引。

B+ 树的优点,比较的次数均衡,减少了 I/O 次数,提高了查找速度,查找也更稳定:

B+树的磁盘读写代价更低。
B+树的查询效率更加稳定。
要知道的是,你每次创建表,系统会为你自动创建一个基于 ID 的聚集索引(上述 B+树),存储全部数据。

你每次增加索引,数据库就会为你创建一个附加索引(上述 B+树),索引选取的字段个数就是每个节点存储数据索引的个数,注意该索引并不存储全部数据。

为什么 MySQL 索引选择了 B+树而不是 B 树?
原因有如下两点:
B+树更适合外部存储(一般指磁盘存储),由于内节点(非叶子节点)不存储 data,所以一个节点可以存储更多的内节点,每个节点能索引的范围更大更精确。也就是说使用 B+树单次磁盘 I/O 的信息量相比较 B 树更大,I/O 效率更高。
MySQL 是关系型数据库,经常会按照区间来访问某个索引列,B+树的叶子节点间按顺序建立了链指针,加强了区间访问性,所以 B+树对索引列上的区间范围查询很友好。而 B 树每个节点的 key 和 data 在一起,无法进行区间查找。

程序员,你应该知道的索引知识点
①回表查询

比如你创建了 name, age 索引 name_age_index,查询数据时使用了:

select * from table where name =‘陈哈哈’ and age = 26;
由于附加索引中只有 name 和 age,因此命中索引后,数据库还必须回去聚集索引中查找其他数据,这就是回表,这也是你背的那条:少用 select * 的原因。

②索引覆盖

结合回表会更好理解,比如上述 name_age_index 索引,有查询:

select name, age from table where name =‘陈哈哈’ and age = 26;
此时 select 的字段 name,age 在索引 name_age_index 中都能获取到,所以不需要回表,满足索引覆盖,直接返回索引中的数据,效率高。是 DBA 同学优化时的首选优化方式。

③最左前缀原则

B+树的节点存储索引顺序是从左向右存储,在匹配的时候自然也要满足从左向右匹配。
通常我们在建立联合索引的时候,也就是对多个字段建立索引,相信建立过索引的同学们会发现,无论是 Oracle 还是 MySQL 都会让我们选择索引的顺序。

比如我们想在 a,b,c 三个字段上建立一个联合索引,我们可以选择自己想要的优先级,a、b、c,或者是 b、a、c 或者是 c、a、b 等顺序。

为什么数据库会让我们选择字段的顺序呢?不都是三个字段的联合索引么?这里就引出了数据库索引的最左前缀原理。

在我们开发中经常会遇到明明这个字段建了联合索引,但是 SQL 查询该字段时却不会使用索引的问题。
最左前缀:顾名思义,就是最左优先,上例中我们创建了 a_b_c 多列索引,相当于创建了(a)单列索引,(a,b)组合索引以及(a,b,c)组合索引。
因此,在创建多列索引时,要根据业务需求,where 子句中使用最频繁的一列放在最左边。

④索引下推优化

还是索引 name_age_index,有如下 sql:

select * from table where name like ‘陈%’ and age > 26;
该语句有两种执行可能:

命中 name_age_index 联合索引,查询所有满足 name 以"陈"开头的数据, 然后回表查询所有满足的行。
命中 name_age_index 联合索引,查询所有满足 name 以"陈"开头的数据,然后顺便筛出 age>20 的索引,再回表查询全行数据。
显然第 2 种方式回表查询的行数较少,I/O 次数也会减少,这就是索引下推。所以不是所有 like 都不会命中索引。

使用索引时的注意事项
①索引不会包含有 null 值的列

只要列中包含有 null 值都将不会被包含在索引中,复合索引中只要有一列含有 null 值,那么这一列对于此复合索引就是无效的。所以我们在数据库设计时建议不要让字段的默认值为 null。

②使用短索引
③索引列排序

查询只使用一个索引,因此如果 where 子句中已经使用了索引的话,那么 order by 中的列是不会使用索引的。

因此数据库默认排序可以符合要求的情况下不要使用排序操作;尽量不要包含多个列的排序,如果需要最好给这些列创建复合索引。

④like 语句操作

一般情况下不推荐使用 like 操作,如果非使用不可,如何使用也是一个问题。like “%陈%” 不会使用索引而 like “陈%”可以使用索引。

⑤不要在列上进行运算

这将导致索引失效而进行全表扫描,例如:

SELECT * FROM table_name WHERE YEAR(column_name)<2017;
⑥不使用 not in 和 <> 操作

这不属于支持的范围查询条件,不会使用索引。

4-快速排序的时间复杂度为什么是nlogn
快速排序由C. A. R. Hoare在1962年提出。它的基本思想是:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。

#include<stdio.h>
 
// 打印数组
 void print_array(int *array, int length)
 {
     int index = 0;
     printf("array:\n");
     for(; index < length; index++){
         printf(" %d,", *(array+index));
     }   
     printf("\n\n");
 }
 
 void quickSort(int array[], int length)
 {
     int start = 0;
     int end = length-1;
     int value = array[start];// 得到哨兵元素
 
     if (1 > length) return;// 递归出口
 
     while(start < end){// 以哨兵元素为标准,分成大于它和小于它的两列元素
 
         while(start < end && array[end] <= value ){// 从数组尾部往前循环得到小于哨兵元素的一个元素
         	end--;
         }   
 		 if ( start < end ){
                 array[start++] = array[end];
             }   
         while( start < end && array[start] >= value){// 从数组头部往后循环得到大于哨兵元素的一个元素  
         	start++;
         }   
         if( start < end ){
                 array[end--] = array[start];
             }   
     }   
 
     array[start] = value;// 放置哨兵元素
     printf("\nstart:%d, end:%d\n", start, end);// 这个是测试下start和end是否一样
     quickSort(array, start);// 递归排序小于哨兵元素的那一列元素
     quickSort(array + start + 1, length - start - 1);// 递归排序大于哨兵元素的那一列
 }
 
 
 int main(void)
 {
     int array[12] = {1,11,12,4,2,6,9,0,3,7,8,2};
     print_array(array, 12);// 开始前打印下
     quickSort(array, 12);// 快速排序
     print_array(array, 12);// 排序后打印下
     return 0;
 }

递归算法的时间复杂度公式:T[n] = aT[n/b] + f(n) ;
这个方法针对形如“T(n) = aT(n/b) + f(n)”的递归方程。这种递归方程是分治法的时间复杂性所满足的递归关系,即一个规模为n的问题被分成规模均为n/b的a个子问题,递归地求解这a个子 问题,然后通过对这a个子间题的解的综合,得到原问题的解。
3递归树
  递归树是一棵结点带权值的树。初始的递归树只有一个结点,它的权标记为T(n)T(n);然后按照递归树的迭代规则不断进行迭代,每迭代一次递归树就增加一层,直到树中不再含有权值为函数的结点(即叶结点都为T(1)T(1))。下面以递归方程

T(n)={O(1),2T(n2)+O(n),当n=1当n>=2;(假设n=2k,则k=log2n)T(n)={O(1),当n=12T(n2)+O(n),当n>=2;(假设n=2k,则k=log2⁡n)

来讲述递归树的迭代规则。
第一步: 把根结点T(n)T(n)用根是cncn、左结点为T(n2)T(n2)、右结点为T(n2)T(n2)的子树代替(即:以分解、合并子问题需要的代价为根,分解得到的子问题为叶的子树。其中常量c代表求解规模为1的问题所需的时间);(如下如(a)→(b)(a)→(b))
第二步:把叶结点按照“第一步”的方式展开;T(n2)T(n2)用根是cn/2cn/2、左节点为T(n4)T(n4)、右结点为T(n4)T(n4)的子树代替。(如下如(b)→©(b)→©)
第三步:反复按照“第一步”的方式迭代,每迭代一次递归树就增加一层,直到树中不再含有权值为函数的结点(即叶结点都为T(1)T(1))。(如下如©→(d)©→(d))
在这里插入图片描述
在得到递归树后,将树中每层中的代价求和,得到每层代价,然后将所有层的代价求和,得到所有层次的递归调用的总代价。在上图(d)部分中,完全展开的递归树高度为lgnlg⁡n(树高为根结点到叶结点最长简单路径上边的数目),所有递归树具有lgn+1lg⁡n+1层,所以总代价为cn∗(lgn+1)cn∗(lg⁡n+1),所有时间复杂度为Θ(nlgn)Θ(nlg⁡n)。

最优情况下时间复杂度
快速排序最优的情况就是每一次取到的元素都刚好平分整个数组(很显然我上面的不是);
此时的时间复杂度公式则为:T[n] = 2T[n/2] + f(n);T[n/2]为平分后的子数组的时间复杂度,f[n] 为平分这个数组时所花的时间;
下面来推算下,在最优的情况下快速排序时间复杂度的计算(用迭代法):
T[n] = 2T[n/2] + n ----------------第一次递归
令:n = n/2 = 2 { 2 T[n/4] + (n/2) } + n ----------------第二次递归

                                        =  2^2 T[ n/ (2^2) ] + 2n

            令:n = n/(2^2)   =  2^2  {  2 T[n/ (2^3) ]  + n/(2^2)}  +  2n                         ----------------第三次递归  

                                        =  2^3 T[  n/ (2^3) ]  + 3n

            ......................................................................................                        

            令:n = n/(  2^(m-1) )    =  2^m T[1]  + mn                                                  ----------------第m次递归(m次后结束)

           当最后平分的不能再平分时,也就是说把公式一直往下跌倒,到最后得到T[1]时,说明这个公式已经迭代完了(T[1]是常量了)。

           得到:T[n/ (2^m) ]  =  T[1]    ===>>   n = 2^m   ====>> m = logn;

           T[n] = 2^m T[1] + mn ;其中m = logn;

           T[n] = 2^(logn) T[1] + nlogn  =  n T[1] + nlogn  =  n + nlogn  ;其中n为元素个数

           又因为当n >=  2时:nlogn  >=  n  (也就是logn > 1),所以取后面的 nlogn;

           综上所述:快速排序最优的情况下时间复杂度为:O( nlogn )

最差情况下时间复杂度
最差的情况就是每一次取到的元素就是数组中最小/最大的,这种情况其实就是冒泡排序了(每一次都排好一个元素的顺序)

 这种情况时间复杂度就好计算了,就是冒泡排序的时间复杂度:T[n] = n * (n-1) = n^2 + n;

 综上所述:快速排序最差的情况下时间复杂度为:O( n^2 )

平均时间复杂度
快速排序的平均时间复杂度也是:O(nlogn)

空间复杂度
其实这个空间复杂度不太好计算,因为有的人使用的是非就地排序,那样就不好计算了(因为有的人用到了辅助数组,所以这就要计算到你的元素个数了);我就分析下就地快速排序的空间复杂度吧;
首先就地快速排序使用的空间是O(1)的,也就是个常数级;而真正消耗空间的就是递归调用了,因为每次递归就要保持一些数据;
最优的情况下空间复杂度为:O(logn) ;每一次都平分数组的情况
最差的情况下空间复杂度为:O( n ) ;退化为冒泡排序的情况
 平均情况下:T(n)=2*T(n/2)+n; 第一次划分

  =2*(2*T(n/4)+n/2)+n;     第二次划分  (=2^2*T(n/4)+2*n)

  =2*(2*(2*T(n/8)+n/4)+n/2)+n;     第三次划分(=2*3*T(n/8)+3*n)

  =.....................

  =2^m+m*n;  第m次划分

因为2^m=n,所以等价于 = n+mn
所以m=logn,所以T(n)=n+n
logn;

5-从一个学生成绩表中,计算出每个学生的平均成绩:
学生成绩表(stuscore):
姓名:name | 课程:subject|分数:score|学号:stuid
张三|数学|89|1
张三|语文|80|1
张三|英语|70|1
李四|数学|90|2
李四|语文|70|2
李四|英语|80|2

  1. 计算每个人的总成绩并排名(要求显示字段:姓名,总成绩)

  2. 计算每个人的总成绩并排名(要求显示字段: 学号,姓名,总成绩)

  3. 计算每个人单科的最高成绩(要求显示字段: 学号,姓名,课程,最高成绩)

  4. 计算每个人的平均成绩(要求显示字段: 学号,姓名,平均成绩)

  5. 列出各门课程成绩最好的学生(要求显示字段: 学号,姓名,科目,成绩)

  6. 列出各门课程成绩最好的两位学生(要求显示字段: 学号,姓名,科目,成绩)

  7. 统计如下:
    学号 姓名 语文 数学 英语 总分 平均分

8.列出各门课程的平均成绩(要求显示字段:课程,平均成绩)

9.列出数学成绩的排名(要求显示字段:学号,姓名,成绩,排名)

10.列出数学成绩在2-3名的学生(要求显示字段:学号,姓名,科目,成绩)

11.求出李四的数学成绩的排名

12.统计如下:
课程 不及格(0-59)个 良(60-80)个 优(81-100)个
13.统计如下:数学:张三(50分),李四(90分),王五(90分),赵六(76分)

  1.   计算每个人的总成绩并排名
    

select name,sum(score) as allscore from stuscore group by name order by allscore

  1. 计算每个人的总成绩并排名

select distinct t1.name,t1.stuid,t2.allscore from stuscore t1,

(

select stuid,sum(score) as allscore from stuscore group by stuid

)t2

where t1.stuid=t2.stuid

order by t2.allscore desc

  1. 计算每个人单科的最高成绩

select t1.stuid,t1.name,t1.subject,t1.score from stuscore t1,

(

select stuid,max(score) as maxscore from stuscore group by stuid

) t2

where t1.stuid=t2.stuid and t1.score=t2.maxscore

4.计算每个人的平均成绩

select distinct t1.stuid,t1.name,t2.avgscore from stuscore t1,

(

select stuid,avg(score) as avgscore from stuscore group by stuid

) t2

where t1.stuid=t2.stuid

5.列出各门课程成绩最好的学生

select t1.stuid,t1.name,t1.subject,t2.maxscore from stuscore t1,

(

select subject,max(score) as maxscore from stuscore group by subject

) t2

where t1.subject=t2.subject and t1.score=t2.maxscore

6.列出各门课程成绩最好的两位学生

select distinct t1.* from stuscore t1

where t1.stuid in

(select top 2 stuscore.stuid from stuscore where subject = t1.subject order by score desc)

order by t1.subject

7.学号 姓名 语文 数学 英语 总分 平均分

select stuid as 学号,name as 姓名,

sum(case when subject=‘语文’ then score else 0 end) as 语文,

sum(case when subject=‘数学’ then score else 0 end) as 数学,

sum(case when subject=‘英语’ then score else 0 end) as 英语,

sum(score) as 总分,(sum(score)/count(*)) as 平均分

from stuscore

group by stuid,name

order by 总分desc

8.列出各门课程的平均成绩

select subject,avg(score) as avgscore from stuscore

group by subject

9.列出数学成绩的排名

declare @tmp table(pm int,name varchar(50),score int,stuid int)

insert into @tmp select null,name,score,stuid from stuscore where subject=‘数学’ order by score desc

declare @id int

set @id=0;

update @tmp set @id=@id+1,pm=@id

select * from @tmp

select DENSE_RANK () OVER(order by score desc) as row,name,subject,score,stuid from stuscore where subject=‘数学’

order by score desc

declare @tmp table(pm int identity(1,1),name varchar(50),score int,stuid int)
insert into @tmp
select name,score,stuid from stuscore where subject=‘数学’ order by score desc
select * from @tmp

  1. 列出数学成绩在2-3名的学生

select t3.* from

(

select top 2 t2.* from (

select top 3 name,subject,score,stuid from stuscore where subject=‘数学’

order by score desc

) t2 order by t2.score

) t3 order by t3.score desc

  1. 求出李四的数学成绩的排名

declare @tmp table(pm int,name varchar(50),score int,stuid int)

insert into @tmp select null,name,score,stuid from stuscore where subject=‘数学’ order by score desc

declare @id int

set @id=0;

update @tmp set @id=@id+1,pm=@id

select * from @tmp where name=‘李四’

  1. 课程 不及格(-59) 良(-80) 优(-100)
    select subject,

(select count(*) from stuscore where score<60 and subject=t1.subject) as 不及格,

(select count(*) from stuscore where score between 60 and 80 and subject=t1.subject) as 良,

(select count(*) from stuscore where score >80 and subject=t1.subject) as 优

from stuscore t1 group by subject

  1. 数学:张三(50分),李四(90分),王五(90分),赵六(76分)
    declare @s varchar(1000)

set @s=’’

select @s =@s+’,’+name+’(’+convert(varchar(10),score)+‘分)’ from stuscore where subject=‘数学’

set @s=stuff(@s,1,1,’’)

print ‘数学:’+@s

2-螺旋矩阵、链表相关、经典dfs/bfs、经典dp(一维)、topK,想要完整的bug free写好,也是需要一定的积累的。且是有必要的。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值