小知识积累中...

  1. linux 下改变环境变量:

    export PATH=/usr/local/mongodb/bin:$PATH

    //配置完后可以通过echo $PATH查看配置结果。

    生效方法:立即生效

    有效期限:临时改变,只能在当前的终端窗口中有效,当前窗口关闭后就会恢复原有的path配置

    用户局限:仅对当前用户。

  2. 双数据源时,从库的sql 需要在表的前边加数据库名称在查询。
  3. vim 下: dd  删除当前行; yy 复制当前行;u:撤销当前操
  4.  jsp EL表达式展示json出错解决: 将表达式用单引号引用,因为json内容里面有双引号,造成读取截断失败,正确的表达式如下:
<input type="hidden" name="huserInfo" id="huserInfo" value='${huserInfo}'>

5. linux 中tar命令:

压缩:tar -czvf  file.tar  filename

解压:

tar -xvf file.tar //解压 tar包

tar -xzvf file.tar.gz //解压tar.gz

6. 涉及到list 多线程异步动态增加删除时,arraylist 不可用,此时可以用concurrent 包里的ConcurrentLinkedDeque,队列.

ConcurrentLinkedQueue 是单向链表结构的无界并发队列。元素操作按照 FIFO (first-in-first-out 先入先出) 的顺序。适合“单生产,多消费”的场景。内存一致性遵循对ConcurrentLinkedQueue的插入操作先行发生于(happen-before)访问或移除操作。

ConcurrentLinkedDeque 是双向链表结构的无界并发队列.

ConcurrentLinkedQueue .toArray(T[] a) 可以转成array数组。 比如:

queue.toArray(new StompSession[0]. 
注意toArray方法:

List接口的toArray()方法就是直接调用Arrays.copyOf(elementData, size),将list中的元素对象的引用装在一个新的生成数组中。

List接口的toArray(T[] a)方法会返回指定类型(必须为list元素类型的父类或本身)的数组对象,如果a.length小于list元素个数就直接调用Arrays的copyOf()方法进行拷贝并且返回新数组对象(不是a,是新生成了一个数组对象),新数组中也是装的list元素对象的引用,否则先调用System.arraycopy()将list元素对象的引用装在a数组中,如果a数组还有剩余的空间,则在a[size]放置一个null,size就是list中元素的个数,这个null值可以使得toArray(T[] a)方法调用者可以判断null后面已经没有list元素了。

基准测试ArrayList的toArray方法:

    //速度排名 1
    @Benchmark
    public Object[] simple() {
        return LIST.toArray();
    }

    //速度排名 2,性能最好,推荐使用
    @Benchmark
    public Character[] zeroCached() {
        return LIST.toArray(EMPTY_CHAR_ARRAY);
    }

    //速度排名 3
    @Benchmark
    public Character[] zero() {
        return LIST.toArray(new Character[0]);
    }

    //速度排名 4
    @Benchmark
    public Character[] sized() {
        return LIST.toArray(new Character[LIST.size()]);
    }

结果:

Benchmark                   Mode  Cnt   Score   Error  Units
ToArrayPerfTest.simple      avgt    5  37.278 ± 0.669  ns/op
ToArrayPerfTest.sized       avgt    5  59.346 ± 0.272  ns/op
ToArrayPerfTest.zero        avgt    5  49.682 ± 1.067  ns/op
ToArrayPerfTest.zeroCached  avgt    5  47.982 ± 1.024  ns/op

7. SpringBoot启动加载数据CommandLineRunner:

SpringBoot应用程序在启动时,会遍历CommandLineRunner接口的实例并运行他们的run()方法。也可以利用@Order注解或者Order接口来规定所有CommandLineRunner实例的运行顺序。

8. java8: Map.computeIfAbsent(k,(k-v)->v):

computeIfAbsent:存在时返回存在的值,不存在时返回新值

9. ReentrantReadWriteLock: 读写互斥锁,只有读读共享,有写都会互斥,以此可得出读读共享,写写互斥,读写互斥,写读互斥。 基准测试BenchMark 后发现 lock 与sync性能差不多

10. 循环依赖:使用@Async异步注解导致该Bean在循环依赖时启动报BeanCurrentlyInCreationException异常的根本原因分析:

@Slf4j
@Service
public class B {
    @Lazy
    @Autowired
    private B b;

    public void test() {
        this.b.tran();
    }

    //必须为 public 以便能够被代理
    @Async
    @Transactional
    public void tran() {
        log.info("ddd");
    }
}


如果是 @Transactional 可以不加 @Lazy

如果是 @Async 必须加 @Lazy , 否则 启动 spring boot 报错.. 原理参考 使用@Async异步注解导致该Bean在循环依赖时启动报BeanCurrentlyInCreationException异常的根本原因分析,以及提供解决方案【享

使用@Async异步注解导致该Bean在循环依赖时启动报BeanCurrentlyInCreationException异常的根本原因分析,以及提供解决方案【享学Spring】_Java方向盘-优快云博客

11. 【读阿里巴巴开发手册有感】-1:

比较的时候 java.sql.TimeStamp 的毫秒不会参与比较,为 000, 所以同一个秒内的两个时间, 一个为new Date,一个为new Timestamp, 用 before 和 after 比较时,Date 的总是大于 TimeStamp,所以程序种不要使用TimeStamp

12. StringBuilder:

1)循环中需要使用StringBuilder来操作字符串拼接工作,不要使用string += str,因为反编译出的字节码文件显示每次循环都会 new 出一个 StringBuilder 对象,然后进行append 操作,最后通过 toString 方法返回 String 对象,造成内存资源浪费,这虽然减少了jvm常量池的压力,但也无疑增加了jvm中新生代的压力(增加了垃圾回收的几率)

