0%


前言

在探究hashmap原理中计算数组位置一部分遇到了用h&(length-1)来替代h%length的问题,不解前者的原理,所以探究了一下。以下摘自文心一言。

正文

在表达式 return h & (length-1) 中,h 是一个哈希值(通常是一个较大的整数),而 length-1 是一个掩码(mask),用于将 h 限制在 0length-1 的范围内。这个表达式是位运算中的一个常见技巧,用于快速地将一个整数映射到一个固定大小的数组或列表的索引。

为了理解这个表达式如何工作,让我们再次考虑 hlength-1 的二进制表示。假设 length 是一个2的幂,例如 length = 2^n,那么 length-1 就是 2^n - 1。这个数在二进制中表示为 n 个1,从最低位到第 n 位。

例如,如果 length = 8(即 2^3),则 length-1 = 7,其二进制表示为 0111(假设我们在一个足够大的位数中考虑,比如8位,则为 00000111)。

现在,假设 h 是一个任意的哈希值,其二进制表示可能看起来像这样(以8位为例):

1
h = 10101010

当我们执行 h & (length-1) 时,我们实际上是在执行以下按位与操作:

1
2
3
4
10101010 (h)  
& 00000111 (length-1)
----------
00000010 (result)

在这个例子中,只有 h 的最低三位与 length-1 的相应位相匹配,因此结果是 00000010,即十进制中的 2。这个值现在可以用作数组或列表的索引,因为它已经被限制在 0length-1(即 07)的范围内。

这种技术的一个关键前提是 length 必须是2的幂。如果 length 不是2的幂,那么 length-1 的二进制表示将不会有一系列连续的1,这可能导致哈希冲突或索引超出数组边界。当 length 是2的幂时,length-1 的二进制表示将有一系列连续的1,这可以确保 h 的任何位模式都会被映射到一个有效的索引。

学习地址

HashMap终极总结,Java7与Java8的区别_java7 和java8 hashmap的区别-CSDN博客



前言

在学习hashCode()的时候发现hashCode()值相同,两个对象返回的equals也不一定相同,这里的equals()关注的是内容的比较。

