精华内容
下载资源
问答
  • 计算机病毒攻击战是将( )植入敌方计算机系统,删除其数据,瘫痪其系统。
    千次阅读
    2021-07-15 03:36:23

    答案

    查看答案

    解析:

    【解析题】当前,应用计算机解决实际问题的能力主要体现为能够熟练使用OFFICE和网页制作工具操作计算机。

    【解析题】现在许多智能手机都具有触摸屏,它兼有键盘和鼠标器的功能,可作为计算机系统的输入设备。

    【解析题】在机器学习的背景上,人工智能区别于传统计算机的地方就在于人工智能能自主进行(),来揭示数据的内在价值

    【解析题】计算机网络

    【解析题】计算机启动后1短报警,请问是以下哪种情况 ( )。

    【解析题】一台计算机远程连接到另一台计算机上,并可以运行远程计算机上的各种程序,这种服务称为Telnet或远程登录。

    【解析题】在计算机网络中,通常把提供并管理共享资源的计算机称为 。

    【解析题】微型计算机中的内存储器,通常采用:

    【解析题】计算机可以进行算数运算不能进行逻辑运算

    【解析题】1983年,我国第一台亿次巨型电子计算机诞生了,它的名称是()

    【解析题】计算机能识别的语言是( )

    【解析题】用计算机对音频信息进行处理,要将模拟信号转换为数字信号,这个过程称为模拟音频的()。

    【解析题】在计算机网络术语中,WAN表示____。

    【解析题】在计算机网络中,带宽指的是____

    【解析题】计算机( )是指运行在计算机硬件系统之上的各种程序、数据及相关文档资料的总称。

    【解析题】为网络中各计算机之间交流信息提供统一的语言和规则的是________。

    【解析题】指令是控制计算机执行的命令,它由( )和地址码组成

    【解析题】被测试的程序不在机器上运行,而是采用人工检测和计算机辅助分析检测的手段称为()测试。

    【解析题】第一台计算机ENIAC的目的是进行科学计算,其主要计算的问题面向于( )。

    【解析题】保持计算机机房清洁有利于防止计算机病毒

    【解析题】退出 Windows 时,直接关闭计算机电源可能产生的后果是( )。

    【解析题】Internet中的用户远程登录,是指用户使用 ( ) 命令,使自己的计算机暂时成为远程计算机的一个仿真终端的过程。

    【解析题】十进制"-65"在计算机内部用二进制代码10111111表示,其表示方式为____________。

    【解析题】计算机绘图模式主要有哪些?()

    【解析题】下列属于计算机外设的是( )。

    【解析题】多媒体计算机中除了通常计算机的硬件外,还必须包括___四个硬部件。

    【解析题】计算机系统由哪2大类组成_____?

    【解析题】7计算机网络的性能指标包括:

    【解析题】通常一条计算机指令用来____。

    【解析题】计算机最主要的工作特点是()。

    【解析题】在计算机网络中,表征数据传输可靠性的指标是( )

    【解析题】数字化时代,需要利用计算机辅助设计处理来完善设计作品,充分表达设计作品的涵义,将设计师的想法最大限度地与受众得到( )与( )

    【解析题】简述计算机病毒的主要传播途径及防范计算机病毒的主要措施

    【解析题】在下面的选项中,( )不属于按计算机的用途分类

    【解析题】计算机网络是由主机、通信设备和【 】构成。

    【解析题】计算机采用二进制是因为()。

    【解析题】在计算机学院学习过程中,除了课堂学习外,学院还为同学们提供哪些学习机会和学习资源:()

    【解析题】在计算机网络中,实现数字信号和模拟信号之间转换的设备是

    【解析题】未来计算机硬件的发展有可能使用的技术是______。

    【解析题】最早的计算机编舞软件取名为“生命形式”,____________第一个试用了这个软件。

    【解析题】下列选项中,赋予计算机综合处理声音、图像、动画、文字、视频和音频信号功能的技术是()

    【解析题】10.计算机网络中常用的3种有线传输媒体是双绞线、________、________

    【解析题】智慧职教: 《中华人民共和国治安管理处罚法》第几条规定,有违反国家规定,对计算机信息系统功能进行删除、修改、增加、干扰,造成计算机信息系统不能正常运行的,会处5-10日拘留。

    【解析题】在计算机中,鼠标器属于()。

    【解析题】中国大学MOOC: 只有当对方的计算机连接到Internet时才能给他发送电子邮件。

    【解析题】下列度量单位中,用来度量计算机外部设备传输率的是______。

    【解析题】程序是问题求解步骤的描述,计算机能直接识别的程序是( )

    【解析题】因特网上许多复杂网络和许多不同类型的计算机之间能够互相通信的基础是____协议

    【解析题】第二代计算机网络的主要特点是 ( )。

    【解析题】若需在一台计算机上同时运行多个应用程序,必须安装使用具有_________处理功能的操作系统。

    相关问题:

    1、【解析题】 汉字内码和ASCII表示方法是一样的,在计算机内部的存储没有区别,只是在显示时可以区分为汉字还是英文。

    2、【解析题】 微型计算机的CPU由( )组成。

    3、【解析题】 占发明创新1%不到,它需要综合运用所有的知识,还要创造新知识,如计算机的发明,属于第( )等级。

    4、【解析题】 计算机在存储波形声音之前,必须进行( )。

    5、【解析题】 计算机网络中,所有的计算机都连接到一个中心节点上,一个网络节点需要传输数据,首先传输到中心节点上,然后由中心节点转发到目的节点,这种连接结构被称为( )。

    6、【解析题】 计算机辅助设计的英文缩写为

    7、【解析题】 计算机中主板上所采用的电源为____。

    8、【解析题】 ()是使计算机对人的意识 、思维的信息过程进行模拟的某些智能行为

    9、【解析题】 一台计算机所有的指令集合,反映了计算机的基本功能,称为()

    10、【解析题】 计算机执行指令的第一步是()

    11、【解析题】 计算机病毒的危害表现为()。

    12、【解析题】 具有高速运算能力和图形处理功能,通常运行unix操作系统,适合工程与产品设计等应用的一类计算机产品,通常称为().

    13、【解析题】 在计算机程序设计语言中,可以直接被计算机识别并执行的是( )。

    14、【解析题】 在微型计算机中,应用最普遍的字符编码是

    15、【解析题】 未来的计算机不仅可以替代人的记忆功能,也能替代人的思维功能,这为作战指挥( )提供了基础。

    16、【解析题】 “计算机”是Windows 7的一个应用程序文件夹

    17、【解析题】 计算机( )是指运行在计算机硬件系统之上的各种程序、数据及相关文档资料的总称。

    18、【解析题】 “云”使用了数据多副本容错、比使用本地计算机可靠

    19、【解析题】 下列四项中不属于微型计算机主要性能指标的是( )

    20、【解析题】 将一个部门中的多台计算机组建成局域网可以实现资源共享。在下列有关局域网的叙述中,错误的是_________。

    21、【解析题】 [08-573]某家庭采用ADSL宽带接入方式连接Internet,ADSL调制解调器连接一个4口的路由器,路由器再连接4台计算机实现上网的共享,这种家庭网络的拓扑结构为:

    22、【解析题】 S7-200系列PLC与计算机PC的通信时,需要把RS-232C端连接到S7-200PLC的通信端口上。

    23、【解析题】 计算机中,负责指挥计算机各部分自动协调一致地进行工作的部件是

    24、【解析题】 组成计算机网络的网络节点包括()节点和()节点。

    25、【解析题】 在计算机中,算法是指()。

    26、【解析题】 采用大规模和超大规模集成电路的计算机属于( )。

    27、【解析题】 微型计算机的显示器显示西文字符时,一般情况下一屏最多可显示( )。

    28、【解析题】 机器语言是用二进制代码表示的,对应于计算机硬件的指令系统,运行效率最高,但可读性和移植性差

    29、【解析题】 计算机可分为主机和____两部分

    30、【解析题】 计算机病毒实际上是一种特殊的程序

    31、【解析题】 中国大学MOOC:"计算机先要用( )设备把波形声音的模拟信号转换成数字信号再处理或存储。";

    32、【解析题】 计算机业界最初的硬件巨头“蓝色巨人”指的是__________。

    33、【解析题】 连接计算机系统结构的五大组成部件一般通过( )

    34、【解析题】 在计算机内部,一切信息的存储、处理与传送都采用二进制来表示。( )

    35、【解析题】 计算机中运算器的作用是( )。

    36、【解析题】 在计算机中,______字节称为1MB

    37、【解析题】 中国大学MOOC: 某计算机采用微程序控制器的微指令格式采用编码方式组织,某互斥命令组由4个微命令组成,则微指令寄存器中相应字段的位数至少需( )。 (单选)

    38、【解析题】 人工智能的实质是计算机智能。

    39、【解析题】 微型计算机硬件系统由( ? )组成。

    40、【解析题】 一台计算机的字长是 4 个字节,这意味着( )。

    41、【解析题】 计算机的网络资源共享包括()的共享。

    42、【解析题】 在数据库设计中,用E-R图来描述信息结构但不涉及信息在计算机中的表示,它是数据库设计的( )段。

    43、【解析题】 根据统计,当前计算机病毒扩散最快的途径是( )

    44、【解析题】 第二代计算机的主要特征是采用___________________作为计算机的逻辑元件。

    45、【解析题】 第一台电子数字计算机是( ),它于1946年诞生于美国。

    46、【解析题】 虚拟现实投术是一种运用计算机仿真系统创建多源信思融合的交互式三维动态实景以及动作仿真的技术,可以给使用者提供沉浸性,多感知性,交互性的互动体验,虚拟现实技术所构造的虚拟环境说明

    47、【解析题】 用户计算机通过电话网接入Internet使用的设备是

    48、【解析题】 运算器是计算机的( )部件

    49、【解析题】 1946年,冯·诺依曼提出了() 原理,奠定了计算机的基本结构、基本工作原理,开创了程序设计的新时代

    50、【解析题】 计算机病毒可以通过( ) 传播。

    更多相关内容
  • linux系列之常用运维命令整理笔录

    万次阅读 多人点赞 2019-10-28 17:33:21
    单位为KB 3、top命令使用 top命令可以实时动态地查看系统的整体运行情况,是一个综合了多方信息监测系统性能和运行信息的实用工具,TOP命令是Linux下常用的性能分析工具,能够实时显示系统中各个进程的资源占用状况...

    系列博客专栏:

    本博客记录工作中需要的linux运维命令,大学时候开始接触linux,会一些基本操作,可是都没有整理起来,加上是做开发,不做运维,有些命令忘记了,所以现在整理成博客,当然vi,文件操作等就不介绍了,慢慢积累一些其它拓展的命令,博客不定时更新,本博客命令基于Centos系统

    在这里插入图片描述

    一、系统监控

    1、free命令使用

    • free命令简介
      free 命令能够显示系统中物理上的空闲和已用内存,还有交换内存,同时,也能显示被内核使用的缓冲和缓存

    • free命令语法

    语法:free [param]
    

    param可以为:

    • -b:以Byte为单位显示内存使用情况;

    • -k:以KB为单位显示内存使用情况;

    • -m:以MB为单位显示内存使用情况;

    • -o:不显示缓冲区调节列;

    • -s<间隔秒数>:持续观察内存使用状况;

    • -t:显示内存总和列;

    • -V:显示版本信息。

    • free命令使用
      在这里插入图片描述
      Mem:表示物理内存统计

    • total:表示物理内存总数(total=used+free)

    • used:表示系统分配给缓存使用的数量(这里的缓存包括buffer和cache)

    • free:表示未分配的物理内存总数

    • shared:表示共享内存

    • buffers:系统分配但未被使用的buffers 数量。

    • cached:系统分配但未被使用的cache 数量。

    -/+ buffers/cache:表示物理内存的缓存统计

    • (-buffers/cache) 内存数: (指的第一部分Mem行中的used – buffers – cached)
    • (+buffers/cache) 内存数: (指的第一部分Mem行中的free + buffers + cached)

    (-buffers/cache)表示真正使用的内存数, (+buffers/cache) 表示真正未使用的内存数

    Swap:表示硬盘上交换分区的使用情况

    2、ulimit命令使用

    ulimit用于显示系统资源限制的信息
    语法:ulimit [param]
    param参数可以为:

    • -a  显示目前资源限制的设定。
    • -c <core文件上限>  设定core文件的最大值,单位为区块。
    • -d <数据节区大小>  程序数据节区的最大值,单位为KB。
    • -f <文件大小>  shell所能建立的最大文件,单位为区块。
    • -H  设定资源的硬性限制,也就是管理员所设下的限制。
    • -m <内存大小>  指定可使用内存的上限,单位为KB。
    • -n <文件数目>  指定同一时间最多可开启的文件数。
    • -p <缓冲区大小>  指定管道缓冲区的大小,单位512字节。
    • -s <堆叠大小>  指定堆叠的上限,单位为KB。
    • -S  设定资源的弹性限制。
    • -t <CPU时间>  指定CPU使用时间的上限,单位为秒。
    • -u <程序数目>  用户最多可开启的程序数目。
    • -v <虚拟内存大小>  指定可使用的虚拟内存上限,单位为KB

    在这里插入图片描述

    3、top命令使用

    top命令可以实时动态地查看系统的整体运行情况,是一个综合了多方信息监测系统性能和运行信息的实用工具,TOP命令是Linux下常用的性能分析工具,能够实时显示系统中各个进程的资源占用状况,有点像window系统的任务管理器

    语法:top [param]
    

    param为:

    • -b:以批处理模式操作;
    • -c:显示完整的治命令;
    • -d:屏幕刷新间隔时间;
    • -I:忽略失效过程;
    • -s:保密模式;
    • -S:累积模式;
    • -u [用户名]:指定用户名;
    • -p [进程号]:指定进程;
    • -n [次数]:循环显示的次数。
    • -H:查看进程下面的子线程

    top命令分为上下两个部分:

    • 系统统计信息
    • 系统进程信息
      在这里插入图片描述
      系统统计信息
    top - 11:38:01 up 231 days,  2:06,  1 user,  load average: 0.88, 0.22, 0.18
    Tasks: 170 total,   1 running, 169 sleeping,   0 stopped,   0 zombie
    %Cpu(s): 38.7 us,  3.5 sy,  0.0 ni, 42.0 id, 15.5 wa,  0.0 hi,  0.3 si,  0.0 st
    KiB Mem :  8010580 total,   927820 free,  2411572 used,  4671188 buff/cache
    KiB Swap:  4063228 total,  2933688 free,  1129540 used.  5153128 avail Mem 
    
    • row1:任务队列信息,同 uptime 命令的执行结果
      top - 11:38:01 up 231 days, 2:06, 1 user, load average: 0.88, 0.22, 0.18

      • 11:38:01 (当前系统时间)
      • up 231 days, 2:06(系统运行时间)
      • 1 user (当前登录用户数)
      • load average: 0.88, 0.22, 0.18 (系统的平均负载数,表示 1分钟、5分钟、15分钟到现在的平均数)
    • row2:进程统计信息
      Tasks: 170 total, 1 running, 169 sleeping, 0 stopped, 0 zombie

      • 170 total(系统当前总进程总数)
      • 1 running (正在运行的进程数)
      • 169 sleeping(睡眠进程数)
      • 0 stopped (停止进程数)
      • 0 zombie (僵尸进程数)
    • row3:CPU 统计信息
      %Cpu(s): 38.7 us, 3.5 sy, 0.0 ni, 42.0 id, 15.5 wa, 0.0 hi, 0.3 si, 0.0 st

      • 38.7 us, (用户空间CPU占用率)
      • 3.5 sy (内核空间CPU占用率)
      • 0.0 ni (用户进程空间改变过优先级的进程CPU的占用率)
      • 42.0 id(空闲CPU占有率)
      • 15.5 wa (等待输入输出的CPU时间百分比)
      • 0.0%hi (硬件中断请求)
      • 0.3%si (软件中断请求)
      • 0.0%st (分配给运行在其它虚拟机上的任务的实际 CPU时间)
    • row4:内存状态
      KiB Mem : 8010580 4671188 , 927820 free, 2411572 used, 4671188 buff/cache

      • 4671188 total (物理内存总量 )
      • 2411572 used (已使用的内存 )
      • 927820 free (空闲内存 )
      • 4671188 buffers (内核缓存使用)
        ps:以k为单位
    • row5:swap交换分区信息
      KiB Swap: 4063228 total, 2933688 free, 1129540 used. 5153128 avail Mem

      • 4063228 total (交换分区总量 )
      • 1129540 used (已使用交换分区内存 )
      • 2933688 free (空闲交换分区 )
      • 5153128 cached (缓冲交换区 )

    在这里插入图片描述

    系统进程信息

    • PID :进程id
    • USER :进程所有者的用户名
    • PR :进程优先级
    • NI :nice值。负值表示高优先级,正值表示低优先级
    • VIRT :进程使用的虚拟内存总量,单位kb。VIRT=SWAP+RES
    • RES :进程使用的、未被换出的物理内存大小,单位kb。RES=CODE+DATA
    • SHR :共享内存大小,单位kb
    • S :进程状态。D=不可中断的睡眠状态 R=运行 S=睡眠 T=跟踪/停止 Z=僵尸进程
    • %CPU :上次更新到现在的CPU时间占用百分比
    • %MEM :进程使用的物理内存百分比
    • TIME+ :进程使用的CPU时间总计,单位1/100秒
    • COMMAND :进程名称[命令名/命令行]

    在这里插入图片描述

    按“1”键,可打开或关闭显示详细CPU统计信息:
    在这里插入图片描述
    按字母“B”键,可打开或关闭当前进程的显示效果
    在这里插入图片描述
    top -H -p pid,查看进程pid下面的子线程
    在这里插入图片描述

    4、df命令使用

    df命令用于显示磁盘分区上的可使用的磁盘空间。默认显示单位为KB。可以利用该命令来获取硬盘被占用了多少空间,目前还剩下多少空间等信息。

    语法:df(选项)(参数)

    选项:

    -a或–all:包含全部的文件系统;
    –block-size=<区块大小>:以指定的区块大小来显示区块数目;
    -h或–human-readable:以可读性较高的方式来显示信息;
    -H或–si:与-h参数相同,但在计算时是以1000 Bytes为换算单位而非1024 Bytes;
    -i或–inodes:显示inode的信息;
    -k或–kilobytes:指定区块大小为1024字节;
    -l或–local:仅显示本地端的文件系统;
    -m或–megabytes:指定区块大小为1048576字节;
    –no-sync:在取得磁盘使用信息前,不要执行sync指令,此为预设值;
    -P或–portability:使用POSIX的输出格式;
    –sync:在取得磁盘使用信息前,先执行sync指令;
    -t<文件系统类型>或–type=<文件系统类型>:仅显示指定文件系统类型的磁盘信息;
    -T或–print-type:显示文件系统的类型;
    -x<文件系统类型>或–exclude-type=<文件系统类型>:不要显示指定文件系统类型的磁盘信息;
    –help:显示帮助;
    –version:显示版本信息。

    参数:

    文件:指定文件系统上的文件。

    比较常用的有:

    • df -a 查看全部的文件系统
    • df -h查看磁盘使用情况
    • df -i 查看inode使用情况

    在这里插入图片描述
    df -h
    在这里插入图片描述

    5、ps命令使用

    ps命令用于查看进程统计信息

    常用参数:

    • a:显示当前终端下的所有进程信息,包括其他用户的进程。
    • u:使用以用户为主的格式输出进程信息。
    • x:显示当前用户在所有终端下的进程。
    • -e:显示系统内的所有进程信息。
    • -l:使用长(long)格式显示进程信息。
    • -f:使用完整的(full)格式显示进程信息。
    • -T:查看进程下面的子线程

    在使用中可以加上grep命令一起使用,也可以单独使用

    # ps命令单独使用的情况
    ps -elf tomcat
    #结合管道操作和grep命令进行过滤,用于查询某一个进程的信息
    ps -elf | grep tomcat
    

    查看进程下面的子线程可以使用命令ps -T -p pid
    在这里插入图片描述

    6、crontab 命令

    crontab 命令,用于定时程序的命令
    -e : 执行文字编辑器来设定时程表,内定的文字编辑器是 VI,如果你想用别的文字编辑器,则请先设定 VISUAL 环境变数来指定使用那个文字编辑器(比如说 setenv VISUAL joe)
    -r : 删除目前的时程表
    -l : 列出目前的时程表

    二、文件操作

    1、tail查看文件

    tail 命令可用于查看文件的内容,语法为

    tail [param] [filename]
    

    其中param可为:

    • -f :循环读取
    • -q :不显示处理信息
    • -v :显示详细的处理信息
    • -c [数目]: 显示的字节数
    • -n [行数]: 显示文件的尾部 n 行内容
    • –pid=PID :与-f合用,表示在进程ID,PID死掉之后结束
    • -q, --quiet, --silent :从不输出给出文件名的首部
    • -s, --sleep-interval=S :与-f合用,表示在每次反复的间隔休眠S秒

    2、查看文件情况

    ll命令,可以用于查看文件情况,罗列出当前文件或目录的详细信息,含有时间、读写权限、大小、时间等信息。可以理解为 ll 和 ls -ll 的功能是相同的, ll 是ls -ll的别名。

    ll -ah
    

    ls 命令仅罗列出当前文件名或目录名

    ls -ll
    

    3、文件权限设置

    Linux的文件基本权限有9个,分别是owenr、group、others三种身份各自有自己的r、w和x,比如“rwxrwxrwx”,就表示owener具有r(read 读)、w(write 写)、x(execute 访问)权限,同样group和others同样具有r、w、x权限,可以用xftp查看文件权限

    在这里插入图片描述

    可以使用数字表示权限:

    r->4

    w->2

    x->1

    当文件权限为“rwxrwxrwx”时,分数是:

    owner->4+2+1=7

    group->4+2+1=7

    others->4+2+1=7

    此时文件的权限数字就是777

    然后要给文件file赋权的话,就可以使用Linux命令:

    chmod 777 file
    

    owner、group和others三种身份各自的三个权限,用u、g、o代表三种身份,用a(all)代表所有身份,所以还有下面的Linux命令

    chmod u|g|o|a  =(设置权限)|+(添加权限)|-(减少权限)  r|w|x  文件或者目录
    

    eg:给文件file赋值权限

        chmod u=rwx file
    

    4、文件上传下载

    在不使用xftp等linux工具的情况,可以通过linux命令,sz命令是利用ZModem协议来从Linux服务器传送文件到本地,一次可以传送一个或多个文件。

    • 下载文件
      sz命令发送文件到本地:
    sz filename
    

    在这里插入图片描述
    敲命令之后,直接弹出下载保存窗口页面

    • 上传文件
    rz
    

    敲命令之后,直接弹出上传窗口页面
    在这里插入图片描述

    rz、sz命令需要有如下条件:

    • linux系统
    • root权限
    • lrzsz安装包

    lrzsz安装步骤:

    // 编译安装
    //root 账号登陆后,依次执行以下命令:
    tar zxvf lrzsz-0.12.20.tar.gz
    cd lrzsz-0.12.20
    ./configure
    make
    make install
    //上面安装过程默认把lsz和lrz安装到了/usr/local/bin/目录下,现在我们并不能直接使用,下面创建软链接,并命名为rz/sz:
    cd /usr/bin
    ln -s /usr/local/bin/lrz rz
    ln -s /usr/local/bin/lsz sz
    

    Centos可以直接这样安装

    yum install lrzsz -y
    

    5、压缩文件解压

    linux解压zip压缩文件可以用unzip命令,如果没安装,可以先安装

    yum install -y unzip zip
    

    语法一般为:unzip [选项] [压缩文件名]

    • -c 将解压缩的结果显示到屏幕上,并对字符做适当的转换。
    • -f 更新现有的文件。
    • -l 显示压缩文件内所包含的文件。
    • -p 与-c参数类似,会将解压缩的结果显示到屏幕上,但不会执行任何的转换。
    • -t 检查压缩文件是否正确。
    • -u 与-f参数类似,但是除了更新现有的文件外,也会将压缩文件中的其他文件解压缩到目录中。
    • -v 执行是时显示详细的信息。
    • -z 仅显示压缩文件的备注文字。
    • -a 对文本文件进行必要的字符转换。
    • -b 不要对文本文件进行字符转换。
    • -C 压缩文件中的文件名称区分大小写。
    • -j 不处理压缩文件中原有的目录路径。
    • -L 将压缩文件中的全部文件名改为小写。
    • -M 将输出结果送到more程序处理。
    • -n 解压缩时不要覆盖原有的文件。
    • -o 不必先询问用户,unzip执行后覆盖原有文件。
    • -P<密码> 使用zip的密码选项。
    • -q 执行时不显示任何信息。
    • -s 将文件名中的空白字符转换为底线字符。
    • -V 保留VMS的文件版本信息。
    • -X 解压缩时同时回存文件原来的UID/GID。
    • [.zip文件] 指定.zip压缩文件。
    • [文件] 指定要处理.zip压缩文件中的哪些文件。
    • -d<目录> 指定文件解压缩后所要存储的目录。
    • -x<文件> 指定不要处理.zip压缩文件中的哪些文件。
    • -Z unzip -Z等于执行zipinfo指令。

    6、查看文件夹大小

    du [选项][文件]
    

    -a或-all 显示目录中个别文件的大小。
    -b或-bytes 显示目录或文件大小时,以byte为单位。
    -c或–total 除了显示个别目录或文件的大小外,同时也显示所有目录或文件的总和。
    -k或–kilobytes 以KB(1024bytes)为单位输出。
    -m或–megabytes 以MB为单位输出。
    -s或–summarize 仅显示总计,只列出最后加总的值。
    -h或–human-readable 以K,M,G为单位,提高信息的可读性。
    -x或–one-file-xystem 以一开始处理时的文件系统为准,若遇上其它不同的文件系统目录则略过。
    -L<符号链接>或–dereference<符号链接> 显示选项中所指定符号链接的源文件大小。
    -S或–separate-dirs 显示个别目录的大小时,并不含其子目录的大小。
    -X<文件>或–exclude-from=<文件> 在<文件>指定目录或文件。
    –exclude=<目录或文件> 略过指定的目录或文件。
    -D或–dereference-args 显示指定符号链接的源文件大小。
    -H或–si 与-h参数相同,但是K,M,G是以1000为换算单位。
    -l或–count-links 重复计算硬件链接的文件。

    常用命令:
    查看opt目录下面所有文件大小

    du -sh /opt
    

    查看当前目录所有文件

    du -sh *
    

    查看具体文件大小

    [root@localhost ~]# du -sh 文件名.doc
    4.0K	文件名.doc
    

    7、文件数据排序

    sort命令可以用于文件数据排序,然后将排序结果打印出来。

    语法:

    sort [选项] [文件]
    

    常用选项:

    选项含义
    -b忽略每行前面开始出的空格字符
    -c检查文件是否已经按照顺序排序
    -d排序时,处理英文字母、数字及空格字符外,忽略其他的字符
    -f排序时,将小写字母视为大写字母
    -i排序时,除了040至176之间的ASCII字符外,忽略其他的字符
    -m将几个排序号的文件进行合并
    -M将前面3个字母依照月份的缩写进行排序
    -n依照数值的大小排序
    -o<输出文件> 将排序后的结果存入制定的文件
    -r以相反的顺序来排序
    -t<分隔字符> 指定排序时所用的栏位分隔字符
    -k指定需要排序的栏位

    8、去除文件重复行

    使用uniq这个命令只能去除连续的的重复行。所以需要结合sort命令使用,先sort排序,然后uniq去除重复的

    语法:

    uniq [选项] [文件]
    
    选项含义
    -c打印每行在文本中重复出现的次数
    -d只显示有重复的纪录,每个重复纪录只出现一次
    -u只显示没有重复的纪录

    三、网络通信

    1、netstat监控命令

    netstat命令是用于监控进出网络的包和网络接口统计的命令行工具

    语法:netstat [param]
    

    param参数可以为:

    • -h : 查看帮助
    • -r : 显示路由表
    • -i : 查看网络接口

    2、linux重启网络

    设置了linux网络,需要重启网络,可以用命令:

    service network restart 
    

    3、SELinux简介

    SELinux全称是 Security-Enhanced Linux,它是由美国国家安全局(NSA)贡献的,它为 Linux 内核子系统引入了一个健壮的强制控制访问Mandatory Access Control架构。详情可以参考SELinux 入门SELINUX工作原理

    其实SELinux的功能也就是类似于防火墙的功能,不过安全相对比较好,ok,所以本博客介绍一下SELinux的使用命令

    查看selinux状态

    getenforce
    

    临时禁用SELINUX(学习用的linux才可以禁用,生产的不建议禁用SELINUX)

    setenforce
    

    永久禁用SELINUX(学习用的linux才可以禁用,生产的不建议禁用SELINUX)

     # 将SELINUX=enforce改成SELINUX=disabled
     vi /etc/selinux/config
    

    4、防火墙设置

    查询linux系统防火墙开启状态

    firewall-cmd --state
    

    临时关闭防火墙(学习用的linux才可以禁用,生产的不建议禁用SELINUX)

    systemctl stop firewalld.service
    

    永久关闭防火墙(学习用的linux才可以禁用,生产的不建议禁用SELINUX)

    systemctl disable firewalld.service
    

    5、CURL命令使用

    curl命令是一个利用URL规则在shell终端命令行下工作的文件传输工具;curl命令作为一款强力工具,curl支持包括HTTP、HTTPS、ftp等众多协议,还支持POST、cookies、认证、从指定偏移处下载部分文件、用户代理字符串、限速、文件大小、进度条等特征;
    在这里插入图片描述
    语法:语法格式:curl [参数] [网址]

    5.1 查看curl帮助

    • 查看命令参数
      curl的参数很多,可以用命令curl --help查看:
    [root@localhost ~]# curl --help
    

    国内翻译过来的curl文档:curl参数介绍

    5.2 查看curl手册

    • 查看详细使用
      也可以使用curl --manual查看基本用法例子:
      在这里插入图片描述

    5.3 提取指定网页

    • 查看网页源码
      语法:curl uri
    [root@localhost ~]# curl www.baidu.com
    <!DOCTYPE html>
    <!--STATUS OK--><html> <head><meta http-equiv=content-type content=text/html;charset=utf-8><meta http-equiv=X-UA-Compatible content=IE=Edge><meta content=always name=referrer><link rel=stylesheet type=text/css href=http://s1.bdstatic.com/r/www/cache/bdorz/baidu.min.css><title>百度一下,你就知道</title></head> <body link=#0000cc> <div id=wrapper> <div id=head> <div class=head_wrapper> <div class=s_form> <div class=s_form_wrapper> <div id=lg> <img hidefocus=true src=//www.baidu.com/img/bd_logo1.png width=270 height=129> </div> <form id=form name=f action=//www.baidu.com/s class=fm> <input type=hidden name=bdorz_come value=1> <input type=hidden name=ie value=utf-8> <input type=hidden name=f value=8> <input type=hidden name=rsv_bp value=1> <input type=hidden name=rsv_idx value=1> <input type=hidden name=tn value=baidu><span class="bg s_ipt_wr"><input id=kw name=wd class=s_ipt value maxlength=255 autocomplete=off autofocus></span><span class="bg s_btn_wr"><input type=submit id=su value=百度一下 class="bg s_btn"></span> </form> </div> </div> <div id=u1> <a href=http://news.baidu.com name=tj_trnews class=mnav>新闻</a> <a href=http://www.hao123.com name=tj_trhao123 class=mnav>hao123</a> <a href=http://map.baidu.com name=tj_trmap class=mnav>地图</a> <a href=http://v.baidu.com name=tj_trvideo class=mnav>视频</a> <a href=http://tieba.baidu.com name=tj_trtieba class=mnav>贴吧</a> <noscript> <a href=http://www.baidu.com/bdorz/login.gif?login&amp;tpl=mn&amp;u=http%3A%2F%2Fwww.baidu.com%2f%3fbdorz_come%3d1 name=tj_login class=lb>登录</a> </noscript> <script>document.write('<a href="http://www.baidu.com/bdorz/login.gif?login&tpl=mn&u='+ encodeURIComponent(window.location.href+ (window.location.search === "" ? "?" : "&")+ "bdorz_come=1")+ '" name="tj_login" class="lb">登录</a>');</script> <a href=//www.baidu.com/more/ name=tj_briicon class=bri style="display: block;">更多产品</a> </div> </div> </div> <div id=ftCon> <div id=ftConw> <p id=lh> <a href=http://home.baidu.com>关于百度</a> <a href=http://ir.baidu.com>About Baidu</a> </p> <p id=cp>&copy;2017&nbsp;Baidu&nbsp;<a href=http://www.baidu.com/duty/>使用百度前必读</a>&nbsp; <a href=http://jianyi.baidu.com/ class=cp-feedback>意见反馈</a>&nbsp;京ICP证030173号&nbsp; <img src=//www.baidu.com/img/gs.gif> </p> </div> </div> </div> </body> </html>
    
    
    • 显示头信息
    curl -i https://www.baidu.com
    

    打印信息:

    [root@localhost ~]# curl -i https://www.baiud.com
    curl: (7) Failed connect to www.baiud.com:443; Connection refused
    [root@localhost ~]# curl -i https://www.baidu.com
    HTTP/1.1 200 OK
    Accept-Ranges: bytes
    Cache-Control: private, no-cache, no-store, proxy-revalidate, no-transform
    Connection: keep-alive
    Content-Length: 2443
    Content-Type: text/html
    Date: Mon, 13 Jul 2020 07:22:02 GMT
    Etag: "588603eb-98b"
    Last-Modified: Mon, 23 Jan 2017 13:23:55 GMT
    Pragma: no-cache
    Server: bfe/1.0.8.18
    Set-Cookie: BDORZ=27315; max-age=86400; domain=.baidu.com; path=/
    ...	
    
    • 显示通信过程
    curl -v www.baidu.com
    
    curl -v www.baidu.com
    * About to connect() to www.baidu.com port 80 (#0)
    *   Trying 182.61.200.7...
    * Connected to www.baidu.com (182.61.200.7) port 80 (#0)
    > GET / HTTP/1.1
    > User-Agent: curl/7.29.0
    > Host: www.baidu.com
    > Accept: */*
    > 
    < HTTP/1.1 200 OK
    < Accept-Ranges: bytes
    < Cache-Control: private, no-cache, no-store, proxy-revalidate, no-transform
    < Connection: keep-alive
    < Content-Length: 2381
    < Content-Type: text/html
    < Date: Mon, 13 Jul 2020 07:24:46 GMT
    < Etag: "588604c8-94d"
    < Last-Modified: Mon, 23 Jan 2017 13:27:36 GMT
    < Pragma: no-cache
    < Server: bfe/1.0.8.18
    < Set-Cookie: BDORZ=27315; max-age=86400; domain=.baidu.com; path=/
    < 
    <!DOCTYPE html>
    ...
    
    • 查看议定书
    [root@localhost ~]# curl --trace-ascii output.txt https://www.baidu.com
    
    

    在这里插入图片描述

    在这里插入图片描述

    • 查看时间
    curl --trace-ascii output.txt --trace-time https://www.baidu.com
    

    在这里插入图片描述

    5.4 用curl进行认证

    • referer设置
      referer参数描述了一个网页的来源,可以按F12调试模式,查看:
      在这里插入图片描述
      访问百度时候,加上referer为csdn:
    [root@localhost ~]# curl --referer https://blog.csdn.net https://www.baidu.com
    
    • 用户代理设置
      用户代理常被用于兼容ie,有时,您会看到获取带有curl的页面不会返回与使用浏览器获取页面时看到的页面相同的页面,这时候可以设置用户代理:
    curl www.baidu.com --user-agent "Mozilla/5.0"
    curl www.baidu.com -A "Mozilla/5.0"
    

    5.5 curl文件操作

    • 保存文件
      语法:curl -o filename uri
    [root@localhost ~]# curl -o baidu.html www.baidu.com
      % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                     Dload  Upload   Total   Spent    Left  Speed
    100  2381  100  2381    0     0  22761      0 --:--:-- --:--:-- --:--:-- 22894
    
    

    在这里插入图片描述

    • 文件下载
      语法:curl uri filename --silent|progress
      • –silent:不显示进度条
      • –progress:显示进度条
    [root@localhost ~]# curl https://avatar.csdnimg.cn/3/5/E/1_meituantech_1564971608.jpg -omeituan.jpg --progress
    ######################################################################## 100.0%
    
    

    在这里插入图片描述

    • 上传文件
      语法:  $ curl --form upload=@localfilename --form press=OK [URL]
    [root@localhost ~]# curl --form upload=@baidu.html --form press=OK url
    
    

    5.6 设置cookie

    设置cookie,可以用命令--cookie

    -c cookie-file可以保存服务器返回的cookie到文件,-b cookie-file可以使用这个文件作为cookie信息,进行后续的请求。

    $ curl -c cookies http://example.com
    $ curl -b cookies http://example.com
    
    [root@localhost ~]# curl -c "name=cookiename" www.baidu.com
    
    

    在这里插入图片描述

    也可以用–cookie-jar指定cookie文件

    [root@localhost ~]# curl www.baidu.com --cookie-jar cookie_file
    
    

    在这里插入图片描述
    指定可下载的最大文件大小,可以用命令–limit-rate

    [root@localhost ~]# curl www.baidu.com --limit-rate 50k
    
    

    5.7 RESTFul API

    ps:-H指定请求header,-d指定参数

    • CURL POST:
    [root@localhost ~]# curl -H "Content-Type:application/json" -X POST localhost:9200/company/employees/1 -d '{"id" :1,"name":"admin","password":"123"}'
    
    
    • CURL GET:
    [root@localhost ~]# curl -X GET localhost:9200/company/employees/1?pretty=true
    
    • CURL DELETE:
    [root@localhost ~]# curl -X DELETE localhost:9200/company/employees/1
    
    • CURL PUT:
    curl -H "Content-Type:application/json" -X PUT localhost:9200/company/employees/1 -d '{"id" :1,"name":"admin","password":"111"}'
    

    curl默认是GET方式请求url的,要调POST等接口,必须加上-X参数指定

    比较详细的可以参考:

    四、系统管理

    1、查看内核版本

    uname命令用于查看内核版本
    在这里插入图片描述

    2、查看linux系统ip

    查看linux的ip地址:可以用命令

     ip addr
    

    3、查看ip是否被占用

    lsof -i:8080
    

    4、uptime命令使用

    uptime命令能够打印系统总共运行了多长时间和系统的平均负载。uptime命令可以显示的信息显示依次为:现在时间、系统已经运行了多长时间、目前有多少登陆用户、系统在过去的1分钟、5分钟和15分钟内的平均负载。

    用help参数参数

    [shared@localhost~]$ uptime --help
    
    Usage:
     uptime [options]
    
    Options:
     -p, --pretty   show uptime in pretty format 
     -h, --help     display this help and exit 
     -s, --since    system up since 
     -V, --version  output version information and exit
    
    For more details see uptime(1).
    [shared@localhost~]$ uptime -V
    uptime from procps-ng 3.3.10
    
    

    Options:

    • -p, --pretty show uptime in pretty format //比较美观的打印
    • -h, --help display this help and exit // 查看参数帮助
    • -s, --since system up since // 查看系统当前时间
    • -V, --version output version information and exit // 查看版本

    在这里插入图片描述

    5、telnet命令使用

    不管在window还是linux系统要校验某台服务器是否可以ping通,都可以使用命令,如果要加上断口的,linux可以使用telnet命令
    语法:telnet ip port

    telnet 127.0.0.1 8080
    

    6、查看系统当前登录用户

    可以使用w命令:

    [root@localhost ~]# w 
    

    下面列举主要的

    选项含义
    -h不显示输出信息的标题
    -l用长格式输出
    -s用短格式输出,不显示登陆时间,JCPU 和 PCPU 时间
    -V显示版本信息
    只显示某个用户的信息
    [root@localhost ~]# w [选项] [用户名]
    

    ps:切换用户可以使用命令su root进行系统用户切换

    附录:

    微信打赏
    在这里插入图片描述
    技术博客公众号
    在这里插入图片描述
    QQ群:1129337987

    展开全文
  • 在了解通信原理之前,我们首先要对通信常用的设备进行熟悉。计算机网络体系中,有几样通信设备或者说网络名词出现的频率相当的高,它们是:中继器、集线器、网桥、交换机、路由器和网关。其实,弄清楚这几个计算机...

    1585340840.jpg

    通信的原理是什么?在了解通信原理之前,我们首先要对通信常用的设备进行熟悉。

    计算机网络体系中,有几样通信设备或者说网络名词出现的频率相当的高,它们是:中继器、集线器、网桥、交换机、路由器和网关。

    其实,弄清楚这几个计算机网络的名词并不困难,如果能以计算机网络层次的概念给它们划清界限的话,那就很容易把它们区分出来。

    现在我们就有条理地梳理一下它们各自的含义和作用,以及它们之间的联系。那我们首先看一下这些网络设备分别处于计算机网络的哪些层次:

    一、中继器

    中继器(Repeater)是连接网络线路的一种装置,常用于两个网络节点之间物理信号的双向转发工作。

    中继器是最简单的网络互联设备,主要完成物理层的功能,负责在两个节点的物理层上按位传递信息,完成信号的复制、调整和放大功能,以此来延长网络的长度。它在OSI参考模型中的位置物理层。

    1585340841.jpg

    由于存在损耗, 在线路上传输的信号功率会逐渐衰减,衰减到一定程度时将造成信号失真,因此会导致接收错误。中继器就是为解决这一问题而设计的。它完成物理线路的连接,对衰减的信号进行放大,保持与原数据相同。

    中继器是模拟设备,用于连接两根电缆段。中继器不理解帧、分组和头的概念,他们只理解电压值。

    一句话总结:中继器,就是简单的信号放大器,信号在传输的过程中是要衰减的,中继器的作用就是将信号放大,使信号能传的更远。

    二、集线器

    集线器(Hub)是中继器的一种形式,区别在于集线器能够提供多端口服务,也称为多口中继器。集线器在OSI/RM中的物理层。

    1585340842.jpg

    一句话总结:集线器,差不多就是个多端口的中继器,把每个输入端口的信号放大再发到别的端口去,集线器可以实现多台计算机之间的互联,因为它有很多的端口,每个口都能连计算机。

    三、网桥

    网桥(Bridge)是一个局域网与另一个局域网之间建立连接的桥梁。网桥是属于数据链路层的一种设备,它的作用是扩展网络和通信手段。

    在各种传输介质中转发数据信号,扩展网络的距离,同时又有选择地将现有地址的信号从一个传输介质发送到另一个传输介质,并能有效地限制两个介质系统中无关紧要的通信。

    1585340843.jpg

    一句话总结:网桥工作在数据链路层,将两个LAN连起来,根据MAC地址来转发帧,可以看作一个“低层的路由器”。

    四、交换机

    交换机(Swich)工作在第二层(即数据链路层),它要比集线器智能一些,它能分辨出帧中的源MAC地址和目的MAC地址,因此可以在任意两个端口间建立联系,在数据帧的始发者和目标接收者之间建立临时的交换路径,使数据帧直接由源地址到达目的地址。

    交换机通过对信息进行重新生成,并经过内部处理后转发至指定端口,具备自动寻址能力和交换作用。但是 交换机并不懂得IP地址,它只知道MAC地址。

    1585340843-1.jpg

    交换机是使用硬件来完成以往网桥使用软件来完成过滤、学习和转发过程的任务。交换机速度比HUB快,这是由于HUB不知道目标地址在何处,发送数据到所有的端口。

    而交换机中有一张MAC地址表,如果知道目标地址在何处,就把数据发送到指定地点,如果它不知道就发送到所有的端口。

    这样过滤可以帮助降低整个网络的数据传输量,提高效率。但是交换机的功能还不止如此,它可以把网络拆解成网络分支、分割网络数据流,隔离分支中发生的故障,这样就可以减少每个网络分支的数据信息流量而使每个网络更有效,提高整个网络效率。

    现代交换机是这样处理数据帧的:一旦目标头域(目标地址)已经进来了,尽管帧的其他部分还没有到达,则只要输出线路可以使用,交换机就开始转发该帧,而不需理会帧后面的内容,也即是说交换机并没有使用“存储—转发”交换方式。

    一句话总结:交换机,可以理解为高级的网桥,他有网桥的功能,但性能比网桥强。交换机和网桥的细微差别就在于:交换机常常用来连接独立的计算机,而网桥连接的目标是LAN,所以交换机的端口较网桥多。

    五、路由器

    路由器(Router)工作在第三层(即网络层),它比交换机还要“聪明”一些,它能理解数据中的IP地址,如果它接收到一个数据包,就检查其中的IP地址,如果目标地址是本地网络的就不理会,如果是其他网络的,就将数据包转发出本地网络。

    与工作在网络物理层,从物理上划分网段的交换机不同,路由器使用专门的软件协议从逻辑上对整个网络进行划分。

    例如,一台支持IP协议的路由器可以把网络划分成多个子网段,只有指向特殊IP地址的网络流量才可以通过路由器。当IP子网中的一台主机发送IP分组给同一IP子网的另一台主机时,它将直接把IP分组送到网络上,对方就能收到。而要送给不同IP于网上的主机时,它要选择一个能到达目的子网上的路由器,把IP分组送给该路由器,由路由器负责把IP分组送到目的地。如果没有找到这样的路由器,主机就把IP分组送给一个称为“缺省网关(default gateway)”的路由器上。对于每一个接收到的数据包,路由器都会重新计算其校验值,并写入新的物理地址。

    网络中的设备用它们的网络地址(TCP/IP网络中为IP地址)互相通信。IP地址是与硬件地址无关的“逻辑”地址。

    目前TCP/IP网络,全部是通过路由器互连起来的,Internet就是成千上万个IP子网通过路由器互连起来的国际性网络。

    1585340844.jpg

    路由器用于连接多个逻辑上分开的网络,几个使用不同协议和体系结构的网络。路由器利用网络层定义的“逻辑”上的网络地址(即IP地址)来区别不同的网络,实现网络的互连和隔离,保持各个网络的独立性。

    当一个子网传输到另外一个子网时,可以用路由器完成。它具有判断网络地址和选择路径的功能,过滤和分隔网络信息流。一方面能够跨越不同的物理网络类型(DDN、FDDI、以太网等等),另一方面在逻辑上将整个互连网络分割成逻辑上独立的网络单位,使网络具有一定的逻辑结构。

    一句话总结:路由器的主要工作就是为经过路由器的每个IP数据包寻找一条最佳传输路径,并将该数据有效地传送到目的站点。路由器的基本功能是,把数据(IP报文)传送到正确的网络。

    六、网关

    网关(Gateway)又称网间连接器、协议转换器。网关在网络层以上实现网络互连,是最复杂的网络互连设备,仅用于两个高层协议不同的网络互连。网关既可以用于广域网互连,也可以用于局域网互连。网关是一种充当转换重任的计算机系统或设备。使用在不同的通信协议、数据格式或语言,甚至体系结构完全不同的两种系统之间,网关是一个翻译器。与网桥只是简单地传达信息不同,网关对收到的信息要重新打包,以适应目的系统的需求。

    一句话总结:网关,通过字面意思解释就是网络的关口。从技术角度来解释,就是连接两个不同网络的接口,比如局域网的共享上网服务器就是局域网和广域网的接口。

    1585340845.jpg

    注意问题

    1、交换机和路由器的区别?

    (1)从应用上说:交换机和路由器的使用中最大的区别莫过于路由器内部可实现拨号上网,然后通过共享给多台电脑同时上网,而交换机内部不具有拨号功能,但交换机的作用是将网络信号分流,以实现更多电脑连接共享上网。

    大家可以这样认为,交换机可以将多台电脑连接起来,与交换机互连的电脑本身则具备了互相通信的功能,组建成了一个内部局域网,但需要访问互联网还需要有网络支持,因此交换机一端需要连接到路由器,路由器即可实现交换功能,还可以拨号,实现宽带连接,并将宽带资源分配个交换机使用,这样就实现了多台电脑共享上网。

    (2)从概念上说:路由,是三层设备,有选择道路的作用。比如你去罗马,有很多路可以走,怎么走省钱省时间,就是路由要做的,解决你应该按照那条路走的问题。当然还有基于三层的其他功能。

    交换机,是二层设备。他就像你家门前的如或者你们楼道,附近的住户都知道去几层几号怎么走。

    1585340846.jpg

    2、为什么有时候还要在路由器的后面先接1台交换机再接计算机?

    路由器是可以直接接电脑等终端设备,为什么标准都是路由器接交换机然后再接电脑等终端,是因为路由器本来就是一个路由设备,用来选路的,不适合大量的数据交换,交换机是用来大量数据交换的,终端在内网的性质就是需要使用交换机,所以标准就是路由器地下接交换机的形式。

    一般是情况就是在路由器下面接交换机,路由器主要起数据转发,也就是寻址、路由的功能,交换机起到用户接入的目的。但是家用的路由器的话直接就接计算机就可以了,而不必考虑再接交换机。

    版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2895593579@qq.com 举报,一经查实,本站将立刻删除。

    展开全文
  • Zuul原理分析 (1):请求给zuulservlet处理(HttpServlet子类) zuulservlet中有一个zuulRunner对象,该对象中初始化了RequestContext(存储请求的数据),RequestContext被所有的zuulfilter共享; (2): ...

    点赞再看,养成习惯,微信搜索【三太子敖丙】关注这个互联网苟且偷生的工具人。

    本文 GitHub https://github.com/JavaFamily 已收录,有一线大厂面试完整考点、资料以及我的系列文章。

    前言

    前段时间敖丙不是在复习嘛,很多小伙伴也想要我的复习路线,以及我自己笔记里面的一些知识点,好了,丙丙花了一个月的时间,整整一个月啊,给大家整理出来了。

    一上来我就放个大招好吧,我的复习脑图,可以说是全得不行,为了防止被盗图,我加了水印哈。

    这期看下去你会发现很硬核,而且我会持续更新,啥也不说了,看在我熬夜一个月满脸痘痘的份上,你可以点赞了哈哈。

    注:如果图被压缩了,可以去公众号【三太子敖丙】回复【复习】获取原图

    Spring

    Spring框架的七大模块

    Spring Core:框架的最基础部分,提供 IoC 容器,对 bean 进行管理。

    Spring Context:继承BeanFactory,提供上下文信息,扩展出JNDI、EJB、电子邮件、国际化等功能。

    Spring DAO:提供了JDBC的抽象层,还提供了声明性事务管理方法。

    Spring ORM:提供了JPA、JDO、Hibernate、MyBatis 等ORM映射层.

    Spring AOP:集成了所有AOP功能

    Spring Web:提供了基础的 Web 开发的上下文信息,现有的Web框架,如JSF、Tapestry、Structs等,提供了集成

    Spring Web MVC:提供了 Web 应用的 Model-View-Controller 全功能实现。

    Bean定义5种作用域

    singleton(单例)
    prototype(原型)
    request
    session
    global session

    spring ioc初始化流程?

    resource定位
    即寻找用户定义的bean资源,由 ResourceLoader通过统一的接口Resource接口来完成
    beanDefinition载入
    BeanDefinitionReader读取、解析Resource定位的资源 成BeanDefinition 载入到ioc中(通过HashMap进行维护BD)
    BeanDefinition注册
    即向IOC容器注册这些BeanDefinition, 通过BeanDefinitionRegistery实现

    BeanDefinition加载流程?

    定义BeanDefinitionReader解析xml的document
    BeanDefinitionDocumentReader解析document成beanDefinition

    DI依赖注入流程? (实例化,处理Bean之间的依赖关系)

    过程在Ioc初始化后,依赖注入的过程是用户第一次向IoC容器索要Bean时触发

    • 如果设置lazy-init=true,会在第一次getBean的时候才初始化bean, lazy-init=false,会容器启动的时候直接初始化(singleton bean);

    • 调用BeanFactory.getBean()生成bean的;

    • 生成bean过程运用装饰器模式产生的bean都是beanWrapper(bean的增强);

      依赖注入怎么处理bean之间的依赖关系?

      其实就是通过在beanDefinition载入时,如果bean有依赖关系,通过占位符来代替,在调用getbean时候,如果遇到占位符,从ioc里获取bean注入到本实例来

    Bean的生命周期?

    • 实例化Bean: Ioc容器通过获取BeanDefinition对象中的信息进行实例化,实例化对象被包装在BeanWrapper对象中
    • 设置对象属性(DI):通过BeanWrapper提供的设置属性的接口完成属性依赖注入;
    • 注入Aware接口(BeanFactoryAware, 可以用这个方式来获取其它 Bean,ApplicationContextAware):Spring会检测该对象是否实现了xxxAware接口,并将相关的xxxAware实例注入给bean
    • BeanPostProcessor:自定义的处理(分前置处理和后置处理)
    • InitializingBean和init-method:执行我们自己定义的初始化方法
    • 使用
    • destroy:bean的销毁

    IOC:控制反转:将对象的创建权,由Spring管理.
    DI(依赖注入):在Spring创建对象的过程中,把对象依赖的属性注入到类中。

    Spring的IOC注入方式

    构造器注入
    setter方法注入
    注解注入
    接口注入

    怎么检测是否存在循环依赖?

    Bean在创建的时候可以给该Bean打标,如果递归调用回来发现正在创建中的话,即说明了循环依赖了。

    Spring如解决Bean循环依赖问题?

    Spring中循环依赖场景有:

    • 构造器的循环依赖
    • 属性的循环依赖
    • singletonObjects:第一级缓存,里面放置的是实例化好的单例对象;
      earlySingletonObjects:第二级缓存,里面存放的是提前曝光的单例对象;
      singletonFactories:第三级缓存,里面存放的是要被实例化的对象的对象工厂
    • 创建bean的时候Spring首先从一级缓存singletonObjects中获取。如果获取不到,并且对象正在创建中,就再从二级缓存earlySingletonObjects中获取,如果还是获取不到就从三级缓存singletonFactories中取(Bean调用构造函数进行实例化后,即使属性还未填充,就可以通过三级缓存向外提前暴露依赖的引用值(提前曝光),根据对象引用能定位到堆中的对象,其原理是基于Java的引用传递),取到后从三级缓存移动到了二级缓存完全初始化之后将自己放入到一级缓存中供其他使用,
    • 因为加入singletonFactories三级缓存的前提是执行了构造器,所以构造器的循环依赖没法解决。
    • 构造器循环依赖解决办法:在构造函数中使用@Lazy注解延迟加载。在注入依赖时,先注入代理对象,当首次使用时再创建对象说明:一种互斥的关系而非层次递进的关系,故称为三个Map而非三级缓存的缘由
      完成注入;

    Spring 中使用了哪些设计模式?

    • 工厂模式:
      spring中的BeanFactory就是简单工厂模式的体现,根据传入唯一的标识来获得bean对象;
    • 单例模式:
      提供了全局的访问点BeanFactory;
    • 代理模式:
      AOP功能的原理就使用代理模式(1、JDK动态代理。2、CGLib字节码生成技术代理。)
    • 装饰器模式:
      依赖注入就需要使用BeanWrapper;
    • 观察者模式:
      spring中Observer模式常用的地方是listener的实现。如ApplicationListener。
    • 策略模式:
      Bean的实例化的时候决定采用何种方式初始化bean实例(反射或者CGLIB动态字节码生成)

    AOP 核心概念

    1、切面(aspect):类是对物体特征的抽象,切面就是对横切关注点的抽象

    2、横切关注点:对哪些方法进行拦截,拦截后怎么处理,这些关注点称之为横切关注点。

    3、连接点(joinpoint):被拦截到的点,因为 Spring 只支持方法类型的连接点,所以在Spring 中连接点指的就是被拦截到的方法,实际上连接点还可以是字段或者构造器。

    4、切入点(pointcut):对连接点进行拦截的定义

    5、通知(advice):所谓通知指的就是指拦截到连接点之后要执行的代码,通知分为前置、后置、异常、最终、环绕通知五类。

    6、目标对象:代理的目标对象

    7、织入(weave):将切面应用到目标对象并导致代理对象创建的过程

    8、引入(introduction):在不修改代码的前提下,引入可以在运行期为类动态地添加方法或字段。

    解释一下AOP

    传统oop开发代码逻辑自上而下的,这个过程中会产生一些横切性问题,这些问题与我们主业务逻辑关系不大,会散落在代码的各个地方,造成难以维护,aop思想就是把业务逻辑与横切的问题进行分离,达到解耦的目的,提高代码重用性和开发效率;

    AOP 主要应用场景有:

    • 记录日志
    • 监控性能
    • 权限控制
    • 事务管理

    AOP源码分析

    • @EnableAspectJAutoProxy给容器(beanFactory)中注册一个AnnotationAwareAspectJAutoProxyCreator对象;

    • AnnotationAwareAspectJAutoProxyCreator对目标对象进行代理对象的创建,对象内部,是封装JDK和CGlib两个技术,实现动态代理对象创建的(创建代理对象过程中,会先创建一个代理工厂,获取到所有的增强器(通知方法),将这些增强器和目标类注入代理工厂,再用代理工厂创建对象);

    • 代理对象执行目标方法,得到目标方法的拦截器链,利用拦截器的链式机制,依次进入每一个拦截器进行执行

      AOP应用场景

      • 日志记录
      • 事务管理
      • 线程池关闭等

    AOP使用哪种动态代理?

    • 当bean的是实现中存在接口或者是Proxy的子类,—jdk动态代理;不存在接口,spring会采用CGLIB来生成代理对象;
    • JDK 动态代理主要涉及到 java.lang.reflect 包中的两个类:Proxy 和 InvocationHandler。
    • Proxy 利用 InvocationHandler(定义横切逻辑) 接口动态创建 目标类的代理对象。

    jdk动态代理

    • 通过bind方法建立代理与真实对象关系,通过Proxy.newProxyInstance(target)生成代理对象
    • 代理对象通过反射invoke方法实现调用真实对象的方法

    动态代理与静态代理区别

    • 静态代理,程序运行前代理类的.class文件就存在了;
    • 动态代理:在程序运行时利用反射动态创建代理对象<复用性,易用性,更加集中都调用invoke>

    CGLIB与JDK动态代理区别

    • Jdk必须提供接口才能使用;
    • C不需要,只要一个非抽象类就能实现动态代理

    SpringMVC

    springMVC流程:

    (1):用户请求发送给DispatcherServlet,DispatcherServlet调用HandlerMapping处理器映射器;

    (2):HandlerMapping根据xml或注解找到对应的处理器,生成处理器对象返回给DispatcherServlet;

    (3):DispatcherServlet会调用相应的HandlerAdapter;

    (4):HandlerAdapter经过适配调用具体的处理器去处理请求,生成ModelAndView返回给DispatcherServlet

    (5):DispatcherServlet将ModelAndView传给ViewReslover解析生成View返回给DispatcherServlet;

    (6):DispatcherServlet根据View进行渲染视图;

    ->DispatcherServlet->HandlerMapping->Handler
    ->DispatcherServlet->HandlerAdapter处理handler->ModelAndView
    ->DispatcherServlet->ModelAndView->ViewReslover->View
    ->DispatcherServlet->返回给客户

    Mybatis

    Mybatis原理

    • sqlsessionFactoryBuilder生成sqlsessionFactory(单例)
    • 工厂模式生成sqlsession执行sql以及控制事务
    • Mybatis通过动态代理使Mapper(sql映射器)接口能运行起来即为接口生成代理对象将sql查询到结果映射成pojo

    sqlSessionFactory构建过程

    • 解析并读取配置中的xml创建Configuration对象 (单例)
    • 使用Configruation类去创建sqlSessionFactory(builder模式)

    Mybatis一级缓存与二级缓存

    默认情况下一级缓存是开启的,而且是不能关闭的。

    • 一级缓存是指 SqlSession 级别的缓存
      原理:使用的数据结构是一个 map,如果两次中间出现 commit 操作 (修改、添加、删除),本 sqlsession 中的一级缓存区域全部清空
    • 二级缓存是指可以跨 SqlSession 的缓存。是 mapper 级别的缓存;
      原理: 是通过 CacheExecutor 实现的。CacheExecutor其实是 Executor 的代理对象

    Zookeeper+eureka+springcloud

    SpringBoot启动流程

    • new springApplication对象,利用spi机制加载applicationContextInitializer,
      applicationLister接口实例(META-INF/spring.factories);

    • 调run方法准备Environment,加载应用上下文(applicationContext),发布事件 很多通过lister实现

    • 创建spring容器, refreshContext() ,实现starter自动化配置,spring.factories文件加载, bean实例化

      SpringBoot自动配置的原理

      • @EnableAutoConfiguration找到META-INF/spring.factories(需要创建的bean在里面)配置文件
      • 读取每个starter中的spring.factories文件

    Spring Boot 的核心注解

    核心注解是@SpringBootApplication 由以下三种组成

    • @SpringBootConfiguration:组合了 @Configuration 注解,实现配置文件的功能。
    • @EnableAutoConfiguration:打开自动配置的功能。
    • @ComponentScan:Spring组件扫描。

    SpringBoot常用starter都有哪些

    spring-boot-starter-web - Web 和 RESTful 应用程序;
    spring-boot-starter-test - 单元测试和集成测试;
    spring-boot-starter-jdbc - 传统的 JDBC;
    spring-boot-starter-security - 使用 SpringSecurity 进行身份验证和授权;
    spring-boot-starter-data-jpa - 带有 Hibernate 的 Spring Data JPA;
    spring-boot-starter-data-rest - 使用 Spring Data REST 公布简单的 REST 服务

    Spring Boot 的核心配置文件

    (1):Application.yml
    一般用来定义单个应用级别的,如果搭配 spring-cloud-config 使用

    (2).Bootstrap.yml(先加载)
    系统级别的一些参数配置,这些参数一般是不变的

    Zuul与Gateway区别

    (1):zuul则是netflix公司的项目集成在spring-cloud中使用而已, Gateway是spring-cloud的
    一个子项目;

    (2):zuul不提供异步支持流控等均由hystrix支持, gateway提供了异步支持,提供了抽象负载均衡,提供了抽象流控; 理论上gateway则更适合于提高系统吞吐量(但不一定能有更好的性能),最终性能还需要通过严密的压测来决定

    (3):两者底层实现都是servlet,但是gateway多嵌套了一层webflux框架

    (4): zuul可用至其他微服务框架中,内部没有实现限流、负载均衡;gateway只能用在springcloud中;

    Zuul原理分析

    (1):请求给zuulservlet处理(HttpServlet子类) zuulservlet中有一个zuulRunner对象,该对象中初始化了RequestContext(存储请求的数据),RequestContext被所有的zuulfilter共享;

    (2): zuulRunner中有 FilterProcessor(zuulfilter的管理器),其从filterloader 中获取zuulfilter;

    (3):有了这些filter之后, zuulservelet执行的Pre-> route-> post 类型的过滤器,如果在执行这些过滤器有错误的时候则会执行error类型的过滤器,执行完后把结果返回给客户端.

    Gateway原理分析

    (1):请求到达DispatcherHandler, DispatchHandler在IOC容器初始化时会在容器中实例化HandlerMapping接口

    (2):用handlerMapping根据请求URL匹配到对应的Route,然后有对应的filter做对应的请求转发最终response返回去

    Zookeeper 工作原理(待查)

    Zookeeper 的核心是原子广播,这个机制保证了各个 server 之间的同步。实现这个机制的协议叫做 Zab 协议。Zab 协议有两种模式,它们分别是恢复模式和广播模式。

    zoo与eur区别

    • zookeeper保证cp(一致性)
    • eureka保证ap(可用性)
    • zoo在选举期间注册服务瘫痪,期间不可用
    • eur各个节点平等关系,只要有一台就可保证服务可用,而查询到的数据可能不是最新的,可以很好应对网络故障导致部分节点失联情况
    • zoo有leader和follower角色,eur各个节点平等
    • zoo采用半数存活原则(避免脑裂),eur采用自我保护机制来解决分区问题
    • eur本质是个工程,zoo只是一个进程
      ZooKeeper基于CP,不保证高可用,如果zookeeper正在选主,或者Zookeeper集群中半数以上机器不可用,那么将无法获得数据。
      Eureka基于AP,能保证高可用,即使所有机器都挂了,也能拿到本地缓存的数据。作为注册中心,其实配置是不经常变动的,只有发版(发布新的版本)和机器出故障时会变。对于不经常变动的配置来说,CP是不合适的,而AP在遇到问题时可以用牺牲一致性来保证可用性,既返回旧数据,缓存数据。
      所以理论上Eureka是更适合做注册中心。而现实环境中大部分项目可能会使用ZooKeeper,那是因为集群不够大,并且基本不会遇到用做注册中心的机器一半以上都挂了的情况。所以实际上也没什么大问题。

    Hystrix原理(待查)

    通过维护一个自己的线程池,当线程池达到阈值的时候,就启动服务降级,返回fallback默认值

    为什么需要hystrix熔断

    防止雪崩,及时释放资源,防止系统发生更多的额级联故障,需要对故障和延迟进行隔离,防止单个依赖关系的失败影响整个应用程序;

    微服务优缺点

    • 每个服务高内聚,松耦合,面向接口编程;
    • 服务间通信成本,数据一致性,多服务运维难度增加,http传输效率不如rpc

    eureka自我保护机制

    • eur不移除长时间没收到心跳而应该过期的服务
    • 仍然接受新服务注册和查询请求,但是不会同步到其它节点(高可用)
    • 当网络稳定后,当前实例新注册信息会同步到其它节点(最终一致性)

    MQ对比

    ActiveMQ:Apache出品,最早使用的消息队列产品,时间比较长了,最近版本更新比较缓慢。
    RabbitMQ:erlang语言开发,支持很多的协议,非常重量级,更适合于企业级的开发。性能较好,但是不利于做二次开发和维护。
    RocketMQ:阿里开源的消息中间件,纯Java开发,具有高吞吐量、高可用性、适合大规模分布式系统应用的特点,分布式事务。
    ZeroMQ:号称最快的消息队列系统,尤其针对大吞吐量的需求场景,采用 C 语言实现。
    消息队列的选型需要根据具体应用需求而定,ZeroMQ 小而美,RabbitMQ 大而稳,Kakfa 和 RocketMQ 快而强劲

    JAVA基础

    AVL树与红黑树(R-B树)的区别与联系

    • AVL是严格的平衡树,因此在增加或者删除节点的时候,根据不同情况,旋转的次数比红黑树要多;
    • 红黑树是用非严格的平衡来换取增删节点时候旋转次数的降低开销;
    • 所以简单说,查询多选择AVL树,查询更新次数差不多选红黑树
    • AVL树顺序插入和删除时有20%左右的性能优势,红黑树随机操作15%左右优势,现实应用当然一般都是随机情况,所以红黑树得到了更广泛的应用
      索引为B+树
      Hashmap为红黑树

    为啥redis zset使用跳跃链表而不用红黑树实现

    • skiplist的复杂度和红黑树一样,而且实现起来更简单。
    • 在并发环境下红黑树在插入和删除时需要rebalance,性能不如跳表。

    JAVA基本数据类型

    (1个字节是8个bit)
    整数型:byte(1字节)、short(2字节)、int(4字节)、long(8字节)
    浮点型:float(4字节)、double(8字节)
    布尔型:boolean(1字节)
    字符型:char(2字节)

    IO与NIO

    包括 类File,outputStream,inputStream,writer,readerseralizable(5类1接口)

    NIO三大核心内容 selector(选择器,用于监听channel),channel(通道),buffer(缓冲区)

    NIO与IO区别,IO面向流,NIO面向缓冲区;io阻塞,nio非阻塞

    异常类

    throwable为父类,子为error跟exception,exception分runtime(空指针,越界等)跟checkexception(sql,io,找不到类等异常)

    LVS(4层与7层)原理

    • 由前端虚拟负载均衡器和后端真实服务器群组成;
    • 请求发送给虚拟服务器后其根据包转发策略以及负载均衡调度算法转发给真实服务器
    • 所谓四层(lvs,f5)就是基于IP+端口的负载均衡;七层(nginx)就是基于URL等应用层信息的负载均衡

    StringBuilder与StringBuffer

    • StringBuilder 更快;
    • StringBuffer是线程安全的

    interrupt/isInterrupted/interrupt区别

    • interrupt() 调用该方法的线程的状态为将被置为"中断"状态(set操作)
    • isinterrupted() 是作用于调用该方法的线程对象所对应的线程的中断信号是true还是false(get操作)。例如我们可以在A线程中去调用B线程对象的isInterrupted方法,查看的是A
    • interrupted()是静态方法:内部实现是调用的当前线程的isInterrupted(),并且会重置当前线程的中断状态(getandset)

    sleep与wait区别

    sleep属于线程类,wait属于object类;sleep不释放锁

    CountDownLatch和CyclicBarrier区别

    • con用于主线程等待其他子线程任务都执行完毕后再执行,cyc用于一组线程相互等待大家都达到某个状态后,再同时执行;
    • CountDownLatch是不可重用的,CyclicBarrier可重用

    终止线程方法

    • 使用退出标志,说线程正常退出;
    • 通过判断this.interrupted() throw new InterruptedException()来停止
      使用String常量池作为锁对象会导致两个线程持有相同的锁,另一个线程不执行,改用其他如new Object()

    ThreadLocal的原理和应用

    原理:

    线程中创建副本,访问自己内部的副本变量,内部实现是其内部类名叫ThreadLocalMap的成员变量threadLocals,key为本身,value为实际存值的变量副本

    应用:

    • 用来解决数据库连接,存放connection对象,不同线程存放各自session;
    • 解决simpleDateFormat线程安全问题;
    • 会出现内存泄漏,显式remove…不要与线程池配合,因为worker往往是不会退出的;

    threadLocal 内存泄漏问题

    如果是强引用,设置tl=null,但是key的引用依然指向ThreadLocal对象,所以会有内存泄漏,而使用弱引用则不会;
    但是还是会有内存泄漏存在,ThreadLocal被回收,key的值变成null,导致整个value再也无法被访问到;
    解决办法:在使用结束时,调用ThreadLocal.remove来释放其value的引用;

    如果我们要获取父线程的ThreadLocal值呢

    ThreadLocal是不具备继承性的,所以是无法获取到的,但是我们可以用InteritableThreadLocal来实现这个功能。InteritableThreadLocal继承来ThreadLocal,重写了createdMap方法,已经对应的get和set方法,不是在利用了threadLocals,而是interitableThreadLocals变量。

    这个变量会在线程初始化的时候(调用init方法),会判断父线程的interitableThreadLocals变量是否为空,如果不为空,则把放入子线程中,但是其实这玩意没啥鸟用,当父线程创建完子线程后,如果改变父线程内容是同步不到子线程的。。。同样,如果在子线程创建完后,再去赋值,也是没啥鸟用的

    线程状态

    线程池有5种状态:running,showdown,stop,Tidying,TERMINATED。

    • running:线程池处于运行状态,可以接受任务,执行任务,创建线程默认就是这个状态了

    • showdown:调用showdown()函数,不会接受新任务,但是会慢慢处理完堆积的任务。

    • stop:调用showdownnow()函数,不会接受新任务,不处理已有的任务,会中断现有的任务。

    • Tidying:当线程池状态为showdown或者stop,任务数量为0,就会变为tidying。这个时候会调用钩子函数terminated()。

    • TERMINATED:terminated()执行完成。

    在线程池中,用了一个原子类来记录线程池的信息,用了int的高3位表示状态,后面的29位表示线程池中线程的个数。

    Java中的线程池是如何实现的?

    • 线程中线程被抽象为静态内部类Worker,是基于AQS实现的存放在HashSet中;
    • 要被执行的线程存放在BlockingQueue中;
    • 基本思想就是从workQueue中取出要执行的任务,放在worker中处理;

    如果线程池中的一个线程运行时出现了异常,会发生什么

    如果提交任务的时候使用了submit,则返回的feature里会存有异常信息,但是如果数execute则会打印出异常栈。但是不会给其他线程造成影响。之后线程池会删除该线程,会新增加一个worker。

    线程池原理

    • 提交一个任务,线程池里存活的核心线程数小于corePoolSize时,线程池会创建一个核心线程去处理提交的任务
    • 如果线程池核心线程数已满,即线程数已经等于corePoolSize,一个新提交的任务,会被放进任务队列workQueue排队等待执行。
    • 当线程池里面存活的线程数已经等于corePoolSize了,并且任务队列workQueue也满,判断线程数是否达到maximumPoolSize,即最大线程数是否已满,如果没到达,创建非核心线程执行提交的任务。
    • 如果当前的线程数达到了maximumPoolSize,还有新的任务过来的话,直接采用拒绝策略处理。

    拒绝策略

    • AbortPolicy直接抛出异常阻止线程运行;
    • CallerRunsPolicy如果被丢弃的线程任务未关闭,则执行该线程;
    • DiscardOldestPolicy移除队列最早线程尝试提交当前任务
    • DiscardPolicy丢弃当前任务,不做处理

    newFixedThreadPool (固定数目线程的线程池)

    • 阻塞队列为无界队列LinkedBlockingQueue
    • 适用于处理CPU密集型的任务,适用执行长期的任务

    newCachedThreadPool(可缓存线程的线程池)

    • 阻塞队列是SynchronousQueue
    • 适用于并发执行大量短期的小任务

    newSingleThreadExecutor(单线程的线程池)

    • 阻塞队列是LinkedBlockingQueue
    • 适用于串行执行任务的场景,一个任务一个任务地执行

    newScheduledThreadPool(定时及周期执行的线程池)

    • 阻塞队列是DelayedWorkQueue
    • 周期性执行任务的场景,需要限制线程数量的场景

    java锁相关

    synchronized实现原理

    contentionList(请求锁线程队列)
    entryList(有资格的候选者队列)
    waitSet(wait方法后阻塞队列)
    onDeck(竞争候选者)
    ower(竞争到锁线程)
    !ower(执行成功释放锁后状态);
    Synchronized 是非公平锁。

    Synchronized 在线程进入 ContentionList 时,等待的线程会先尝试自旋获取锁,如果获取不到就进入 ContentionList,这明显对于已经进入队列的线程是不公平的,还有一个不公平的事情就是自旋获取锁的线程还可能直接抢占 OnDeck 线程的锁资源。

    底层是由一对monitorenter和monitorexit指令实现的(监视器锁)

    每个对象有一个监视器锁(monitor)。当monitor被占用时就会处于锁定状态,线程执行monitorenter指令时尝试获取monitor的所有权,过程:

    • 如果monitor的进入数为0,则该线程进入monitor,然后将进入数设置为1,该线程即为monitor的所有者。
    • 如果线程已经占有该monitor,只是重新进入,则进入monitor的进入数加1.
    • 如果其他线程已经占用了monitor,则该线程进入阻塞状态,直到monitor的进入数为0,再重新尝试获取monitor的所有权。

    ReentrantLock 是如何实现可重入性的 ?

    内部自定义了同步器 Sync,加锁的时候通过CAS 算法 ,将线程对象放到一个双向链表 中,每次获取锁的时候 ,看下当前维 护的那个线程ID和当前请求的线程ID是否一样,一样就可重入了;

    ReentrantLock如何避免死锁?

    • 响应中断lockInterruptibly()
    • 可轮询锁tryLock()
    • 定时锁tryLock(long time)

    tryLock 和 lock 和 lockInterruptibly 的区别

    (1):tryLock 能获得锁就返回 true,不能就立即返回 false,

    (2):tryLock(long timeout,TimeUnit unit),可以增加时间限制,如果超过该时间段还没获得锁,返回 false

    (3):lock 能获得锁就返回 true,不能的话一直等待获得锁

    (4):lock 和 lockInterruptibly,如果两个线程分别执行这两个方法,但此时中断这两个线程, lock 不会抛出异常,而 lockInterruptibly 会抛出异常。

    CountDownLatch和CyclicBarrier的区别是什么

    CountDownLatch是等待其他线程执行到某一个点的时候,在继续执行逻辑(子线程不会被阻塞,会继续执行),只能被使用一次。最常见的就是join形式,主线程等待子线程执行完任务,在用主线程去获取结果的方式(当然不一定),内部是用计数器相减实现的(没错,又特么是AQS),AQS的state承担了计数器的作用,初始化的时候,使用CAS赋值,主线程调用await()则被加入共享线程等待队列里面,子线程调用countDown的时候,使用自旋的方式,减1,知道为0,就触发唤醒。

    CyclicBarrier回环屏障,主要是等待一组线程到底同一个状态的时候,放闸。CyclicBarrier还可以传递一个Runnable对象,可以到放闸的时候,执行这个任务。CyclicBarrier是可循环的,当调用await的时候如果count变成0了则会重置状态,如何重置呢,CyclicBarrier新增了一个字段parties,用来保存初始值,当count变为0的时候,就重新赋值。还有一个不同点,CyclicBarrier不是基于AQS的,而是基于RentrantLock实现的。存放的等待队列是用了条件变量的方式。

    synchronized与ReentrantLock区别

    • 都是可重入锁; R是显示获取和释放锁,s是隐式;
    • R更灵活可以知道有没有成功获取锁,可以定义读写锁,是api级别,s是JVM级别;
    • R可以定义公平锁;Lock是接口,s是java中的关键字

    什么是信号量Semaphore

    信号量是一种固定资源的限制的一种并发工具包,基于AQS实现的,在构造的时候会设置一个值,代表着资源数量。信号量主要是应用于是用于多个共享资源的互斥使用,和用于并发线程数的控制(druid的数据库连接数,就是用这个实现的),信号量也分公平和非公平的情况,基本方式和reentrantLock差不多,在请求资源调用task时,会用自旋的方式减1,如果成功,则获取成功了,如果失败,导致资源数变为了0,就会加入队列里面去等待。调用release的时候会加一,补充资源,并唤醒等待队列。

    Semaphore 应用

    • acquire() release() 可用于对象池,资源池的构建,比如静态全局对象池,数据库连接池;
    • 可创建计数为1的S,作为互斥锁(二元信号量)

    可重入锁概念

    (1):可重入锁是指同一个线程可以多次获取同一把锁,不会因为之前已经获取过还没释放而阻塞;

    (2):reentrantLock和synchronized都是可重入锁

    (3):可重入锁的一个优点是可一定程度避免死锁

    ReentrantLock原理(CAS+AQS)

    CAS+AQS队列来实现

    (1):先通过CAS尝试获取锁, 如果此时已经有线程占据了锁,那就加入AQS队列并且被挂起;

    (2): 当锁被释放之后, 排在队首的线程会被唤醒CAS再次尝试获取锁,

    (3):如果是非公平锁, 同时还有另一个线程进来尝试获取可能会让这个线程抢到锁;

    (4):如果是公平锁, 会排到队尾,由队首的线程获取到锁。

    AQS 原理

    Node内部类构成的一个双向链表结构的同步队列,通过控制(volatile的int类型)state状态来判断锁的状态,对于非可重入锁状态不是0则去阻塞;

    对于可重入锁如果是0则执行,非0则判断当前线程是否是获取到这个锁的线程,是的话把state状态+1,比如重入5次,那么state=5。 而在释放锁的时候,同样需要释放5次直到state=0其他线程才有资格获得锁

    AQS两种资源共享方式

    • Exclusive:独占,只有一个线程能执行,如ReentrantLock
    • Share:共享,多个线程可以同时执行,如Semaphore、CountDownLatch、ReadWriteLock,CyclicBarrier

    CAS原理

    内存值V,旧的预期值A,要修改的新值B,当A=V时,将内存值修改为B,否则什么都不做;

    CAS的缺点:

    (1):ABA问题;
    (2):如果CAS失败,自旋会给CPU带来压力;
    (3):只能保证对一个变量的原子性操作,i++这种是不能保证的

    CAS在java中的应用:

    (1):Atomic系列

    公平锁与分公平锁

    (1):公平锁指在分配锁前检查是否有线程在排队等待获取该锁,优先分配排队时间最长的线程,非公平直接尝试获取锁
    (2):公平锁需多维护一个锁线程队列,效率低;默认非公平

    独占锁与共享锁

    (1):ReentrantLock为独占锁(悲观加锁策略)
    (2):ReentrantReadWriteLock中读锁为共享锁
    (3): JDK1.8 邮戳锁(StampedLock), 不可重入锁
    读的过程中也允许获取写锁后写入!这样一来,我们读的数据就可能不一致,所以,需要一点额外的代码来判断读的过程中是否有写入,这种读锁是一种乐观锁, 乐观锁的并发效率更高,但一旦有小概率的写入导致读取的数据不一致,需要能检测出来,再读一遍就行

    4种锁状态

    • 无锁

    • 偏向锁
      会偏向第一个访问锁的线程,当一个线程访问同步代码块获得锁时,会在对象头和栈帧记录里存储锁偏向的线程ID,当这个线程再次进入同步代码块时,就不需要CAS操作来加锁了,只要测试一下对象头里是否存储着指向当前线程的偏向锁
      如果偏向锁未启动,new出的对象是普通对象(即无锁,有稍微竞争会成轻量级锁),如果启动,new出的对象是匿名偏向(偏向锁)
      对象头主要包括两部分数据:Mark Word(标记字段, 存储对象自身的运行时数据)、class Pointer(类型指针, 是对象指向它的类元数据的指针)

    • 轻量级锁(自旋锁)
      (1):在把线程进行阻塞操作之前先让线程自旋等待一段时间,可能在等待期间其他线程已经 解锁,这时就无需再让线程执行阻塞操作,避免了用户态到内核态的切换。(自适应自旋时间为一个线程上下文切换的时间)

    • (2):在用自旋锁时有可能造成死锁,当递归调用时有可能造成死锁

    • (3):自旋锁底层是通过指向线程栈中Lock Record的指针来实现的

    • 重量级锁

    轻量级锁与偏向锁的区别

    (1):轻量级锁是通过CAS来避免进入开销较大的互斥操作

    (2):偏向锁是在无竞争场景下完全消除同步,连CAS也不执行

    自旋锁升级到重量级锁条件

    (1):某线程自旋次数超过10次;

    (2):等待的自旋线程超过了系统core数的一半;

    读写锁了解嘛,知道读写锁的实现方式嘛

    常用的读写锁ReentrantReanWritelock,这个其实和reentrantLock相似,也是基于AQS的,但是这个是基于共享资源的,不是互斥,关键在于state的处理,读写锁把高16为记为读状态,低16位记为写状态,就分开了,读读情况其实就是读锁重入,读写/写读/写写都是互斥的,只要判断低16位就好了。

    zookeeper实现分布式锁

    (1):利用节点名称唯一性来实现,加锁时所有客户端一起创建节点,只有一个创建成功者获得锁,解锁时删除节点。

    (2):利用临时顺序节点实现,加锁时所有客户端都创建临时顺序节点,创建节点序列号最小的获得锁,否则监视比自己序列号次小的节点进行等待

    (3):方案2比1好处是当zookeeper宕机后,临时顺序节点会自动删除释放锁,不会造成锁等待;

    (4):方案1会产生惊群效应(当有很多进程在等待锁的时候,在释放锁的时候会有很多进程就过来争夺锁)。

    (5):由于需要频繁创建和删除节点,性能上不如redis锁

    volatile变量

    (1):变量可见性

    (2):防止指令重排序

    (3):保障变量单次读,写操作的原子性,但不能保证i++这种操作的原子性,因为本质是读,写两次操作

    volatile如何保证线程间可见和避免指令重排

    volatile可见性是有指令原子性保证的,在jmm中定义了8类原子性指令,比如write,store,read,load。而volatile就要求write-store,load-read成为一个原子性操作,这样子可以确保在读取的时候都是从主内存读入,写入的时候会同步到主内存中(准确来说也是内存屏障),指令重排则是由内存屏障来保证的,由两个内存屏障:

    • 一个是编译器屏障:阻止编译器重排,保证编译程序时在优化屏障之前的指令不会在优化屏障之后执行。
    • 第二个是cpu屏障:sfence保证写入,lfence保证读取,lock类似于锁的方式。java多执行了一个“load addl $0x0, (%esp)”操作,这个操作相当于一个lock指令,就是增加一个完全的内存屏障指令。

    JVM

    jre、jdk、jvm的关系:

    jdk是最小的开发环境,由jre++java工具组成。

    jre是java运行的最小环境,由jvm+核心类库组成。

    jvm是虚拟机,是java字节码运行的容器,如果只有jvm是无法运行java的,因为缺少了核心类库。

    JVM内存模型

    (1):堆<对象,静态变量,共享

    (2):方法区<存放类信息,常量池,共享>(java8移除了永久代(PermGen),替换为元空间(Metaspace))

    (3):虚拟机栈<线程执行方法的时候内部存局部变量会存堆中对象的地址等等数据>

    (4):本地方法栈<存放各种native方法的局部变量表之类的信息>

    (5):程序计数器<记录当前线程执行到哪一条字节码指令位置>

    对象4种引用

    (1):强(内存泄露主因)

    (2):软(只有软引用的话,空间不足将被回收),适合缓存用

    (3):弱(只,GC会回收)

    (4):虚引用(用于跟踪GC状态)用于管理堆外内存

    对象的构成:

    一个对象分为3个区域:对象头、实例数据、对齐填充

    对象头:主要是包括两部分,1.存储自身的运行时数据比如hash码,分代年龄,锁标记等(但是不是绝对哦,锁状态如果是偏向锁,轻量级锁,是没有hash码的。。。是不固定的)2.指向类的元数据指针。还有可能存在第三部分,那就是数组类型,会多一块记录数组的长度(因为数组的长度是jvm判断不出来的,jvm只有元数据信息)

    实例数据:会根据虚拟机分配策略来定,分配策略中,会把相同大小的类型放在一起,并按照定义顺序排列(父类的变量也会在哦)

    对齐填充:这个意义不是很大,主要在虚拟机规范中对象必须是8字节的整数,所以当对象不满足这个情况时,就会用占位符填充

    如果判断一个对象是否存活:

    一般判断对象是否存活有两种算法,一种是引用计数,另外一种是可达性分析。在java中主要是第二种

    java是根据什么来执行可达性分析的:

    根据GC ROOTS。GC ROOTS可以的对象有:虚拟机栈中的引用对象,方法区的类变量的引用,方法区中的常量引用,本地方法栈中的对象引用。

    JVM 类加载顺序

    (1):加载
    获取类的二进制字节流,将其静态存储结构转化为方法区的运行时数据结构

    (2):校验
    文件格式验证,元数据验证,字节码验证,符号引用验证

    (3):准备
    在方法区中对类的static变量分配内存并设置类变量数据类型默认的初始值,不包括实例变量,实例变量将会在对象实例化的时候随着对象一起分配在Java堆中

    (4):解析
    将常量池内的符号引用替换为直接引用的过程

    (5):初始化
    为类的静态变量赋予正确的初始值(Java代码中被显式地赋予的值)

    JVM三种类加载器

    (1):启动类加载器(home)
    加载jvm核心类库,如java.lang.*等

    (2):扩展类加载器(ext),
    父加载器为启动类加载器,从jre/lib/ext下加载类库

    (3):应用程序类加载器(用户classpath路径)
    父加载器为扩展类加载器,从环境变量中加载类

    双亲委派机制

    (1):类加载器收到类加载的请求

    (2):把这个请求委托给父加载器去完成,一直向上委托,直到启动类加载器

    (3):启动器加载器检查能不能加载,能就加载(结束);否则,抛出异常,通知子加载器进行加载

    (4):保障类的唯一性和安全性以及保证JDK核心类的优先加载

    双亲委派模型有啥作用:

    保证java基础类在不同的环境还是同一个Class对象,避免出现了自定义类覆盖基础类的情况,导致出现安全问题。还可以避免类的重复加载。

    如何打破双亲委派模型?

    (1):自定义类加载器,继承ClassLoader类重写loadClass方法;

    (2):SPI

    tomcat是如何打破双亲委派模型:

    tomcat有着特殊性,它需要容纳多个应用,需要做到应用级别的隔离,而且需要减少重复性加载,所以划分为:/common 容器和应用共享的类信息,/server容器本身的类信息,/share应用通用的类信息,/WEB-INF/lib应用级别的类信息。整体可以分为:boostrapClassLoader->ExtensionClassLoader->ApplicationClassLoader->CommonClassLoader->CatalinaClassLoader(容器本身的加载器)/ShareClassLoader(共享的)->WebAppClassLoader。虽然第一眼是满足双亲委派模型的,但是不是的,因为双亲委派模型是要先提交给父类装载,而tomcat是优先判断是否是自己负责的文件位置,进行加载的。

    SPI: (Service Provider interface)

    (1):服务提供接口(服务发现机制):

    (2):通过加载ClassPath下META_INF/services,自动加载文件里所定义的类

    (3):通过ServiceLoader.load/Service.providers方法通过反射拿到实现类的实例

    SPI应用?

    (1):应用于JDBC获取数据库驱动连接过程就是应用这一机制

    (2):apache最早提供的common-logging只有接口.没有实现…发现日志的提供商通过SPI来具体找到日志提供商实现类

    双亲委派机制缺陷?

    (1):双亲委派核心是越基础的类由越上层的加载器进行加载, 基础的类总是作为被调用代码调用的API,无法实现基础类调用用户的代码….

    (2):JNDI服务它的代码由启动类加载器去加载,但是他需要调独立厂商实现的应用程序,如何解决?
    线程上下文件类加载器(Thread Context ClassLoader), JNDI服务使用这个线程上下文类加载器去加载所需要的SPI代码,也就是父类加载器请求子类加载器去完成类加载动作Java中所有涉及SPI的加载动作基本上都采用这种方式,例如JNDI,JDBC

    导致fullGC的原因

    (1):老年代空间不足

    (2):永久代(方法区)空间不足

    (3):显式调用system.gc()

    堆外内存的优缺点

    Ehcache中的一些版本,各种 NIO 框架,Dubbo,Memcache 等中会用到,NIO包下ByteBuffer来创建堆外内存
    堆外内存,其实就是不受JVM控制的内存。

    相比于堆内内存有几个优势:

    减少了垃圾回收的工作,因为垃圾回收会暂停其他的工作。
    加快了复制的速度。因为堆内在 flush 到远程时,会先复制到直接内存(非堆内存),然后在发送;而堆外内存相当于省略掉了复制这项工作。
    可以扩展至更大的内存空间。比如超过 1TB 甚至比主存还大的空间。

    缺点总结如下:

    堆外内存难以控制,如果内存泄漏,那么很难排查,通过-XX:MaxDirectMemerySize来指定,当达到阈值的时候,调用system.gc来进行一次full gc
    堆外内存相对来说,不适合存储很复杂的对象。一般简单的对象或者扁平化的比较适合
    jstat查看内存回收概况,实时查看各个分区的分配回收情况,
    jmap查看内存栈,查看内存中对象占用大小,
    jstack查看线程栈,死锁,性能瓶颈

    JVM七种垃圾收集器

    (1): Serial 收集器 复制算法,单线程,新生代)

    (2): ParNew 收集器(复制算法,多线程,新生代)

    (3): Parallel Scavenge 收集器(多线程,复制算法,新生代,高吞吐量)

    (4):Serial Old 收集器(标记-整理算法,老年代)

    (5):Parallel Old 收集器(标记-整理算法,老年代,注重吞吐量的场景下,jdk8默认采用 Parallel Scavenge + Parallel Old 的组合)

    (6):CMS 收集器(标记-清除算法,老年代,垃圾回收线程几乎能做到与用户线程同时工作,吞吐量低,内存碎片)以牺牲吞吐量为代价来获得最短回收停顿时间-XX:+UseConcMarkSweepGC
    jdk1.8 默认垃圾收集器Parallel Scavenge(新生代)+Parallel Old(老年代)
    jdk1.9 默认垃圾收集器G1

    使用场景:

    (1):应用程序对停顿比较敏感

    (2):在JVM中,有相对较多存活时间较长的对象(老年代比较大)会更适合使用CMS

    cms垃圾回收过程:

    (1):初始标识<找到gcroot(stw)>

    GC Roots有以下几种:

    1:系统类加载器加载的对象

    2:处于激活状态的线程

    3:JNI栈中的对象

    4:正在被用于同步的各种锁对象

    5:JVM自身持有的对象,比如系统类加载器等。

    (2):并发标记(三色标记算法)
    三色标记算法处理并发标记出现对象引用变化情况:
    黑:自己+子对象标记完成
    灰:自己完成,子对象未完成
    白:未标记;
    并发标记 黑->灰->白
    重新标记 灰->白引用消失,黑引用指向->白,导致白漏标
    cms处理办法是incremental update方案 (增量更新)把黑色变成灰色
    多线程下并发标记依旧会产生漏标问题,所以cms必须remark一遍(jdk1.9以后不用cms了)

    G1 处理方案:

    SATB(snapshot at the begining)把白放入栈中,标记过程是和应用程序并发运行的(不需要Stop-The-World)
    这种方式会造成某些是垃圾的对象也被当做是存活的,所以G1会使得占用的内存被实际需要的内存大。不过下一次就回收了
    ZGC 处理方案: 颜色指针(color pointers) 2*42方=4T

    (3):重新标记(stw)

    (4)并发清理

    备注:重新标记是防止标记成垃圾之后,对象被引用

    (5):G1 收集器(新生代 + 老年代,在多 CPU 和大内存的场景下有很好的性能)
    G1在java9 便是默认的垃圾收集器,是cms 的替代者
    逻辑分代,用分区(region)的思想(默认分2048份) 还是有stw
    为解决CMS算法产生空间碎片HotSpot提供垃圾收集器,通过-XX:+UseG1GC来启用

    G1中提供了三种模式垃圾回收模式

    (1):young gc(eden region被耗尽无法申请内存时,就会触发)

    (2):mixed gc(当老年代大小占整个堆大小百分比达到该阈值时,会触发)

    (3):full gc(对象内存分配速度过快,mixed gc来不及回收,导致老年代被填满,就会触发)

    (8):ZGC和shenandoah (oracle产收费) no stw

    arthas 监控工具

    (1):dashboard命令查看总体jvm运行情况

    (2):jvm显示jvm详细信息

    (3):thread 显示jvm里面所有线程信息(类似于jstack) 查看死锁线程命令thread -b

    (4):sc * 显示所有类(search class)

    (5):trace 跟踪方法

    定位频繁full GC,堆内存满 oom

    第一步:jps获取进程号
    第二步:jmap -histo pid | head -20 得知有个对象在不断创建
    备注:jmap如果线上服务器堆内存特别大,,会卡死需堆转存(一般会说在测试环境压测,导出转存)
    -XX:+HeapDumpOnOutOfMemoryError或jmap -dumpLformat=b,file=xxx pid 转出文件进行分析
    (arthas没有实现jmap命令)heapdump --live /xxx/xx.hprof导出文件

    G1垃圾回收器(重点)

    回收过程
    (1):young gc(年轻代回收)–当年轻代的Eden区用尽时–stw
    第一阶段,扫描根。
    根是指static变量指向的对象,正在执行的方法调用链条上的局部变量等
    第二阶段,更新RS(Remembered Sets)。
    处理dirty card queue中的card,更新RS。此阶段完成后,RS可以准确的反映老年代对所在的内存分段中对象的引用
    第三阶段,处理RS。
    识别被老年代对象指向的Eden中的对象,这些被指向的Eden中的对象被认为是存活的对象。
    第四阶段,复制对象。
    此阶段,对象树被遍历,Eden区内存段中存活的对象会被复制到Survivor区中空的内存分段
    第五阶段,处理引用。
    处理Soft,Weak,Phantom,Final,JNI Weak 等引用。

    (2):concrruent marking(老年代并发标记)
    当堆内存使用达到一定值(默认45%)时,不需要Stop-The-World,在并发标记前先进行一次young gc

    (3):混合回收(mixed gc)
    并发标记过程结束以后,紧跟着就会开始混合回收过程。混合回收的意思是年轻代和老年代会同时被回收

    (4):Full GC?
    Full GC是指上述方式不能正常工作,G1会停止应用程序的执行,使用单线程的内存回收算法进行垃圾回收,性能会非常差,应用程序停顿时间会很长。要避免Full GC的发生,一旦发生需要进行调整。

    什么时候发生Full GC呢?

    比如堆内存太小,当G1在复制存活对象的时候没有空的内存分段可用,则会回退到full gc,这种情况可以通过增大内存解决

    尽管G1堆内存仍然是分代的,但是同一个代的内存不再采用连续的内存结构

    年轻代分为Eden和Survivor两个区,老年代分为Old和Humongous两个区

    新分配的对象会被分配到Eden区的内存分段上

    Humongous区用于保存大对象,如果一个对象占用的空间超过内存分段Region的一半;

    如果对象的大小超过一个甚至几个分段的大小,则对象会分配在物理连续的多个Humongous分段上。

    Humongous对象因为占用内存较大并且连续会被优先回收

    为了在回收单个内存分段的时候不必对整个堆内存的对象进行扫描(单个内存分段中的对象可能被其他内存分段中的对象引用)引入了RS数据结构。RS使得G1可以在年轻代回收的时候不必去扫描老年代的对象,从而提高了性能。每一个内存分段都对应一个RS,RS保存了来自其他分段内的对象对于此分段的引用

    JVM会对应用程序的每一个引用赋值语句object.field=object进行记录和处理,把引用关系更新到RS中。但是这个RS的更新并不是实时的。G1维护了一个Dirty Card Queue

    那为什么不在引用赋值语句处直接更新RS呢?

    这是为了性能的需要,使用队列性能会好很多。

    线程本地分配缓冲区(TLAB: Thread Local Allocation Buffer)?

    栈上分配->tlab->堆上分配
    由于堆内存是应用程序共享的,应用程序的多个线程在分配内存的时候需要加锁以进行同步。为了避免加锁,提高性能每一个应用程序的线程会被分配一个TLAB。TLAB中的内存来自于G1年轻代中的内存分段。当对象不是Humongous对象,TLAB也能装的下的时候,对象会被优先分配于创建此对象的线程的TLAB中。这样分配会很快,因为TLAB隶属于线程,所以不需要加锁

    PLAB: Promotion Thread Local Allocation Buffer

    G1会在年轻代回收过程中把Eden区中的对象复制(“提升”)到Survivor区中,Survivor区中的对象复制到Old区中。G1的回收过程是多线程执行的,为了避免多个线程往同一个内存分段进行复制,那么复制的过程也需要加锁。为了避免加锁,G1的每个线程都关联了一个PLAB,这样就不需要进行加锁了

    OOM问题定位方法

    (1):jmap -heap 10765如上图,可以查看新生代,老生代堆内存的分配大小以及使用情况;

    (2):jstat 查看GC收集情况

    (3):jmap -dump:live,format=b,file=到本地

    (4):通过MAT工具打开分析

    DUBBO

    dubbo流程

    (1):生产者(Provider)启动,向注册中心(Register)注册

    (2):消费者(Consumer)订阅,而后注册中心通知消费者

    (3):消费者从生产者进行消费

    (4):监控中心(Monitor)统计生产者和消费者

    Dubbo推荐使用什么序列化框架,还有哪些?

    推荐使用Hessian序列化,还有Duddo、FastJson、Java自带序列化

    Dubbo默认使用的是什么通信框架,还有哪些?

    默认使用 Netty 框架,也是推荐的选择,另外内容还集成有Mina、Grizzly。

    Dubbo有哪几种负载均衡策略,默认是哪种?

    (1):随机调用<默认>

    (2):权重轮询

    (3):最少活跃数

    (4):一致性Hash

    RPC流程

    (1)消费者调用需要消费的服务,

    (2):客户端存根将方法、入参等信息序列化发送给服务端存根

    (3):服务端存根反序列化操作根据解码结果调用本地的服务进行相关处理

    (4):本地服务执行具体业务逻辑并将处理结果返回给服务端存根

    (5):服务端存根序列化

    (6):客户端存根反序列化

    (7):服务消费方得到最终结果

    RPC框架的实现目标PC框架的实现目标是把调用、编码/解码的过程给封装起来,让用户感觉上像调用本地服务一样的调用远程服务

    服务暴露、服务引用、服务调用(TODO)

    Redis

    redis单线程为什么执行速度这么快?

    (1):纯内存操作,避免大量访问数据库,减少直接读取磁盘数据,redis将数据储存在内存里面,读写数据的时候都不会受到硬盘 I/O 速度的限制,所以速度快

    (2):单线程操作,避免了不必要的上下文切换和竞争条件,也不存在多进程或者多线程导致的切换而消耗CPU,不用去考虑各种锁的问题,不存在加锁释放锁操作,没有因为可能出现死锁而导致的性能消耗

    (3):采用了非阻塞I/O多路复用机制

    Redis数据结构底层实现

    String:

    (1)Simple dynamic string(SDS)的数据结构

    struct sdshdr{
     //记录buf数组中已使用字节的数量
     //等于 SDS 保存字符串的长度
     int len;
     //记录 buf 数组中未使用字节的数量
     int free;
     //字节数组,用于保存字符串
     char buf[]}
    

    它的优点:
    (1)不会出现字符串变更造成的内存溢出问题

    (2)获取字符串长度时间复杂度为1

    (3)空间预分配, 惰性空间释放free字段,会默认留够一定的空间防止多次重分配内存

    应用场景:
    String 缓存结构体用户信息,计数

    Hash:

    数组+链表的基础上,进行了一些rehash优化;
    1.Reids的Hash采用链地址法来处理冲突,然后它没有使用红黑树优化。

    2.哈希表节点采用单链表结构。

    3.rehash优化 (采用分而治之的思想,将庞大的迁移工作量划分到每一次CURD中,避免了服务繁忙)

    应用场景:
    保存结构体信息可部分获取不用序列化所有字段

    List:

    应用场景:
    (1):比如twitter的关注列表,粉丝列表等都可以用Redis的list结构来实现

    (2):list的实现为一个双向链表,即可以支持反向查找和遍历

    Set:

    内部实现是一个 value为null的HashMap,实际就是通过计算hash的方式来快速排重的,这也是set能提供判断一个成员 是否在集合内的原因。
    应用场景:
    去重的场景,交集(sinter)、并集(sunion)、差集(sdiff),实现如共同关注、共同喜好、二度好友等功能

    Zset:

    内部使用HashMap和跳跃表(SkipList)来保证数据的存储和有序,HashMap里放的是成员到score的映射,而跳跃表里存放的是所有的成员,排序依据是HashMap里存的score,使用跳跃表的结构可以获得比较高的查找效率,并且在实现上比较简单。
    跳表:每个节点中维持多个指向其他节点的指针,从而达到快速访问节点的目的
    应用场景:
    实现延时队列

    redis事务

    (1):Multi开启事务

    (2):Exec执行事务块内命令

    (3):Discard 取消事务

    (4):Watch 监视一个或多个key,如果事务执行前key被改动,事务将打断

    redis事务的实现特征

    (1):所有命令都将会被串行化的顺序执行,事务执行期间,Redis不会再为其它客户端的请求提供任何服务,从而保证了事物中的所有命令被原子的执行

    (2):Redis事务中如果有某一条命令执行失败,其后的命令仍然会被继续执行

    (3):在事务开启之前,如果客户端与服务器之间出现通讯故障并导致网络断开,其后所有待执行的语句都将不会被服务器执行。然而如果网络中断事件是发生在客户端执行EXEC命令之后,那么该事务中的所有命令都会被服务器执行

    (4):当使用Append-Only模式时,Redis会通过调用系统函数write将该事务内的所有写操作在本次调用中全部写入磁盘。

    然而如果在写入的过程中出现系统崩溃,如电源故障导致的宕机,那么此时也许只有部分数据被写入到磁盘,而另外一部分数据却已经丢失。

    Redis服务器会在重新启动时执行一系列必要的一致性检测,一旦发现类似问题,就会立即退出并给出相应的错误提示。此时,我们就要充分利用Redis工具包中提供的redis-check-aof工具,该工具可以帮助我们定位到数据不一致的错误,并将已经写入的部分数据进行回滚。修复之后我们就可以再次重新启动Redis服务器了

    Redis的同步机制?

    (1):全量拷贝,
    1.slave第一次启动时,连接Master,发送PSYNC命令,

    2.master会执行bgsave命令来生成rdb文件,期间的所有写命令将被写入缓冲区。

    1. master bgsave执行完毕,向slave发送rdb文件

    2. slave收到rdb文件,丢弃所有旧数据,开始载入rdb文件

    3. rdb文件同步结束之后,slave执行从master缓冲区发送过来的所以写命令。

    4. 此后 master 每执行一个写命令,就向slave发送相同的写命令。

      (2):增量拷贝
      如果出现网络闪断或者命令丢失等异常情况,从节点之前保存了自身已复制的偏移量和主节点的运行ID

    5. 主节点根据偏移量把复制积压缓冲区里的数据发送给从节点,保证主从复制进入正常状态。

      redis集群模式性能优化

      (1) Master最好不要做任何持久化工作,如RDB内存快照和AOF日志文件

      (2) 如果数据比较重要,某个Slave开启AOF备份数据,策略设置为每秒同步一次

      (3) 为了主从复制的速度和连接的稳定性,Master和Slave最好在同一个局域网内

      (4) 尽量避免在压力很大的主库上增加从库

      (5) 主从复制不要用图状结构,用单向链表结构更为稳定,即:Master <- Slave1 <- Slave2 <- Slave3…这样的结构方便解决单点故障问题,实现Slave对Master的替换。如果Master挂了,可以立刻启用Slave1做Master,其他不变。

      Redis集群方案

      (1):官方cluster方案

      (2):twemproxy

      代理方案twemproxy是一个单点,很容易对其造成很大的压力,所以通常会结合keepalived来实twemproy的高可用

      (3):codis
      基于客户端来进行分片

    集群不可用场景

    (1):master挂掉,且当前master没有slave

    (2):集群超过半数以上master挂掉,无论是否有slave集群进入fail状态

    redis 最适合的场景

    (1):会话缓存session cache

    (2):排行榜/计数器ZRANGE

    (3):发布/订阅

    缓存淘汰策略

    (1):先进先出算法(FIFO)

    (2):最近使用最少Least Frequently Used(LFU)

    (3):最长时间未被使用的Least Recently Used(LRU)

    当存在热点数据时,LRU的效率很好,但偶发性的、周期性的批量操作会导致LRU命中率急剧下降,缓存污染情况比较严重

    redis过期key删除策略

    (1):惰性删除,cpu友好,但是浪费cpu资源

    (2):定时删除(不常用)

    (3):定期删除,cpu友好,节省空间

    缓存雪崩以及处理办法

    同一时刻大量缓存失效;

    处理方法:

    (1):缓存数据增加过期标记

    (2):设置不同的缓存失效时间

    (3):双层缓存策略C1为短期,C2为长期

    (4):定时更新策略

    缓存击穿原因以及处理办法

    频繁请求查询系统中不存在的数据导致;

    处理方法:

    (1):cache null策略,查询反馈结果为null仍然缓存这个null结果,设置不超过5分钟过期时间

    (2):布隆过滤器,所有可能存在的数据映射到足够大的bitmap中
    google布隆过滤器:基于内存,重启失效不支持大数据量,无法在分布式场景
    redis布隆过滤器:可扩展性,不存在重启失效问题,需要网络io,性能低于google

    redis阻塞原因

    (1):数据结构使用不合理bigkey

    (2):CPU饱和

    (3):持久化阻塞,rdb fork子线程,aof每秒刷盘等

    hot key出现造成集群访问量倾斜解决办法

    (1):使用本地缓存

    (2): 利用分片算法的特性,对key进行打散处理(给hot key加上前缀或者后缀,把一个hotkey 的数量变成 redis 实例个数N的倍数M,从而由访问一个 redis key 变成访问 N * M 个redis key)

    Redis分布式锁

    2.6版本以后lua脚本保证setnx跟setex进行原子性(setnx之后,未setex,服务挂了,锁不释放)
    a获取锁,超过过期时间,自动释放锁,b获取到锁执行,a代码执行完remove锁,a和b是一样的key,导致a释放了b的锁。
    解决办法:remove之前判断value(高并发下value可能被修改,应该用lua来保证原子性)

    Redis如何做持久化

    bgsave做镜像全量持久化,aof做增量持久化。因为bgsave会耗费较长时间,不够实时,在停机的时候会导致大量丢失数据 ,所以需要aof来配合使用。在redis实例重启时,会使用bgsave持久化文件重新构建内存,再使用aof重放近期的操作指令来 实 现完整恢复重启之前的状态。

    对方追问那如果突然机器掉电会怎样?

    取决于aof日志sync属性的配置,如果不要求性能,在每条写指令时都sync一下磁盘,就不会丢失数据。但是在高性能的要求下每次都sync是不现实的,一般都使用定时sync,比如1s1次,这个时候最多就会丢失1s的数据.

    redis锁续租问题?

    (1):基于redis的redission分布式可重入锁RLock,以及配合java集合中lock;

    (2):Redission 内部提供了一个监控锁的看门狗,不断延长锁的有效期,默认检查锁的超时时间是30秒

    (3):此方案的问题:如果你对某个redis master实例,写入了myLock这种锁key的value,此时会异步复制给对应的master ,slave实例。但是这个过程中一旦发生redis master宕机,主备切换,redis slave变为了redis master。

    接着就会导致,客户端2来尝试加锁的时候,在新的redis master上完成了加锁,而客户端1也以为自己成功加了锁。
    此时就会导致多个客户端对一个分布式锁完成了加锁
    解决办法:只需要将新的redis实例,在一个TTL时间内,对客户端不可用即可,在这个时间内,所有客户端锁将被失效或者自动释放.

    bgsave的原理是什么?

    fork和cow。fork是指redis通过创建子进程来进行bgsave操作,cow指的是copy on write,子进程创建后,父子进程共享数据段,父进程继续提供读写服务,写进的页面数据会逐渐和子进程分离开来。

    RDB与AOF区别

    (1):R文件格式紧凑,方便数据恢复,保存rdb文件时父进程会fork出子进程由其完成具体持久化工作,最大化redis性能,恢复大数据集速度更快,只有手动提交save命令或关闭命令时才触发备份操作;

    (2):A记录对服务器的每次写操作(默认1s写入一次),保存数据更完整,在redis重启是会重放这些命令来恢复数据,操作效率高,故障丢失数据更少,但是文件体积更大;

    1亿个key,其中有10w个key是以某个固定的已知的前缀开头的,如果将它们全部找出来?

    使用keys指令可以扫出指定模式的key列表。
    如果这个redis正在给线上的业务提供服务,那使用keys指令会有什么问题?
    redis的单线程的。keys指令会导致线程阻塞一段时间,线上服务会停顿,直到指令执行完毕,服务才能恢复。这个时候可以使用scan指令,scan指令可以无阻塞的提取出指定模式的key列表,但是会有一定的重复概率,在客户端做一次去重就可以了 ,但是整体所花费的时间会比直接用keys指令长。

    如何使用Redis做异步队列?

    一般使用list结构作为队列,rpush生产消息,lpop消费消息。当lpop没有消息的时候,要适当sleep一会再重试。

    可不可以不用sleep呢?

    list还有个指令叫blpop,在没有消息的时候,它会阻塞住直到消息到来。

    能不能生产一次消费多次呢?

    使用pub/sub主题订阅者模式,可以实现1:N的消息队列。

    pub/sub有什么缺点?

    在消费者下线的情况下,生产的消息会丢失,得使用专业的消息队列如rabbitmq等。

    redis如何实现延时队列?

    使用sortedset,想要执行时间的时间戳作为score,消息内容作为key调用zadd来生产消息,消费者用zrangebyscore指令获取N秒之前的数据轮询进行处理。

    为啥redis zset使用跳跃链表而不用红黑树实现?

    (1):skiplist的复杂度和红黑树一样,而且实现起来更简单。

    (2):在并发环境下红黑树在插入和删除时需要rebalance,性能不如跳表。

    MYSQL

    数据库三范式

    一: 确保每列的原子性

    二:非主键列不存在对主键的部分依赖 (要求每个表只描述一件事情)

    三: 满足第二范式,并且表中的列不存在对非主键列的传递依赖

    数据库主从复制原理

    (1):主库db的更新事件(update、insert、delete)被写到binlog

    (2):主库创建一个binlog dump thread线程,把binlog的内容发送到从库

    (3):从库创建一个I/O线程,读取主库传过来的binlog内容并写入到relay log.

    (4):从库还会创建一个SQL线程,从relay log里面读取内容写入到slave的db.

    复制方式分类

    (1):异步复制(默认)
    主库写入binlog日志后即可成功返回客户端,无须等待binlog日志传递给从库的过程,但是一旦主库宕机,就有可能出现丢失数据的情况。

    (2)半同步复制:( 5.5版本之后)
    (安装半同步复制插件)确保从库接收完成主库传递过来的binlog内容已经写入到自己的relay log(传送log)后才会通知主库上面的等待线程。如果等待超时,则关闭半同步复制,并自动转换为异步复制模式,直到至少有一台从库通知主库已经接收到binlog信息为止

    存储引擎

    (1):Myiasm是mysql默认的存储引擎,不支持数据库事务,行级锁,外键;插入更新需锁表,效率低,查询速度快,Myisam使用的是非聚集索引

    (2):innodb 支持事务,底层为B+树实现,适合处理多重并发更新操作,普通select都是快照读,快照读不加锁。InnoDb使用的是聚集索引

    聚集索引

    (1):聚集索引就是以主键创建的索引

    (2):每个表只能有一个聚簇索引,因为一个表中的记录只能以一种物理顺序存放,实际的数据页只能按照一颗 B+ 树进行排序

    (3):表记录的排列顺序和与索引的排列顺序一致

    (4):聚集索引存储记录是物理上连续存在

    (5):聚簇索引主键的插入速度要比非聚簇索引主键的插入速度慢很多

    (6):聚簇索引适合排序,非聚簇索引不适合用在排序的场合,因为聚簇索引叶节点本身就是索引和数据按相同顺序放置在一起,索引序即是数据序,数据序即是索引序,所以很快。非聚簇索引叶节点是保留了一个指向数据的指针,索引本身当然是排序的,但是数据并未排序,数据查询的时候需要消耗额外更多的I/O,所以较慢

    (7):更新聚集索引列的代价很高,因为会强制innodb将每个被更新的行移动到新的位置

    非聚集索引

    (1):除了主键以外的索引

    (2):聚集索引的叶节点就是数据节点,而非聚簇索引的叶节点仍然是索引节点,并保留一个链接指向对应数据块

    (3):聚簇索引适合排序,非聚簇索引不适合用在排序的场合

    (4):聚集索引存储记录是物理上连续存在,非聚集索引是逻辑上的连续。

    使用聚集索引为什么查询速度会变快?

    使用聚簇索引找到包含第一个值的行后,便可以确保包含后续索引值的行在物理相邻

    建立聚集索引有什么需要注意的地方吗?

    在聚簇索引中不要包含经常修改的列,因为码值修改后,数据行必须移动到新的位置,索引此时会重排,会造成很大的资源浪费

    InnoDB 表对主键生成策略是什么样的?

    优先使用用户自定义主键作为主键,如果用户没有定义主键,则选取一个Unique键作为主键,如果表中连Unique键都没有定义的话,则InnoDB会为表默认添加一个名为row_id隐藏列作为主键。

    非聚集索引最多可以有多少个?

    每个表你最多可以建立249个非聚簇索引。非聚簇索引需要大量的硬盘空间和内存

    BTree 与 Hash 索引有什么区别?

    (1):BTree索引可能需要多次运用折半查找来找到对应的数据块
    (2):HASH索引是通过HASH函数,计算出HASH值,在表中找出对应的数据
    (3):大量不同数据等值精确查询,HASH索引效率通常比B+TREE高
    (4):HASH索引不支持模糊查询、范围查询和联合索引中的最左匹配规则,而这些Btree索引都支持

    数据库索引优缺点

    (1):需要查询,排序,分组和联合操作的字段适合建立索引

    (2):索引多,数据更新表越慢,尽量使用字段值不重复比例大的字段作为索引,联合索引比多个独立索引效率高

    (3):对数据进行频繁查询进建立索引,如果要频繁更改数据不建议使用索引

    (4):当对表中的数据进行增加、删除和修改的时候,索引也要动态的维护,降低了数据的维护速度。

    索引的底层实现是B+树,为何不采用红黑树,B树?

    (1):B+Tree非叶子节点只存储键值信息,降低B+Tree的高度,所有叶子节点之间都有一个链指针,数据记录都存放在叶子节点中

    (2): 红黑树这种结构,h明显要深的多,效率明显比B-Tree差很多

    (3):B+树也存在劣势,由于键会重复出现,因此会占用更多的空间。但是与带来的性能优势相比,空间劣势往往可以接受,因此B+树的在数据库中的使用比B树更加广泛

    索引失效条件

    (1):条件是or,如果还想让or条件生效,给or每个字段加个索引

    (2):like开头%

    (3):如果列类型是字符串,那一定要在条件中将数据使用引号引用起来,否则不会使用索引

    (4):where中索引列使用了函数或有运算

    数据库事务特点

    ACID 原子性,一致性,隔离性,永久性

    数据库事务说是如何实现的?

    (1):通过预写日志方式实现的,redo和undo机制是数据库实现事务的基础

    (2):redo日志用来在断电/数据库崩溃等状况发生时重演一次刷数据的过程,把redo日志里的数据刷到数据库里,保证了事务 的持久性(Durability)

    (3):undo日志是在事务执行失败的时候撤销对数据库的操作,保证了事务的原子性

    数据库事务隔离级别

    (1):读未提交read-uncommitted-- 脏,不可重复读–幻读
    A读取了B未提交的事务,B回滚,A 出现脏读;

    (2):不可重复读read-committed-- 不可重复读–幻读
    A只能读B已提交的事务,但是A还没结束,B又更新数据隐式提交,然后A又读了一次出现不可重复读;

    (3):可重复读repeatable-read<默认>-- 幻读
    事务开启,不允许其他事务的UPDATE修改操作
    A读取B已提交的事务,然而B在该表插入新的行,之后A在读取的时候多出一行,出现幻读;

    (4):串行化serializable–

    七种事务传播行为

    (1)Propagation.REQUIRED<默认>
    如果当前存在事务,则加入该事务,如果当前不存在事务,则创建一个新的事务。

    (2)Propagation.SUPPORTS
    如果当前存在事务,则加入该事务;如果当前不存在事务,则以非事务的方式继续运行。

    (3)Propagation.MANDATORY
    如果当前存在事务,则加入该事务;如果当前不存在事务,则抛出异常。

    (4)Propagation.REQUIRES_NEW
    重新创建一个新的事务,如果当前存在事务,延缓当前的事务。

    (5)Propagation.NOT_SUPPORTED
    以非事务的方式运行,如果当前存在事务,暂停当前的事务。

    (6)Propagation.NEVER
    以非事务的方式运行,如果当前存在事务,则抛出异常。

    (7)Propagation.NESTED
    如果没有,就新建一个事务;如果有,就在当前事务中嵌套其他事务。

    产生死锁的四个必要条件

    (1):互斥: 资源x的任意一个时刻只能被一个线程持有
    (2):占有且等待:线程1占有资源x的同时等待资源y,并不释放x
    (3):不可抢占:资源x一旦被线程1占有,其他线程不能抢占x
    (4):循环等待:线程1持有x,等待y,线程2持有y,等待x
    当全部满足时才会死锁

    @Transaction

    底层实现是AOP,动态代理
    (1):实现是通过Spring代理来实现的。生成当前类的代理类,调用代理类的invoke()方法,在invoke()方法中调用 TransactionInterceptor拦截器的invoke()方法;

    (2):非public方式其事务是失效的;

    (3):自调用也会失效,因为动态代理机制导致

    (4)多个方法外层加入try…catch,解决办法是可以在catch里 throw new RuntimeException()来处理

    分布式事务

    XA方案

    有一个事务管理器的概念,负责协调多个数据库(资源管理器)的事务
    不适合高并发场景,严重依赖数据库层面,同步阻塞问题;协调者故障则所有参与者会阻塞

    TCC方案

    严重依赖代码补偿和回滚,一般银行用,和钱相关的支付、交易等相关的场景,我们会用TCC
    Try,对各个服务的资源做检测,对资源进行锁定或者预留
    Confirm,在各个服务中执行实际的操作
    Cancel,如果任何一个服务的业务方法执行出错,那么这里就需要进行补偿,即执行已操作成功的业务逻辑的回滚操作

    可靠消息最终一致性方案

    1):本地消息服务
    本地消息表其实是国外的 ebay 搞出来的这么一套思想。
    主动方是认证服务,有个消息异常处理系统,mq,还有消息消费端应用系统,还有采集服务;

    • 在我认证返回数据中如果有发票是已经认证的,在处理认证数据的操作与发送消息在同一个本地事务中,业务执行完,消息数据也同时存在一条待确认的数据;
    • 发送消息给mq,,mq发送消息给消息消费端服务,同时存一份消息数据,然后发送给采集服务,进行抵账表更新操作;
    • 采集服务逻辑处理完以后反馈给消息消费端服务,其服务删除消息数据,同时通知认证服务,把消息记录改为已确认成功费状态;
    • 对于异常流程,消息异常处理系统会查询认证服务中过期未确认的消息发送给mq,相当于重试

    2):独立消息最终一致性方案:
    A 主动方应用系统,B消息服务子系统,C消息状态确认子系统,C2消息管理子系统
    D 消息恢复子系统,mq ,消息消费端E ,被动系统F

     流程:
    A预发送消息给B,然后执行A业务逻辑,B存储预发送消息,A执行完业务逻辑发送业务操作结果给B,B更新预发送消息为确认并发送消息状态同时发送消息给mq,然后被E监听然后发送给F消费掉
    C:对预发送消息异常的处理,去查询待确认状态超时的消息,去A中查询进行数据处理,如果A中业务处理成功了,那么C需改消息状态为确认并发送状态,然后发送消息给mq;如果A中业务处理失败了..那么C直接把消息删除即可.
    C2 : 查询消息的页面,对消息的可视化,以及批量处理死亡消息;
    D: B给mq放入数据如果失败,,通过D去重试,多次重试失败,消息设置为死亡 
    E:确保F执行完成,发送消息给B删除消息
    优化建议: 
     (1)数据库:如果用redis,持久化要配置成appendfsync always,确保每次新添加消息都能持久化进磁盘
     (2)在被动方应用业务幂等性判断比较麻烦或者比较耗性能情况下,增加消息日志记录表.用于判断之前有无发送过;
    

    最大努力通知性(定期校对)

    (1)业务主动方完成业务处理之后,设置时间阶梯型通知规则向业务活动的被动方发送消息,允许消息丢失.

    (2)被动方根据定时策略,向主动方查询,恢复丢失的业务消息

    (3)被动方的处理结果不影响主动方的处理结果

    (4)需增加业务查询,通知服务,校对系统服务的建设成本

    (5)适用于对业务最终一致性的时间敏感度低,跨企业的业务通知活动

    (6)比如银行通知,商户通知,交易业务平台间商户通知,多次通知,查询校对等

    Seata(阿里)

    应用层基于SQL解析实现了自动补偿,从而最大程度的降低业务侵入性;
    将分布式事务中TC(事务协调者)独立部署,负责事务的注册、回滚;
    通过全局锁实现了写隔离与读隔离。

    网络

    TCP和UDP的比较

    TCP向上层提供面向连接的可靠服务 ,UDP向上层提供无连接不可靠服务。
    虽然 UDP 并没有 TCP 传输来的准确,但是也能在很多实时性要求高的地方有所作为
    对数据准确性要求高,速度可以相对较慢的,可以选用TCP

    TCP三次握手

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Z5cVyZQc-1588909160041)(https://tva1.sinaimg.cn/large/007S8ZIlgy1gek7kv86p8j31a80s0wny.jpg)]

    TCP四次挥手

    (1):客户端发送终止命令FIN

    (2):服务端收到后回复ACK,处于close_wait状态

    (3):服务器将关闭前需要发送信息发送给客户端后处于last_ack状态

    (4):客户端收到FIN后发送ack后处于tim-wait而后进入close状态

    为什么要进行第三次握手

    为了防止服务器端开启一些无用的连接增加服务器开销以及防止已失效的连接请求报文段突然又传送到了服务端

    JDK1.8新特性

    Lambda表达式

    java也开始承认了函数式编程, 就是说函数既可以作为参数,也可以作为返回值,
    大大的简化了代码的开发

    default关键字

    打破接口里面是只能有抽象方法,不能有任何方法的实现,接口里面也可以有方法的实现了

    新时间日期APILocalDate | LocalTime | LocalDateTime

    之前使用的java.util.Date月份从0开始,我们一般会+1使用,很不方便,java.time.LocalDate月份和星期都改成了enum
    java.util.Date和SimpleDateFormat都不是线程安全的,而LocalDate和LocalTime和最基本的String一样,是不变类型,不但线程安全,而且不能修改。
    新接口更好用的原因是考虑到了日期时间的操作,经常发生往前推或往后推几天的情况。用java.util.Date配合Calendar要写好多代码,而且一般的开发人员还不一定能写对。

    JDK1.7与JDK1.8 ConcurrentHashMap对比

    (1):JDK1.7版本的ReentrantLock+Segment+HashEntry(数组)

    (2):JDK1.7采用segment的分段锁机制实现线程安全

    (3):JDK1.8版本中synchronized+CAS+HashEntry(数组)+红黑树

    (4):JDK1.8采用CAS+Synchronized保证线程安全

    (5):查询时间复杂度从原来的遍历链表O(n),变成遍历红黑树O(logN)

    1.8 HashMap数组+链表+红黑树来实现hashmap,当碰撞的元素个数大于8时 & 总容量大于64,会有红黑树的引入
    除了添加之后,效率都比链表高,1.8之后链表新进元素加到末尾

    JDK1.8使用synchronized来代替重入锁ReentrantLock?

    (1):因为粒度降低了,在相对而言的低粒度加锁方式,synchronized并不比ReentrantLock差

    (2):基于JVM的synchronized优化空间更大

    (3):在大数据量下,基于API的ReentrantLock会比基于JVM的内存压力开销更多的内存

    JDK1.9新特性

    模块系统:

    模块是一个包的容器,Java 9 最大的变化之一是引入了模块系统(Jigsaw 项目)。

    集合工厂方法

    通常,您希望在代码中创建一个集合(例如,List 或 Set ),并直接用一些元素填充它。 实例化集合,几个 “add” 调用,使得代码重复。 Java 9,添加了几种集合工厂方法:

    Set<Integer> ints = Set.of(123);
    List<String> strings = List.of("first""second");
    

    改进的 Stream API

    Stream 接口中添加了 4 个新的方法:dropWhile, takeWhile, ofNullable。还有个 iterate 方法的新重载方法

    改进的 Javadoc:

    Javadoc 现在支持在 API 文档中的进行搜索。另外,Javadoc 的输出现在符合兼容 HTML5 标准。

    redis代理集群模式,spring有哪些注解,b+b 红黑树区别,三次握手,valitile重排序底层代码,
    cas 事务的4个特性,java8 java11 特性, filter和interceptor的区别 @autowired原理,
    dispatcherservlet,分布式事务解决方案spring都有哪些模块,fork join队列,排序算法,

    集合

    java的集合框架有哪几种:

    两种:collection和map,其中collection分为set和List。

    List你使用过哪些

    ArrayList和linkedList使用的最多,也最具代表性。

    你知道vector和ArrayList和linkedList的区别嘛

    ArrayList实现是一个数组,可变数组,默认初始化长度为10,也可以我们设置容量,但是没有设置的时候是默认的空数组,只有在第一步add的时候会进行扩容至10(重新创建了数组),后续扩容按照3/2的大小进行扩容,是线程不安全的,适用多读取,少插入的情况

    linkedList是基于双向链表的实现,使用了尾插法的方式,内部维护了链表的长度,以及头节点和尾节点,所以获取长度不需要遍历。适合一些插入/删除频繁的情况。

    Vector是线程安全的,实现方式和ArrayList相似,也是基于数组,但是方法上面都有synchronized关键词修饰。其扩容方式是原来的两倍。

    hashMap和hashTable和ConcurrentHashMap的区别

    hashMap是map类型的一种最常用的数据结构,其底部实现是数组+链表(在1.8版本后变为了数组+链表/红黑树的方式),其key是可以为null的,默认hash值为0。扩容以2的幂等次(为什么。。。因为只有是2的幂等次的时候(n-1)&x==x%n,当然不一定只有一个原因)。是线程不安全的

    hashTable的实现形式和hashMap差不多,它是线程安全的,是继承了Dictionary,也是key-value的模式,但是其key不能为null。

    ConcurrentHashMap是JUC并发包的一种,在hashMap的基础上做了修改,因为hashmap其实是线程不安全的,那在并发情况下使用hashTable嘛,但是hashTable是全程加锁的,性能不好,所以采用分段的思想,把原本的一个数组分成默认16段,就可以最多容纳16个线程并发操作,16个段叫做Segment,是基于ReetrantLock来实现的

    说说你了解的hashmap吧

    hashMap是Map的结构,内部用了数组+链表的方式,在1.8后,当链表长度达到8的时候,会变成红黑树,这样子就可以把查询的复杂度变成O(nlogn)了,默认负载因子是0.75,为什么是0.75呢?

    我们知道当负载因子太小,就很容易触发扩容,如果负载因子太大就容易出现碰撞。所以这个是空间和时间的一个均衡点,在1.8的hashmap介绍中,就有描述了,貌似是0.75的负载因子中,能让随机hash更加满足0.5的泊松分布。

    除此之外,1.7的时候是头插法,1.8后就变成了尾插法,主要是为了解决rehash出现的死循环问题,而且1.7的时候是先扩容后插入,1.8则是先插入后扩容(为什么?正常来说,如果先插入,就有可能节点变为树化,那么是不是多做一次树转化,比1.7要多损耗,个人猜测,因为读写问题,因为hashmap并不是线程安全的,如果说是先扩容,后写入,那么在扩容期间,是访问不到新放入的值的,是不是不太合适,所以会先放入值,这样子在扩容期间,那个值是在的)。

    1.7版本的时候用了9次扰动,5次异或,4次位移,减少hash冲突,但是1.8就只用了两次,觉得就足够了一次异或,一次位移。

    concurrentHashMap呢

    concurrentHashMap是线程安全的map结构,它的核心思想是分段锁。在1.7版本的时候,内部维护了segment数组,默认是16个,segment中有一个table数组(相当于一个segmeng存放着一个hashmap。。。),segment继承了reentrantlock,使用了互斥锁,map的size其实就是segment数组的count和。而在1.8的时候做了一个大改版,废除了segment,采用了cas加synchronize方式来进行分段锁(还有自旋锁的保证),而且节点对象改用了Node不是之前的HashEntity。

    Node可以支持链表和红黑树的转化,比如TreeBin就是继承了Node,这样子可以直接用instanceof来区分。1.8的put就很复杂来,会先计算出hash值,然后根据hash值选出Node数组的下标(默认数组是空的,所以一开始put的时候会初始化,指定负载因子是0.75,不可变),判断是否为空,如果为空,则用cas的操作来赋值首节点,如果失败,则因为自旋,会进入非空节点的逻辑,这个时候会用synchronize加锁头节点(保证整条链路锁定)这个时候还会进行二次判断,是否是同一个首节点,在分首节点到底是链表还是树结构,进行遍历判断。

    concurrentHashMap的扩容方式

    1.7版本的concurrentHashMap是基于了segment的,segment内部维护了HashEntity数组,所以扩容是在这个基础上的,类比hashmap的扩容,

    1.8版本的concurrentHashMap扩容方式比较复杂,利用了ForwardingNode,先会根据机器内核数来分配每个线程能分到的busket数,(最小是16),这样子可以做到多线程协助迁移,提升速度。然后根据自己分配的busket数来进行节点转移,如果为空,就放置ForwardingNode,代表已经迁移完成,如果是非空节点(判断是不是ForwardingNode,是就结束了),加锁,链路循环,进行迁移。

    hashMap的put方法的过程

    判断key是否是null,如果是null对应的hash值就是0,获得hash值过后则进行扰动,(1.7是9次,5次异或,4次位移,1.8是2次),获取到的新hash值找出所在的index,(n-1)&hash,根据下标找到对应的Node/entity,然后遍历链表/红黑树,如果遇到hash值相同且equals相同,则覆盖值,如果不是则新增。如果节点数大于8了,则进行树化(1.8)。完成后,判断当前的长度是否大于阀值,是就扩容(1.7是先扩容在put)。

    为什么修改hashcode方法要修改equals

    都是map惹的祸,我们知道在map中判断是否是同一个对象的时候,会先判断hash值,在判断equals的,如果我们只是重写了hashcode,没有顺便修改equals,比如Intger,hashcode就是value值,如果我们不改写equals,而是用了Object的equals,那么就是判断两者指针是否一致了,那就会出现valueOf和new出来的对象会对于map而言是两个对象,那就是个问题了

    TreeMap了解嘛

    TreeMap是Map中的一种很特殊的map,我们知道Map基本是无序的,但是TreeMap是会自动进行排序的,也就是一个有序Map(使用了红黑树来实现),如果设置了Comparator比较器,则会根据比较器来对比两者的大小,如果没有则key需要是Comparable的子类(代码中没有事先check,会直接抛出转化异常,有点坑啊)。

    LinkedHashMap了解嘛

    LinkedHashMap是HashMap的一种特殊分支,是某种有序的hashMap,和TreeMap是不一样的概念,是用了HashMap+链表的方式来构造的,有两者有序模式:访问有序,插入顺序,插入顺序是一直存在的,因为是调用了hashMap的put方法,并没有重载,但是重载了newNode方法,在这个方法中,会把节点插入链表中,访问有序默认是关闭的,如果打开,则在每次get的时候都会把链表的节点移除掉,放到链表的最后面。这样子就是一个LRU的一种实现方式。

    数据结构+算法

    TODO(未完待续)

    总结

    内容过于硬核了,导致很多排版细节,我没办法做得像其他期一样精致了,大家见谅。

    涉及的内容和东西太多了,可能很多都是点到为止,也有很多不全的,也有很多错误的点,已经快3W字了,我校验实在困难,我会放在GitHub上面,大家可以跟我一起更新这个文章,造福后人吧。

    搞不好下次我需要看的时候,我都得看着这个复习了。

    我是敖丙,一个在互联网苟且偷生的工具人。

    你知道的越多,你不知道的越多人才们的 【三连】 就是丙丙创作的最大动力,我们下期见!

    注:如果本篇博客有任何错误和建议,欢迎人才们留言,你快说句话啊


    文章持续更新,可以微信搜索「 三太子敖丙 」第一时间阅读,回复【资料】【面试】【简历】有我准备的一线大厂面试资料和简历模板,本文 GitHub https://github.com/JavaFamily 已经收录,有大厂面试完整考点,欢迎Star。

    展开全文
  • 本实验所用设备: 硬件设备及工具:Windows Server 2003/2012 R2;Windows 10。...(4)学会建立网络访问及资源共享的方法; (5)熟练掌握网络常用命令的使用方法。 2 实验内容 (1)给PC配置IP地址及相关
  • (4) 学会建立网络访问及资源共享的方法。 (5) 熟练掌握网络常用命令的使用方法。 2 实验内容 (1) 给PC配置IP地址及相关网络参数。 (2) 建立对等网络。 (3) 建立网络访问及资源共享。 (4) 基本网络命令的...
  • C++面试常用知识点总结——基础篇

    万次阅读 多人点赞 2019-07-15 18:13:04
    温备份:的是当数据库进行备份时, 数据库的读操作可以执行, 但是不能执行写操作 冷备份:的是当数据库进行备份时, 数据库不能进行读写操作, 即数据库要下线 2.2.3、Mysql如何备份 直接拷贝数据库 ...
  • Linux学习之路 1.Linux安装篇 1.1 Linux安装教程 1.2 vm的安装步骤 1.3 .CentOS安装步骤 ...2.3 使用 vmtools 来设置 windows 和 linux 的共享文件夹 2.4 Linux目录结构 2.5 目录结构的具体介绍 3.Linux实操篇 3....
  • 二、VR/AR 游戏的常用插件 三、模型构建/环境构建插件相关 四、Shader 相关插件 五、动画插件 六、网络/网络视频语音 插件 七、AI 相关 八、区块链相关 九、资源/数据相关插件 一、 UI / 2D 相关 1、...
  • Java常见设计模式总结

    万次阅读 多人点赞 2021-09-18 17:18:54
    12、结构型-享元模式: 享元模式通过共享技术有效地支持细粒度、状态变化小的对象复用,当系统中存在有多个相同的对象,那么只共享一份,不必每个都去实例化一个对象,极大地减少系统中对象的数量,从而节省资源。...
  • 牛逼!Java 从入门到精通,超全汇总版

    万次阅读 多人点赞 2021-05-06 19:40:33
    设计目标 从 Paxos 到 Zookeeper ZooKeeper : 分布式过程协同技术详解 Nginx Nginx 基础知识 Nginx 正向代理与反向代理 Nginx 基本配置 Nginx 负载均衡 Nginx常用命令 深入理解 Nginx Netty Netty 实战 ES Elastic...
  • 共享内存的常用函数详解shmget shmat

    千次阅读 2015-03-31 07:16:28
    共享内存区域是被多个进程共享的一部分物理内存。如果多个进程都把该内存区域映射到自己的虚拟地址空间,则这些进程就都可以直接访问该共享内存区域,从而可以通过该区域进行通信。共享内存是进程间共享数据的一种最...
  • 工作之余从网络整理的常用术语,内容上未必严谨(分类仅供参考)。欢迎斧正,专业人士可绕道。
  • 入门学习Linux常用必会60个命令实例详解doc/txt

    千次下载 热门讨论 2011-06-09 00:08:45
    资源来自网络,如有纰漏还请告知,如觉得还不错,请留言告知后来人,谢谢!!!!! 入门学习Linux常用必会60个命令实例详解 Linux必学的60个命令 Linux提供了大量的命令,利用它可以有效地完成大量的工作,如...
  • 这是作者的网络安全自学教程系列,主要是关于安全工具和实践操作的在线笔记,特分享出来与博友们学习,希望您们喜欢,一起进步。前文分享了微软证书漏洞(CVE-2020-0601),并详细讲解了Windows验证机制、可执行文件...
  • 1 引言  并发、并行、串行、同步、异步、阻塞、非阻塞、进程、线程、协程是并发编程中的常见... 并发是在同一个处理器上通过时间片轮转的方式在多个线程之间频繁切换,由于切换速度极快,所以看似多个线程似...
  • 共享内存共享内存是进程间通信中最简单的方式之一。共享内存是系统出于多个进程之间通讯的考虑,而预留的的一块内存区。共享内存允许两个或更多进程访问同一块内存,就如同 malloc() 函数向不同进程返回了指向同一个...
  • Java中常用的设计模式

    万次阅读 多人点赞 2019-03-15 17:25:14
    优点:只有一个实例,节约了内存资源,提高了系统性能 缺点:  没有抽象层,不能扩展  职责过重,违背了单一性原则 首先我们写一个简单的单例类: public class Singleton { /* 持有私有静态实例...
  • 常用网络设备

    千次阅读 2018-07-26 13:58:46
    对所接收的信号进行放大,然后直接发送到另一个端口连接的电缆上,主要用于扩展网络的物理连接范围 集线器:hub 集线器(HUB)属于数据通信系统中的基础设备,它和双绞线等传输介质一样,是一种不需任何软件支持或...
  • 该楼层疑似违规已被系统折叠隐藏此楼查看此楼常用的java开发框架java作为主流的开发语言之一其框架的使用也是非常广泛的,java到javaee部分全部是在以框架来开发,因为框架可以大大节约时间以及成本,那么java中常用...
  • 华为C语言编程规范(精华总结)

    万次阅读 多人点赞 2020-03-24 09:48:55
    5、禁止头文件循环依赖 头文件循环依赖,a.h包含b.h,b.h包含c.h,c.h包含a.h之类导致任何一个头文件修改,都导致所有包含了a.h/b.h/c.h的代码全部重新编译一遍。而如果是单向依赖,如a.h包含b.h,b.h包含c.h,而...
  • Java Web前端到后台常用框架介绍

    万次阅读 多人点赞 2016-03-18 11:44:16
    //blog.csdn.net/evankaka/article/details/45501811Spring Web MVC是一种基于Java的实现了Web MVC设计模式的请求驱动类型的轻量级Web框架,即使用了MVC架构模式的思想,将web层进行职责解耦,基于请求驱动的就是...
  • 「K8s入门北」Docker不香吗?为什么还需要K8s?

    万次阅读 多人点赞 2022-04-12 11:45:17
    容器技术常用来在宿主机上隔离出环境来部署应用(用容器化技术部署的应用称为 “容器化应用” ),而虚拟机常用来运行一个与宿主机不同的操作系统,从而运行特定的软件。 容器的特性 容器量级非常轻,无论是启动...
  • 共享汽车充电桩方案开发详解

    千次阅读 2019-09-02 09:40:03
    共享汽车充电桩模式就是把闲置的资源对外开放,让更多人能够共享。此外,由于国内小区整体电力不足,通常10个充电桩就会使小区电容量达到饱和,这时共享汽车充电桩就能在不增加总体电容量的前提下解决更多车主的充电问题...
  • 1、频分多路复用,特点是把电路或空间的频带资源分为多个频段,并将其分配给多个用户,每个用户终端的数据通过分配给它的子通路传输。主要用于电话和电缆电视系统。 2、时分多路复用,特点是按传输的时间进行分割,...
  • 计算机常用重点

    万次阅读 多人点赞 2020-06-22 11:01:26
    是计算机系统的一个系统软件,能有效地组织和管理计算机系统中的硬件和软件资源,合理(公平对待不同用户程序,不发生“死锁”和“饥饿”)组织计算机工作流程,控制程序的执行,并向用户提供各种服务功能,使用户能...
  • Windows系统IPC$共享与勒索病毒

    千次阅读 2022-03-31 11:44:24
    因此进程间要进行数据交互就要通过内核,在内核中开辟一块缓冲区,每个进程只需把要共享的数据拷贝到缓冲区即可,内核提供的这种机制称为进程间通信(IPC) 共享命名管道   关于进程间通信(InterProcess ...
  • AIoT在智慧景区中的应用

    千次阅读 2022-04-08 16:03:24
    智慧景区是景区能够通过智能网络对景区地理事物、自然资源、旅游者行为、景区工作人员行迹、景区基础设施和服务设施进行全面、透彻、及时的感知,对游客、景区工作人员实现可视化管理,优化再造景区业务流程和智能...
  • 产品经理常用术语

    千次阅读 2018-04-14 20:56:51
    UI设计主要指界面的样式,美观程度。而使用上,对软件的人机交互、操作逻辑、界面美观的整体设计则是同样重要的另一个门道。 UGC :User Generated Content(用户原创内容) 它并不是某一种具体的业务,而是一种...
  • AJAX跨域请求和CORS跨域资源共享

    千次阅读 2016-07-19 12:44:38
    整理了同源策略限制,出现了跨域请求的需求,原生传统的跨域请求方式,原生js和jQuery中对跨域的处理(JSONP),以及HTML5 中的CORS跨域资源共享。系统条理得梳理好传说中的跨域了!o(^▽^)o

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 130,219
精华内容 52,087
关键字:

常用的共享资源主要指