极客996

极客996

  • 22文章
  • 1评论
  • 1080文章浏览
我们走后,他们会给你们修学校和医院,会提高你们的工资,这不是因为他们良心发现,也不是因为他们变成了好人,而是因为我们来过

置顶牢记SOLID原则

设计模式之SOLID原则 介绍 设计模式中的SOLID原则,分别是单一原则、开闭原则、里氏替换原则、接口隔离原则、依赖倒置原则。前辈们总结出来的,遵循五大原则可以使程序解决紧耦合,更加健壮。 SRP 单一责任原则 OCP 开放封闭原则 LSP 里氏替换原则 ISP 接口隔离原则 DIP 依赖倒置原则 单一责任原则 指的是一个类或者一个方法只做一件事。如果一个类承担的职责过多,就等于把这些职责耦合在一起,一个职责的变化就可能抑制或者削弱这个类完成其他职责的能力。例如餐厅服务员负责把订单给厨师去做,而不是服务员又要订单又要炒菜。 开放封闭原则 对扩展开放,对修改关闭。意为一个类独立之后就不应该去修改它,而是以扩展的方式适应新需求。例如一开始做了普通计算器程序,突然添加新需求,要再做一个程序员计算器,这时不应该修改普通计算器内部,应该使用面向接口编程,组合实现扩展。 里氏替换原则 所有基类出现的地方都可以用派生类替换而不会程序产生错误。子类可以扩展父类的功能,但不能改变父类原有的功能。例如机动车必须有轮胎和发动机,子类宝马和奔驰不应该改写没轮胎或者没发动机。 接口隔离原则 类不应该依赖不需要的接口,知道越少越好。例如电话接口只约束接电话和挂电话,不需要让依赖者知道还有通讯录。 依赖倒置原则 指的是高级模块不应该依赖低级模块,而是依赖抽象。抽象不能依赖细节,细节要依赖抽象。比如类A内有类B对象,称为类A依赖类B,但是不应该这样做,而是选择类A去依赖抽象。例如垃圾收集器不管垃圾是什么类型,要是垃圾就行。 总述 没人写一款程序能完全遵守SOLID原则,甚至有些设计模式是违反SOLID原则。如何权衡就要看利是否大于弊。不足之处望指教。

Rick  23  2020-10-10 阅读全文

类、对象、实例的关系

一句话概括:类是对象的抽象,对象是类的实例 好比我们的.class文件,未被虚拟机加载的时候他是不存在的,是对对象的一种描述形式,当对象被创建后,是真是存在虚拟机当中,也就是.class的实例。 比如 Object obj=new Object(); 类:Object.class 对象:obj 实例:new Object();

Rick  10  2020-10-13 阅读全文

反码与补码

这个东西看多了头疼,用自己比较好理解的方式记下 无符号数与有符号数,用1byte举例,1和-1 0000 00001 1 1000 00001 -1 原码 在8位二进制中他们原来的二进制码 无符号位 0000 0001 1 无符号位 1000 0001 -1 反码 正数的反码不变,负数的符号位不变,其余位取反 无符号位 0000 0001 1 有符号位 1111 1110 -127 补码 正数的补码不变,负数的反码+1 无符号位 0000 0001 1 有符号位 1111 1111 -128 为什么要补码? 方便计算机进行位运算

Rick  2020-10-13 阅读全文

浅谈Java AtomicInteger中的CAS实现过程

开始之前先说下AtomicInteger类中的几个成员

 private static final Unsafe unsafe = Unsafe.getUnsafe(); //Unsage是Java中用来直接对内存进行管理的一个对象
private static final long valueOffset;   //偏移量,存储数据的内存地址就是对象+偏移量来获取的
private volatile int value;           //用来获取valueOffset的偏移地址,可通过偏移地址直接获取这个值 //demo

public static void main(String[] args) {
        AtomicInteger atomicInteger = new AtomicInteger(5);
        System.out.println(atomicInteger.compareAndSet(5, 100) + "\t current data:" + atomicInteger.get()); //true	 current data:100

        System.out.println(atomicInteger.compareAndSet(5, 200) + "\t current data:" + atomicInteger.get());//false	 current data:100
    }



 
//源码

/*
 * 
 *  expect 期望的值 
 *  update 更新的值 
 *  
 */

public final boolean compareAndSet(int expect, int update) {
        return unsafe.compareAndSwapInt(this, valueOffset, expect, update);
    }


/*
 * 
 *  compareAndSwapInt这个是本地方法,作用是通过对象和偏移地址获取value后与期望值expect比较
 *  如果相等将内存中的值替换为update
 */
  public final native boolean compareAndSwapInt(Object var1, long var2, int var4, int var5);

Rick  12  2020-10-12 阅读全文

对象锁如何理解?

/**
 * 对象锁: 多个线程访问同一个实例对象会对该实例对象的锁进行竞争,谁先拿到谁就能操作上锁的资源
 * 
 * 以下是三种对象锁的设置方式
 */

public class ObjectLock {
    private Object lock = new Object();

    /**
     * 1.锁住非静态变量
     *
     * @throws InterruptedException
     */
    public void lockObjectField() throws InterruptedException {
        synchronized (lock) {
            System.out.println(Thread.currentThread().getName());
            Thread.sleep(2 * 1000);
        }
    }

    /**
     * 2.锁住 this 对象 this 就是当前对象实例
     *
     * @throws InterruptedException
     */
    public void lockThis() throws InterruptedException {
        synchronized (this) {
            System.out.println(Thread.currentThread().getName());
            Thread.sleep(2 * 1000);
        }
    }

