秋招学习准备中2!

网易的笔试人都自闭了哎,复盘一下其中遇到比较有印象的题。

1.怎么理解一个类是线程安全的。
当多个线程访问一个变量的时候,可能会取到跟我们预想不一样的值,如

count++;

我们预想是多个线程依次累加,但是可能一个线程取值得时候上一个线程的count++还未执行,所以会得到一样的值,跟我们预想不一样,线程不安全。

线程安全:当多个线程访问某个方法时,不管你通过怎样的调用方式、或者说这些线程如何交替地执行,我们在主程序中不需要去做任何的同步,这个类的结果行为都是我们设想的正确行为,那么我们就可以说这个类是线程安全的。同时多个线程之间操作的数据不共享也是线程安全的。

可以使用synchronized和lock加锁使之变成线程安全,不同的是lock需要释放锁

2.java数据库开发怎么理解两个方法数据库操作在一个事务里面,事务和数据库连接池有什么关系,JTA事务和普通事务的区别。
首先解释事务是什么,转载一下:

事务处理在数据库开发中有着非常重要的作用,所谓事务就是所有的操作要么一起成功,要么一起失败。事务本身具有原子性(Atomicity),一致性(Consistency),隔离性或独立性(Isolation),持久性(Durability)4个特性,这4个特性也被称为ACID特性。

1.原子性:原子性是事务最小的单元,是不可再分割的单元,相当于一个个小小的数据库操作,如果这些操作必须同时完成,如果有一个失败了,则一切的操作将全部失败。例如,A给B转账,如果A转账失败了,则B收账也就失败。
2.一致性:指的是在数据库操作的前后是完全一致的,保证数据的有效性,如果事务正常操作则系统会维持有效性,如果事务出现了错误,则回到最原始的状态,也要维持其有效性,这样保证事务开始时和结束时系统处于一致状态。例如:A给B转账,如果转账成功,则保持其一致性,即A的钱减少x元,B的钱增加x元。如果现在A给B转账失败,则保持操作之前的一致性,即A的钱不会减少,B的钱不会增加
3.隔离性:多个事务可以同时进行而且彼此之间无法访问,只有当事务完成最终操作时才可以看到结果。
4.持久性:当一个系统崩溃是,一个事务依然可以坚持提交,当一个事务完成后,操作的结果保存在磁盘中,永远不会被回滚。例如在转账操作时,所有资金数都保存在磁盘中,所以即使系统发生错误,用户账户里的资金也不会增加或减少。

所以两个方法在一个事务里是两个方法有关联关系,如果一个不成功另一个也不会执行,逻辑和操作上关联起来。

数据库连接池:
一开始先在内存中开辟一块空间(集合),一开始先往池中放置多个连接对象,后面需要连接的话,直接从池子中取,不要自己取创建连接,使用完毕要记得归还连接,确保连接对象能够循环利用。

事务提交之后去连接池取连接完成事务操作。
最后一个jta事务和普通事务的区别,做完查资料才知道什么事JTA事务,惭愧,就是单库操作与多库操作的区别,JTA事务支持多个数据库事务的操作,简单认识一下。

3.一道编程题:给出一个数列,两个数只要和为奇数就能交换,输出字典序最小的数列。
刚刚看了一下别人的解答,恍然大悟,脑子真是转不过来。附大佬的思路:

这道题的意思是如果两个数的和是奇数,也就是奇偶性不同,则可以交换,否则不能交换。稍作分析可知,只要不是全为偶数或全为奇数,都可以通过交换随意排序。另外要满足题目中的字典序最小。所以判断一下如果全是偶数或全是奇数则直接输出,否则排序输出。

4.复习了一遍归并排序,就是递归拆分数组,再从小数组排序递归回到大数组。利用分治法的思想,通过不断把数组拆分成一半,最后再把每个数组排好序合并,合并后排序继续合并,得出最后有序的大数组。合并的时候因为已经用下标记录两个数组开始的位置,逐个比较把小的放进新的数组,因为小数组已经预先排好序,所以只需要逐个比较然后标记往下走就行,最后得出新的数组再复制进旧的数组。

public static void main(String[] args) {
        int[] array={2,4,5,1,6,8,3,7};//test
        sort(array,0,array.length-1);
        for(int i=0;i<array.length;i++)
            System.out.print(array[i]+" ");
    }

    public static void sort(int[] arr, int L, int R) {
        if(L == R) {
            return;
        }
        int mid =(L+R)/2;
        //拆分
        sort(arr, L, mid);//左边数组
        sort(arr, mid + 1, R);//右边数组
        merge(arr, L, mid, R);//拆分完就排序合并
    }

    public static void merge(int[] arr, int L, int mid, int R) {
        int[] temp = new int[R - L + 1];//新的记录数组
        int i = 0;//记录数组下标
        int p1 = L;//左数组标记
        int p2 = mid + 1;//右数组标记
        // 比较左右两部分的元素,哪个小,把那个元素填入temp中
        while(p1 <= mid && p2 <= R) {
            temp[i++] = arr[p1] < arr[p2] ? arr[p1++] : arr[p2++];
        }
        // 把剩余的元素依次填入到temp
        while(p1 <= mid) {
            temp[i++] = arr[p1++];
        }
        while(p2 <= R) {
            temp[i++] = arr[p2++];
        }
        // 把最终的排序的结果复制给原数组
        for(i = 0; i < temp.length; i++) {
            arr[L + i] = temp[i];
        }
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值