1.git 是分布式的,svn不是,每个开发人员从中心版本库/服务器上chect out代码后会在自己的机器上克隆一个自己的版本库。 2.git 把内容安装元数据进行存储,svn是按照文件进行存储
select class,max(score) from table group by class;
只要有一个小于80就加入集合
select distinct name from table where name not in (select name from table score <= 80);
select a.student,a.class from table a ,(select student ,max(score) as max_score from table group by student) b where a.score = b.max_score and a.student = b.student;
select student from table group by student having avg(score) > 80;
select student,score,count(1) group by student,score having count(score) > 2;
可以保证扫面点左边的数字都是尚未确定位置的,而右边的数字都是已经安排好位置的
public static <T> void swap(T[] a, int i, int j){
T temp = a[i];
a[i] = a[j];
a[j] = temp;
}
public static <T> void shuffle(T[] arr) {
int length = arr.length;
for ( int i = length; i > 0; i-- ){
int randInd = rand.nextInt(i);
swap(arr, randInd, i - 1);
}
}
2 ^ 32 = 4G 2 ^ 64 = G 当然这是理论值
冯诺依曼内存模型
1.如果其他方法没加synchronized 可以进去; 2.如果这个方法内部调用wait,其他synchronized方法也可以进去,没有调wait,不能进去其他synchronized方法; 3.如果其他方法是静态的他用的同步锁和当前不同可以进去;
保证可见性和原子性
这是因为,mysql 如果打开语句级binlog就不支持,读已提交和读未提交两个事物隔离级别;
mysql 设置默认隔离级别为可重复读的原因是:
其次,mysql的可重复读,在一定程度上也避免了幻读的问题;
InnoDB通过gap锁来避免幻象,从而实现SQL的可串行化,保证Binlog的一致性。
其实,RR隔离级别的防止幻象主要是针对写操作的,即只保证写操作的可串行化,因为只有写操作影响Binlog;而读操作是通过MVCC来保证一致性读。
原则有:
TX1 TX2
begin;
update b set name2='test' where id=2999; 对id:2999加LOCK_X锁
update b set name2='test' where id=999;
使用insert select 查询 select 会加锁
begin;
insert into a select * from b where id in (996,997,998,999,2995,2996,2997,2998,2999);对id:在加锁到996,997,998,999,2995,2996加LOCK_S锁,在对id:2997加锁前睡眠30秒,为下面的update语句腾出时间)
update b set name2='test' where id=999;对id:999加LOCK_X锁等待但发现已经加LOCK_S锁,需等待
描述:一个事务内要更新两个id的数据,id = 2999,id = 999; 另一个个事务在他执行了一个更新语句后,要执行包含id = 2999.id = 999 的插入,但是需要等待第一个事务释放锁,但是第一个事务的第二个语句,又需要第二个事务释放id = 999 的锁,最终形成死锁;
尽量少使用insert search
思路查找出最小的id,只保留最小的其他删除
delete from order where id not in (select id from ( select min(id) as id from order group by order_number) as b);
delete from table where id not in (select min(id) from table group by name having count(name)>1) and id in (select id group by name having count(name)>1)
开启两个事务来读取状态,会将所有未消费的进行锁住;
update user set session=CONNECTION_ID(),status='using' where status='un_use' limit 2;
保证hash时,相同的hash到同一个位置
String 和 StringBuilder 是效率和内存分配结果 当我们通过+来拼接字符串时,编译器会自动替我们优化成StringBuilder来拼接
public static void main(java.lang.String[]);
descriptor: ([Ljava/lang/String;)V
flags: ACC_PUBLIC, ACC_STATIC
Code:
stack=2, locals=3, args_size=1
0: ldc #2 // String
2: astore_1
3: iconst_0
4: istore_2
5: iload_2
6: bipush 10
8: if_icmpge 36
11: new #3 // class java/lang/StringBuilder
14: dup
15: invokespecial #4 // Method java/lang/StringBuilder."<init>":()V
18: aload_1
19: invokevirtual #5 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
22: iload_2
23: invokevirtual #6 // Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
26: invokevirtual #7 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
29: astore_1
30: iinc 2, 1
33: goto 5
36: getstatic #8 // Field java/lang/System.out:Ljava/io/PrintStream;
39: aload_1
40: invokevirtual #9 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
43: return
LineNumberTable:
line 10: 0
line 11: 3
line 12: 11
line 11: 30
line 14: 36
line 15: 43
LocalVariableTable:
Start Length Slot Name Signature
5 31 2 i I
0 44 0 args [Ljava/lang/String;
3 41 1 res Ljava/lang/String;
StackMapTable: number_of_entries = 2
frame_type = 253 /* append */
offset_delta = 5
locals = [ class java/lang/String, int ]
frame_type = 250 /* chop */
offset_delta = 30
}
概念用法:
Java中的泛型基本上都是在编译器这个层次来实现的。在生成的Java字节码中是不包含泛型中的类型信息的。使用泛型的时候加上的类型参数,会在编译器在编译的时候去掉。这个过程就称为类型擦除。
List<object>和List<String>
泛型擦除:
public void test(List<Integer> li)
public void test(List<String> Li)
编译出错
在程序中定义了一个ArrayList泛型类型实例化为Integer的对象,如果直接调用add方法,那么只能存储整形的数据。不过当我们利用反射调用add方法的时候,却可以存储字符串。这说明了Integer泛型实例在编译之后被擦除了,只保留了原始类型。
类型擦除引起的问题及解决方法?
ArrayList<String> arrayList1=new ArrayList<Object>();//编译错误
ArrayList<Object> arrayList1=new ArrayList<String>();//编译错误
3、类型擦除与多态的冲突和解决方法,我们本意重写setValue和getValue方法的子类,竟然有4个方法,其实不用惊奇,最后的两个方法,就是编译器自己生成的桥方法。可以看到桥方法的参数类型都是Object,也就是说,子类中真正覆盖父类两个方法的就是这两个我们看不到的桥方法。而打在我们自己定义的setvalue和getValue方法上面的@Oveerride只不过是假象。而桥方法的内部实现,就只是去调用我们自己重写的那两个方法。 所以,虚拟机巧妙的使用了巧方法,来解决了类型擦除和多态的冲突。
System.arrayCopy()
使用预分配先创建一定数量的核心,执行完会继续阻塞,等待新的任务,其他大于核心线程数的线程会在一定时间后进行回收;
如果程序中不再持有线程池的引用,并且线程池中没有线程时,线程池将会自动关闭。
线程池自动关闭的两个条件:1、线程池的引用不可达;2、线程池中没有线程; 这里对于条件2解释一下,线程池中没有线程是指线程池中的所有线程都已运行完自动消亡。
在并发度低情况下使用 Synchronized ,这是因为,Synchronied 有一个锁升级的过程;
在要求中断,多个等待队列,可操作性性的,并发度高的情况下使用Lock锁;
Semaphore CountDownLatch CyclicBarrier Exchanger Phaser
Semaphore 信号量是一类经典的同步工具。信号量通常用来限制线程可以同时访问的(物理或逻辑)资源数量。
CountDownLatch 一种非常简单、但很常用的同步辅助类。其作用是在完成一组正在其他线程中执行的操作之前,允许一个或多个线程一直阻塞。
CyclicBarrier 一种可重置的多路同步点,在某些并发编程场景很有用。它允许一组线程互相等待,直到到达某个公共的屏障点 (common barrier point)。在涉及一组固定大小的线程的程序中,这些线程必须不时地互相等待,此时 CyclicBarrier 很有用。因为该 barrier在释放等待线程后可以重用,所以称它为循环的barrier。
Phaser一种可重用的同步屏障,功能上类似于CyclicBarrier和CountDownLatch,但使用上更为灵活。非常适用于在多线程环境下同步协调分阶段计算任务(Fork/Join框架中的子任务之间需同步时,优先使用Phaser)
Exchanger允许两个线程在某个汇合点交换对象,在某些管道设计时比较有用。Exchanger提供了一个同步点,在这个同步点,一对线程可以交换数据。每个线程通过exchange()方法的入口提供数据给他的伙伴线程,并接收他的伙伴线程提供的数据并返回。当两个线程通过Exchanger交换了对象,这个交换对于两个线程来说都是安全的。Exchanger可以认为是 SynchronousQueue 的双向形式,在运用到遗传算法和管道设计的应用中比较有用。
预创建技术,创建流程
Java的线程是不允许启动两次的,第二次调用必然会抛出IllegalThreadStateException,这是一种运行时异常