位运算

Java的位运算主要有:按位与(&)、按位或(|)、按位取反(~)、按位异或(^)、左移(<<)、带符号右移(>>)、无符号右移(>>>)

按位与(&)

当相同位上的两个数字都为1时,结果为1;否则为0

1&1=1 
1&0=0
0&1=0 
0&0=0 

按位或(|)

当相同位上的数字至少有一个为1时,结果为1;否则为0

 1|1=1 
 1|0=1 
 0|1=1 
 0|0=0

按位取反(~)

^1=0
^0=1

按位异或(^)

当相同位上的两个数字不同时,结果为1;相同时为0

1^1=0 
1^0=1 
0^1=1 
0^0=0

左移(«)

将二进制数字向左移动,移动几位就在最右侧补多少个0。 例如 3<<1,因为3的二进制表示形式为11,向左移动一位后变为110,所以 3<<1=6。 左移n位相当于乘上2的n次方。

带符号右移(»)

将二进制数字向右移动,移动几位就在最右侧消去多少个比特位,并最左侧填充符号位。 例如 3>>1,因为3的二进制表示形式为011,所以向右移动一位后变为001,所以 3>>1=1。 例如 -3>>1,因为-3的二进制补码表示为111111111111111111111111111111011 2,所以带符号向右移动一位后变为11111111111111111111111111111110,对应的数字为-2,所以 -3>>1=-2。 1左移一位会变成0,0左移依旧为0。

无符号右移(»>)

将二进制数字向右移动,移动几位就在最右侧消去多少个比特位,并最左侧填充0。 例如 -3>>>1,因为-3的二进制补码表示为11111111111111111111111111111101,所以无符号向右移动一位后变为01111111111111111111111111111110,对应的数字为2147483646,所以 -3>>>1=2147483646

Java集合-队列

Java中对应的队列接口为 Queue,是一个先进先出(FIFO)队列。新元素会被插入到队列尾端,移除元素时会先移除队列首端的元素。

Queue主要方法有:

抛出错误 返回特殊值(null或false)
插入 add() offer()
移除 remove() poll()
查看 element() peek()

通常情况下,推荐使用 offer()poll()peek(),这三个方法。

当插入的新元素已经存在于队列时,offer()方法返回false;当队列为空时,poll()peek()方法返回 null

Queue主要实现类有: ![[Queue主要实现类.png]]

我们平常使用的实现类为 LinkedList,该类为 QueueDeque的双向链表实现类。

例如:

Queue<Integer> queue=new LinkedList<>();
queue.offer(1);
queue.peek();
queue.poll();

判断ip是否在某ip范围内

判断某个ip是否在[start,end]两个ip的范围内,即判断start≤ip≤end是否符合。

首先分析start≤ip。

因为ip的一般形式为 "a.b.c.d",通过 .将整个ip分为四段。假设判断的ip为{a,b,c,d},start为{a1,b1,c1,d1}。从左开始分析的话,每段有小于、等于、大于三个比较关系。如果a>a1,直接就能说明ip>start,不用再继续判断start后面的段;如果a=a1,则需要继续判断start剩下部分;如果a<a1,说明ip<start,直接返回false即可。

因为还存在start=ip的情况,所以需要保留循环的次数,如果比较到最后一段,说明start≤ip。

end的比较与start同理。

代码如下:

public static boolean ipInRange(String ip,String start,String end){
        String[] ips=ip.split("\\\\.");
        String[] starts=start.split("\\\\.");
        String[] ends=end.split("\\\\.");
        boolean flags=false,flage=false;  //flags为true代表ip已经符合start,不用判断;flage标记end
        int i=0;
        for (; i <ips.length; i++){
            int t_ip=Integer.parseInt(ips[i]);
            int t_start=Integer.parseInt(starts[i]);
            int t_end=Integer.parseInt(ends[i]);
            if(!flags){   
                if(t_ip>t_start){
                    flags=true;   //说明start不用判断了
                }else if(t_ip<t_start){
                    return false;   //说明ip小于start
                }
            }
            if(!flage){
                if(t_ip<t_end){
                    flage=true;
                }else if(t_ip>t_end){
                    return false;
                }
            }
        }
        return (flags&&flage)||i==ips.length;  //i==ips.length为true代表ip从头判断到尾,说明ip与某个边界相等。
    }
    public static void main(String[] args) {
        System.out.println(ipInRange("192.168.215.253","192.168.215.1","192.168.215.252"));
    }

自定义hugo的even主题,禁止复制代码行数

hugo是一个静态网站生成框架,基于go实现。

hugo-theme-even是一个hugo的主题。

因为even默认生成的代码存在代码行数,但是复制文章时会把代码行数也一并复制,所以特地对even的代码进行修改,让其复制时不复制代码行数。

因为需要修改assets目录里面的文件,所以需要hugo extended版,可使用命令 hugo查看版本。

even默认代码高亮为chroma,所以我们先禁用chroma,并启用highlight作为代码高亮。

修改config.toml配置文件:

# 将下面配置设置为false
pygmentsCodefences = false
pygmentsUseClasses = false
pygmentsCodefencesGuessSyntax = false

#将下面配置设置为true
highlightInClient = true

然后修改assets\js目录下面的even.js文件,使得代码行数禁止复制:

Even.highlight = function() {
  const blocks = document.querySelectorAll('pre code');
  for (let i = 0; i < blocks.length; i++) {
    const block = blocks[i];
    const rootElement = block.parentElement;
    const lineCodes = block.innerHTML.split(/\\n/);
    if (lineCodes[lineCodes.length - 1] === '') lineCodes.pop();
    const lineLength = lineCodes.length;

    let codeLineHtml = '';
    for (let i = 0; i < lineLength; i++) {
      codeLineHtml += `<div class="line">${i + 1}</div>`;
    }

    let codeHtml = '';
    for (let i = 0; i < lineLength; i++) {
      codeHtml += `<div class="line">${lineCodes[i]}</div>`;
    }

    block.className += ' highlight';
    const figure = document.createElement('figure');
    figure.className = block.className;
		//修改该行代码,添加style="user-select:none"
    figure.innerHTML = `<table><tbody><tr><td class="gutter"><pre style="user-select:none">${codeLineHtml}</pre></td><td class="code"><pre>${codeHtml}</pre></td></tr></tbody></table>`;

    rootElement.parentElement.replaceChild(figure, rootElement);
  }
};

重新编译,能看到复制代码时不再复制代码行数。