2)普通代码中使用加号连接字符串会被jvm优化成使用StringBuilder拼接

13. 局域网拷贝:

scp a.tar root@局域网的ip地址:/usr/local/xgj /urs/local/xgj

进入跳板机,输入l可查看外网地址和内网地址

14. nginx 所在目录:/var/nginx 或者 /etc/nginx/

日志所在目录:/var/log/nginx/access.log

15.

## 创建时间插入时更新,更新时间在更新时才更新
ALTER TABLE cdk_wd_sysapi_log_oms
    MODIFY COLUMN created_date timestamp NULL DEFAULT CURRENT_TIMESTAMP,
    MODIFY COLUMN last_up_date timestamp NULL DEFAULT null ON UPDATE CURRENT_TIMESTAMP;

16. 一个普通的bean, 能否作为map的key?  需要注意什么?

重写equals和hashcode方法

17. synchronized 方法的实现是在锁定的对象上加锁, 方式锁定对象的最开始的两位设置为锁, 俗称markWord

  • 对于同步方法,锁是当前实例对象 this。 
  • 对于静态同步方法,锁是当前对象的Class对象 this.XX.class。
  • 对于同步方法块,锁是Synchonized括号里配置的对象 。
  • 锁定方法和非锁定方法 可同时执行
  • 锁升级: 偏向锁-->自旋锁 -->重量级锁(操作耗时太长, 用重量级锁)
  • 原子性
  • String,Integer, Long 等不能用sychronized

17.2 volatile : 两个特点

  1. 保证可见性:缓存一致性协议
  2. 禁止指令重排: 单例模式下, double check Lock时 ,一般情况下能保证线程安全, 超高并发下, 可能会有问题, 原因:new Instance() 很不幸它并不是一个原子操作,其实际上可以抽象为下面几条JVM指令:(读写屏障)
     
memory =allocate(); //1:分配对象的内存空间

ctorInstance(memory); //2:初始化对象

instance =memory; //3:设置instance指向刚分配的内存地址

我们可以看出 第一条指令对第二条指令有依赖关系,但是第二条指令与第三条指令并没有依赖关系,所以根据JVM指令重排的规矩可以对第二条与第三条指令的执行顺序进行交换,这样看起来没有什么问题,但是在多线程中这样就会产生问题了

我们假定有两个线程,第一个线程调用单例模式的getSingInstance() 开始执行1 ->2 -> 3要是这个时候在JVM中执行的是 1 -> 3 ->2,也就是分配好内存空间后,为instance分配内存地址,这个时候线程二抢占cpu资源,执行getSingInstacne发现instance不为空 就会返回instance,这个时候返回的instanc还没进行初始化,肯定会报错了

解决方案
给单例类中引用的instance加上volatile关键字,volatile关键字有一个作用就是防止JVM对其进行指令重排序
在 volatile 变量的赋值操作后面会有一个内存屏障,大多数的处理器都支持内存屏障的指令。

单例模式: 有懒汉模式,饿汉模式

17.3 CAS : compare and set: 比较并且设定, 无锁优化 自旋, 利用CPU原语Unsafe; Automic方法是使用CAS,
 

 18. @Transactional 注解加在private方法上不起作用;

serviceA.methdA 里面调用本类方法@Transactional .methodB,  如果不加serviceA. , 则事务注解不起作用, 需要serviceA.methB调用. serviceB 本类注入使用延迟注入注解@Lazy

19. 1.  oracle: mybatis中用Map接收oracle的结果集key默认是大写的: select name  as   "name" from detail;   这样处理即可,注意是双引号,    as   "name"

20:  ZK保证一致性, 但不能保证可用性: 因为可能master与其他集群失去联系, 此时会重新推荐master 导致整个zk不可用,  

Eureka 保证可用性: 各个节点平衡, 如果挂掉一个, 其他不受影响, 所以服务会一直可用;

21. on duplicate key update  存在即修改。但是当修改时,数据库中没有字段值变化,即返回的影响行为0时,这时是不返回主键的!!!!!!

所以要确保一定有主键返回,就必须让mysql有影响行

on duplicate key update  修改时如果原值保存,就不能确保一定有字段值更新,就不保证一定有影响行,确保影响行就是加上更新时间字段,每次带上。updated_at = NOW(); 最为合适

请不要依赖Mysql  datetime的 修改自动填入值 (ON UPDATE CURRENT_TIMESTAMP),因为影响行依然为0;

22. truncate = drop+create, 是新建了一张表, 自增主键会从1开始;

delete 是一行一行的删除, 自增主键不会重置, 会继续

trop 直接删除了表, 表不存在;

23. ulimit -a 查看inginx最大接入量

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值