1
2
3
4
String str1 = "适量";
String str2 = "通话";
System.out.println(String.format("str1:%d | str2:%d",str1.hashCode(),str2.hashCode());
System.out.println(str1.equals(str2));

执行结果发现hashCode()返回值相同,equals()返回的却是false,因为hash值相同并不能确定两个对象在内容上是相同的。hash是一种单向密码体制,即它是一个从明文到密文的不可逆的映射,只有加密过程,没有解密过程。同时,哈希函数可以将任意长度的输入经过变化以后得到固定长度的输出。哈希函数的这种单向特征和输出数据长度固定的特征使得它可以生成消息或者数据。



前言

准备面试时候的记录

使用 == 比较

Java中的8种基本数据类型(byte,short,char,int,long,float,double,boolean)比较他们之间的值是否相等。
引用数据类型,比较的是他们在堆内存地址是否相等。每新new一个引用类型的对象,会重新分配堆内存空间,使用==比较返回false。

使用 equals 比较

equals方法是Object类的一个方法,Java当中所有的类都是继承于Object这个超类。
JDK1.8 Object类equals方法源码如下,即返回结果取决于两个对象的使用==判断结果。

1
2
3
public boolean equals(Object obj) {
return (this == obj);
}
需要注意的例子
1
2
3
String s1 = "abc";
String s2 = "abc";
System.out.println(s1 == s2);

返回的是true,因为在”abc”在第一次赋值的时候就存在了变量池中,所以在第二次“abc”被赋值给s2的时候,直接将s2指向了“abc”的同一内存地址。所以返回true。

参考文章

== 和 equals 的区别_==和equals的区别-CSDN博客

java中equals以及==的用法(简单介绍) - 韦邦杠 - 博客园 (cnblogs.com)

今天更新博客,结果推送仓库的时候发现连不上github,一直报错超时。就顺手记录下解决方法。在C://Users/用户名/.ssh/ 目录下的config(没有就新建)内写下。

1
2
Host github.com
HostName ssh.github.com

重试,成功。

补充

2024年2月21日发现没有联网也会报这个错。

arm64开发板上armbian换源报错E: 无法下载 https://mirrors.tuna.tsinghua.edu.cn/ubuntu-ports/dists/focal/restricted/binary-amd64/Packages 404 Not Found [IP: 101.6.15.130 443]

sources.list如图

结果 sudo apt update 却遇上了报错

分明使用的是ubuntu-ports,处理器架构也是arm64,apt 怎么会去获取amd64的软件包呢,多次换源无果,实在令人难解。

好在根据关键词多次搜索,终于发现原因所在。使用dpkg查看系统软件包架构发现

1
2
3
ajin@CRRC:~$ dpkg --print-foreign-architectures
armhf
amd64

这一指令可以显示已安装软件包中包含的其他体系架构,比如系统本身是64位的,而用户安装了一个32位的软件,则这个32位的体系结构就被称为”foreign-architectures”.

所以解决方法就是用dpkg来移除这个amd64的额外架构。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
ajin@CRRC:~$ sudo dpkg --remove-architecture amd64
ajin@CRRC:~$ sudo apt update
命中:1 http://mirrors.tuna.tsinghua.edu.cn/armbian focal InRelease
命中:2 https://mirrors.tuna.tsinghua.edu.cn/ubuntu-ports focal InRelease
命中:3 https://mirrors.tuna.tsinghua.edu.cn/ubuntu-ports focal-updates InRelease
命中:4 https://mirrors.tuna.tsinghua.edu.cn/ubuntu-ports focal-backports InRelease
命中:6 http://ppa.launchpad.net/openjdk-r/ppa/ubuntu focal InRelease
命中:7 http://ports.ubuntu.com/ubuntu-ports focal-security InRelease
命中:5 http://mirrors.ustc.edu.cn/armbian focal InRelease
命中:8 https://download.docker.com/linux/ubuntu focal InRelease
获取:9 https://mirrors.tuna.tsinghua.edu.cn/ubuntu-ports focal/universe armhf Packages [10.9 MB]
获取:10 https://mirrors.tuna.tsinghua.edu.cn/ubuntu-ports focal/restricted armhf Packages [10.8 kB]
获取:11 https://mirrors.tuna.tsinghua.edu.cn/ubuntu-ports focal/main armhf Packages [1,227 kB]
获取:12 https://mirrors.tuna.tsinghua.edu.cn/ubuntu-ports focal/multiverse armhf Packages [141 kB]
获取:13 https://mirrors.tuna.tsinghua.edu.cn/ubuntu-ports focal-updates/multiverse armhf Packages [9,898 B]
获取:14 https://mirrors.tuna.tsinghua.edu.cn/ubuntu-ports focal-updates/restricted armhf Packages [21.9 kB]
获取:15 https://mirrors.tuna.tsinghua.edu.cn/ubuntu-ports focal-updates/main armhf Packages [1,835 kB]
获取:16 https://mirrors.tuna.tsinghua.edu.cn/ubuntu-ports focal-updates/universe armhf Packages [1,172 kB]
获取:17 https://mirrors.tuna.tsinghua.edu.cn/ubuntu-ports focal-backports/universe armhf Packages [27.8 kB]
获取:18 https://mirrors.tuna.tsinghua.edu.cn/ubuntu-ports focal-backports/main armhf Packages [54.7 kB]
获取:19 http://ports.ubuntu.com/ubuntu-ports focal-security/universe armhf Packages [887 kB]
获取:20 http://ports.ubuntu.com/ubuntu-ports focal-security/multiverse armhf Packages [5,099 B]
获取:21 http://ports.ubuntu.com/ubuntu-ports focal-security/main armhf Packages [1,475 kB]
获取:22 http://ports.ubuntu.com/ubuntu-ports focal-security/restricted armhf Packages [21.6 kB]
正在读取软件包列表... 完成
正在分析软件包的依赖关系树
正在读取状态信息... 完成
有 286 个软件包可以升级。请执行 ‘apt list --upgradable’ 来查看它们。

之后果然没有报错了。

另外一种解决方法是在/etc/apt/sources.list中去指定自己需要的架构的软件包
1
deb [arch=arm64] https://mirrors.tuna.tsinghua.edu.cn/ubuntu-ports/ focal main restricted universe multiverse

awk技能实战

数组

  • 数组声明 declare -a
  • 关联数组声明 declare -A

字符串

  • 切片
  • 查找替换
  • 查找删除
  • 变量赋值

awk工具

文档报告生成器,格式化文本输出

  • 基本用法 awk [options] ‘program’ file

    • program: PATTERN{ACTION STATEMENTS},这里的PATTERN不是正则中的模式,而是内置的模式

      • ACTION_STATEMENTSb

        • expressions

        • Control statements

        • Compound statements

        • input statements

        • out statements

        • print print item1,item2

        • printf 用法print FORMAT,item1,item2

          • FORMAT必须给出
          • printf不会自动换行
          • FORMAT中需要为后面的每一个item指明一个格式化符号
          • 格式符
            • %c,显示ASCII码
            • %d,%i,显示十进制整数
            • %e,%E,科学计数法
            • %f,浮点数
            • %g,%G,科学计数法或者浮点数显示数值
            • %s,显示字符串
            • %u,无符号整数
            • %%,显示为%自身
          • 修饰符
            • %n.n,比如%15s,表示这个变量用15个位置显示
            • -:左对齐 0
            • +:显示数值的符号
        • 操作符

          • 算符运算操作符
            • x+y,x-y,x*y,x/y,x%y
            • -x,取负
        • +x,转化为数值

          • 赋值操作符 =,+=,-=,*=,%=,%=,……=,++,–
      • 比较操作符 >,>=,==,等等

        • 模式匹配符

          • ~,左边是否能被右侧匹配
          • !~
        • 逻辑 && || !

        • 函数调用function_name(arg1,arg2,arg3)

        • 条件表达式 判断条件?expression:expression三元表示式

        • PATTERN

          • empty:空模式匹配每一行,不写出来就行
          • /regular expression/:能被此处的模式匹配到的
          • relation expression ,关系表达式,结果有真有假,结果为真就处理,非0为真。非空字符串表示为真。
          • line ranges,行范围/pat1/,/pat2/,不支持直接数字格式
          • BEGIN/END,BEGIN尽在开始处理文件中的文本之前执行一次,end仅仅在处理完成之后,命令结束之前执行一次。
          1
          awk -F: 'BEGIN{print "    name       uid  "}{print $1,$3}' /etc/passwd

      Notes:输出的item可以是字符串,也可以是数值,当前记录的字段,变量或awk表达式。想要变量替换,变量不能写在引号内

      • 变量
        • 内建变量(使用的时候不需要$)
          • FS,输入时分隔符,默认为空白
          • OFS,输出时分隔符,默认为空白字符
          • RS,输入的换行符
          • ORS,输出时的换行符
          • NF,每一行的字段数量
          • NR,行数
          • FNR,每一个文件进行单独计数
          • FILENAME,当前文件名
          • ARGC,命令行参数个数
          • ARGV,数组,命令行中给定的各个参数
        • 自定义变量
          • 变量名一样区分大小写
          • 可以在program中直接定义,就是后面的{},多个就用分号分隔
    • options

      • -F ,指明输入时数据的字段分隔符
      • -v: var=value 自定义变量

Linux连接

查看系统是否监听22端口

1
ss -tnl

查看网卡信息

1
2
3
4
5
ifconfig

addr list

ip a

查看端口是否开启

1
2
3
iptables -L -n
临时关闭
iptables -F

linux终端类型

  • 串行端口终端(/dev/ttySn),利用计算机串口连接的终端设备。

  • 伪终端(/dev/pts/#)如mobaxterm里虚拟出来的终端。

  • 虚拟终端(/dev/tty#[1-6]

  • 物理终端(/dev/console)

    查看接口
    1
    tty

linux交互接口

  • Cli接口:

    ​ [fu@localhost ~]$

    ​ fu:当前登录的用户

    ​ localhost:主机名

    ​ ~:当前工作目录,相对路径

    ​ #:命令提示符,#为管理员账号,为root,$表示普通用户

Linux哲学思想

  • 一切皆文件,几乎所有资源都抽象成文件
  • 由众多单一的程序组成
  • 进行避免和用户进行交互,以编程的方式实现
  • 使用文本文件保存配置信息

文件系统

  • 层级结构,
  • 倒置树状结构

Linux系统初识别

kernel:用来解决底层硬件的驱动,使程序员可以面对统一规范风格的接口进行对硬件的调用,进行编程

libraries:对kernel的调用再一次进行封装,在库之上可以进行统一的,规范的代码编写。不同系统的库有所区别。


bash中的函数

  • 函数:把一段独立的代码当成一个整体,并为之一个名字。即为函数。

  • 语法一

    1
    2
    3
    function f_name{
    函数体
    }
  • 语法2

    1
    2
    3
    f_name(){
    函数体
    }
  • 函数的声明周期:每次被调用时候创建,返回时候终止。状态返回结果是最后一条命令的状态结果。

    • 自定义状态返回值return n,0表示成功,1-255表示失败。
  • 传递给参数的函数

    • 在函数体当中可以使用$1,$2…引用传给函数的参数,也可以$*,$@引用所有参数,@#i引用传递给函数的参数的个数
    • 在引用函数时,用空白分隔参数即可,也可以(arg1,arg2..)
  • 变量作用域

    • 局部变量,在函数内部定义的变量,在函数结束时自动销毁
      • 定义方法: local VAR=value
    • 本地变量, 作用域是运行脚本shell的声明周期
  • 函数递归

Notes:

1
2
echo $(seq 1 10)表示从1到10
$(1..10) 也是

BASH特性和bash编程

bash 的特性

  • 命令行展开: ~,{}
  • 命令别名:alias,unalias
  • 命令历史:history
  • 文件名通配:glob
  • 快捷键:Ctrl+a,e,u,k,l
  • 命令补全
  • 路径补全
  • 命令hash,缓存之前命令的查找结果,用hash 可以查看
  • 变量
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
程序:数据+指令
指令:程序文件提供
数据:IO设备,文件,管道,变量
bash是一种弱类型的编程语言,把所有变量视为字符传芳。并且变量无需事先声明。
变量引用:${var_name},$var_name
变量名:包含数字,字母,下划线,同时不能以数字开头。
变量类型:
本地变量:当前shell进程
变量引用:${var_name},$var_name
"":变量名会替换为值
'':变量名不会替换为值
设置或者查看变量:set
撤销:unset var_name(不适用$)
环境变量:当前shell以及子shell
变量赋值:
1.export name=fu
2.name=fu
export name
3.declare -x name=fu
查看环境变量:export,declare -x printenv,env
撤销环境变量:unset var_name
局部变量:某个代码作用域
位置参数变量:向执行脚本的shell进程传递的参数
特殊变量:shell内置的由特殊功能的变量

Notes:
设置为只读变量:readonly var_name或者declare -r var_name.
  • 多命令执行:
    command;command;….按顺序执行
  • 逻辑运算:
    • 真(true,yes,on,1)
    • 假(false,no,off,0)
    • 与 &&
    • 或 ||
    • 非 !