面试总结

1、servlet生命周期

(1) 初始化阶段,调用init()方法
(2) 响应客户端请求阶段,调用service()方法
(3) 终止阶段,调用destroy()方法

servlet容器装载servlet

  1. Servlet容器启动时自动装载某些Servlet,实现它只需要在web.XML文件中的<Servlet></Servlet>之间添加如下代码:
    <loadon-startup>1</loadon-startup>
  2. 在Servlet容器启动后,客户首次向Servlet发送请求
  3. Servlet类文件被更新后,重新装载Servlet,Servlet被装载后,Servlet容器创建一个Servlet实例并且调用Servlet的init()方法进行初始化。在Servlet的整个生命周期内,init()方法只被调用一次。

servlet工作原理
  首先客户发送一个请求,servlet调用service()方法对请求进行响应,service()方法对请求的方式进行匹配,选择调用doGet(), doPost()这些方。servlet接口中没有 doGet,doPost这些方法,httpServlet中有这些方法,但返回值都是error信息,所有需要将doPost,doGet重写。
  每一个自定义的servlet都需要实现servlet接口(init,service,destory就在这个接口中)。GenericServlet是一个通用的、不特定于任何协议的servlet,它实现了servlet接口,而httpServlet又继承与GenericServlet,所以我们定义servlet时只需要继承httpServlet即可。
  httpServlet是特定于http协议的类,它实现了service()方法,并将servletRequest和servletResponse强转为httpRequest和httpResponse。

2、sql 左外连接、右外连接、内连接、全连接

--左外连接,就算emp表中员工的deptno没有与dept表中的deptno对应也会查出来,不过显示emp表中的字段
select e.*,d.*
from emp e left join dept d on e.deptno=d.deptno;
左连接.png
--右外连接,就算emp表中员工的deptno没有与dept表中的deptno对应也会查出来,不过显示dept表中的字段
select e.*,d.*
from emp e right join dept d on e.deptno=d.deptno;
右连接.png
-- 内连接,只会查询出两表deptno一一对应的数据
select e.*,d.*
from emp e inner join dept d on e.deptno=d.deptno;
内连接.png
-- 全连接,不管两张表的数据是否一一对应,全都会查出来
select e.*,d.*
from emp e full join dept d on e.deptno=d.deptno;
全连接.jpg

3、数据库并发问题

数据库带来的并发问题有:

  1. 丢失更新。
  2. 未确认的相关性(脏读)。
  3. 不一致的分析(非重复读)。
  4. 幻读。
1.1 丢失更新

当两个或多个事务选择同一行,然后基于最初选定的值进行更新,会发生丢失更新问题。每个事务都不知道其实事务的存在。最后进行提交的事务会将之前的更新覆盖,导致数据丢失。
  此时需要对数据库进行加锁,两种方式,一种是一开始就锁住,防的很彻底,但是一旦锁的时间过长会影响他人操作;另一种是在最后做更新提交时上锁,将更新失败视为小概率事件,只在最后一步才上锁。
1.1.1 悲观锁
  当我们对数据进行修改时,首先需要将数据查询出来,在查询语中加锁,即 select .......for update nowwait,在一开始的查询中就开始加锁,避免其他用户更新
1.1.2 乐观锁
(a)旧值条件法:
  在更新语句中,使用旧的状态值作为更新的条件(不推荐)
(b)版本列法:
  当我们设计表的时候往往会多设置两个number/date类型的列,以便以后对表进行拓展。我们将一个number列作为版本列,每次修改数据时,以 限制条件 = 主键 + 版本列号的形式进行修改,同时每修改一次数据,都对版本号进行更新。

我们通常在冲突较为严重的系统中使用悲观锁,其他情况优先使用乐观锁。
2.1 未确认的相关性(脏读)

当一个事务读取到另一个事务还未提交的修改时候,产生脏读。
  张三的工资原本是2000,财务不小心将张三工资改成了5000,此时尚未提交,张三查询时发现自己工资变成5000后很开心,此时财务发现数据异常,回滚事务,张三工资又变成了2000,这就叫脏读。

解决办法:在事务提交之前,其他任何事务都不能读取其修改过的值。

3.1 不一致的分析(非重复读)
4.1 幻读

4、线程的两种创建方式

第一种:new Thread 重写 Thread 中的 run() 方法。

