美文网首页
Java笔试题

Java笔试题

作者: Sophie12138 | 来源:发表于2017-10-06 20:01 被阅读88次

一、Java

1、请实现一个单例类,提示:如何保证线程安全?

public class MySingleton {  
    //内部类  
    private static class MySingletonHandler{  
        private static MySingleton instance = new MySingleton();  
    }   
    private MySingleton(){}  
    public static MySingleton getInstance() {   
        return MySingletonHandler.instance;  
    }  
} 

2、请写一个User的纯数据类,有id与name字段。写完后,请简述此时需要在User类中添加其它字段时,有哪些需要注意的地方。

/*当需要修改时
* 1.作为entity,因保证安全,则修饰符为private
* 2.修改构造方法
* */

public class User {
    private int id;
    private String name;

    public User(int id, String name) {
        this.id = id;
        this.name = name;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

3、请实现一个观察者模式observer pattern。

修改1.0

被观察者
public abstract class Observer {
    public abstract void update();
}
被观察者进一步实现
public class ConcreateObserver extends Observer {
    private String name;
    private ConcreateSubject subject;
    private String state;

    public ConcreateObserver(String name, ConcreateSubject subject) {
        this.name = name;
        this.subject = subject;
    }

    @Override
    public void update() {
        state = subject.getState();
        System.out.println("running");
    }
}

观察者
public class Subject {
    private List<Observer> list = new ArrayList<>();

    public void add(Observer o) {
        list.add(o);
    }

    public void remove(Observer o) {
        list.remove(o);
    }

    public void toNotify() {
        for (Observer o:list) {
            o.update();
        }
    }
}

public class ConcreateSubject extends Subject{
    String state;

    public String getState() {
        return state;
    }

    public void setState(String state) {
        this.state = state;
    }
}
执行
public class Main {
    public static void main(String[] args) {
        ConcreateSubject c = new ConcreateSubject();
        c.add(new ConcreateObserver("liao", c));
        c.add(new ConcreateObserver("chuan", c));
        c.setState("boss coming");
        c.toNotify();
    }
}

补充1.

uml图

4、请简述你对hashcode, equals 与==的理解。

对于hashcode与equals()
1.是Object的方法.
2.使用equals判断字符串内容是否相等.
3.特别的,对于String类型,可以生成特定的hash,在hashmap中插入String内容,后期跟据equals与hashcode进行碰撞冲突检测
4.能被重写

对于==
1.比较地址
2.运算符

补充1
equals与hashcode属于object的方法,而hashcode是native字段修饰,所以是原生方法,即是使用c/cpp写成,而equals在object中是比较地址

补充2
hashcode是为了比较的高效性存在,当存在两个比较值,若hashcode不同,则equals必为false,若hashcode相同,则equals可为true可为false,hashcode就像存储的段地址一样,并不是精确的地址

补充3
在java中摒弃了运算符重载

5、请简述在你所使用的框架中,数据库操作时添加@Transactional会产生什么效果,工作原理是什么。

效果:
1.事务传播等很多重要方面可以自动处理
2.跨越多个事务使用

工作原理:
1.EntityManager Proxy本身
2.事务的切面
3.事务管理器

补充1
@Transactional在JPA中有其定义,但诸如spring,hibenate对于其接口定义的不满足,所有重新继承并实现新的功能,这样在使用过程中更加方便.所有的orm面向对象框架都会遵循jpa规范.这是oracle的野心所在,想要将所有的持久层框架的规范统一,但在后期三方框架拓展过程中或用户使用过程中,不能满足于当前规范,所以有spring的@Transactional或者hibenate的@Transactional.

补充2
@Transactional是指对数据库事务属性的设置,比如只读,可读可写,可重复读,读已提交,读未提交

补充3
在数据库中为了效率高效,是多个事务共同工作,所以涉及到并发操作,也就是悲观锁,乐观锁,死锁的使用

补充4.数据库相关锁有哪些?
1.行锁:锁住相应的记录
2.表锁:锁住整张表
3.页锁:
4.排他写锁:若事务A对数据对象加上X锁,则只允许A进行操作,其他事务不能操作
5.共享锁:若事务A对数据对象加上S锁,则其他事务也只能加S锁,不能加X锁
6.悲观锁(使用for update使用mysql的悲观锁机制,在之前关闭autocommit,之后使用事务)
7.乐观锁
8.死锁:产生死锁的四个条件
(1)互斥条件:指进程对所分配到的资源进行排它性使用,即在一段时间内某资源只由一个进程占用。如果此时还有其它进程请求资源,则请求者只能等待,直至占有资源的进程用毕释放.
(2)请求和保持条件:指进程已经保持至少一个资源,但又提出了新的资源请求,而该资源已被其它进程占有,此时请求进程阻塞,但又对自己已获得的其它资源保持不放
(3)不剥夺条件:指进程已获得的资源,在未使用完之前,不能被剥夺,只能在使用完时由自己释放
(4)环路等待条件:指在发生死锁时,必然存在一个进程——资源的环形链,即进程集合{P0,P1,P2,···,Pn}中的P0正在等待一个P1占用的资源;P1正在等待P2占用的资源,……,Pn正在等待已被P0占用的资源

补充5
虚读:事务1读取数据,之后事务2修改数据,事务1再次读取发现数据和之前不一致
幻读:事务1对全部数据进行修改,事务2插入一条数据,事务1发现还有未修改的数据,就像发生幻觉一样
脏读:事务1读取某个数据,而事务2修改了数据但还未提交,导致事务1读取了脏数据

二、网络工程、安全

6、请简述你对git merge与git rebase的理解。

1.merge只是合并另外一个分支的内容
2.rebase也合并另外一个分支的内容,但是会把本分支的commits顶到最顶端

7、请描述从浏览器地址栏输入www.163.com以后浏览器和各类型服务器的相关响应事件。

1.dns解析域名
2.tcp封装数据
3.添加源和目的端口
4.通过路由器转发
5.得到mac地址,到达服务器.

补充1
浏览器首先查找本地hosts文件,是否有该域名与ip的索引关系,如果没有,才通过dns到外网查找.

补充2
三次握手:一次握手客户发送信息段,syn=1(synchronous建立联机),Sequence Number为x,客户端进入SYN_SEND状态,二次握手syn=1,ack+1,Sequence Number=y,进入SYN_RECEIVED状态,三次握手客户端收到ack=y+1,两端进入ESTABLISHED(已连接状态)

补充3
四次挥手,第一次发送fin信号,二次确认接收发送ack=1,并进入wait状态,三次发送fin,并进入LASK_ACK状态,四次另一端接收发送确认,并进入time_out,若没有再来请求,则关闭

8、请简述项目中优化数据库查询的方法。

1.减少select *的使用,尽量指明字段
2.尽量避免在 where 子句中对字段进行 null 值判断,尽量避免在 where 子句中使用!=或<>操作符(因为这样会数据库会放弃索引,而全表扫描)
4.尽量避免在where子句中对字段进行函数操作

补充1
能使用数字的字段尽量使用字段,如果使用字符串,在查询时会逐个字符比较,增加查询开销
补充2.强制使用某个索引查询,select * from table force index(PRI) limit 2;

9、请说明CSRF攻击的例子,以及危害,如何防范?

1.例子:欺骗用户的浏览器发送HTTP请求
2.危害,盗取密码等违法行为
3.将持久化的授权方法(例如cookie)切换为瞬时的授权方法

补充1
csrf与xss不同之处在于,csrf的攻击动作是由用户自己完成,而xss是攻击者发现漏洞,于是构造请求,由攻击者亲自执行,在log中容易被发现

三、数据结构、算法

10、请填写下列容器实现各操作的时间复杂度,及内部数据结构(若不支持某操作,请标记).

内部数据结构  随机Index/Key取值   随机Index/Key插入   随机Index/Key删除   追加元素    
ArrayList   数组         O(1)             O(n)                O(n)    O(1)    
LinkedList  链表         O(n)             O(n)                O(n)    O(1)    
TreeMap 二叉搜索树   O(log(n))        O(log(n))           O(log(n))  O(log(n))   
HashMap 数组  O(1)       O(1)             O(1)                O(1)    
PriorityQueue   堆       O(n)        O(log(n))                O(n)   O(log(n))   
LinkedHashMap   链表     O(n)             O(1)                O(1)    O(1)    

补充1.treemap底层数据结构二叉搜索树,也就是红黑树,特点和相关操作如下:

  • 基本特点
    • 每个节点要么是红要么是黑
    • 跟节点是黑
    • 树叶节点是黑
    • 节点为红,则两个孩子为黑
    • 对任意叶节点,每条路径都包含相同数目的黑节点
红黑树左旋 红黑树右旋

补充2
因为hashtable线程同步,同一时刻单线程处理,所以时间比hashmap慢

补充3.linkedlist

  • 双链表机制(可以直接访问前一个节点,linux内核中的实现)

11、给出一个链表,比如链表1→2→3→4→5→6,则翻转后6→5→4→3→2→1,请用程序实现。

public class Solution {
    public ListNode ReverseList(ListNode head) {
        if(head==null || head.next==null){
            return head;
        }        
        //递归
        ListNode start = ReverseList(head.next);
        
        head.next.next = head;
        head.next = null;
        
        //返回尾节点
        return start;
    }
}

12、已知函数 rand3(), 能等概率地返回 [0, 2] 区间的整数。
请依赖 rand3()设计一个能等概率返回 [0, 4] 区间整数的函数 rand5()。

public int rand5(){
    int r;
    do{
        r = 2*rand3() + rand3();
    } while(r >= 5);
    return r;
}

补充1.

public int rand5(){
    int r;
    do{
        r = 3*rand3() + rand3();
    } while(r >= 5);
    return r;
}

居然把其中的rand3()写成rand1(),简直是不能原谅自己.

13、矩阵置零
给定一个M*N的int类型矩阵, 如果一个元素为0,则把其所在的行列的所有元素全部置为 0(无需处理输入输出)。
请原地(in-place)完成。
*原地完成: 除给定数据外,申请额外空间的复杂度为O(1)。
例:
Input:
1 2 6 0
2 1 0 1
4 5 3 1
Output:
0 0 0 0
0 0 0 0
4 5 0 0

14、矩阵搜索
给定一个0,1矩阵M1, 求它在另外一个大0, 1矩阵M2中出现了几次(无需处理输入输出),例如下
Input:
M1 = 1 1 M2 = 0 0 0 1 1
1 1 1 0 1 1 1
1 0 1 1 1
Output:
3

相关文章

网友评论

      本文标题:Java笔试题

      本文链接:https://www.haomeiwen.com/subject/uuvbjxtx.html