测试、测试开发面试准备和复习
目录
按读者姓名查询指定读者的借还书历史记录,假设读者姓名为刘勇。
现在有100W个账户密码,要存起来,要求查找时速度尽可能快,你选择什么数据结构?为什么?
测开面试复习文档
一:网络知识方面
基础的网络通信知识
Cookie:记住身份信息,将我们在网站的行为记录号,自动登录账号,不用重新登录账号,可以将我们查的东西来推广告
Token:在计算机身份认证中是令牌(临时)的意思,在词法分析中是标记的意思。一般作为邀请、登录系统使用。
token其实说的更通俗点可以叫暗号,在一些数据传输之前,要先进行暗号的核对,不同的暗号被授权不同的数据操作。
Cache : 缓存之前浏览过的东西,数据被缓存到附近的主机,再次打开的时候,速度就很快。cdn
Host:接受请求的服务器地址,可以是IP或者是域名
状态码,100~199表示请求已收到继续处理,200~299表示成功,300~399表示资源重定向,400~499表示客户端请求出错,500~599表示服务器端出错
200:响应成功
302:跳转,重定向
400:客户端有语法错误
403:服务器拒绝提供服务
404:请求资源不存在
500:服务器内部错误
OSI七层模型:
- ①物理层、②数据链路层、③网络层、④传输层、⑤会话层、⑥表示层、⑦应用层
TCP/IP四层网络协议:应用层,网络层,传输层,数据链路层
HTTP: 80端口
超文本传输协议(HTTP,HyperText Transfer Protocol)是互联网上应用最为广泛的一种网络协议。所有的WWW文件都必须遵守这个标准。设计HTTP最初的目的是为了提供一种发布和接收HTML页面的方法。Http协议是以明文方式发送信息的,如果黑客截取了Web浏览器和服务器之间的传输报文,就可以直接获得其中的信息。
HTTPS: 443 端口
是以安全为目标的Http通道,是Http的安全版。Https的安全基础是SSL。
SSL协议可分为两层:SSL记录协议(SSL Record Protocol),它建立在可靠的传输协议(如TCP)之上,为高层协议提供数据封装、压缩、加密等基本功能的支持。SSL握手协议(SSL Handshake Protocol),它建立在SSL记录协议之上,用于在实际的数据传输开始前,通讯双方进行身份认证、协商加密算法、交换加***等。
FTP是File Transfer Protocol,文件传输协议;简单说HTTP是面向网页的,而FTP是面向文件的。
TCP/IP 是用于因特网 (Internet) 的通信协议。计算机通信协议是对那些计算机必须遵守以便彼此通信的规则的描述。
TCP 使用固定的连接
TCP 用于应用程序之间的通信。
当应用程序希望通过 TCP 与另一个应用程序通信时,它会发送一个通信请求。这个请求必须被送到一个确切的地址。在双方“握手”之后,TCP 将在两个应用程序之间建立一个全双工 (full-duplex) 的通信。
这个全双工的通信将占用两个计算机之间的通信线路,直到它被一方或双方关闭为止。
IP 是无连接的
IP 用于计算机之间的通信。
IP 是无连接的通信协议。它不会占用两个正在通信的计算机之间的通信线路。这样,IP 就降低了对网络线路的需求。每条线可以同时满足许多不同的计算机之间的通信需要。
通过 IP,消息(或者其他数据)被分割为小的独立的包,并通过因特网在计算机之间传送。
IP 负责将每个包路由至它的目的地。
TCP/IP
TCP/IP 意味着 TCP 和 IP 在一起协同工作。
TCP 负责应用软件(比如你的浏览器)和网络软件之间的通信。
IP 负责计算机之间的通信。
TCP 负责将数据分割并装入 IP 包,然后在它们到达的时候重新组合它们。
IP 负责将包发送至接受者。
短连接和长链接
在HTTP/1.0中,默认使用的是短连接。也就是说,浏览器和服务器每进行一次HTTP操作,就建立一次连接,但任务结束就中断连接。
但从HTTP/1.1起,默认使用长连接,用以保持连接特性。使用长连接的HTTP协议,会在响应头有加入这行代码:Connection:keep-alive
在使用长连接的情况下,当一个网页打开完成后,客户端和服务器之间用于传输HTTP数据的 TCP连接不会关闭,如果客户端再次访问这个服务器上的网页,会继续使用这一条已经建立的连接。Keep-Alive不会永久保持连接,它有一个保持时间,可以在不同的服务器软件(如Apache)中设定这个时间。实现长连接要客户端和服务端都支持长连接。
域名系统(英文:Domain Name System,缩写:DNS)是互联网的一项服务。它作为将域名和IP地址相互映射的一个分布式数据库,能够使人更方便地访问互联网。DNS使用TCP和UDP端口53[1]。
● 请你说一说PC网络故障,以及如何排除障碍
首先是排除接触故障、使用ipconfig查看计算机的上网参数、使用ping命令测试网络的连通性、ping本机IP、ping网关
(1)首先是排除接触故障,即确保你的网线是可以正常使用的。然后禁用网卡后再启用,排除偶然故障。打开网络和共享中心窗口,单击窗口左上侧“更改适配器设置”右击其中的“本地连接“或”无线网络连接”,单击快捷菜单中的“禁用”命令,即可禁用所选网络。接下来重启网络,只需右击后单击启用即可。
(2)使用ipconfig查看计算机的上网参数
1、单击“开始|所有程序|附件|命令提示符“,打开命令提示符窗口
2、输入ipconfig,按Enter确认,可以看到机器的配置信息,输入ipconfig/all,可以看到IP地址和网卡物理地址等相关网络详细信息。
(3)使用ping命令测试网络的连通性,定位故障范围
在命令提示符窗口中输入”ping 127.0.0.1“,数据显示本机分别发送和接受了4个数据包,丢包率为零,可以判断本机网络协议工作正常,如显示”请求超时“,则表明本机网卡的安装或TCP/IP协议有问题,接下来就应该检查网卡和TCP/IP协议,卸载后重装即可。
(4)ping本机IP
在确认127.0.0.1地址能被ping通的情况下,继续使用ping命令测试本机的IP地址能否被ping通,如不能,说明本机的网卡驱动程序不正确,或者网卡与网线之间连接有故障,也有可能是本地的路由表面收到了破坏,此时应检查本机网卡的状态是否为已连接,网络参数是否设置正确,如果正确可是不能ping通,就应该重新安装网卡驱动程序。丢失率为零,可以判断网卡安装配置没有问题,工作正常。
(5)ping网关
网关地址能被ping通的话,表明本机网络连接以及正常,如果命令不成功,可能是网关设备自身存在问题,也可能是本机上网参数设置有误,检查网络参数。
http和https的区别
- https协议需要到CA(Certificate Authority,证书颁发机构)申请证书,一般免费证书较少,因而需要一定费用。
- http是超文本传输协议,信息是明文传输,https则是具有安全性的ssl加密传输协议。
- http和https使用的是完全不同的连接方式,用的端口也不一样,前者是80,后者是443。
- http的连接很简单,是无状态的。Https协议是由SSL+Http协议构建的可进行加密传输、身份认证的网络协议,比http协议安全。(无状态的意思是其数据包的发送、传输和接收都是相互独立的。无连接的意思是指通信双方都不长久的维持对方的任何信息。)
GET 和 POST 的区别
- GET在浏览器回退时是无害的,而POST会再次提交请求。
- GET产生的URL地址可以被Bookmark,而POST不可以。
- GET请求会被浏览器主动cache,而POST不会,除非手动设置。
- GET请求只能进行url编码,而POST支持多种编码方式。
- GET请求参数会被完整保留在浏览器历史记录里,而POST中的参数不会被保留。
- GET请求在URL中传送的参数是有长度限制的,而POST么有。
- 对参数的数据类型,GET只接受ASCII字符,而POST没有限制。
- GET比POST更不安全,因为参数直接暴露在URL上,所以不能用来传递敏感信息。
- GET参数通过URL传递,POST放在Request body中。
TCP和UDP的区别、特点
-
TCP的主要特点是:
- 面向连接。
- 每一条TCP连接只能是点对点的(一对一)。
- 提供可靠交付的服务(无差错,不丢失,不重复,且按序到达)(校验和、重传控制、序号标识、滑动窗口、确认应答实现可靠传输。如丢包时的重发控制,还可以对次序乱掉的分包进行顺序控制。)。
- 提供全双工通信。
- 面向字节流。
-
UDP的主要特点是:
- 无连接。
- 尽最大努力交付(不保证可靠交付)。
- 面向报文。
- 无拥塞控制。
- 支持一对一、一对多、多对一和多对多的交互通信。
- 首部开销小(只有四个字段:源端口、目的端口、长度、检验和)。
采用TCP,一旦发生丢包,TCP会将后续的包缓存起来,等前面的包重传并接收到后再继续发送,延时会越来越大。
UDP对实时性要求较为严格的情况下,采用自定义重传机制,能够把丢包产生的延迟降到最低,尽量减少网络问题对游戏性造成影响。
三次握手
第一次握手:建立连接时,客户端发送syn包(syn=j)到服务器,并进入SYN_SENT状态,等待服务器确认;SYN:同步序列编号(Synchronize Sequence Numbers)。
第二次握手:服务器收到syn包,必须确认客户的SYN(ack=j+1),同时自己也发送一个SYN包(syn=k),即SYN+ACK包,此时服务器进入SYN_RECV状态;
第三次握手:客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ack=k+1),此包发送完毕,客户端和服务器进入ESTABLISHED(TCP连接成功)状态,完成三次握手。
四次挥手:
由于TCP连接是全双工的,因此每个方向都必须单独进行关闭。这个原则是当一方完成它的数据发送任务后就能发送一个FIN来终止这个方向的连接。收到一个 FIN只意味着这一方向上没有数据流动,一个TCP连接在收到一个FIN后仍能发送数据。首先进行关闭的一方将执行主动关闭,而另一方执行被动关闭。四次挥手过程:
(1)客户端A发送一个FIN,用来关闭客户A到服务器B的数据传送。
(2)服务器B收到这个FIN,它发回一个ACK,确认序号为收到的序号加1。和SYN一样,一个FIN将占用一个序号。
(3)服务器B关闭与客户端A的连接,发送一个FIN给客户端A。
(4)客户端A发回ACK报文确认,并将确认序号设置为收到序号加1。
四次挥手原因:这是因为服务端的LISTEN状态下的
请你说一下在浏览器中输入一个网址它的运行过程是怎样的?
参考回答:
1、查询DNS,获取域名对应的IP。
(1)检查浏览器缓存、检查本地hosts文件是否有这个网址的映射,如果有,就调用这个IP地址映射,解析完成。
(2)如果没有,则查找本地DNS解析器缓存是否有这个网址的映射,如果有,返回映射,解析完成。
(3)如果没有,则查找填写或分配的首选DNS服务器,称为本地DNS服务器。服务器接收到查询时:
如果要查询的域名包含在本地配置区域资源中,返回解析结果,查询结束,此解析具有权威性。
如果要查询的域名不由本地DNS服务器区域解析,但服务器缓存了此网址的映射关系,返回解析结果,查询结束,此解析不具有权威性。
(4)如果本地DNS服务器也失效:
如果未采用转发模式(迭代),本地DNS就把请求发至13台根DNS,根DNS服务器收到请求后,会判断这个域名(如.com)是谁来授权管理,并返回一个负责该*域名服务器的IP,本地DNS服务器收到*域名服务器IP信息后,继续向该*域名服务器IP发送请求,该服务器如果无法解析,则会找到负责这个域名的下一级DNS服务器(如http://baidu.com)的IP给本地DNS服务器,循环往复直至查询到映射,将解析结果返回本地DNS服务器,再由本地DNS服务器返回解析结果,查询完成。如果采用转发模式(递归),则此DNS服务器就会把请求转发至上一级DNS服务器,如果上一级DNS服务器不能解析,则继续向上请求。最终将解析结果依次返回本地DNS服务器,本地DNS服务器再返回给客户机,查询完成。
2、得到目标服务器的IP地址及端口号(http 80端口,https 443端口),会调用系统库函数socket,请求一个TCP流套接字。客户端向服务器发送HTTP请求报文:
(1)应用层:客户端发送HTTP请求报文。
(2)传输层:(加入源端口、目的端口)建立连接。实际发送数据之前,三次握手客户端和服务器建立起一个TCP连接。
(3)网络层:(加入IP头)路由寻址。
(4)数据链路层:(加入frame头)传输数据。
(5)物理层:物理传输bit。
3、服务器端经过物理层→数据链路层→网络层→传输层→应用层,解析请求报文,发送HTTP响应报文。
4、关闭连接,TCP四次挥手。
5、客户端解析HTTP响应报文,浏览器开始显示HTML
请你说一说DNS解析过程
参考回答:
1、浏览器先检查自身缓存中有没有被解析过的这个域名对应的ip地址,如果有,解析结束。同时域名被缓存的时间也可通过TTL属性来设置。
2、如果浏览器缓存中没有(专业点叫还没命中),浏览器会检查操作系统缓存中有没有对应的已解析过的结果。而操作系统也有一个域名解析的过程。在windows中可通过c盘里一个叫hosts的文件来设置,如果你在这里指定了一个域名对应的ip地址,那浏览器会首先使用这个ip地址。
但是这种操作系统级别的域名解析规程也被很多黑客利用,通过修改你的hosts文件里的内容把特定的域名解析到他指定的ip地址上,造成所谓的域名劫持。所以在windows7中将hosts文件设置成了readonly,防止被恶意篡改。
3.如果至此还没有命中域名,才会真正的请求本地域名服务器(LDNS)来解析这个域名,这台服务器一般在你的城市的某个角落,距离你不会很远,并且这台服务器的性能都很好,一般都会缓存域名解析结果,大约80%的域名解析到这里就完成了。
4. 如果LDNS仍然没有命中,就直接跳到Root Server 域名服务器请求解析
5. 根域名服务器返回给LDNS一个所查询域的主域名服务器(gTLD Server,国际顶尖域名服务器,如.com .cn .org等)地址
6. 此时LDNS再发送请求给上一步返回的gTLD
7. 接受请求的gTLD查找并返回这个域名对应的Name Server的地址,这个Name Server就是网站注册的域名服务器
8. Name Server根据映射关系表找到目标ip,返回给LDNS
9. LDNS缓存这个域名和对应的ip
10. LDNS把解析的结果返回给用户,用户根据TTL值缓存到本地系统缓存中,域名解析过程至此结束
请你说一下为什么tcp可靠,哪些方法保证可靠
参考回答:
[1] 确认和重传机制
建立连接时三次握手同步双方的“*** + 确认号 + 窗口大小信息”,是确认重传、流控的基础
传输过程中,如果Checksum校验失败、丢包或延时,发送端重传。
[2] 数据排序
TCP有专门的***SN字段,可提供数据re-order
[3] 流量控制
滑动窗口和计时器的使用。TCP窗口中会指明双方能够发送接收的最大数据量,发送方通过维持一个发送滑动窗口来确保不会发生由于发送方报文发送太快接收方无法及时处理的问题。
[4] 拥塞控制
TCP的拥塞控制由4个核心算法组成:
“慢启动”(Slow Start)
“拥塞避免”(Congestion avoidance)
“快速重传 ”(Fast Retransmit)
“快速恢复”(Fast Recovery)
ARP协议
- 第一步:首先,每个主机都会有自己的ARP缓存区中建立一个ARP列表,以表示IP地址和MAC地址之间的对应关系
- 第二步:当源主机要发送数据时,首先检测ARP列表中是否对应IP地址的目的主机的MAC地址如果有,则直接发送数据。如果没有,就向本网段的所有主机发送ARP数据包,内容:我是IP地址,mac地址,谁是IP地址,mac?
- 第三步:当本网络的所有主机收到该ARP数据包时,首先检查数据包中的IP地址是否是自己的IP地址,如果不是,则忽略该数据包。如果是,则首先从数据包中取出源主机的IP和mac地址写入到ARP列表中,如果以存在,则覆盖。然后将自己的mac地址写入arp响应包中,告诉源主机自己是它想要找的mac地址
- 第四步:源主机收到ARP响应包后,将目的主机的IP和mac地址写入arp列表,并利用此信息发送数据如果源主机一直没有收到arp响应数据包,表示arp查询失败。
-
为什么要使用ARP协议
- OSI模型把网络工作分为七层,彼此不直接打交道,只通过接口(layer interface)。IP地址工作在第三层,MAC地址工作在第二层。当协议在发送数据包时,需要先封装第三层IP地址,第二层MAC地址的报头,但协议只知道目的节点的IP地址,不知道目的节点的MAC地址,又不能跨第二、三层,所以得用ARP协议服务,来帮助获取到目的节点的MAC地址。
-
ARP协议是第几层协议
- 工作在二层,是三层协议。
-
ARP在生成环境产生的问题及解决办法:
- ARP病毒,ARP欺骗。
- 高可用服务器对之间切换时要考虑ARP缓存的问题。
- 路由器等设备无缝迁移时要考虑ARP缓存的问题,例如:更换办公室的路由器。
网页很卡的原因
- 带宽不足、硬件配置低、CPU或者是内存被占满。
- http请求次数太多。
- 接收数据时间过长,如下载资源过大。
- JS脚本过大,阻塞了页面的加载。
- 网页资源过多、接受数据时间长、加载某个资源慢。
- DNS解析速度。
二、数据库方面
数据的操作(增删改查)
1.插入数据:
(1)单行INSERT语句
INSERT INTO [表名] (字段1,字段2) VALUES (100,'51WINDOWS.NET')
(2)多行INSERT语句
INSERT INTO [表名] (字段1,字段2) SELECT (字段1,字段2) FROM [表名2] WHERE [条件]
2.删除数据:
DELETE FROM [表名] WHERE [字段名]>100
更新数据:
UPDATE [表名] SET [字段1] = 200,[字段2] = '51WINDOWS.NET' WHERE [字段三] =
\'HAIWA\'
3.查询数据:
select (字段1,字段2) from [表名] where [条件] order by [字段] desc;
4.删除表:
Drop table [表名]
5.新增字段:
ALTER TABLE [表名] ADD [字段名] NVARCHAR (50) NULL
6.删除字段:
ALTER TABLE [表名] DROP COLUMN [字段名]
7.修改字段:
ALTER TABLE [表名] ALTER COLUMN [字段名] NVARCHAR (50) NULL
8.删除表中的所有字段:
truncate table tb;
关系型数据库与NOSQL
- 关系型数据库
- Oracle、DB2、Microsoft SQL Server、Microsoft Access、MySQL
- 非关系型数据库 NOSQL(Not Only SQL)
- NOSQL特点:
- 易扩展,数据之间没有关系的。
- 大数据量,高性能。高性能读写非常灵活的。
- 灵活的数据模型。不需要事先对存储数据建立字段。
- 高可用。
- NOSQL主要主流产品
- Redis、CouchDB、mongoDB、Cassandra。NOSQL中比较火的三个数据库Redis、Memchache、MongoDb。
- NOSQL特点:
MySQL中char、varchar和text三者的区别
在MySQL中,char、varchar和text类型的字段都可以用来存储字符类型的数据,char、varchar都可以指定最大的字符长度,但text不可以。
它们的存储方式和数据的检索方式也都不一样。
数据的检索效率是:char > varchar > text
- 具体说明:
- char:存储定长数据很方便,CHAR字段上的索引效率级高,必须在括号里定义长度,可以有默认值,比如定义char(10),那么不论你存储的数据是否达到了10个字节,都要占去10个字节的空间(自动用空格填充),且在检索的时候后面的空格会隐藏掉,所以检索出来的数据需要记得用trim之类的函数去过滤空格。
- varchar:存储变长数据,但存储效率没有char高,必须在括号里定义长度,可以有默认值。保存数据的时候,不进行空格自动填充,而且如果数据存在空格时,当值保存和检索时尾部的空格仍会保留。另外,varchar类型的实际长度是它的值的实际长度+1,这一个字节用于保存实际使用了多大的长度。
- text:存储可变长度的非Unicode数据,最大长度为2^31-1个字符。text列不能有默认值,存储或检索过程中,不存在大小写转换,后面如果指定长度,不会报错误,但是这个长度是不起作用的,意思就是你插入数据的时候,超过你指定的长度还是可以正常插入。
- 关于存储空间:
在使用UTF8字符集的时候,MySQL手册上是这样描述的:- 基本拉丁字母、数字和标点符号使用一个字节;
- 大多数的欧洲和中东手写字母适合两个字节序列:扩展的拉丁字母(包括发音符号、长音符号、重音符号、低音符号和其它音符)、西里尔字母、希腊语、亚美尼亚语、希伯来语、阿拉伯语、叙利亚语和其它语言;
- 韩语、中文和日本象形文字使用三个字节序列。
- 结论:
- 经常变化的字段用varchar;
- 知道固定长度的用char;
- 超过255字节的只能用varchar或者text;
- 能用varchar的地方不用text;
- 能够用数字类型的字段尽量选择数字类型而不用字符串类型,这会降低查询和连接的性能,并会增加存储开销。这是因为引擎在处理查询和连接回逐个比较字符串中每一个字符,而对于数字型而言只需要比较一次就够了;
- 同一张表出现多个大字段,能合并时尽量合并,不能合并时考虑分表
查询借了“数据库”书籍的所有读者的的姓名
SELECT name
FROM reader
WHERE cardid IN
(SELECT cardid
FROM borrow
WHERE bookid IN
(SELECT bookid
FROM book
WHERE bookname = “数据库”))
查询借书期限超过两个月的所有读者的姓名、所借书籍和借书日期
SELECE name, bookname, bdate
FROM reader, book, borrow
WHERE book.bookid = borrow.bookid
AND book.cardid = borrow.cardid
AND MONTHS_BETWEEN(SYSDATE,bdate)>2
AND sdate IS NULL
按读者姓名查询指定读者的借还书历史记录,假设读者姓名为刘勇。
SELECT bookname, bdate, sdate
FROM book, borrow, reader
WHERE book.bookid = borrow.bookid
AND borrow.cardid = reader.cardid
AND reader.name = “刘勇”
三、Java语言
Integer和int的区别
- Integer是int的包装类,int则是java的一种基本数据类型
- Integer变量必须实例化后才能使用,而int变量不需要
- Integer实际是对象的引用,当new一个Integer时,实际上是生成一个指针指向此对象;而int则是直接存储数据值
- Integer的默认值是null,int的默认值是0
判断一个类是否“无用”,则需同时满足三个条件:
- 该类所有的实例都已经被回收,也就是Java堆中不存在该类的任何实例;
- 加载该类的ClassLoader已经被回收
- 该类对应的java.lang.Class对象没有在任何地方被引用,无法在任何地方通过反射访问该类的方法。
主方法
import java.util.scanner;
import java.util.*;
public class test{
public static void main(String args[]){
System.out.println("Hello, 欢迎学习JAVA");
}
}
输入和输出
Scanner sc = new Scanner(System.in); 构造一个输入对象
System.out.println("enter your name:"); 输出
String name = sc.nextLine(); 输入字符创
System.out.println("enter your age:");
int age = sc.nextInt(); 输入整数型数据
System.out.println("enter your occupation:");
Double occ = sc. nextDouble(); 输入双精度型数
创建字符串
1)通过引用字符数组来创建字符串
char a[]={'A','b','c','E'};
String str1=new String(a);
System.out.println(str1);
2)先定义后赋值
String str2;
str2="this is a book";
System.out.println(str2);
3)通过截取字符数组的一部分来创建字符串
char a3[]={'a','b','c','D','6','p'};
String str3=new String(a3,2,4);
System.out.println(str3);
4)通过类的实例化对象方法实例化一串字符来创建字符串
String str4=new String("this is a book");
System.out.println(str4);
创建数组
一、声明并赋值
int[] arr = {1,2,4, …};
注意这里的花括号不是语句块,而且而且花括号后的分号也不能省
二、声明数组名开辟空间并且赋值
int[] arr;
arr = new int[]{1,2,3, …};
三、声明数组时指定元素个数然后赋值
int[] arr1= new int[3];
数据类型转换
字符串转化为整形数组
String str="123456";
int[] a = new int[str.length()];
for(int i=0;i<str.length();i++) {
a[i] = str.charAt(i)-'0';
}
字符串转化为字符数组
String str="123456";
char[] c = str.toCharArray() ;
System.out.println(c);
字符数组转化为字符串
char[] c = {'a','s','d','4','5',};
String str = new String(c);
System.out.println(str);
字符数组转化为整型数组
char[] c = { '1', '2', '3', '4', '5', };
int[] a = new int[c.length];
for (int i = 0; i < 5; i++) {
a[i] = c[i] - '0';
System.out.println(a[i]);
}
整型数转化为字符串
1.String str = Integer.toString(i); 将整数型转换为字符串
2.String s = String.valueOf(i); 这个可以将double类型转换为字符串
3.String s = "" + i;
字符串转化为整型数
1、int i = Integer.valueOf(str).intValue();
2、double b = Double.parseDouble(str); 将字符串转换为double型
3、int b = Integer.parseInt(str); 将字符串转换为int型
如果
String str1 = “ad45nfdf”;
则
str1.charAt(0) 是为 “a”;
str1.charAt(7)是为”f”;
继承的注意事项:
1,使用关键字 extends 让类与类之间 产生继承关系
2, 父类私有的成员,子类不能继承,因为根本看不到
3,不能为了继承某个功能而随意进行继承操作, 必须要符合 is a 的关系
苹果 is a 水果
男人 is a 人
狗 is a 人 , 这种情况就不能继承了
l 继承中的成员变量关系:
不同名的变量:子类直接继承使用
同名的变量:默认访问的是子类自己的成员变量, 想访问父类中的同名变量,请使用 super.成员变量;
l 继承中的成员方法关系:
不同名的方法:子类直接继承使用
同名的方法:默认访问的是子类自己的成员方法,想访问父类中的同名方法,请使用 super.成员方法();
l super:用来表示当前对象中包含的父类对象空间的引用
调用父类的成员变量:
super.成员变量;
调用方法的成员方法:
super.成员方法();
l 方法重写(override):指 在子父类中,出现了方法声明相同的情况,也叫做方法覆盖,方法复写
l 方法重写的注意事项:
1、 子类的方法声明要与父类相同
2、子类要重写方法的方法,方法的权限修饰符不能比父类的更低
3, 父类私有的方法,子类不能够进行方法重写
方法重载(overload):指 在同一个类中,多个方法名称相同,它们的参数列表不同(个数不同,数据类型不同)
抽象
抽象方法: 方法只有声明部分,没有方法体
抽象类: 包含抽象方法的类,一定是抽象类
使用 abstract 修饰的类,是抽象类
抽象类的特点:
1,抽象类与抽象方法都必须使用 abstract来修饰
2,抽象类不能直接创建对象
3,抽象类中可以有抽象方法,也可以没有抽象方法
4,抽象类的子类
a,实现了抽象方法的具体类
b,抽象类
抽象类面试题:
1,抽象类中是否可以没有抽象方法?如果可以,那么,该类还定义成抽象类有意义吗?为什么?
可以没有抽象方法,有意义,不会让其他人直接创建该类对象
抽象类总结
抽象类不能被实例化(初学者很容易犯的错),如果被实例化,就会报错,编译无法通过。只有抽象类的非抽象子类可以创建对象。
抽象类中不一定包含抽象方法,但是有抽象方法的类必定是抽象类。
抽象类中的抽象方法只是声明,不包含方法体,就是不给出方法的具体实现也就是方法的具体功能。
构造方法,类方法(用 static 修饰的方法)不能声明为抽象方法。
抽象类的子类必须给出抽象类中的抽象方法的具体实现,除非该子类也是抽象类。
JAVA 接口和抽象类的区别
本质:从设计层面来说,抽象是对类的抽象,是一种模板设计,接口是行为的抽象,是一种行为的规范
区别:
1.接口的方法默认是public,所有方法在接口中不能有实现,抽象类可以有非抽象的方法
2.接口中的实例变量默认是final类型的,而抽象类中则不一定
3.一个类可以实现多个接口,但最多只能实现一个抽象类
4.一个类实现接口的话要实现接口的所有方法,而抽象类不一定
5.接口不能用new实例化,但可以声明,但是必须引用一个实现该接口的对象
参数 |
抽象类 |
接口 |
默认的方法实现 |
它可以有默认的方法实现 |
接口完全是抽象的。它根本不存在方法的实现 |
实现 |
子类使用extends关键字来继承抽象类。如果子类不是抽象类的话,它需要提供抽象类中所有声明的方法的实现。 |
子类使用关键字implements来实现接口。它需要提供接口中所有声明的方法的实现 |
构造器 |
抽象类可以有构造器 |
接口不能有构造器 |
与正常Java类的区别 |
除了你不能实例化抽象类之外,它和普通Java类没有任何区别 |
接口是完全不同的类型 |
访问修饰符 |
抽象方法可以有public、protected和default这些修饰符 |
接口方法默认修饰符是public。你不可以使用其它修饰符。 |
main方法 |
抽象方法可以有main方法并且我们可以运行它 |
接口没有main方法,因此我们不能运行它。 |
多继承 |
抽象方法可以继承一个类和实现多个接口 |
接口只可以继承一个或多个其它接口 |
速度 |
它比接口速度要快 |
接口是稍微有点慢的,因为它需要时间去寻找在类中实现的方法。 |
添加新方法 |
如果你往抽象类中添加新的方法,你可以给它提供默认的实现。因此你不需要改变你现在的代码。 |
如果你往接口中添加方法,那么你必须改变实现该接口的类。 |
序列化和反序列化
- 定义:
- Java序列化就是指把Java对象转换为字节序列的过程。Java反序列化就是指把字节序列恢复为Java对象的过程。
- 作用
- 序列化:在传递和保存对象时,保证对象的完整性和可传递性。对象转换为有序字节流,以便在网络上传输或者保存在本地文件中。
- 反序列化:根据字节流中保存的对象状态及描述信息,通过反序列化重建对象。
- 总结
- 核心作用就是对象状态的保存和重建。
四、数据结构和算法
堆栈空间分配区别:
1、栈(操作系统):由操作系统自动分配释放,存放函数的参数值,局部变量的值等。其操作方式类似于数据结构中的栈;
2、堆(操作系统):一般由程序员分配释放,若程序员不释放,程序结束时可能由OS回收,分配方式倒是类似于链表。
堆栈缓存方式区别:
1、栈使用的是一级缓存,他们通常都是被调用时处于存储空间中,调用完毕立即释放;
2、堆是存放在二级缓存中,生命周期由虚拟机的垃圾回收算法来决定(并不是一旦成为孤儿对象就能被回收)。所以调用这些对象的速度要相对来得低一些。
堆栈数据结构区别:
堆(数据结构):堆可以被看成是一棵树,如:堆排序;
栈(数据结构):一种先进后出的数据结构。
Hash表即散列表,其最突出的优点是查找和插入删除具有常数时间的复杂度
其实现原理是:把Key通过一个固定的算法函数即所谓的哈希函数转换成一个整型数字,然后就将该数字对数组长度进行取余,取余结果就当作数组的
先、中、后序遍历
红黑树
- 结点是红色或黑色
- 根结点始终是黑色
- 叶子结点(NIL结点)都是黑色
- 红色结点的两个直接孩子结点都是黑色(即从叶子到根的所有路径上不存在两个连续的红色结点)
- 从任一结点到每个叶子的所有简单路径都包含相同数目的黑色结点
现在有100W个账户密码,要存起来,要求查找时速度尽可能快,你选择什么数据结构?为什么?
参考回答:
选择hash_map,因为其查找速度与数据量基本无关,是常数级别,但是对空间的要求很高,所以是已空间换时间
查找方法和复杂度
查找方法 |
查找长度 |
适用范围 |
|
顺序查找 |
(n+1)/2 |
|
|
折半查找 |
Log2(n+1)-1 |
有序表 |
|
静态树表查找 |
O(nlogn) |
|
|
二叉查找树 |
0(log2n) |
|
|
平衡二叉树 |
|
|
|
排序方法 |
复杂度 |
次数 |
|
直接插入排序法 |
|
|
最简单的排序方法 |
冒泡排序法 |
|
|
|
快速排序法 |
|
|
|
希尔排序法 |
O(n²) |
|
|
直接选择排序法 |
O(n²) |
均为n(n-1)/2 |
|
|
|
|
|
冒泡排序
/*冒泡排序 */
1 public class BubbleSort{
2 public static void main(String[] args){
3 int score[] = {67, 69, 75, 87, 89, 90, 99, 100};
4 for (int i = 0; i < score.length -1; i++){ //最多做n-1趟排序
5 for(int j = 0 ;j < score.length - i - 1; j++){ //对当前无序区间score[0......length-i-1]进行排序(j的范围很关键,这个范围是在逐步缩小的)
6 if(score[j] < score[j + 1]){ //把小的值交换到后面
7 int temp = score[j];
8 score[j] = score[j + 1];
9 score[j + 1] = temp;
10 }
11 }
12 System.out.print("第" + (i + 1) + "次排序结果:");
13 for(int a = 0; a < score.length; a++){
14 System.out.print(score[a] + "\t");
15 }
16 System.out.println("");
17 }
18 System.out.print("最终排序结果:");
19 for(int a = 0; a < score.length; a++){
20 System.out.print(score[a] + "\t");
21 }
22 }
23 }
选择排序法
public class afrr4{
public static void main(String[] args){
int score[] = {67, 69, 75, 87, 89, 90, 99, 100,8,9,45,98};
System.out.print("原始的序列:"+"\t");
for(int b = 0; b < score.length; b++){
System.out.print(score[b] + "\t");
}
System.out.println("");
for (int i = 0; i < score.length; i++){ //最多做n-1趟排序
for(int j = i+1 ;j < score.length; j++){ //对当前无序区间score[0......length-i-1]进行排序(j的范围很关键,这个范围是在逐步缩小的)
if(score[i] < score[j]){ //把小的值交换到后面
int temp = score[j];
score[j] = score[i];
score[i] = temp;
}
}
System.out.print("第" + (i + 1) + "次排序结果:");
for(int a = 0; a < score.length; a++){
System.out.print(score[a] + "\t");
}
System.out.println("");
}
System.out.print("最终排序结果:");
for(int a = 0; a < score.length; a++){
System.out.print(score[a] + "\t");
}
}
}
二分法查找
public static int search(int[] arr, int key) {
int start = 0;
int end = arr.length - 1;
while (start <= end) {
int middle = (start + end) / 2;
if (key < arr[middle]) {
end = middle - 1;
} else if (key > arr[middle]) {
start = middle + 1;
} else {
return middle;
}
}
return -1;
}
五、测试常识
软件测试流程:
1、需求分析 2、软件测试计划(写测试计划书) 3、软件测试设计阶段(写测试用例) 4、软件测试执行阶段 5、评估阶段(出具测试报告)
压力测试和负载测试
软件在一些超负荷情况下的运行情况属于压力测试,或者说属于负载测试应该也是合理的。而压力测试和负载测试属于性能测试,所以选B
压力测试是通过逐步增加系统负载的方式来测试系统性能的变化,最终确定在什么负载条件下系统性能处于失效状态
下面是依据的文档:
单元测试,详细设计文档
集成测试,概括设计文档
系统测试,系统设计文档
SOW:statement of work,工作任务说明书
HLD: High Level Design,概要设计说明书
LLD: Low Level Design,详细设计说明书
UTC: Unit Testing Cases,单元测试用例
单元测试的策略:
- 逻辑覆盖、
- 循环覆盖、
- 同行评审、
- 桌前检查、
- 代码走查、
- 代码评审、
- 景泰数据流分析
设计用例的方法、依据有那些
-
白盒测试
- 白盒测试用例设计有如下方法:语句覆盖、判定覆盖、条件覆盖、判定/条件覆盖、条件组合覆盖和路径覆盖。依据就是代码结构。
-
黑盒测试
- 黑盒测试用例设计方法:基于用户需求的测试、等价类划分方法、边界值分析方法、错误推测方法、因果图方法、判定表驱动分析方法、正交实验法、场景法。依据是用户需求规格说明书,详细设计说明书。
等值分析测试=等价类划分+边界值分析测试
单元测试、集成测试、系统测试
-
粒度不同:
- 单元测试粒度最小,集成测试粒度居中,系统测试粒度最大。
-
测试方式不同:
- 单元测试一般由开发小组采用白盒方式来测试,集成测试一般由开发小组采用白盒加黑盒的方式来测试,系统测试一般由独立测试小组采用黑盒方式来测试。
-
测试内容不同:
- 单元测试主要测试单元是否符合“设计”,集成测试既验证“设计”,又验证“需求”,系统测试主要测试系统是否符合“需求规格说明书”。
-
使用阶段不同:
- 单元测试为开发人员在开发阶段要做的事情,集成测试和系统测试为测试人员在测试周期内级层做的工作。
有效等价类和无效等价类
无效等价类是指对于软件规格说明而言,是没有意义的、不合理的输入数据集合。利用无效等价类可以找出程序异常说明情况,检查程序的功能和性能的实现是否有不符合规格说明要求的地方。
有效等价类是指输入数据完全满足程序输入的规格说明,是有效、有意义的输入数据所构成的集合。利用有效等价类可以检验程序是否满足规格说明所规定的功能和性能。
六、操作系统
对文件和目录进行操作的命令
- pwd
- cd
- ls
- touch
- mkdir
- rmdir
- cp
- mv
- rm
- wc
- du
pwd:显示工作目录路径
命令语法:pwd [选项]
选项 | 含义 |
---|---|
-L | 目录链接时,输出链接路径 |
-P | 输出物理路径 |
cd:更改工作目录路径
命令语法:cd[选项][目录]
选项 | 含义 |
---|---|
cd或cd ~ | 回到用户主目录 |
cd .. | 变当前工作目录路径位置至当前目录的父目录。 |
cd -P | 如果是链接路径,则进入链接路径的源物理路径 |
cd ~li | 改用户工作目录路径位置至用户li的主目录。 |
ls:列出目录和文件信息
选项 | 选项含义 |
---|---|
-a | 显示指定目录下所有子目录的文件,包括隐藏文件 |
-A | 显示指定目录下所有子目录与文件,包括隐藏文件,但不列出“.”和“..” |
-c | 配合-lt:根据车体么排序并显示ctime |
-d | 如果参数是目录,只显示其名称而不显示其下的歌文件和子目录 |
-F | 显示文件类型 |
-i | 在输出的第一列显示文件的inode号 |
-l | 以长格式显示文件的详细信息 |
-r | 逆序排列 |
-t | 根据修改时间排序 |
-s | 一块数形式先生每个文件分配的尺寸 |
-S | 根据文件大小排序 |
例子:显示目录/var下文件的子目录的简单信息
~]# ls /var
显示/root目录下所以文件和子目录的详细信息,包括隐藏文件
~]# ls -al /root
显示/etc目录下的文件和子目录信息,用标记标出文件类型
~]# ls -F /etc
touch:创建空文件、更改文件时间
命令语法:touch [选项] [文件]
选项 | 选项含义 |
---|---|
-a | 只更改访问时间(atime) |
-m | 更改文件的修改时间记录(mtime) |
-c | 假如目标文件存在,则不会建立新的文件 |
-r<文件> | 使用指定文件的时间属性而非当前时间 |
-d<字符串> | 使用指定字符串表示时间而非当前时间 |
-t<日期时间> | 使用[CC]YY]MMDDhhmm[.ss]格式的时间而非当前时间 |
例如:在当前目录下创建文件file1、file2、file3
[aaa@qq.com ~]# touch file1
[aaa@qq.com ~]# touch file2 file3
[aaa@qq.com ~]# ls -l file1 file2 file3
-rw-r--r--. 1 root root 5 Aug 3 22:12 file1
-rw-r--r--. 1 root root 6 Aug 3 22:12 file2
-rw-r--r--. 1 root root 0 Aug 3 22:12 file3
将文件file1的时间记录改为9月17日19点30分
[aaa@qq.com ~]# ls -l /root/file1
-rw-r--r--. 1 root root 5 Aug 4 2019 /root/file1
[aaa@qq.com ~]# touch -c -t 09171930 /root/file1
[aaa@qq.com ~]# ls -l /root/file1
-rw-r--r--. 1 root root 5 Sep 17 2019 /root/file1
时间格式是MMDDHHmm,如果要加上2019年年份
[aaa@qq.com ~]# touch -c -t 09171930 /root/file1
mkdir:创建目录
命令语法:mkdir [选项] [目录]
选项 | 选项含有 |
---|---|
-m<权限模式> | 对新创建的目录设置权限,在没有-m选项时,默认权限是755 |
-v | 每次创建新目录都显示信息 |
-p | 可以是一个路径名称。此时若路径中的某些目录尚不存在,加上此选项后,系统将自动创建那些尚不存在的目录,即以此可以建立多个目录 |
例子:创建目录newdir1 ,其默认权限为755
[aaa@qq.com ~]# touch -c -t 09171930 /root/file1
[aaa@qq.com ~]# ls -ld newdir1
drwxr-xr-x. 2 root root 6 Jun 22 22:27 newdir1
创建目录newdir2,其权限为777
[aaa@qq.com ~]# mkdir -m 777 newdir2
[aaa@qq.com ~]# ls -ld newdir2
drwxrwxrwx. 2 root root 6 Aug 3 22:39 newdir2
rmdir:删除空目录 命令语法:rmdir [选项] [目录]
选项 | 选项含义 |
---|---|
-p | 递归删除目录,当子目录删除后其父目录为空时,也一同被删除 |
-v | 输出处理的目录详情 |
例子:同时删除/root/newdir2和/root/newdir2/newdir3这两个空目录
[aaa@qq.com ~]# mkdir /root/newdir2
[aaa@qq.com ~]# mkdir /root newdir2/newdir3
[aaa@qq.com ~]# rmdir -pv /root/newdir2/newdir3
rmdir: removing directory, ‘/root/newdir2/newdir3’
rmdir: removing directory, ‘/root/newdir2’
rmdir: removing directory, ‘/root’
rmdir: failed to remove directory ‘/root’: Device or resource busy
cp:复制文件的和目录
命令语法:cp [选项] [源文件|目录] [目标文件|目录]
选项 | 选项含义 |
---|---|
-a | 在复制目录时保留链接、文件属性、并递归地复制目录,等同于-dpr选项 |
-d | 复制时保留链接 |
-f | 在覆盖目标文件之前不给出提示信息要求用户确认 |
-i | 和-f选项相反看,在覆盖目标文件之前给出提示信息,要求用户确认 |
-p | 出复制源文件的内容外,还把其修改时间和访问权限也复制到新文件中 |
-l | 不做复制,只是链接文件 |
-r | 如果给出的源文件是一个目录文件,将递归复制该目录下所有的子目录和文件。此时目标必须为一个目录名 |
例子:将/etc/grub2.cfg文件复制到/root目录下,并改名为grub
[aaa@qq.com ~]# cp /etc/grub2.cfg /root/grub
cp: overwrite ‘/root/grub’? y
[aaa@qq.com ~]# ls
anaconda-ks.cfg grub newdir1
将/etc/grub2.cfg文件复制到/root目录下
[aaa@qq.com ~]# cp /etc/grub2.cfg /root
[aaa@qq.com ~]# ls
anaconda-ks.cfg grub grub2.cfg newdir1
[aaa@qq.com ~]#
将/boot目录以及该目录中的所有文件和子目录都复制到/root目录中
[aaa@qq.com ~]# cp -r /boot /root
[aaa@qq.com ~]# ls -l /root
total 24
-rw-------. 1 root root 1260 Jun 9 14:21 anaconda-ks.cfg
dr-xr-xr-x. 5 root root 4096 Jun 22 23:21 boot
-rw-r--r--. 1 root root 4287 Jun 22 23:15 grub
-rw-r--r--. 1 root root 4287 Jun 22 23:18 grub2.cfg
drwxr-xr-x. 2 root root 6 Jun 22 22:27 newdir1
mv:文件和目录改名、移动文件和目录路径
命令语法:mv [选项] [源文件|目录] [目标文件|目录]
选项 | 选项含义 |
---|---|
-i | 覆盖前询问 |
-f | 覆盖前不询问 |
-n | 不覆盖已存在的文件 |
-u | 只有在源文件文件比目标文件新,或目标文件不存在时才进行移动 |
-T | 将目标文件视作普通文件处理 |
例子:将/root/pic目录下所以的后缀名为“.png”的文件移动到/usr/local/share/pic目录下
[aaa@qq.com ~]# mv -f /root/pic/*.png /usr/local/share/pic
把/root/pic/kpic.png文件改名为/root/pic/life.png
[aaa@qq.com ~]# mv /root/pic/kpic.png /root/pic/life.png
[aaa@qq.com ~]# ls /root/pic
{kpic.png life.png
把/root/pic目录名称更改为/root/mypic
aaa@qq.com ~]# mv /root/pic /root/mypic
[aaa@qq.com ~]# ls /root
123.png} anaconda-ks.cfg boot grub grub2.cfg mypic newdir1
rm:删除文件或目录
命令语法:rm [选项] [文件|目录]
选项 | 选项含义 |
---|---|
-f | 强制删除。忽略不存在的文件,不给出提示信息 |
-r | 递归删除目录及其内容 |
-i | 在删除前需要确认 |
例子:删除当前目录下的file4文件
aaa@qq.com ~]# rm file4
rm: remove regular empty file ‘file4’? y
[aaa@qq.com ~]# ls
123.png} anaconda-ks.cfg boot grub grub2.cfg mypic newdir1
连同/root/ab/a文件和/root/ab目录一起删除
[aaa@qq.com ~]# mkdir /root/ab
[aaa@qq.com ~]# touch /root/ab/a
[aaa@qq.com ~]# ls -l /root/ab/a
-rw-r--r--. 1 root root 0 Jun 22 23:51 /root/ab/a
[aaa@qq.com ~]# rm -rf /root/ab
[aaa@qq.com ~]# ls /root
123.png} anaconda-ks.cfg boot grub grub2.cfg mypic newdir1
wc:统计文件行数、单词数、字节数和字符数
命令语法:wc [选项] [文件]
选项 | 选项含义 |
---|---|
-l | 统计行数 |
-w | 统计单词数 |
-c | 统计字节数 |
-m | 统计字符数 |
-L | 统计文件中最长行的长度 |
例子:统计/root/aa文件的行数、单词数和字节数
[aaa@qq.com ~]# wc -l /root/aa/ce.log
3 /root/aa/ce.log
统计/root目录下有多少子目录和文件
[aaa@qq.com ~]# ls /root|wc -l
8
du:计算机文件或目录的容量
命令语法:du [选项]...[文件或目录]...
选项 | 选项含义 |
---|---|
-h | 人性化显示容量信息 |
-a | 查看所有目录以及文件的容量信息 |
-s | 仅显示总容量 |
-c | 显示总计信息 |
-l | 如果是硬连接,就多次计算其尺寸 |
-x | 跳过处于不同文件系统之上的目录 |
-S | 不包括子目录的占用量 |
-L | 找出任何符号链接指示的真正目的地 |
查看/root目录及子目录的容量信息
[aaa@qq.com ~]# du /root
[aaa@qq.com ~]# du -a /root
查看/root所占磁盘空间总和
[aaa@qq.com ~]# du -sh /root
100M /root
以MB为单位显示/root目录磁盘占用量
[aaa@qq.com ~]# du -sh /root
100M /root
选项 | 选项含义 |
---|---|
-h | 人性化显示容量信息 |
-a | 查看所有目录以及文件的容量信息 |
-s | 仅显示总容量 |
-c | 显示总计信息 |
-l | 如果是硬连接,就多次计算其尺寸 |
-x | 跳过处于不同文件系统之上的目录 |
-S | 不包括子目录的占用量 |
-L | 找出任何符号链接指示的真正目的地 |
查看/root目录及子目录的容量信息
[aaa@qq.com ~]# du /root
[aaa@qq.com ~]# du -a /root
查看/root所占磁盘空间总和
[aaa@qq.com ~]# du -sh /root
100M /root
以MB为单位显示/root目录磁盘占用量
[aaa@qq.com ~]# du -sh /root
100M /root
linux系统显示的命令
- uname
- hostname
- free
- du
uname:显示计算机及操作系统相关信息
命令语法:uname [选项]
选项 | 选项含义 |
---|---|
-a | 显示全部的信息 |
-m | 显示计算机硬件架构名称 |
-n | 显示在网络上的主机名称 |
-r | 显示操作系统的内核发行号 |
-s | 显示操作系统名称 |
例子:显示操作系统的内核发行号
[aaa@qq.com ~]# uname -r
3.10.0-957.el7.x86_64
显示操作系统的全部信息
[aaa@qq.com ~]# uname -a
Linux localhost.localdomain 3.10.0-957.el7.x86_64 #1 SMP Thu Nov 8 23:39:32 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux
hostname:显示或修改计算机主机名
命令语法:
-
hostname [选项] [主机名|-F <文件>]
-
hostname [选项]
选项 | 选项含义 |
---|---|
-s | 显示短主机名 |
-i | 显示IP地址 |
-f | 显示长主机名 |
-d | 显示DNS |
例子:显示当前计算机主机名
[aaa@qq.com ~]# hostname
localhost.localdomain
设置当前计算机的主机名为linux[1]
[aaa@qq.com ~]# hostname linux
[aaa@qq.com ~]# hostname
linux
free:查看内存信息
命令语法:free [选项]
选项 | 选项含义 |
---|---|
-c <次数> | 显示指定次数结果数据 |
-t | 显示内存加上swap总的容量 |
-b | 以字节为单位显示内存使用情况 |
-k | 以KB为单位显示内存使用情况 |
-m | 以MB为单位显示内存使用情况 |
-g | 以GB为单位显示内存使用情况 |
例子:查看系统物理内存和swap使用情况
[aaa@qq.com ~]# free
total used free shared buff/cache available
Mem: 995896 148252 403780 7828 443864 621672
Swap: 2097148 0 2097148
显示系统的物理内存加上swap总的容量
[aaa@qq.com ~]# free -t
total used free shared buff/cache available
Mem: 995896 147960 404052 7828 443884 621964
Swap: 2097148 0 2097148
Total: 3093044 147960 2501200
linux命令,找出关键字出现的次数
- 语法:grep 字符串 文件名|wc -l ,grep输出,wc -l按行统计
- 例子:
- 统计task-hbase-transform.log中NullPointerException出现的次数:
grep NullPointerException task-hbase-transform.log|wc -l
。 - 如果是多个字符串出现次数,可使用:
grep 'objStr1\|objStr2' filename|wc -l
#直接用 | 链接起来即可。
- 统计task-hbase-transform.log中NullPointerException出现的次数:
常用命令
- "|": 管道符“|”将两个命令隔开,管道符左边命令的输出就会作为管道符右边命令的输入。连续使用管道意味着第一个命令的输出会作为第二个命令的输入,第二个命令的输出又会作为第三个命令的输入,依此类推。
- grep:-v 不显示匹配上的内容;-n 显示匹配上的内容
- grep -v down,显示不包含down的内容。
- grep -n down,显示包含down的内容。
- du:(disk use)显示每个文件和目录的磁盘使用空间。
- df:(disk free)显示磁盘分区上可以使用的磁盘空间。
进程和线程
- 区别:
- 进程是资源分配的最小单位,线程是程序执行的最小单位(资源调度的最小单位)
- 进程有自己的独立地址空间,每启动一个进程,系统就会为它分配地址空间,建立数据表来维护代码段、堆栈段和数据段,这种操作非常昂贵。而线程是共享进程中的数据的,使用相同的地址空间,因此CPU切换一个线程的花费远比进程要小很多,同时创建一个线程的开销也比进程要小很多。
- 线程之间的通信更方便,同一进程下的线程共享全局变量、静态变量等数据,而进程之间的通信需要以通信的方式(IPC)进行。不过如何处理好同步与互斥是编写多线程程序的难点。
- 但是多进程程序更健壮,多线程程序只要有一个线程死掉,整个进程也死掉了,而一个进程死掉并不会对另外一个进程造成影响,因为进程有自己独立的地址空间。
- 进程与线程的资源
- 线程共享:进程代码段、进程的公有数据(利用这些共享的数据,线程很容易的实现相互之间的通讯)、进程打开的文件描述符、信号的处理器、进程的当前目录和进程用户ID与进程组ID。
- 线程独有:栈(保存其运行状态和局部自动变量)、程序计数器。
- 进程与线程的同步
- 进程:无名管道、有名管道、信号、共享内存、消息队列、信号量
- 线程:互斥量、读写锁、自旋锁、线程信号、条件变量
- 僵尸进程
- 定义:一个进程使用fork创建子进程,如果子进程退出,而父进程并没有调用wait或者waitpid获取子进程的状态信息,那么子进程的进程描述符等一系列信息还会保存在系统中。这种进程称之为僵死进程。
- 危害:在Unix系统管理中,当用ps命令观察进程的执行状态时,经常看到某些进程的状态栏为defunct,这就是所谓的“僵尸”进程。“僵尸”进程是一个早已死亡的进程,但在进程表(processs table)中仍占了一个位置(slot)。由于进程表的容量是有限的,所以,defunct进程不仅占用系统的内存资源,影响系统的性能,而且如果其数目太多,还会导致系统瘫痪。
- 处理方法:
- 改写父进程,在子进程死后要为它收尸。具体做法是接管SIGCHLD信号。子进程死后,会发送SIGCHLD信号给父进程,父进程收到此信号后,执行waitpid()函数为子进程收尸。这是基于这样的原理:就算父进程没有调用wait,内核也会向它发送SIGCHLD消息,尽管默认处理是忽略,如果想响应这个消息,可以设置一个处理函数。
- 把父进程杀掉。父进程死后,僵尸进程成为”孤儿进程”,过继给1号进程init,init始终会负责清理僵尸进程.它产生的所有僵尸进程也跟着消失。
- 孤儿进程
- 父进程运行结束,但子进程还在运行(未运行结束)的子进程就称为孤儿进程。孤儿进程最终会被init进程(进程号为1)所收养,因此init进程此时变成孤儿进程的父进程,并由init进程对它们完成状态收集工作。(linux下,init是内核启动的第一个用户级进程,init有许多很重要的任务,比如像启动getty(用于用户登录)、实现运行级别、以及处理孤立进程。)
Linux命令
- "|": 管道符“|”将两个命令隔开,管道符左边命令的输出就会作为管道符右边命令的输入。连续使用管道意味着第一个命令的输出会作为第二个命令的输入,第二个命令的输出又会作为第三个命令的输入,依此类推。
- grep:-v 不显示匹配上的内容;-n 显示匹配上的内容
- grep -v down,显示不包含down的内容。
- grep -n down,显示包含down的内容。
- du:(disk use)显示每个文件和目录的磁盘使用空间。
- df:(disk free)显示磁盘分区上可以使用的磁盘空间。
显示终端上的所有进程
ps -a
Linux杀死某个进程的方法
1.定位进程
ps -aux | grep ***
2.杀死进程
我们可以通过 进程的名字和进程的ID(PID)来结束进程。
结束命令:
kill:通过进程ID来结束进程
killall:通过进程名字结束进程
最常使用的结束进程的信号是:
Signal Name |
Single Value | Effect |
SIGHUP | 1 | 挂起 |
SIGINT | 2 | 键盘的中断信号 |
SIGKILL | 9 | 发出杀死信号 |
SIGTERM | 15 | 发出终止信号 |
SIGSTOP | 17, 19, 23 | 停止进程 |
我们可以通过Single Value的值来代替信号的名字。所以我们现在来杀死python进程:
kill SIGNAL PID
SIGNAL 是要发送的信号,PID是进程号。
kill -9 14992
上面的命令就是杀死python进程的。如果有多个python程序在运行,想要全部结束的话,可以
killall -9 python
七、智力题
1、10个堆,每堆10个苹果,其中9个堆里苹果是50g/个,一个堆里苹果是40g/个,有一杆秤只能称一次,所称重量为x,求40g苹果所在堆。
-
- 将堆编码为1-10;然后每堆拿出k个,最后少了k*10克,则知道是第几堆的苹果。
2、5L和6L水桶,得到三升水。
-
- 1、6L的水桶装满水,倒满5L的桶。 2、将5L桶里的水倒了,将6L桶里剩余的1L放入5L桶。 3、6L的桶装满水,倒满5L桶里,6L桶里还剩2L(6-4)水。 4、 将5L桶里的水倒了,将6L桶里剩余的2L水放入5L桶里。 5、将6L桶装满水,倒满5L的桶,这时6L的桶里还剩3L水。
3、两个一小时蚊香怎么得到15分钟的记时
-
- 同时点燃AB两只蚊香,其中A蚊香点燃两头,等A蚊香烧完后(30分钟),点燃B蚊香的另一头。
4、4分钟沙漏和7分钟沙漏怎么漏出9分钟
-
- 4分钟的和7分钟的同时开始,4分钟的完后又倒过来开始。7分钟的沙漏完后立马倒过来,(4分钟的沙漏还剩1分钟)。等4分钟的沙漏完后,将7分钟的又立马倒过来,等漏完就是9分钟。
5、八个球,其中有一个是其余球重量的1.5倍,有什么方案找出来
-
- 3次。 AB两边,一边放4个,如果A重,则把B端的去了,A端的4个分成AB端一边两个。在把轻的那端去了,重的那端的2个分成一边一个,重的那个球就找出来了。
6、桌上100个球,每次可以拿一到五个, 现在我们两个人依次拿球,你先拿,使用怎样的拿球策略,可以使你最终能拿到最后一个球?
-
- 第一次拿四个,后来每个你拿球的时候只要保证剩下的球是6的倍数就行了如果他拿n个球 ,你就拿6-n个球。
7、有10个石头,每人每次可以拿1-2个,轮流拿,最后一个拿的人算输,有什么必赢的方案。
-
- 对方先拿、保证两个人每一轮回拿满3个(对方拿一个,我拿两个、对方拿两个,我拿一个)。
8、一亿数据获取前1000个最大值 https://zhuanlan.zhihu.com/p/73233544
-
- 把一亿个数字的前100个 首先放入数组。 然后把最小值放在ary[0]。然后再循环100到一亿之间的。 每次循环判断当前数字是否大于ary[0]当大于时,当前数字放入ary[0] 并再次重构数组最小值进入ary[0]以此类推 。当循环完这一亿个数字后。 最大的前100个数字就出来了。
推荐阅读
-
【开发调试】谷歌浏览器中调试移动网页和测试网速下页面效果
-
【开发调试】谷歌浏览器中调试移动网页和测试网速下页面效果
-
android模拟器开发和测试nfc应用实例详解
-
在微信开发框架中增加对菜单分组的管理,方便多个项目*切换处理和功能测试
-
springboot配置开发和测试环境并添加启动路径方式
-
测试和开发人员之项目打包部署
-
适用于Java开发人员的微服务:性能和负载测试
-
iOS14公测版和开发者测试版有什么区别
-
《ServerSuperIO Designer IDE使用教程》-1.标准Modbus和非标准协议的使用、测试以及驱动开发。附:v4.2发布
-
Slickflow.NET 开源工作流引擎高级开发(二) -- 流程快速测试和流程图形代码创建介绍