Thread thread = new Thread() {
            @Override
            public void run() {
                while (true) {
                    try {
                        Thread.sleep(2000);
                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                    System.out.println("1: " + Thread.currentThread().getName());
                    System.out.println("2: " + this.getName());
                }
            }
        };

第二种:Thread 的构造方法中有一个是以 Runnable对象为参数,Runnable是一个接口,当中有run()方法,Thread是implements了Runnable接口,继而实现了run()方法,我们可以在new Thread的时候,通过构造方法传一个Runnable对象,而Runnable对象中又有run()方法,通过这种方式,也能实现线程的创建。

Thread thread2 = new Thread(new Runnable() {
            @Override
            public void run() {
                while (true) {
                    try {
                        Thread.sleep(2000);
                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                    System.out.println("3: " + Thread.currentThread().getName());
                }
            }
        });

5、SVN多用户开发 --- 代码冲突&解决

修改同一文件的不同位置引发的冲突

现在有两个用户:zhangsan 和 lisi。他们需要同时修改一个文件,原始代码如下:

public void Test{
    System.out.println("Test!");
    return 1;
}

此时 zhangsan 需要修改第二行代,

public void Test{
    System.out.println("Test!xingoo");
    return 1;
}

lisi 则修改第三行代码,

public void Test{
    System.out.println("Test!");
    return 0;
}

假设 zhangsan 先提交代码,当 lisi 提交代码时,会提示错误:
  提示用户该文件已经过期,需要先更新文件。
此时 lisi 需要先进行更新代码,再提交代码。
  这种情况,是最简单的代码冲突样例。不同用户修改了不同位置的代码,因此只需要在提交前进行更新,就可以解决冲突。

修改同一文件相同位置引发的冲突

还是这个例子,zhangsan 当前代码如下,版本号为9,

public void Test{
    System.out.println("Test!xingoo");
    return 1;
}

lisi 代码如下,版本号为10,

public void Test{
    System.out.println("Test!xingoo");
    return 0;
}

此时 lisi 的代码是最新的版本。
这时,zhangsan 想要修改第三行的返回值如下,

public void Test{
    System.out.println("Test!xingoo");
    return 2;
}

这时提交代码会出现提示,发生错误,需要更新,OK,更新之后再次提交还是报错,提示 文件存在冲突!

观察文件目录,会发现多了三个文件


SVN文件冲突

分别打开三个文件:
其中<<<<<<.mine到====之间为当前用户修改的内容;
====到>>>>>.r10为版本库中的内容:

public void Test{
    System.out.println("Test!xingoo");
<<<<<<< .mine
    return 2;
=======
    return 0;
>>>>>>> .r10
}

test.txt.mine 记录当前用户修改后的文件内容快照

public void Test{
    System.out.println("Test!xingoo");
    return 2;
}

test.txt.r9 记录当前用户修改前,版本库中的内容快照

public void Test{
    System.out.println("Test!xingoo");
    return 1;
}

test.txt.r10 记录当前版本库中内容快照

public void Test{
    System.out.println("Test!xingoo");
    return 0;
}

通过这四个文件就可以很快速的发现,哪里有冲突。

至于如何修改:

直接拷贝mine文件,然后把r10文件的r10后缀去掉,进行更新。更新后,对比mine中的内容在进行修改。

也可以直接与其他人员进行协商沟通;更新版本库中的内容。

6、排序算法

冒泡排序

左右相邻的两个数进行比较,将大的放到右边,小的放到左边,每次排序都会将最大的数放到序列的最后,最差时间复杂度为 O(n^2),最好情况为 O(n)

public class BubbleSort {
    public static void sort(int[] num) {
        for (int i = 0; i < num.length - 1; i++) {
            int demo = 0;
            for(int j = 0; j < num.length -1-i; j++) {
                if (num[j] > num[j + 1]) {
                    demo = num[j];
                    num[j] = num[j + 1];
                    num[j + 1] = demo;
                }
            }
        }
        for(int k = 0; k < num.length; k++) {
            System.out.print(num[k] + ", ");
        }
    }   

    public static void main(String[] args) {
        int[] num = {8, 2, 3, 1, 6, 9, 7};
        sort(num);
    }
}
插入排序

将序列的第一个数默认为已排序序列,从第二个数开始(目标数get),对已排序序列进行从后往前的比较,如果已排序序列的当前数大于get,则该元素移动到下一位,重复比较,直到已排序序列的当前数小于get,则在该元素后一个位置将get插入。

最好空间复杂度为 O(n),最坏为O(n^2),与冒泡排序类似。

这个过程类似与打扑克摸手牌,此时已排序序列表左手已经抓好的牌,get表示右手新摸到的牌,从右往左进行比较,直到有小于get的牌,在其后插入get。

public class InsertionSort {
    public static void insertion(int[] arr) {
        int len = arr.length;
        for(int i = 1; i < len; i++) {
            int get = arr[i];
            int j = i -1;
            while(j >= 0 && get < arr[j]) {
                arr[j + 1] = arr[j];
                j--;
            }
            arr[j + 1] = get;
        }
    }
    
    public static void main(String[] args) {
        int[] arr = {2, 3, 1, 5, 6};
        insertion(arr);
        for(int i = 0; i < arr.length; i++) {
            System.out.println(arr[i]);
        }
    }
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,560评论 4 361
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,104评论 1 291
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,297评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,869评论 0 204
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,275评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,563评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,833评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,543评论 0 197
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,245评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,512评论 2 244
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,011评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,359评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,006评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,062评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,825评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,590评论 2 273
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,501评论 2 268

推荐阅读更多精彩内容