分享一道DBA面试题,亲历
问:想要查询表A中列B包含'\'的字段,SQL应该怎么写?
答:select * from A where B like '%\\\\%'
为什么需要四个'\'?
因为一条SQL首先要经过编译,这时'\'就只剩下两个,再经过一次正则匹配的转义,则可以匹配'\'了!
书归正传
单链表
单链表是一个有序列表,以节点的形式来存储,有data域和next域.如下图
1.头指针不存放数据,存放第一个节点的地址值
2.普通节点存放数据,和下一个节点的地址值,如果没有下一个节点,next域中,就存null
3.各个相邻的节点在内存中的位置不一定连续
4.链表不一定必须有头指针,头指针只是用来表明第一个节点的位置而已
整体代码
实现了
1.添加节点(现在只实现了尾部追加节点,明天会实现按照编号添加)
2.删除节点(逻辑就是把要删除的节点的前一个节点的next域指向要删除节点的下一个节点)
3.显示链表
要点就是临时变量tmp的设计和使用
public class SingleLinkedListDemo {
public static void main(String[] args) {
//创建节点
HeroNode hero1 = new HeroNode(1, "唐僧", "师傅");
HeroNode hero2 = new HeroNode(2,"孙悟空","大师兄");
HeroNode hero3 = new HeroNode(3,"猪八戒","二师兄");
HeroNode hero4 = new HeroNode(4,"沙和尚","三师弟");
//创建链表
SingleLinkedList singleLinkedList = new SingleLinkedList();
//加入链表
singleLinkedList.add(hero1);
singleLinkedList.add(hero2);
singleLinkedList.add(hero3);
singleLinkedList.add(hero4);
//显示链表
singleLinkedList.show();
//删除节点
singleLinkedList.remove(2);
//显示链表
singleLinkedList.show();
}
}
//定义单链表,来管理HeroNode
class SingleLinkedList{
//定义头结点,指向链表头位置,因为是不存放数据的,所以用一个空的HeroNode来占位.
private HeroNode header = new HeroNode(0,"","");
//添加节点方法
//不考虑编号,统一加到最后一个位置.
TODO: 2021/11/27 所以怎么找到链表的最后一个位置?
//为了实现,我们需要一个临时的变量tmp,来保存未插入之前的最后一个节点
public void add(HeroNode node){
HeroNode tmp = header;
while (true){
if (tmp.next == null){
break;
}
//如果next不为null,说明还不是最后一个,所以继续往下查
tmp = tmp.next;
}
//到这一步,说明跳出了循环,所以tmp此时就代表了最后一个元素
//所以我们将tmp的next指向了新插入的node.这就完成了插入.
tmp.next = node;
System.out.println("==========添加成功==========");
}
//显示列表
public void show(){
if (isEmpty()){
System.out.println("链表为空");
}else{
System.out.println("============显示列表============");
HeroNode tmp = header.next;
while (true){
//每次循环,都要判断tmp是否为null,如果为null,说明已经没有节点了,要退出循环
if (tmp == null){
break;
}
System.out.println(tmp);
tmp = tmp.next;
}
}
}
//判断链表是否为空
public boolean isEmpty(){
return header.next == null;
}
//删除某个节点(将要删除的节点的前后两个节点连接起来)
public void remove(int id){
//先判断是否为空
if (isEmpty()){
System.out.println("链表为空");
return;
}
//不为空的话
HeroNode tmp1 = header.next;
//如果恰好第一个就是要删除的目标,把头指针改为指向第二个元素(如果有的话),如果没有第二个元素,就只向null
if (tmp1.no == id){
header.next = (tmp1.next==null?null:tmp1.next);
System.out.println("=======执行删除成功=======");
return;
}
//剩下的情况就是:队列不为空.且要删除的节点不是头结点
HeroNode tmp2 = tmp1.next;
while (true) {
if (tmp2 == null){
System.out.println("找不到删除目标");
return;
}
if (tmp2.no == id){
//说明tmp2是要被删除的节点
tmp1.next = tmp2.next;
System.out.println("=======执行删除成功=======");
return;
}
tmp1 = tmp2;
tmp2 = tmp1.next;
}
}
}
class HeroNode{ //一个HeroNode,就代表一个节点
int no; //节点编号★★★
String name; //节点姓名 --不重要
String nickName; // 节点小名(昵称) --不重要
HeroNode next; //后一个节点★★★★★
public HeroNode(int no, String name, String nickName){
this.no = no;
this.name = name;
this.nickName = nickName;
}
//重写toString方法
@Override
public String toString() {
return "HeroNode{" +
"no=" + no +
", name='" + name + '\'' +
", nickName='" + nickName + '\'' +
'}';
}
}