    /**
     * 3.直接锁住非静态方法
     *
     * @throws InterruptedException
     */
    public synchronized void methodLock() throws InterruptedException {
        System.out.println(Thread.currentThread().getName());
        Thread.sleep(2 * 1000);
    }

    public static void main(String[] args) {
        //创建线程共享的资源
        ObjectLock objectLock = new ObjectLock();
        for (int i = 0; i < 5; i++) {
            //创建多线程访问同一个对象
            Thread worker = new Thread(new ObjectLockWorker(objectLock));
            worker.setName("geek996-" + i);
            worker.start();
        }
    }

    public static class ObjectLockWorker implements Runnable {
        ObjectLock objectLock;
        public ObjectLockWorker(ObjectLock objectLock) {
            this.objectLock = objectLock;
        }

        @Override
        public void run() {
            //访问锁资源
            try {
                // 方式 1
                objectLock.lockObjectField();
                //方式 2
                objectLock.lockThis();
                // 方式 3
//                objectLock.methodLock();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}

Rick  12  2020-10-12 阅读全文

Mysql——使用ngram解析器创建全文索引模拟搜索引擎查询

开始之前,先说一下全文索引的版本、存储引擎、数据类型的支持情况 MySQL 5.6 以前的版本,只有 MyISAM 存储引擎支持全文索引; MySQL 5.6 及以后的版本,MyISAM 和 InnoDB 存储引擎均支持全文索引; 只有字段的数据类型为 char、varchar、text 及其系列才可以建全文索引。 为什么要使用ngram解析器? 内置的MySQL全文解析器使用单词之间的空格作为分隔符来确定单词的开始和结束位置,这在处理不使用单词分隔符的表意文字语言时是一个限制。为了解决这个限制,MySQL提供了一个ngram全文解析器,它支持中文、日文和韩文(CJK)。InnoDB和MyISAM支持ngram全文解析器。 索引需要了解的参数 # 参数名称 默认值 最小值 最大值 作用 1 ft_min_word_len 4 1 3600 MyISAM 引擎表全文索引包含的最小词长度 2 ft_query_expansion_limit 20 0 1000 MyISAM引擎表使用 with query expansion 进行全文搜索的最大匹配数 3 innodb_ft_min_token_size 3 0 16 InnoDB 引擎表全文索引包含的最小词长度 4 innodb_ft_max_token_size 84 10 84 InnoDB 引擎表全文索引包含的最大词长度 5 ngram_token_size 2 1 10 使用ngram解析器创建的索引时,以上四种参数不生效。如果你想通过单个词匹配,将该值设置为1 6 INNODB_FT_DEFAULT_STOPWORD 在InnoDB表上创建FULLTEXT索引所使用的默认停止字表。通俗点就是用里面的词进行索引查询直接返回空 如何理解ngram_token_sizez这个参数? 例词 '信息系统' 在设置为不同值时的分词情况     ngram_token_size=1 : '信', '息', '系', '统'     ngram_token_size=2 : '信息', '息系', '系统';     ngram_token_size=3 : '信息系', '息系统';     ngram_token_size=4 : '信息系统'; 创建方式全文索引方式 ALTER TABLE user_message ADD FULLTEXT INDEX msg_content_idx (content); //常规创建
ALTER TABLE user_message ADD FULLTEXT INDEX msg_content_idx (content) with PARSER ngram; //ngram创建 使用全文索引查询(非ngram解析器同样适用,不过结果不同,达不到我们想要的效果-例如搜索引擎) select * from user_message where MATCH(content) AGAINST('+服' IN BOOLEAN MODE) //通配符搜索模式

select * from user_message where MATCH(content) AGAINST('服* 生日' IN NATURAL LANGUAGE MODE ) //自然语言搜索模式
 对比下效果,为了方便测试索引参数均设置为1 常规分析器 select * from user_message where MATCH(content) AGAINST('今天你生日' IN NATURAL LANGUAGE MODE) //无法匹配数据
 select * from user_message where MATCH(content) AGAINST('今天你生日啊' IN NATURAL LANGUAGE MODE) //常规解析器支持全文匹配 select * from user_message where MATCH(content) AGAINST('[email protected]' IN NATURAL LANGUAGE MODE)  //支持非中文自然语言匹配/通配符匹配 ngram分析器 select * from user_message where MATCH(content) AGAINST('生日' IN NATURAL LANGUAGE MODE)
select * from user_message where MATCH(content) AGAINST('日生' IN NATURAL LANGUAGE MODE) 以上查询结果一样 部分测试代码 ALTER TABLE user_message ADD FULLTEXT INDEX msg_content_idx (content)  ;


select  * from user_message where content like '生日';

select * from user_message where MATCH(content) AGAINST('dd fff geek996' IN NATURAL LANGUAGE MODE)
select * from user_message where MATCH(content) AGAINST('日 生 别' IN NATURAL LANGUAGE MODE)

drop index msg_content_idx on user_message ; 

SELECT * FROM information_schema.`INNODB_FT_INDEX_TABLE`; 总结:了解ngram之后不经意看到ElsaticSearch ,技术互通性还是挺大的。

Rick  24  2020-10-11 阅读全文

Java设计模式——抽象工厂模式

抽象工厂模式应该如何理解原理? 根据我的理解可以分为已下几个关注点: 1.抽象工厂—定义生产的抽象产品,一般为一个产品族 2.具体工厂—实现抽象工厂,一般用于获取每个类型的产品 3.抽象产品—抽象产品类型并集为一个产品族 4.具体产品—抽象产品的具体实现 使用场景:某家服饰公司要生产鞋、衣服、裤子等服装,服装又分婴儿、儿童、成人,请问应该如何设计? 下面是我的设计思路,

Rick  24  2020-10-11 阅读全文