精华内容
下载资源
问答
  • 华为UltraPath多路径软件配置ASM磁盘

    千次阅读 2021-05-10 05:23:14
    最近安装19c数据库,准备配置UDEV的时候,发现使用的多路径软件不是RHEL自带的multipath,而是华为的UltraPath。第一次使用,为了安全起见,先查阅了相关资料,记录一下。UltraPath简介UltraPath软件是基于Linux...

    最近安装19c数据库,准备配置UDEV的时候,发现使用的多路径软件不是RHEL自带的multipath,而是华为的UltraPath。第一次使用,为了安全起见,先查阅了下相关资料,记录一下。

    UltraPath简介

    UltraPath软件是基于Linux内核开发的多路径软件。它安装在应用服务器上,主要用于控制应用服务器对存储设备的访问,实现应用服务器到存储设备之间的路径选择以及路径管理。

    主机操作系统一般都自带多路径(通常称为Multi-Path I/O,MPIO)功能,但仅能实现基本的故障转移和负载均衡功能,不能满足高可靠性系统的应用要求。而华为多路径软件UltraPath既能满足基本的故障转移和负载均衡功能,又具备了很多自带多路径没有的高级功能,如路径例测、路径闪断保护、路径隔离、路径告警推送、路径性能监控等等,同时与华为存储设备兼容性更好,所以UltraPath能满足整个IT系统对可靠性、性能、可维护性以及存储适配度等方面的要求。故在使用华为存储设备时,如果没有特殊要求,建议使用华为多路径软件UltraPath。

    UltraPath组网图

    5f95c3d8982c19974c088fcca6f28e4a.png

    安装

    接下来在安装的部分看到,在/dev下看到的sda、sdb等磁盘,是UltraPath生成的虚拟磁盘,而且是操作系统分配的盘符,可能会发生盘符漂移。也建议使用UDEV绑定的方式提供给Oracle使用。

    e8f3d5975e59cefaf2c0c2a405dc0004.png

    查看虚拟磁盘

    UltraPath提供了upadmin客户端工具,查询方法如下:

    [root@test ~]# upadmin

    UltraPath CLI #0 >show vlun

    -----------------------------------------------------------------------------------------------------------------------------------------------------------------------------

    Vlun ID Disk Name Lun WWN Status Capacity Ctrl(Own/Work) Array Name Dev Lun ID No. of Paths(Available/Total)

    0 sdd test_mgmt001 6c8a7761009835632299e0ac000000ce Normal 512.00GB 0C/0C TEST-OS18800A 206 8/8

    1 sde test_mgmt002 6c8a7761009835632299e0d4000000cf Normal 512.00GB 0D/0D TEST-OS18800A 207 8/8

    2 sdf test_ocr001 6c8a77610098356322a0501f000000d3 Normal 10.00GB 0A/0A TEST-OS18800A 211 8/8

    3 sdg test_ocr002 6c8a77610098356322a06b10000000d4 Normal 10.00GB 0B/0B TEST-OS18800A 212 8/8

    4 sdh test_ocr003 6c8a77610098356322a08304000000d5 Normal 10.00GB 0C/0C TEST-OS18800A 213 8/8

    5 sdi test_data001 6c8a77610098356322a0e7b2000000d6 Normal 1.50TB 0D/0D TEST-OS18800A 214 8/8

    6 sdj test_data002 6c8a77610098356322a0e7e4000000d7 Normal 1.50TB 0A/0A TEST-OS18800A 215 8/8

    7 sdk test_data003 6c8a77610098356322a0e810000000d8 Normal 1.50TB 0B/0B TEST-OS18800A 216 8/8

    8 sdl testc_data004 6c8a77610098356322a0e8ed000000d9 Normal 1.50TB 0C/0C TEST-OS18800A 217 8/8

    9 sdm test_data005 6c8a77610098356322a0e911000000da Normal 1.50TB 0D/0D TEST-OS18800A 218 8/8

    10 sdn test_data006 6c8a77610098356322a0e9e8000000db Normal 1.50TB 0A/0A TEST-OS18800A 219 8/8

    配置磁盘或分区别名

    继续查阅资料,发现可以为vlun配置别名,本质上还是通过UDEV的方式实现

    原文链接:https://support.huawei.com/enterprise/zh/doc/EDOC1100026705/7316c49d

    命令格式:

    upLinux setGlobalDiskAlias alias_prefix=name [owner=user group=group method={SYMLINK|NAME}]

    -- 生成的磁盘或分区别名保存在“/dev/ultrapath”目录

    以下是我尝试配置/dev/sdd来验证

    [root@test ~]# upLinux setDiskAlias src_name=sdd dest_alias=test_mgmt001 owner=grid group=asmadmin method=SYMLINK

    cat: /etc/issue: No such file or directory

    cat: /etc/issue: No such file or directory

    cat: /etc/issue: No such file or directory

    cat: /etc/issue: No such file or directory

    Succeeded in executing the command.

    [root@test ~]# upLinux showDiskAlias

    cat: /etc/issue: No such file or directory

    cat: /etc/issue: No such file or directory

    ----------------------------------------------------------------------------------------------------------------------------------------

    ID Alias Lun WWN Disk Type

    0 asm-test_mgmt001 6c8a7761009835632299e0ac000000ce sdd SYMLINK

    ----------------------------------------------------------------------------------------------------------------------------------------

    [root@test ~]# cd /dev/ultrapath

    [root@test ultrapath]# ls

    asm-test_mgmt001

    [root@test ultrapath]# cd /etc/udev/rules.d/

    [root@test rules.d]# ls -lrt

    total 16

    -rw-r--r--. 1 root root 628 Feb 6 2019 70-persistent-ipoib.rules

    -rw------- 1 root root 211 Mar 2 20:14 56-nxup.rules

    -rw------- 1 root root 571 Mar 2 20:14 99-ultrapath.rules

    -rw------- 1 root root 299 Mar 27 11:40 99-ultrapath-alias.rules

    [root@test rules.d]# cat 99-ultrapath-alias.rules

    # Do not modify this rule configuration file; otherwise, the usage of UltraPath may be affected.

    KERNEL=="sd*[a-z]", SUBSYSTEM=="block", ENV{ID_SERIAL}=="36c8a7761009835632299e0ac000000ce", ENV{DEVTYPE}=="disk", SYMLINK+="ultrapath/asm-test_mgmt001", OWNER="grid", GROUP="asmadmin", MODE="0660"

    其他命令

    查看所有磁盘和分区别名:

    upLinux showDiskAlias

    删除指定磁盘或分区别名:

    upLinux unsetDiskAlias alias=name

    命令用于清除未正常生效的别名配置:

    upLinux unsetDiskAlias

    另外,我通过传统的方式进行配置,发现也是可以的。详细步骤不记录了,规则文件如下:

    KERNEL=="sd*", SUBSYSTEM=="block", PROGRAM=="/usr/lib/udev/scsi_id -g -u -d $devnode", RESULT=="36c8a77610098356322a0501f000000d3", SYMLINK+="asm-test_ocr001", OWNER="grid", GROUP="asmadmin", MODE="0660"

    KERNEL=="sd*", SUBSYSTEM=="block", PROGRAM=="/usr/lib/udev/scsi_id -g -u -d $devnode", RESULT=="36c8a77610098356322a06b10000000d4", SYMLINK+="asm-test_ocr002", OWNER="grid", GROUP="asmadmin", MODE="0660"

    KERNEL=="sd*", SUBSYSTEM=="block", PROGRAM=="/usr/lib/udev/scsi_id -g -u -d $devnode", RESULT=="36c8a776100983564c3e29b34000000e2", SYMLINK+="asm-test_ocr001", OWNER="grid", GROUP="asmadmin", MODE="0660"

    KERNEL=="sd*", SUBSYSTEM=="block", PROGRAM=="/usr/lib/udev/scsi_id -g -u -d $devnode", RESULT=="36c8a776100983564c3e29b63000000e3", SYMLINK+="asm-test_ocr002", OWNER="grid", GROUP="asmadmin", MODE="0660"

    展开全文
  • 华为软件笔试题4.10

    2021-03-15 20:58:43
    截断8位字符打印 ACdef ysy(board):n=int(board[0])strlist=[]for i in range(1,n+1):s=board[i]strlist+=mysplit(s)strlist.sort()return strlistdef mysplit(s):slist=[]i=0while islist.append(s[i:i+8])i+=8a=s...

    截断8位字符打印 AC

    def ysy(board):

    n=int(board[0])

    strlist=[]

    for i in range(1,n+1):

    s=board[i]

    strlist+=mysplit(s)

    strlist.sort()

    return strlist

    def mysplit(s):

    slist=[]

    i=0

    while i

    slist.append(s[i:i+8])

    i+=8

    a=s[i:]+'0'*(8-len(s[i:]))

    slist.append(a)

    return slist

    if __name__=='__main__':

    board=list(input().split())

    res=ysy(board)

    print(' '.join(res))

    括号反转

    字符打印 AC

    def ysy(s):

    def group(a):

    num=''

    i=0

    while i

    num+=a[i]

    i+=1

    num=int(num)

    j,cnt=i+1,1

    while j0:

    if a[j] in '{([':

    cnt+=1

    elif a[j] in '})]':

    cnt-=1

    j+=1

    return num,i,j-1

    res=''

    while s:

    cur=s[0]

    if cur.isdigit():

    num,i,j=group(s)

    res+=ysy(s[i+1:j])*num

    s=s[j+1:]

    else:

    res+=cur

    s=s[1:]

    return res

    if __name__=='__main__':

    s=input()

    print(ysy(s)[::-1])

    海拔路径题题目

    #####90.91%测试用例

    def ysy(board,n,m,ax,ay,bx,by):

    target=board[bx][by]

    start=board[ax][ay]

    mod=10**9

    visit=[[0]*m for _ in range(n)]

    visit[ax][ay]=1

    mydict={start:[[ax,ay]]}

    for tmp in range(start,target):

    if tmp in mydict:

    for index in mydict[tmp]:

    x,y=index

    for dx,dy in zip([-1,0,1,0],[0,-1,0,1]):

    nx,ny=x+dx,y+dy

    if 0<=nx

    visit[x][y]+=visit[nx][ny]

    visit[x][y]=visit[x][y]%mod

    for dx,dy in zip([-1,0,1,0],[0,-1,0,1]):

    nx,ny=x+dx,y+dy

    if 0<=nxboard[x][y] and board[nx][ny]

    if board[nx][ny] in mydict:

    if [nx,ny] not in mydict[board[nx][ny]]:

    mydict[board[nx][ny]].append([nx,ny])

    else:

    mydict[board[nx][ny]]=[[nx,ny]]

    del mydict[tmp]

    print(visit)

    res=0

    x,y=bx,by

    for dx,dy in zip([-1,0,1,0],[0,-1,0,1]):

    nx,ny=x+dx,y+dy

    if 0<=nx

    res+=visit[nx][ny]

    return res%mod

    ####内存超出 80%

    def ysy(board,n,m,ax,ay,bx,by):

    target=board[bx][by]

    start=board[ax][ay]

    mod=10**9

    visit=[[0]*m for _ in range(n)]

    visit[ax][ay]=1

    mydict={}

    for i in range(n):

    for j in range(m):

    c=board[i][j]

    if start < c < target:

    x,y,f=i,j,False

    for dx,dy in zip([-1,0,1,0],[0,-1,0,1]):

    nx,ny=x+dx,y+dy

    if 0<=nxboard[nx][ny]: f=True

    if f:

    if  c not in mydict:

    mydict[c]=[[i,j]]

    else:

    mydict[c].append([i,j])

    for num in range(start+1,target):

    if num in mydict:

    for tmp in mydict[num]:

    x,y=tmp

    for dx,dy in zip([-1,0,1,0],[0,-1,0,1]):

    nx,ny=x+dx,y+dy

    if 0<=nx

    visit[x][y]+=visit[nx][ny]

    visit[x][y]=visit[x][y]%mod

    res=0

    x,y=bx,by

    for dx,dy in zip([-1,0,1,0],[0,-1,0,1]):

    nx,ny=x+dx,y+dy

    if 0<=nx

    res+=visit[nx][ny]

    return res%mod

    if __name__=='__main__':

    n,m=map(int,input().split())

    board=[]

    for _ in range(n):

    board.append(list(map(int,input().split())))

    ax,ay,bx,by=map(int,input().split())

    print(ysy(board,n,m,ax,ay,bx,by))

    展开全文
  • 1、Collection接口有哪些子类? 1.1 集合和数组的区别 1.2 Collection和Map 1.3 Collection接口 1.4 集合的遍历方法 用迭代器迭代 Iterator it = list.iterator(); while(it.hasNext()) { System.ou.println...

    1、Collection接口下有哪些子类?

    在这里插入图片描述

    1.1 集合和数组的区别

    在这里插入图片描述

    1.2 Collection和Map

    在这里插入图片描述

    1.3 Collection接口

    在这里插入图片描述

    1.4 集合的遍历方法

    用迭代器迭代

    Iterator it = list.iterator();
    while(it.hasNext()) {
      System.ou.println(it.next);
    }
    

    1.5 List接口的实现类

    (1)ArrayList:底层数据结构是数组,查询快,增删慢,线程不安全,效率高,可以存储重复元素
    (2)LinkedList 底层数据结构是链表,查询慢,增删快,线程不安全,效率高,可以存储重复元素
    (3)Vector:底层数据结构是数组,查询快,增删慢,线程安全,效率低,可以存储重复元素
    在这里插入图片描述

    1.6 Set集合

    (1)HashSet : 底层数据结构采用哈希表实现,元素无序且唯一,线程不安全,效率高,可以存储null元素,元素的唯一性是靠所存储元素类型是否重写hashCode()和equals()方法来保证的,如果没有重写这两个方法,则无法保证元素的唯一性。
    a、实现唯一性:
      存储元素首先会使用hash()算法函数生成一个int类型hashCode散列值,然后已经的所存储的元素的hashCode值比较,如果hashCode不相等,则所存储的两个对象一定不相等,此时存储当前的新的hashCode值处的元素对象;如果hashCode相等,存储元素的对象还是不一定相等,此时会调用equals()方法判断两个对象的内容是否相等,如果内容相等,那么就是同一个对象,无需存储;如果比较的内容不相等,那么就是不同的对象,就该存储了,此时就要采用哈希的解决地址冲突算法,在当前hashCode值处类似一个新的链表, 在同一个hashCode值的后面存储存储不同的对象,这样就保证了元素的唯一性。
    b、实现不重复
      HashSet也一样他是使用了一种标识来确定元素的不重复,HashSet用一种算法来保证HashSet中的元素是不重复的, HashSet采用哈希算法,底层用数组存储数据。默认初始化容量16,加载因子0.75。
      Object类中的hashCode()的方法是所有子类都会继承这个方法,这个方法会用Hash算法算出一个Hash(哈希)码值返回,HashSet会用Hash码值去和数组长度取模, 模(这个模就是对象要存放在数组中的位置)相同时才会判断数组中的元素和要加入的对象的内容是否相同,如果不同才会添加进去。
    在这里插入图片描述

    (2)、LinkedHashSet底层数据结构采用链表和哈希表共同实现,链表保证了元素的顺序与存储顺序一致,哈希表保证了元素的唯一性。线程不安全,效率高。
    (3)、TreeSet底层数据结构采用二叉树来实现,元素唯一且已经排好序;唯一性同样需要重写hashCode和equals()方法,二叉树结构保证了元素的有序性。根据构造方法不同,分为自然排序(无参构造)和比较器排序(有参构造)。
      自然排序要求元素必须实现Compareable接口,并重写里面的compareTo()方法,元素通过比较返回的int值来判断排序序列,返回0说明两个对象相同,不需要存储;
      比较器排需要在TreeSet初始化是时候传入一个实现Comparator接口的比较器对象,或者采用匿名内部类的方式new一个Comparator对象,重写里面的compare()方法;
    **

    比较:

    **
      1、TreeSet 是二叉树(红黑树的树据结构)实现的,Treeset中的数据是自动排好序的,不允许放入null值;
      2、HashSet 是哈希表实现的,HashSet中的数据是无序的,可以放入null,但只能放入一个null,两者中的值都不能重复,就如数据库中唯一约束 ;
      3、HashSet要求放入的对象必须实现HashCode()方法,放入的对象,是以hashcode码作为标识的,而具有相同内容的String对象,hashcode是一样,所以放入的内容不能重复。但是同一个类的对象可以放入不同的实例;
      适用场景分析:HashSet是基于Hash算法实现的,其性能通常都优于TreeSet。为快速查找而设计的Set,我们通常都应该使用HashSet,在我们需要排序的功能时,我们才使用TreeSet。

    1.7 List和Set的比较

    (1)、List,Set都是继承自Collection接口;
    (2)、List特点:元素有放入顺序,元素可重复 ;Set特点:元素无放入顺序,元素不可重复,重复元素会覆盖掉;
    (3)、Set:检索元素效率低下,删除和插入效率高,插入和删除不会引起元素位置改变。
        List:和数组类似,List可以动态增长,查找元素效率高,插入删除元素效率低,因为会引起其他元素位置改变。
    https://www.cnblogs.com/dongtian-blogs/p/10861138.html

    2 排序算法有哪些?冒泡算法的时间复杂度和空间复杂度

    排序算法分为两种:比较算法、非比较算法
    1、比较算法时间复杂度O(nlogn) ~ O(n^2)
    冒泡排序、选择排序、插入排序、归并排序、堆排序、快速排序
    2、非比较排序O(n)
    计数排序、基数排序、桶排序
    特点:排序算法的稳定性:如果Ai = Aj,排序前Ai在Aj之前,排序后Ai还在Aj之前,则称这种排序算法是稳定的
    排序算法如果是稳定的,那么从一个键上排序,然后再从另一个键上排序,前一个键排序的结果可以为后一个键排序所用
    具体算法以及代码请参考: https://editor.csdn.net/md/?articleId=105536263
    时间复杂度
    这个时间复杂度还是很好计算的:外循环和内循环以及判断和交换元素的时间开销;
    最优的情况也就是开始就已经排序好序了,那么就可以不用交换元素了,则时间花销为:[ n(n-1) ] / 2;所以最优的情况时间复杂度为:O( n^2 );
    最差的情况也就是开始的时候元素是逆序的,那么每一次排序都要交换两个元素,则时间花销为:[ 3n(n-1) ] / 2;(其中比上面最优的情况所花的时间就是在于交换元素的三个步骤);所以最差的情况下时间复杂度为:O( n^2 );
    综上所述:
    最优的时间复杂度为:O( n^2 ) ;有的说 O(n),下面会分析这种情况;
    最差的时间复杂度为:O( n^2 );
    平均的时间复杂度为:O( n^2 );
    空间复杂度
    空间复杂度就是在交换元素时那个临时变量所占的内存空间;
    最优的空间复杂度就是开始元素顺序已经排好了,则空间复杂度为:0;
    最差的空间复杂度就是开始元素逆序排序了,则空间复杂度为:O(n);
    平均的空间复杂度为:O(1);

    1、时间复杂度:

    (1)时间频度 一个算法执行所耗费的时间,从理论上是不能算出来的,必须上机运行测试才能知道。但我们不可能也没有必要对每个算法都上机测试,只需知道哪个算法花费的时间多,哪个算法花费的时间少就可以了。并且一个算法花费的时间与算法中语句的执行次数成正比例,哪个算法中语句执行次数多,它花费时间就多。一个算法中的语句执行次数称为语句频度或时间频度。记为T(n)。
    (2)时间复杂度 在刚才提到的时间频度中,n称为问题的规模,当n不断变化时,时间频度T(n)也会不断变化。但有时我们想知道它变化时呈现什么规律。为此,我们引入时间复杂度概念。 一般情况下,算法中基本操作重复执行的次数是问题规模n的某个函数,用T(n)表示,若有某个辅助函数f(n),使得当n趋近于无穷大时,T(n)/f(n)的极限值为不等于零的常数,则称f(n)是T(n)的同数量级函数。记作T(n)=O(f(n)),称O(f(n)) 为算法的渐进时间复杂度,简称时间复杂度。
    说人话:举例来

    for (i=1; i<=n; i++)
       x++;
      for (i=1; i<=n; i++)
       for (j=1; j<=n; j++)
       x++;

    第一个for循环的时间复杂度为Ο(n),第二个for循环的时间复杂度为Ο(n2),则整个算法的时间复杂度为Ο(n+n2)=Ο(n2)。
    再来一个例子:

     i=1;while (i<=n)
       i=i*2;

    解: 语句1的频度是1,
    设语句2的频度是f(n), 则:2^f(n)<=n; f(n)<=log2n
    取最大值f(n)=log2n,
    T(n)=O(log2n )
    这下应该明白时间复杂度怎么求了吧。。。不会求的直接背也行,记得是一个平均值
    在这里插入图片描述

    2、空间复杂度

    类似于时间复杂度的讨论,一个算法的空间复杂度(Space Complexity)S(n)定义为该算法所耗费的存储空间,它也是问题规模n的函数。渐近空间复杂度也常常简称为空间复杂度。
    存储算法本身所占用的存储空间与算法书写的长短成正比,要压缩这方面的存储空间,就必须编写出较短的算法。
    算法在运行过程中临时占用的存储空间随算法的不同而异,有的算法只需要占用少量的临时工作单元,而且不随问题规模的大小而改变,我们称这种算法是“就地"进行的,是节省存储的算法,如这一节介绍过的几个算法都是如此;有的算法需要占用的临时工作单元数与解决问题的规模n有关,它随着n的增大而增大,当n较大时,将占用较多的存储单元,例如将在第九章介绍的快速排序和归并排序算法就属于这种情况。
    说人话:代码长短、代码运行时占用的临时存储空间
    怎么求呢?
    当一个算法的空间复杂度为一个常量,即不随被处理数据量n的大小而改变时,可表示为O(1);
    当一个算法的空间复杂度与以2为底的n的对数成正比时,可表示为0(10g2n);
    当一个算法的空I司复杂度与n成线性比例关系时,可表示为0(n).
    若形参为数组,则只需要为它分配一个存储由实参传送来的一个地址指针的空间,即一个机器字长空间;
    若形参为引用方式,则也只需要为其分配存储一个地址的空间,用它来存储对应实参变量的地址,以便由系统自动引用实参变量。
    问题在于你怎么判断空间复杂度为什么呢?
    举例

    int[] m = new int[n]
    for(i=1; i<=n; ++i)
    {
       j = i;
       j++;
    }
    

    这段代码中,第一行new了一个数组出来,这个数据占用的大小为n,这段代码的2-6行,虽然有循环,但没有再分配新的空间,因此,这段代码的空间复杂度主要看第一行即可,即 S(n) = O(n)
    转载的:https://www.cnblogs.com/jsjwk/p/9993802.html
    那就是说和分配空间相关了?应该是分配的空间会随N变化满足上面第3条的要求,所以 S(n) = O(n) 这个解释应该是更好一些

    3 java数据类型有哪些?

    基本数据类型
    在这里插入图片描述

    封装类型
    在这里插入图片描述

    引用数据类型: 数组、类、接口

    4 java的异常分类

    在这里插入图片描述

    Java语言按照错误严重性,从throwale根类衍生出Error和Exception两大派系
    **Error(错误):**程序在执行过程中所遇到的硬件或操作系统的错误。错误对程序而言是致命的,将导致程序无法运行。
    常见的错误有内存溢出,jvm虚拟机自身的非正常运行,calss文件没有主方法。
    程序本身是不能处理错误的,只能依靠外界干预。
    Error是系统内部的错误,由jvm抛出,交给系统来处理。
    EXCEPTION(异常):是程序正常运行中,可以预料的意外情况。
    比如数据库连接中断,空指针,数组下标越界。
    异常出现可以导致程序非正常终止,也可以预先检测,被捕获处理掉,使程序继续运行。
    编译异常(可检测)和运行时异常(不可检测)
    **编译时异常:**又叫可检查异常,通常时由语法错和环境因素(外部资源)造成的异常。比如输入输出异常IOException,数据库操作SQLException。其特点是,Java语言强制要求捕获和处理所有非运行时异常。通过行为规范,强化程序的健壮性和安全性。
    **运行时异常:**又叫不检查异常RuntimeException,这些异常一般是由程序逻辑错误引起的,即语义错。比如算术异常,空指针异常NullPointerException,下标越界IndexOutOfBoundsException。运行时异常应该在程序测试期间被暴露出来,由程序员去调试,而避免捕获。
    java语言处理运行时错误有三种方式:
    一是程序不能处理的错误,
    二是程序应该避免而可以不去捕获的运行时异常,
    三是必须捕获的非运行时异常。

    5 OutOfMemoryError是哪种异常?

    内存溢出异常

    操作系统为每个进程分配的内存是具有一定限制性。譬如,32位的操作系统限制为2GB。而当检查出哪个区域出现OutOfMemoryError异常时,需要平衡该进程的某个区域内存大小来解决另一个区域出现内存溢出的情况。例如,在高并发情况下,不断地创建线程可能会使线程私有的虚拟机栈出现内存溢出情况,在不能减少线程数或者更换更大位数的操作系统时,就只能通过减少最大堆和减少栈容量的方式来解决虚拟机栈导致的内存溢出。所以,无论在处理异常或者是实验,我们都要学会调整设置虚拟机启动参数
    以下为了解内容

    1、Java堆溢出原因及其解决方案

    Java堆用于存储对象实例和数组的,只要不断地创建对象或者数组,并且保证GC Roots到对象之间有可达的路径来避免垃圾回收机制清除这些对象,那么在对象数量达到最大堆的容量限制后就会产生内存溢出异常。
    要了解Java堆内存可能溢出原因,首先我们要知道当生成新对象时,向Java堆申请内存的过程:
    ① JVM先尝试在Eden区(Young区包括1个Eden和2个survivor)分配新建对象所需要的内存;
    ② 如果内存大小足够,则申请结束。反之,执行下一步;

         ③ JVM启动新生代GC,试图将Eden区中不活跃的对象释放掉,释放后若Eden空间仍然不足以放入新对象,则试图将部分Eden中活跃对象放入Survivor区;
    
         ④ Survivor区被用来作为Eden及old的中间交换区域,当old区空间足够时,Survivor区的对象会被移到old区,否则会被保留在Survivor区;
    
         ⑤ 当old区空间不够时,JVM会在old区进行GC;
    
         ⑥ old区被清理后,若old区仍无法存放从Eden复制过来的部分对象,导致JVM无法在Eden区为新生对象创建内存区域,则会出现内存溢出异常(OutOfMemmory)。
    

    原文链接:https://blog.csdn.net/qq_41285600/article/details/82798920
    解决方案:
    Java堆出现内存溢出异常有两种解决方案。一种是基于内存调整来改变堆区内存大小以便能够存储更多的对象,但堆内存受到物理内存的限制,当出现无法再扩展堆内存的情况时,就采用第二种方式,从代码上检查是否存在某些对象的生命周期过长、持有状态时间过长的情况,尝试减少程序在运行期的内存消耗。

    2、虚拟机栈和本地方法栈溢出

    虚拟机栈和本地方法栈的内存分布在不同的虚拟机上是有差别的。例如,在HotSpot上是将虚拟机栈和本地方法栈合二为一的。虽然有-Xoss参数用于设置本地方法栈,但实际上是无效的,栈容量只由-Xss参数设定。关于虚拟机栈和本地方法栈,在Java虚拟机规范中描述了两种异常:①如果线程请求的栈深度大于虚拟机所允许的最大栈深度,将抛出StackOverflowError异常。②如果虚拟机在扩展栈时无法申请到足够的空间,则抛出OutOfMemoryError异常。
    导致这两种异常的原因是有一定区别的。虚拟机栈是线程私有的,它存储的是存放着局部变量表、操作数栈、动态链接以及方法出口等信息的栈帧,当前线程每执行一个方法时,实际上都对应着一个栈帧在虚拟机栈中出栈到入栈的过程,而当这个线程执行方法较多时,创建的栈帧也会随之越来越多,而虚拟机栈内存是受到了JVM总体内存的一个分布限制,一旦栈帧较多时,可能就会出现栈满溢出异常,也就是StackOverflowError异常。而出现OutOfMemoryError异常的情况是相对于多线程环境下而言的,一旦线程数量过多,并且都没有即使回收,从而会不断地申请内存给虚拟机栈,从而导致在扩展栈时无法申请到足够的空间,出现OutOfMemoryError异常。当然,OutOfMemoryError异常也可能出现在单钱程的情况下。当为一个线程设置虚拟机栈内存大小与其它区内存之和大于JVM所允许的最大内存,就可能出现OutOfMemoryError异常。

    3、方法区和运行时常量池溢出

    在jdk1.7之前,运行时常量池属于方法区的一部分,也就是运行时常量池处于永久代。而方法区出现的内存溢出异常经常是由运行时常量池内存溢出异常所导致的。但在jdk1.7时,为了消除永久代,常量池位置发生了一定的变化,由原来的方法区转移到了堆区,但永久代实际上还是存在的,因为内加载机制还在永久代。我们也知道,堆区是GC管理的主要区域,而常量池存储了该类的所有常量,如果使其处于永久代不进行及时的回收,导致内存溢出可能会是经常的。放入堆区个人理解就是为了方便及时合理回收运行时常量池。在jdk1.8之后,完全消除永久代这一个区域,jvm将方法区放入了一个与堆不相连的区域,该区域称为元空间(元空间介绍引用:https://www.cnblogs.com/duanxz/p/3520829.html)。

    4、本机直接内存溢出

    本机直接内存容量可以通过-XX:MaxDirectMemorySize指定,如果不指定,则默认与Java堆最大值(-Xmx制定)一样。NIO提供了一个不经过JVM直接访问本机物理内存的类——DirectMemory。DircetMemory继承与ByteBuffer,但和普通的ByteBuffer不同,普通的ByteBuffer在堆上进行内存分配,其最大的内存受到堆内存的限制。而DircetMemory是向本机物理内存申请内存分配,所以其大小只受物理内存的限制。由于直接内存是介于堆区和操作系统之间的一个Buffer,所以读写操作比普通的Buffer要快,同样也造成创建和销毁较普通Buffer慢的特点。以下代码清单中直接越过DircetByteBuffer(存储在Java堆上的操作直接内存的一个对象引用)类,直接通过反射获取unsafe实例进行内存分配。因为虽然使用了DircetByteBuffer分配内存也会抛出内存溢出异常,但它抛出异常时并没有真正向操作系统申请分配内存,而是通过计算得知内存无法分配,于是手动抛出异常,真正申请分配内存的方法是unsafe.allocateMemory()。

    6、Hashmap、Hashtable、ConcurrentHashmap的原理和区别

    HashTable

    底层数组+链表实现,无论key还是value都不能为null,线程安全,实现线程安全的方式是在修改数据时锁住整个HashTable,效率低,ConcurrentHashMap做了相关优化
    初始size为11,扩容:newsize = olesize*2+1
    计算index的方法:index = (hash & 0x7FFFFFFF) % tab.length

    HashMap

    底层数组+链表实现,可以存储null键和null值,线程不安全
    初始size为16,扩容:newsize = oldsize*2,size一定为2的n次幂
    扩容针对整个Map,每次扩容时,原来数组中的元素依次重新计算存放位置,并重新插入
    插入元素后才判断该不该扩容,有可能无效扩容(插入后如果扩容,如果没有再次插入,就会产生无效扩容)
    当Map中元素总数超过Entry数组的75%,触发扩容操作,为了减少链表长度,元素分配更均匀
    计算index方法:index = hash & (tab.length – 1)

    ConcurrentHashMap

    底层采用分段的数组+链表实现,线程安全
    通过把整个Map分为N个Segment,可以提供相同的线程安全,但是效率提升N倍,默认提升16倍。(读操作不加锁,由于HashEntry的value变量是 volatile的,也能保证读取到最新的值。)
    Hashtable的synchronized是针对整张Hash表的,即每次锁住整张表让线程独占,ConcurrentHashMap允许多个修改操作并发进行,其关键在于使用了锁分离技术
    有些方法需要跨段,比如size()和containsValue(),它们可能需要锁定整个表而而不仅仅是某个段,这需要按顺序锁定所有段,操作完毕后,又按顺序释放所有段的锁
    扩容:段内扩容(段内元素超过该段对应Entry数组长度的75%触发扩容,不会对整个Map进行扩容),插入前检测需不需要扩容,有效避免无效扩容
    在这里插入图片描述

    锁分段技术:

    首先将数据分成一段一段的存储,然后给每一段数据配一把锁,当一个线程占用锁访问其中一个段数据的时候,其他段的数据也能被其他线程访问。
    ConcurrentHashMap提供了与Hashtable和SynchronizedMap不同的锁机制。Hashtable中采用的锁机制是一次锁住整个hash表,从而在同一时刻只能由一个线程对其进行操作;而ConcurrentHashMap中则是一次锁住一个桶。
    ConcurrentHashMap默认将hash表分为16个桶,诸如get、put、remove等常用操作只锁住当前需要用到的桶。这样,原来只能一个线程进入,现在却能同时有16个写线程执行,并发性能的提升是显而易见的。

    6、java的锁机制分类

    6.1自旋锁

    自旋锁原理非常简单,如果持有锁的线程能在很短时间内释放锁资源,那么那些等待竞争锁的线程就不需要做内核态和用户态之间的切换进入阻塞挂起状态,它们只需要等一等(自旋),等持有锁的线程释放锁后即可立即获取锁,这样就避免用户线程和内核的切换的消耗。

    6.2 偏向锁

    偏向锁,顾名思义,它会偏向于第一个访问锁的线程,如果在运行过程中,同步锁只有一个线程访问,不存在多线程争用的情况,则线程是不需要触发同步的,这种情况下,就会给线程加一个偏向锁。

    6.3 轻量级锁

    轻量级锁是由偏向所升级来的,偏向锁运行在一个线程进入同步块的情况下,当第二个线程加入锁争用的时候,偏向锁就会升级为轻量级锁;其他线程会通过自旋的形式尝试获取锁,不会阻塞,提高性能。

    6.4 重量级锁Synchronized

    当作用于静态方法时,锁住的是Class实例,又因为Class的相关数据存储在永久带PermGen(jdk1.8则是metaspace),永久带是全局共享的,因此静态方法锁相当于类的一个全局锁,会锁所有调用该方法的线程

    7、Synchronized有多少种用法?锁方法和锁代码块哪种比较好?听说过锁类和锁实例么?

    7.1、同步普通方法(锁实例对象)

    这个也是我们用得最多的,只要涉及线程安全,上来就给方法来个同步锁。这种方法使用虽然最简单,但是只能作用在单例上面,如果不是单例,同步方法锁将失效。

    /**
     * 用在普通方法
     */
    private synchronized void synchronizedMethod() {
        System.out.println("synchronizedMethod");
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
    

    此时,同一个实例只有一个线程能获取锁进入这个方法。

    7.2、同步静态方法(锁类本身)

    同步静态方法,不管你有多少个类实例,同时只有一个线程能获取锁进入这个方法。

    /**
     * 用在静态方法
     */
    private synchronized static void synchronizedStaticMethod() {
        System.out.println("synchronizedStaticMethod");
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    } 
    

    同步静态方法是类级别的锁,一旦任何一个线程进入这个方法,其他所有线程将无法访问这个类的任何同步类锁的方法。

    7.3、同步类(锁类本身)

    下面提供了两种同步类的方法,锁住效果和同步静态方法一样,都是类级别的锁,同时只有一个线程能访问带有同步类锁的方法。

    /**
     * 用在类
     */
    private void synchronizedClass() {
        synchronized (TestSynchronized.class) {
            System.out.println("synchronizedClass");
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
    
    /**
     * 用在类
     */
    private void synchronizedGetClass() {
        synchronized (this.getClass()) {
            System.out.println("synchronizedGetClass");
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    } 
    

    这里的两种用法是同步块的用法,这里表示只有获取到这个类锁才能进入这个代码块。

    7.4、同步this实例(锁实例对象)

    这也是同步块的用法,表示锁住整个当前对象实例,只有获取到这个实例的锁才能进入这个方法。

    /**
     * 用在this
     */
    private void synchronizedThis() {
        synchronized (this) {
            System.out.println("synchronizedThis");
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    } 
    

    用法和同步普通方法锁一样,都是锁住整个当前实例。

    7.5、同步对象实例

    这也是同步块的用法,和上面的锁住当前实例一样,这里表示锁住整个 LOCK 对象实例,只有获取到这个 LOCK 实例的锁才能进入这个方法。

    /**
     * 用在对象
     */
    private void synchronizedInstance() {
        synchronized (LOCK) {
            System.out.println("synchronizedInstance");
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
    

    1.当加锁的方法是实例方法时,同一个对象在多线程情况下不能同时访问加锁的实例方法,换句话意思是,同一个实例内的加锁实例方法是相互约束的。当然,对于不同的实例对象,因为在不同的域,就没有这种约束。
    2.当加锁的方法是类方法时,属于该类的对象在多线程情况下不能同时访问加锁的静态方法,也就是加锁的静态方法在该类下都是相互约束的,作用域是整个类。
    3.线程可同时获得实例方法和类方法的锁,这点很关键。看测试3结果就能发现,类锁和对象锁控制着两个不同区域,互不约束。
    4当加锁的代码块时,同一个实例对象在多线程情况下不能同时访问加锁的代码块,但是方法的未加锁段是可以同时访问的

    8、java的内存分区

    Java程序是交由JVM执行的,所以Java内存区域划分的时候事实上是指JVM区域划分

    如图所示,首先Java源代码文件(.java后缀)会被Java编译器编译为字节码文件(.class后缀),然后由JVM中的类加载器加载各个类的字节码文件,加载完毕之后,交由JVM执行引擎执行。在整个程序执行过程中,JVM会用一段空间来存储程序执行期间需要用到的数据和相关信息,这段空间一般被称作Runtime Data Area(运行时数据区)也就是我们常常说的JVM内存。因此,在Java中我们常常说到的内存管理就是针对这段空间进行管理(如何分配和回收内存空间)。

    运行时数据区的每部分到底存储了那些数据?

    1、程序计数器

     程序计数器(Program Counter Regist)也有称作为PC寄存器,在汇编语言中,程序计数器是指CUP中的寄存器就,它保存的是程序当前执行的指令地址(也可以说是下一条指令的所在存储单元地址),当CUP需要指令时,需要从程序计数器中得到当前 执行的指令所在存储单元地址,然后根据得到的地址获取到指令,在得到指令后,程序计数器便会自动加1或者根据转移指针得到下一条指令的地址,如此循环,直至执行完所有指令。
    

    2、Java栈

      Java栈也称作是虚拟机栈(Java Vitual Machine Stack),也就是我们常常所说的栈,跟c语言的数据段中的栈类似。事实上,Java栈是Java方法执行的内存模型。
       Java栈中存放的是一个个栈帧,每个栈帧对应着一个被调用的方法,在栈帧中包括局部变量表(Local Variable)、操作数栈(Operaand Stack)、指向当前方法所属的类的运行时常量池的引用(Reference to runtime constant tool)、方法返回地址(Return Address)和一些额外的附加信息。当线程执行一个方法时,就会随之创建一个对应的栈帧,并将建立的栈帧压栈。当方法执行完毕之后,便会将栈帧出栈。因此可知,线程当前执行的方法所对应的栈帧必定位于Java栈的顶部。
    

    3、本地方法栈

    本地方法栈与Java栈的作用和原理相似,区别只不过是Java栈是为执行Java方法服务的,而本地方法栈则是执行本地方法(Native Method)服务的,在JVM规范中,并没有对本地方法栈的具体实现方法以及数据结构做强制规定,虚拟机可以自由实现它,在HOTSpot虚拟机中直接把本地方法栈和Java栈合二为一。

    4、堆

     在c语言中,堆这部分空间是唯一一个程序员管理的内存区域,程序员可以通过malloc函数和free函数在堆上申请和释放空间
      Java中的堆是用来存储对象本身以及数组(当然,数组引用是放在Java栈中的)。只不过和c语言不通,在Java中,程序员基本不关心空间释放的问题,Java的垃圾回收机制会自动进行处理,因此这部分空间也是Java垃圾收集器管理的主要区域。另外堆是被所有线程池共享的,在JVM中只有一个堆。
    

    5、方法区

     方法区在JVM中也是一个非常重要的区域,它与堆一样,是被线程池共享的区域。在方法区中,存储每个类的信息(包括类的名称、方法信息、字段信息)静态变量、常量以及编译器变异后的的代码等。
    

    在class文件中除了类的字段、方法、接口等描述信息外,还有一项是常量池,用来存储编译期间生成的字面量和符号引用。
    在方法区中有一个非常重要的部分就是运行时常量池,它是每一个类或接口的常量池的运行时表示形式,在类和接口被加载到JVM后,对应的常量池就被创建出来。当然并非class文件常量池中的内容才能进入运行时常量池,在运行期间也可将新的常量放入运行时常量池中,比如string的intern方法。

    9、利用jdbc进行查询的步骤

    七个步骤:
    第一步:加载JDBC驱动程序

    第二步:创建连接

    第三步:写sql

    第四步:得到statement对象

    第五步:执行sql 得到结果集

    第六步:处理结果集

    第七步:关闭资源
    1、关闭记录集
    2、关闭声明
    3、关闭连接对象

    10、PreparedStatement和Statement区别

    1、 执行静态sql语句时,通常通过Statement实例实现。
    2、 执行动态sql语句时,通常通过PreparedStatement实例实现。
    3、 执行数据库存储过程,通常通过CallableStatement实例实现。
    

    联系:
    1.PreparedStatement和Statement都是用来执行SQL查询语句的API之一
    2.PreparedStatement接口继承了Statement接口
    区别:
    Statement不对sql语句作处理,直接交给数据库;而PreparedStatement支持预编译,会将编译好的sql语句放在数据库端,相当于缓存。对于多次重复执行的sql语句,使用PreparedStatement可以使得代码的执行效率更高。

    Statement的sql语句使用字符串拼接的方式,容易导致出错,且存在sql注入的风险;PreparedStatement使用“?”占位符提升代码的可读性和可维护性,并且这种绑定参数的方式,可以有效的防止sql注入。

    11、基本数据类型和包装数据类的区别?为什么使用包装类?

    1、包装类是对象,拥有方法和字段,对象的调用都是通过引用对象的地址;基本类型不是
    2、包装类型是引用的传递;基本类型是值的传递
    3、声明方式不同:
    基本数据类型不需要new关键字;
    包装类型需要new在堆内存中进行new来分配内存空间
    4、存储位置不同:
    基本数据类型直接将值保存在值栈中;
    包装类型是把对象放在堆中,然后通过对象的引用来调用他们
    5、初始值不同:
    int的初始值为 0 、 boolean的初始值为false
    包装类型的初始值为null
    6、使用方式不同:
    基本数据类型直接赋值使用就好;
    包装类型是在集合如 coolectionMap时使用

    why?

    我们知道Java是一个面相对象的编程语言,基本类型并不具有对象的性质,为了让基本类型也具有对象的特征,就出现了包装类型(如我们在使用集合类型Collection时就一定要使用包装类型而非基本类型),它相当于将基本类型“包装起来”,使得它具有了对象的性质,并且为其添加了属性和方法,丰富了基本类型的操作。
    另外,当需要往ArrayList,HashMap中放东西时,像int,double这种基本类型是放不进去的,因为容器都是装object的,这是就需要这些基本类型的包装器类了。
    基本数据类型和包装类之间的转换
    包装类–>基本数据类型:包装类对象.xxxValue()
    基本数据类型–>包装类:new 包装类(基本类型值)
    JDK1.5 开始提供了自动装箱(autoboxing)和自动拆箱(autounboxing)功能, 实现了包装类和基本数据类型之间的自动转换
    包装类可以实现基本类型和字符串之间的转换,字符串转基本类型:parseXXX(String s);基本类型转字符串:String.valueOf(基本类型)

    12、数据库的DDL和DML的用法和区别?

    在这里插入图片描述

    DML(data manipulation language): 它们是SELECT、UPDATE、INSERT、DELETE,就象它的名字一样,这4条命令是用来对数据库里的数据进行操作的语言
    DDL(data definition language): DDL比DML要多,主要的命令有CREATE、ALTER、DROP等,DDL主要是用在定义或改变表(TABLE)的结构,数据类型,表之间的链接和约束等初始化工作上,他们大多在建立表时使用
    DCL(Data Control Language): 是数据库控制功能。是用来设置或更改数据库用户或角色权限的语句,包括(grant,deny,revoke等)语句。在默认状态下,只有sysadmin,dbcreator,db_owner或db_securityadmin等人员才有权力执行DCL
    TCL - Transaction Control Language:事务控制语言,COMMIT - 保存已完成的工作,SAVEPOINT - 在事务中设置保存点,可以回滚到此处,ROLLBACK - 回滚,SET TRANSACTION - 改变事务选项
    下表一目了然

    13、JDK1.8新特性

    最想说的是这个:HashMap在Jdk1.7和1.8中的实现
    https://yuanrengu.com/2020/ba184259.html 这个链接针对源码解析,分析了区别。
    总结:
    1.7中采用数组+链表,1.8采用的是数组+链表/红黑树,即在1.7中链表长度超过一定长度后就改成红黑树存储。
    1.7扩容时需要重新计算哈希值和索引位置,1.8并不重新计算哈希值,巧妙地采用和扩容后容量进行&操作来计算新的索引位置。
    1.7是采用表头插入法插入链表,1.8采用的是尾部插入法。
    在1.7中采用表头插入法,在扩容时会改变链表中元素原本的顺序,以至于在并发场景下导致链表成环的问题;在1.8中采用尾部插入法,在扩容时会保持链表元素原本的顺序,就不会出现链表成环的问题了

    下面是了解内容
    1、default关键字
      在java里面,我们通常都是认为接口里面是只能有抽象方法,不能有任何方法的实现的,那么在jdk1.8里面打破了这个规定,引入了新的关键字default,通过使用default修饰方法,可以让我们在接口里面定义具体的方法实现,如下。

    public interface NewCharacter {
        
        public void test1();
        
        public default void test2(){
            System.out.println("我是新特性1");
        }
    
    }
    

    2、Lambda 表达式
      Lambda表达式是jdk1.8里面的一个重要的更新,这意味着java也开始承认了函数式编程,并且尝试引入其中。
      首先,什么是函数式编程,引用廖雪峰先生的教程里面的解释就是说:函数式编程就是一种抽象程度很高的编程范式,纯粹的函数式编程语言编写的函数没有变量,因此,任意一个函数,只要输入是确定的,输出就是确定的,这种纯函数我们称之为没有副作用。而允许使用变量的程序设计语言,由于函数内部的变量状态不确定,同样的输入,可能得到不同的输出,因此,这种函数是有副作用的。函数式编程的一个特点就是,允许把函数本身作为参数传入另一个函数,还允许返回一个函数!
      简单的来说就是,函数也是一等公民了,在java里面一等公民有变量,对象,那么函数式编程语言里面函数也可以跟变量,对象一样使用了,也就是说函数既可以作为参数,也可以作为返回值了
    3、函数式接口
      定义:“函数式接口”是指仅仅只包含一个抽象方法的接口,每一个该类型的lambda表达式都会被匹配到这个抽象方法。jdk1.8提供了一个@FunctionalInterface注解来定义函数式接口,如果我们定义的接口不符合函数式的规范便会报错。
    4.方法与构造函数引用
      jdk1.8提供了另外一种调用方式::,当 你 需 要使用 方 法 引用时 , 目 标引用 放 在 分隔符::前 ,方法 的 名 称放在 后 面 ,即ClassName :: methodName 。例如 ,Apple::getWeight就是引用了Apple类中定义的方法getWeight。请记住,不需要括号,因为你没有实际调用这个方法。方法引用就是Lambda表达式(Apple a) -> a.getWeight()的快捷写法,如下示例。
    5、局部变量限制
      Lambda表达式也允许使用自由变量(不是参数,而是在外层作用域中定义的变量),就像匿名类一样。 它们被称作捕获Lambda。 Lambda可以没有限制地捕获(也就是在其主体中引用)实例变量和静态变量。但局部变量必须显式声明为final,或事实上是final。
      为什么局部变量有这些限制?
      (1)实例变量和局部变量背后的实现有一个关键不同。实例变量都存储在堆中,而局部变量则保存在栈上。如果Lambda可以直接访问局部变量,而且Lambda是在一个线程中使用的,则使用Lambda的线程,可能会在分配该变量的线程将这个变量收回之后,去访问该变量。因此, Java在访问自由局部变量时,实际上是在访问它的副本,而不是访问原始变量。如果局部变量仅仅赋值一次那就没有什么区别了——因此就有了这个限制。
      (2)这一限制不鼓励你使用改变外部变量的典型命令式编程模式。
    6、Date Api更新  
      1.8之前JDK自带的日期处理类非常不方便,我们处理的时候经常是使用的第三方工具包,比如commons-lang包等。不过1.8出现之后这个改观了很多,比如日期时间的创建、比较、调整、格式化、时间间隔等。这些类都在java.time包下。比原来实用了很多。
    7、流
      定义:流是Java API的新成员,它允许我们以声明性方式处理数据集合(通过查询语句来表达,而不是临时编写一个实现)。就现在来说,我们可以把它们看成遍历数据集的高级迭代器。此外,流还可以透明地并行处理,也就是说我们不用写多线程代码了。

    14、java线程池有哪几类?

    (了解内容)
    ①:FixedThreadPool,特点:固定池子中线程的个数。使用静态方法newFixedThreadPool()创建线程池的时候指定线程池个数。
    ②:CachedThreadPool(弹性缓存线程池),特点:用newCachedThreadPool()方法创建该线程池对象,创建之初里面一个线程都没有,当execute方法或submit方法向线程池提交任务时,会自动新建线程;如果线程池中有空余线程,则不会新建;这种线程池一般最多情况可以容纳几万个线程,里面的线程空余60s会被回收。
    ③:SingleThreadPool(单线程线程池),特点:池中只有一个线程,如果扔5个任务进来,那么有4个任务将排队;作用是保证任务的顺序执行。
    ④:ScheduledThreadpool(定时器线程池)
    ⑤:WorkStealingPool
    ⑥:ForkJoinPool

    展开全文
  • 天下武功,唯快破,手机充电就是要快。目前各个厂家的快充技术大致分两种,一种是高通的高压快充,另一种是VOOC的低压大电流快充。两种技术各有各的特点,高压快充对线材要求较低,兼容性好,而低压大电流快充除了...

    天下武功,唯快不破,手机充电就是要快。目前各个厂家的快充技术大致分两种,一种是高通的高压快充,另一种是VOOC的低压大电流快充。

    两种技术各有各的特点,高压快充对线材要求较低,兼容性好,而低压大电流快充除了协议之外,往往需要厂家特定的线材支持。华为手机较早的快充技术是高压快充的FCP,而后推出了低压大电流的SCP快充。

    拿到华为支持SCP快充技术的充电器,做个拆解以飨读者。这款充电器的型号为:HW-050800C1WH,输出参数为:5V/2A, 5V/8A 。

    白色外壳,这款做的比较圆润

    国标拆解,可以折叠,不用的时候方便收纳外带

    插脚这面是参数镭雕,型号 HW-050800C1WH,输入是200-240V,不是一般的宽电压输出:5V/2A,或者5V/8AMAX,华为科技有限公司制造,有3C认证

    这款用了橘红色的USB-A接口,接触点弹片都是加宽的

    华为的另外一款,4.5V/5A版本SCP超级快充,右边是8A版超级快充

    USB口的方向不同

    5A版本不能折叠,8A版本可以折叠脚

    宽度46mm

    厚度28mm

    用ChargerLab Power-z FL001 协议测试,发现只能支持SCP模式快充

    华为的几款快充头子,左起SCP 8A,pd头子, SCP 5A,FCP+QC2.0双协议头子

    四款单口快充 USB输出对比

    用ChargerLab Power-z FL001诱骗至SCP模式,然后用EBC-A10负载测试最大功率,可以看到拉到8A的大电流

    测试两次,EBC-A10显示都是8.2A,再上去电源保护

    华为5V8A_功率测试,软件记录到最高8.1A

    尝试一下8A大电流负载2分钟,很坚挺

    拆解

    可以无损开壳

    里面是卡槽的,灌胶,PCB模块拉出来

    两块PCB组成的,中间看到是灌了黑色的胶,固定和辅助导热。

    中间还有一整个塑料保护壳,将上下两层电路板固定成一个整体。

    焊开两片PCB,全部物件,可以看到中间的白色塑料框负责连通上下两块电路板。

    中间两面PCB,PULSE的变压器很是显眼,在PULSE的官网查了下,没有这个型号,目测定制品。

    两边两面PCB,左边的是次级识别同步整流,左边的是初级整流加开关管。

    左侧电路板,RT7207,识别芯片,支持同步整流。

    同步整流管,并联了肖特基二极管提高效率,安森美NTMFS5C612NL,丝印5C612L。

    输出开关,Diodes PMOS DMP2002UPS。

    2512 3毫欧合金电阻用于检测输出电流,在输出过流时检测异常过电流关闭输出。

    左侧输出板正面有两颗固态电容,6.3V/820μF,输出滤波。AC输入的保险丝在这块板上,通过塑料框上的连线接到初级板上。

    右侧初级板,RT7786,初级PWM

    3个串联的MLCC是传统蓝色的Y电容。3个串联提高绝缘等级和可靠性。

    输入保险丝在另外一块电路板上,可以看到一级输入EMI电路,线圈和X电容之间夹着热敏电阻。

    初级采用台湾立隆电容器。

    两颗400V/22μF。

    开关管 STFU13N65M2。

    - THE END -

    原文链接:充电头网

    责任编辑:

    展开全文
  • 我希望在没有联想或者华为电脑管家的情况,设置充电阈值,充电充到70%就不再充电 在csdn等网站搜索教程,无法查到。希望给我一个方法,设置充电阈值。 例如 ...
  • 在开源软件发展之初, 商业组织的投入很少甚至没有, 完全是靠Richard Stallman 或者 linus Torvalds 这样的个人在努力推动开源软件艰难前行. 甚至在开源文化及商业化相当成熟之后,很多开源项目还是只能依靠个人的...
  • 万众瞩目的华为手机可以升级鸿蒙系统了,我的华为手机型号能不能升级?...华为鸿蒙系统升级时间表分享我的华为手机为什么不可以升级鸿蒙?华为鸿蒙系统支持的手机型号分批次,要根据官方升级时间表进行升级。6月2...
  • 2017华为软件精英挑战赛总结

    千次阅读 2017-05-01 22:43:46
    边变量-> 表示该边所跑的流量用glpk试过,变量个数太庞大,内存都开不下,解的效果也不好,只能解很小点数的,连28个点的都解出来;清华大佬,手写了一份高性能整数规划求解器,解的非常好,膜拜了。建模思路可以...
  • 上个月华为发布了全新的EMUI11系统和升级的鸿蒙2.0,但是大家知道鸿蒙系统暂时并未用在手机业务上,好在官方表示最快将在年底面向开发者推出适配手机的鸿蒙测试版,且EMUI11版本机型将率先升级体验鸿蒙系统。...
  • 华为荣耀8C安装Google play store的记录

    千次阅读 2019-05-05 11:43:04
    尝试新机华为荣耀8C,因为不是习惯的MIUI系统不能进行原始的小米系统备份的恢复,一度出现巨大不良“排斥”反应。 挂上VPN,当我想要运行当年在MIUI中耍过的无操心版谷歌安装器进行google play store 的安装, ...
  • 【6月1日讯】相信大家都知道,如今越来越接近6月2日华为鸿蒙OS系统正式版发布日期,很多网友们都非常期待华为鸿蒙OS系统能够早日大面积推广适配,虽然目前各大国产手机厂商们都纷纷对鸿蒙OS系统保持沉默态度,这也...
  • 华为交换机配置命令后需要重启吗

    千次阅读 2021-01-17 17:05:50
    展开全部华为交换机有下面几种情况需要重启:1、清空配置,e68a84e8a2ad62616964757a686964616f31333433623131reset config,后,需要重启。2、去除密码时需要重启。3、更新非热补丁需要重启。4、软件版本升级完成后...
  • 华为HG556A固件

    2013-11-27 18:09:32
    华为HG556a固件,不错的升级软件华军软件园是中国起步较早,口碑良好的大型 专业软件网站。是中国最具影响力的著名网站之一,目前已在全国一半以 上大中城市设立镜像站点及独立下载服务器且还在不断增加中以保证全国...
  • IT之家曾报道,华为消费者业务软件部总裁、AI 与智慧全场景业务部部长王成录上个月初就表示华为手机用户可以在今年 6 月初升级到鸿蒙 OS 系统,并且提供多款型号的升级。 此外,他还认为搭载鸿蒙 OS 的手机、Pad ...
  • 鱼羊 金磊 发自 凹非寺 量子位 报道 | 公众号 QbitAI果然高手在民间。谁料到,一辆自行车的硬核打开方式,竟是大火的自动驾驶。踢开脚撑,金鸡独立、稳如泰山:单侧加个板砖?小场面:...
  • 华为是近几年比较热门的品牌,尤其在2019年的贸易事件中,华为更是展现了其实力,直接发布了鸿蒙系统。它是一款独立于安卓、苹果之外的系统,许多人都对它充满的好奇。下面就和小编一起来看看华为哪些手机可以升级到...
  • 华为手机拍照技巧从入门到精通

    千次阅读 2020-12-31 00:05:08
    展开全部华为手机拍照技巧从入门到精通技巧:1、保持稳定:手机的设计趋势显然是轻薄,所以你不会得到单反e68a84e8a2ad3231313335323631343130323136353331333433663030相机的大手柄。此外,并是所有的手机都有...
  • 华为云鲲鹏云服务器介绍

    千次阅读 2020-11-30 12:16:44
    华为海思设计的鲲鹏(Kunpeng)920系列芯片是兼容ARMv8A架构的高性能处理器片上系统,也是华为 “算、存、传、管、智”五个产品系列构成的鲲鹏芯片家族的核心产品。 鲲鹏处理器是华为在2019年1月向业界发布的高性能...
  • 华为交换机打补丁

    千次阅读 2020-09-02 15:36:47
    补丁安装前,必须保证FLASH上有足够的空间存放补丁包软件。 检查剩余空间 在用户视图,执行dir命令,查看设备的FLASH中的剩余空间,确认FLASH中有足够的剩余空间容纳补丁包软件。 执行dir flash:/命令查看设备剩余...
  • 华为电脑管家PcManager多屏协同功能破解

    万次阅读 多人点赞 2019-11-06 12:25:39
    让友商电脑兼容了一下华为系专属的多屏协同功能 笔者注:文中出现的大写C,请轻声念出北京大爷的口头禅。 华为刚发布多屏协同功能的时候,我就被种草了。 后来一天在微博看到@Navis-MDT发布的一个体验视频,果然碉堡...
  • 华为升腾安装

    千次阅读 2020-08-31 00:11:42
    若未安装,则安装命令如下(如果只有部分软件未安装,则如下命令修改只安装还未安装的软件即可)。其中:toolkit包中算子比对工具依赖:protobuf、scipy;profiling工具依赖:protobuf、grpcio、grpcio-tools、...
  • 该楼层疑似违规已被系统折叠隐藏此楼查看此楼\system\media铃声音乐文件夹,除了常规的铃声外还有一些系统提示事件音\system\media\audio\system\media\audio\alarms 闹铃音\system\media\audio\notifications 提示...
  • 05-20210222在WIN10通过串口给华为海思Hi3518EV300刷机(鸿蒙系统) 2021/2/23 17:38 1、串口刷机工具下载:HiTool-HM-5.4.9-win32-x86_64.zip http://www.hoperun.com/ http://www.hihope.org/ ...
  • 本文来自:量子位(ID:QbitAI)果然高手在民间。谁料到,一辆自行车的硬核打开方式,竟是大火的自动驾驶。踢开脚撑,金鸡独立、稳如泰山:单侧加个板砖?小场面:毕竟,它是连高难度“杂...
  • 华为鸿蒙系统正式发布了,也公布了支持机型与升级时间表...荣耀可以升级升级鸿蒙系统吗荣耀手机是可以升级鸿蒙系统的,不过现在暂时还不能升级,大家需要耐心等待。荣耀机型将分为两个批次升级鸿蒙系统,分别是在20...
  • 」 这样就显示该软件的信息将它写入代码中。 6.安卓模拟器 安卓模拟器是在 PC 平台模拟安卓手机系统的模拟器软件。比较常用的安卓模拟器有:夜神、海马、逍遥、genymotion 等。 模拟器默认是有 root 权限的。 「...
  • 配置华为AP6050DN胖AP

    千次阅读 2020-09-28 12:08:57
    首先买到的新AP需要先转换成FAT模式。...先根据说明书给到的地址输入169.254.1.1时会引导你转换FAT模式的,先下载辅助软件putty来转换FAT格式,百度搜一下就有。 下面放上华为官方的步骤图配置胖AP ...
  • 10-20210308华为海思Hi3516DV300在鸿蒙系统测试网络(以太网+WIFI) 2021/3/8 17:13 https://blog.csdn.net/qq_33475105/article/details/109279517 【HarmonyOS HiSpark AI Camera试用连载 】AI_Camera_Hi3516...
  • 华为试题

    2011-11-19 20:54:30
    1. 什么是UML?分哪两类? 2. OS一般的两种进程调度策略 3. 进程间的四种通讯方式 4. 一棵二叉树的前序,中序,后序遍历结果 第三部分,问答题 1. 通常递归所采用的数据结构?递归和循环的区别? 2. 将...
  • 软件工程——模型驱动工程(MDE)

    千次阅读 2020-09-24 15:22:25
    模型驱动的软件开发(model driven software development, MDS)是软件工程(software engineering, SE)发展的一个重要方向,是一种以建模(modeling)和模型转换(model transformation)主要途径的软件开发方法...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 581
精华内容 232
关键字:

华为8a为什么有些软件不能下