精华内容
下载资源
问答
  • 编程笔记
    千次阅读
    2021-09-20 23:15:28

    1.查看电脑当前进程和端口cmd netstat -pid netstat -a  查看全部端口信息:netstat –ano

    2.创建文件夹 mkdir 文件名或文件路径

    3.删除文件夹 rmdir

    4.删除文件 del

    5.打开计算机calc

    6.打开画图mspaint

    7.用echo "写入新数据">d:\a.txt,echo 字符串 >文件路径 文件名(会覆盖原内容)

    8.用echo "写入新数据">>d:\a.txt,echo 字符串 >文件路径 文件名(不会覆盖原内容,添加到后面)

    9.powershell和cmd功能类似

    10.架构师需要关注编程语言的版本,初学者不要关注版本,只需要学会常用版本

    11.java简单易用,健壮性,开源,跨平台

    12.java源文件后缀是.java,编译文件后缀是.class由JVM虚拟机运行,常用虚拟机是ORACLE版本的

    13.JVM不是跨平台的,各种平台系统有对应的JVM

    14.jdk是java开发核心工具包

    15.Mysql数据库里的is仅用在is null或is not null,=用在2种情况下:一是判断值是否相等 where id=1;二是用于赋值set id=1

    16.bin目录里面有.class可执行文件,src里面有.java源码文件。

    17.//alt+/表示补全代码,//ctrl+F11表示执行代码

    18.程序的主方法就相当于入口,相当于进入房间的大门,只允许一个大门。

    19.用来分析当前进程占用内存的数据统计excel统计表的powershell命令如下:

    # create new excel instance

    $objExcel = New-Object -comobject Excel.Application

    $objExcel.Visible = $True

    $objWorkbook = $objExcel.Workbooks.Add()

    $objWorksheet = $objWorkbook.Worksheets.Item(1)

    # write information to the excel file

    $i = 0

    $first10 = (ps | sort ws -Descending | select -first 10)

    $first10 | foreach -Process {$i++; $objWorksheet.Cells.Item($i,1) = $_.name; $objWorksheet.Cells.Item($i,2) = $_.ws}

    $otherMem = (ps | measure ws -s).Sum - ($first10 | measure ws -s).Sum

    $objWorksheet.Cells.Item(11,1) = "Others"; $objWorksheet.Cells.Item(11,2) = $otherMem

    # draw the pie chart

    $objCharts = $objWorksheet.ChartObjects()

    $objChart = $objCharts.Add(0, 0, 500, 300)

    $objChart.Chart.SetSourceData($objWorksheet.range("A1:B11"), 2)

    $objChart.Chart.ChartType = 70

    $objChart.Chart.ApplyDataLabels(5)

    20.项目峰会,接口设计,算法和数据结构设计,数据库设计,原型设计

    21.eclipse,syso+alt+/打印输出快捷键

    22.后缀.java的源文件在按ctrl+s时会触发编译,编译生成.class字节码文件,在按Ctrl+F11后JVM虚拟机会执行.class字节码文件

    23.文档注释格式 (斜杠/+2个*+内容+1个*+斜杠/)举例:/**文档注释 author ***  2021年4月30日*/

       多行注释格式 (斜杠/+1个*+内容+1个*+斜杠/)举例:/*多行注释 练习map遍历*/

    24.位(比特) bit,来自英文bit,音译为“比特”,表示二进制位。比特是英文 binary digit的缩写。比特是表示信息的最小单位,

       是二进制数的一位包含的信息或2个选项中特别指定1个的需要信息量。一般来说,n比特的信息量可以表现出2的n次方种选择。

       Byte字节,1Byte = 8Bits (1字节 = 8位)  8字节=64位,4字节=32位

    25.java共有53个关键字,2个保留字const或goto,8个基本数据类型,单行注释,多行注释,文档注释

    26.0b开头表示2进制数,0开头表示8进制数,0x表示16进制数,\u表示char类型数据

    27.byte/short/char 三种比int范围小的数,在运算时会自动提升为int类型;

    28.java里整数不能除以0,浮点数可以除以0,结果是无穷大,Infinity是无穷大

    29.代码中的命名严禁使用拼音和英文混合。比如DaZheModule这样就是错误的。

    30.0.0除以0或0.0除以0结果是NaN表示Not a Number;

    31.类名大驼峰,方法名小驼峰,变量名小驼峰,常量名全大写

    32.alt+↓,向下移动某行代码alt+↑表示向上移动某行代码,ctrl+d删除某行代码,alt+/补全代码

    33.java跨平台的含义:一份代码,处处运行。

    34.变量不能只申明不赋值; 不赋值,不使用就不要申明,否则会浪费内存空间。

    35.数据小转大没问题,但是大转小可能会溢出。

    36.方法内部的变量是局部变量,方法之外的是全局变量。

    37.静态web资源是指:千人一面的,不同人不同条件下访问的内容一样,比如百度首页,京东首页

       动态web资源是指:千人千面,不同的人在不同条件下访问的内容不一样,比如淘宝的订单页,收藏页,因为带有用户的属性.

    38.小到大,直接转;大到小,强制转; 浮变整,小数没

       低 ------------------------------------> 高

       byte,short,char→ int→ long→float→double(boolean不能类型转换)

    39.1?2:3表示三元运算符;?前面是条件表达式1;若条件为真计算结果为2;若条件为假计算结果为3。

    40.同一个类中,两个方法名相同,参数类型相同,只是形参名不同,这样的两个方法不是方法的重载。

    41.同一个类中,两个方法名相同,参数个数不同,一定构成重载。

    42.同一个类中,两个方法名相同,参数个数相同,要看参数类型才能确定是否为方法的重载。

    43.局部变量:

       位置:定义在方法里或局部代码块中,必须手动初始化来分配内存,如int i=5;

       作用域:在方法里或代码块之内有效,方法运行完内存就释放了。

    44.成员变量:

       位置:定义在类里,方法外

       不用手动初始化,也会被自动初始化为默认值,作用域:在类中有效,类消失,成员变量会被释放

    45.java里8种基本数据类型,整数型byte short int long  浮点型float double 字符型char 布尔型boolean

         整数的默认字面值是int,小数的默认字面值是double,byte short char 在运算时会提升为int类型

        a=a+b这种如果两边类型不同的话,可能会报错,但是a+=b这种会自动进行类型转换.

    46.java里面的switch case 分支结构如果case后面没有加break,那么会向下穿透依次执行,就像糖葫芦一样.

    47.java里面给程序添加断点,双击行数列左边的蓝色区域确定断点,然后点击小虫子debug图标.

    48.switch(分支条件){ //分支条件可以是byte short char int String 5种数据类型,不能是布尔类型.

         case表达式1:语句1;break;

         case表达式2:语句2;break;

         case表达式3:语句3;break;

         default:语句4;break;}

    49.for循环里的统计数量的count,用count++或者++count或者count=count+1都行,但是常用count++,因为都是循环结束再返回统计结果。

    50.java里的parallelSort 和 sort 哪个更快,取决于待排序的数据的规模,以及可以利用的核数。parallelsort(并行排序) 会利用多线程优势,将原始数据

       分为多个子数组,子数组内在利用类似 merge & sort 方法排序,多个子数组会并行排序,所以理应更快。虽然多线程调度会带来额外开销,

       但在数据规模较大时额外开销可能会显得微不足道。具体多大的数据量应该使用 parallelsort,取决于你代码运行机器允许的资源和处理

       数据量大小,时效性要求等。如果数据量大于某个 threshold(阈值/临界点) (源码中默认是 8192),机器允许利用多核并且有较高的时效性要求,

       不妨优先使用 parallelSort。

    51.for(开始条件申明循环变量;循环条件;更改条件){循环体}

    52.方法的返回值可以不用变量接收,直接用print打印,比如println(method());

    53.//自创的另类的冒泡排序,用嵌套for循环对数组元素进行排序,(这种是把一个数组看成两个一样的数组,相当于两个手掌,左手掌和右手掌,看做两个一样的数组,左右手的手指按序进行比较)

    for(int i=0;i<b.length;i++) {

    for(int j=0;j<b.length;j++) {

    if(i<j&&b[i]>b[j]) {

    char temp=0;

    temp=b[i];

    b[i]=b[j];

    b[j]=temp;

    }

    }

    }

    System.out.println(Arrays.toString(b));

       //传统的冒泡排序,用嵌套for循环对数组元素进行排序,这种效率高一点点!!!

    for(int i=1;i<=b.length-1;i++) {

    for(int j=0;j<b.length-i;j++) {

    if(b[j]>b[j+1]) {

    char temp=0;

    temp=b[j+1];

    b[j+1]=b[j];

    b[j]=temp;

    }

    }

    }

    System.out.println("这是用传统冒泡排序进行升序排序");

    System.out.println(Arrays.toString(b));

    54.break和continue之后都不允许写代码,因为在它们之后的代码是无法到达和执行的unreachable.

    55.return可以返回方法的返回值,同时结束方法。

    56.程序报出空指针异常,nullpointer异常,都是因为某个变量或某个对象没有申明或者没有new,导致没有创建内存空间。

    57.do while循环格式,do{循环体}while(循环条件);注意最右边有分号,do while至少执行一次。

    58.三种循环的区别:

       for:知道循环次数

       while/do while:当循环次数不确定时

       while:先判断,不符合规则,不执行代码

       do while:代码最少被执行一次,再去判断,符合规则,再次执行代码

       循环之间都可以互相替代,但是一般最好选择合适的循环结构来完成代码.

    59.冒泡排序,外循环i 循环1到(length-1)轮,内循环j 循环0到(length-i-1)轮,在内循环中交换顺序,内循环是相邻元素比较,所以j下标从0开始

    例子:原始数组:[99,97,95,92,90,86,82],内循环的轮数是递减的

    97,95,92,90,86,82,99,7个数,外循环第i=1轮,内循环相邻2个数比较0到length-i-1=6轮

    95,92,90,86,82,97,99,7个数,外循环第i=2轮,内循环相邻2个数比较0到length-i-1=5次     

    92,90,86,82,95,97,99,7个数,外循环第i=3轮,内循环相邻2个数比较0到length-i-1=4次

    90,86,82,92,95,97,99,7个数,外循环第i=4轮,内循环相邻2个数比较0到length-i-1=3次

    86,82,90,92,95,97,99,7个数,外循环第i=5轮,内循环相邻2个数比较0到length-i-1=2次

    82,86,90,92,95,97,99,7个数,外循环第i=6轮,内循环相邻2个数比较0到length-i-1=1次

    60. 八大基本类型字节大小:

        byte 1字节,short 2字节,char 2字节,int 4字节,

        long 8字节,float 4字节,double 8字节,boolean 1个字节。

    61.数组的工具类Arrays,数组的名称Array,标志[].

    62.for循环和while循环可以互相替代,包括嵌套的for循环也可以用嵌套的while循环替代,只是两者设置的循环条件的放置顺序不一样.

    63.面向对象的三大特征:封装,继承,多态

    64.什么是面向对象:把功能按类型封装起来装箱作为一个工具箱,比如工具箱里装:

        起子 扳手 钳子 锤子 螺丝 钉子 等,需要干什么活只需要拿出对应的工具就行。

    65.类相当于设计图纸或者模板,对象相当于按照图纸生产的产品的实例。

    66.类是一类事物的抽象,对象是具体的实现。

    67.栈内存:先进后出,Firt in Last Out,存储:方法/局部变量/地址

       堆内存:先进先出,First in First Out,存储:对象(对象的属性和方法)

    68.创建对象时,内存经历了什么:

       a.在栈内存中开辟一个块空间,存放引用类型变量var,并把它压入栈底

       b.在堆内存中开辟一个块空间,存放类的对象

       c.完成对象的实例化/初始化,并赋予默认值

       d.给初始化完毕的对象赋予唯一的地址值

       e.把地址值交给引用类型变量var保存,该地址指向堆中的对象

    69.报错的常见英语单词:visible,nullPointerException,

    70.类-一类事物的抽象-模板

       1.创建类

       2.创建类的属性

       3.封装类的属性

       4.提供set和get方法,toString,hashcode,.equal等方法.

       5.提供类的一些方法/功能

       创建对象(类的实例化)

       如果封装了私有属性的话:

       通过对象调用方法

       1.可以调用set方法设置私有属性的值

       2.可以调用get方法获取私有属性的值

       3.可以调用普通方法执行对应的功能

       4.私有的方法可以在类的公有方法里调用,间接的对外提供私有方法的调用。

    71.私有方法如果不放在公有的方法中调用,那么对外就无法调用,程序设计就有问题。

    71.面向过程:思想-干活的主体是自己(属性和方法分离),面向对象:干活的不是自己,我们是指挥者不是干活的。

    72.类:把一类事物抽象成一个类型-模板/图纸,对象:根据图纸创建的实例。

    73.无参构造方法不写也是有的,默认存在无参构造,

       构造方法是没有返回值类型的不能用void修饰,构造方法也可以重载。

    74.同一个类可以有任意个构造方法(任意个的构造方法重载)。

    75.构造方法主要用来创建对象和完成属性初始化

    76.当只提供了含参构造方法时,无参构造方法会被覆盖,

        所以在创建重载的构造方法时,需要手动的创建无参构造。

    77.构造方法的方法体里可以调用成员方法包括私有的成员方法。

    78.重载让程序更灵活,但也容易导致混淆和脆弱。

    79.无参构造是默认存在的,不写也有,但是如果写了含参构造,无参会被覆盖

    80.创建对象时构造方法会被立即执行。

    81.构造代码块含义:

       *1.每次创建对象,都会执行一次构造代码块

       *2.它的位置在类里方法外,用一对花括号括起来

       *3.用于提取所有构造方法中的共性内容

       *4.构造代码块优先于构造方法执行。

    82.当创建对象时,程序会自动调用构造方法,

       但是如果有构造代码块,会先执行构造代码块,再执行构造方法。

    83.当通过对象调用方法时,会执行方法中的功能,如果方法中有局部代码块会执行此局部代码块。

    84.执行顺序:构造代码块-->构造方法-->局部代码块

    85.局部代码块含义:

       * 1.局部代码块在方法里,用一对花括号括起来,作用域只限于括号之内

       * 2.局部代码作用:是用来控制变量的作用范围(作用范围越小越好,因为越小越安全)

       * 3.局部代码作用执行时机:调用方法时。

    86.Java类编码流程:

       1.抽取形成类,如Phone/Student/Teacher/Person

       2.成员属性,可以封装

       3.构造方法

       4.构造代码块

       5.成员方法

    87.this的用法:this表示当前类,可以用this.调用当前类的成员属性和成员方法

       a.当一个类存在同名的两个变量:一个是成员变量,一个是局部变量,

         如果想要使用成员变量,可以用:this.成员变量 进行指定

       b.如果想在无参构造中调用含参构造,写上:this(参数),this语句必须在构造方法里的第一行

       c.如果想在含参构造中调用无参构造,写上:this(),this语句必须在构造方法里的第一行

       d.无参里调含参,或者含参里调无参,只能二选一或不选,不能二选二,否则就是死锁/死循环。

    88.Java里的继承:

       1.只能单继承,一脉相传:爸爸/儿子/孙子,一个子类只能有一个直接父类,

         父类的私有资源,子类不可见,是一种is A的强耦合关系。

       2.子类可以有自己独有的方法和属性,子类可以重写父类的同名方法。

    89.在子类中使用父类的成员属性或方法,需要使用super指定,super是表示父类的一个对象的引用。

        super.成员属性=value,这种赋值要写在成员方法里,如果写在构造方法或构造代码块中,赋的是初始默认值null或0或空。

    90.构造方法可以重载,全参构造一般用于给对象的全属性赋值。

    91.权限修饰符,权限由大到小排名:

       *public(同类 同包 子类 其他工程)

       *protected(同类 同包 子类)

       *缺省(同类 同包)缺省就是没有修饰符

       *private(同类)

    92.软件编程的OCP原则,面向功能修改关闭,面向功能拓展开放,只允许功能拓展,不允许修改原来的。

       *这个功能的修改被称作方法的重写*重写和父类的方法签名一致*

       *修改的是子类的功能,父类的功能没有改变。

       *重写时,子类必须有权限去重写父类的功能,父类的private和final方法不能被重写。

       *子类的方法修饰符权限>=父类被重写方法的修饰符权限,

       *子类继承父类方法时不能降低父类方法的可见性。

       *子类重写父类方法只是修改了子类的功能,父类的功能不被影响。

       *重写父类方法时不能改变方法的名字和返回值。

    93.父类的构造方法不能被子类继承。

    94.子类的构造方法中,默认存在super(),也就是创建子类对象时会默认调用父类的无参构造。

    95.如果父类中没有无参构造,这时调用的就是含参构造super(实参),super(实参)这种需要写才存在。

    96.创建子类对象时默认会先看父类的无参构造方法。

    97.如果发生了重写,还需要调用父类的方法,要使用super.来调用。

    98.*this("")代表调用本类的含参构造,括号需要加上实参

       *this() 代表调用本类的无参构造

       *super() 代表调用父类的无参构造

       *super("") 代表调用父类的含参构造,括号需要加上实参

       *this 和super调用方法时必须写在第一行,二选一,两个不能都写。

    99.static资源也就是类的静态资源,静态资源特征:

       * 可以修饰成员变量与成员方法

       * 随着类的加载而加载,优先于对象加载

       * 只加载一次,就会一直存在,不再开辟新空间, 直到类消失才一起消失

       * 静态资源也叫做类资源,全局唯一,被类所有对象共享

       * 可以直接被类名调用

       * 静态只能调用静态,非静态可以随意调用(非静态或静态)

       * static不能和this或者super共用,因为有static时可能还没有对象

    100.静态代码块 构造代码块 构造方法 普通方法 局部代码块的加载顺序:

       * 在创建对象之前会自动加载静态代码块static{},且只加载一次

       * 在创建对象时会自动调用构造代码块和构造方法,构造代码块先执行

       * 当通过对象调用方法时,若方法里有局部代码块,局部代码块才会执行

       * 再次创建对象,静态代码块也不会再加载了*/

       * 代码块的执行顺序:静态代码块-->构造代码块-->构造方法-->普通方法-->局部代码块。

    101.如何判断一个方法该不该写返回值?没有强制要求,写不写返回值取决于程序设计的思路

        如果想在方法外部继续使用这个方法的结果,就需要写返回值。

        如果只是在方法调用时输出结果,就无需返回值。

    102.main方法是入口函数,也必须用static修饰

    103.静态资源里面不能写super.和this.因为静态资源优先于对象加载,那时候还没有产生对象

    105.父类和子类的各种代码块执行顺序:

        a.父类静态代码块

        b.子类静态代码块

        c.父类构造代码块

        d.父类构造方法

        e.子类构造代码块

        f.子类构造方法

        g.子类重写父类的方法

        h.子类局部代码块

    106.private让子类不能用,final让子类不能改

    107.多态的前提条件:1.要有子类继承父类 2.要有方法的重写

    108.多态的特征:1.父类引用指向子类对象 2.编译看左边运行看右边

    109.多态的例子:例如 花木兰替父从军,用父亲的名义去参军打仗,只能用父亲的方法

    110.异常的继承结构:

        Throwable:可抛出

             -Erro:系统错误,不可修复错误

             -Exception:可修复错误

              -RunTimeException:运行时异常,这类异常不受检查

               -ClassCastException

               -ClassNotFoundException

    111.遇到异常要么向上抛出throw,要么捕获try{代码块} catch{异常类型 异常名}{解决方案}

    112.同一种事务的多种表现形式,可以把子类当做父类来看,统一/简化调用标准。

    113.实现多态的前提:继承+重写,多态特点:父类引用指向子类对象,编译看左运行看右

    114.多态的使用:成员变量是父类的,成员方法:父类的声明&子类的实现,

        多态中如果父子类中都有同名静态方法,调用的静态方法使用的是父类的。

    115.多态:Father f=new Son();把子类对象赋给父类引用属于向上转型。

        Son s=(Son)f;把父类引用f强转为子类Son对象,属于向下强制转型。

    116.静态方法可以继承,但是静态方法不能被重写,父类和子类可以有同名的静态方法,静态方法直接用类名.调用

    117.抽象类中可以没有抽象方法,抽象类不能实例化,不能创建对象

    118.抽象方法要求子类继承后必须实现抽象方法,

        private:私有资源,子类不可见不可继承,但是abstract类需要子类来实现,这样就矛盾

        final:final资源不可被继承,但是abstract需要子类来实现,这样就矛盾,所以不能与abstract搭配

        static:静态优先于对象存在,所以abstract不能与static搭配使用

    119.接口与接口的关系:

        是继承关系,可以单继承,也可以多继承

    interface A extends B,C{}

    其中ABC都是接口,

        A是子接口,具有B,C接口的所有功能(抽象方法)

    class X implements A{}

    X实现类需要重写ABC接口的所有方法,

        否则就是抽象类

    class A extends B implements C,D{}

    其中A是实现类,也是B的子类,同时拥有CD接口的所有

        功能

    这时A需要重写CD接口里的所有抽象方法

    120.抽象类与接口的区别:

        抽象类是一个特殊的类,特殊在抽象类中可以包含没有方法体的方法(抽象方法)

        接口可以理解成一个特殊的抽象类,特殊在接口里的都是抽象方法,java8以前接口里没有普通方法

        接口里会为抽象方法自动拼接public abstract,还会为变量自动拼接public final static

        抽象类可以有构造方法,用来给子类创建对象,接口中没有构造方法,接口的实现类调用的Object类的构造

        抽象类和接口都不能实例化就是不能创建对象

        接口可继承接口,并可继承多个接口,但类/抽象类只能单继承

        接口是设计的结果,抽象类是重构的结果

        接口一般先继承再实现,面向接口编程,创建接口,抽取共性,形成抽象层,体现接口。

    121.idea里面的project是工作空间而不是工程,这个跟eclipse不同。

    121.数组的定义书写

        *一维数组:1)int[] x;2)int x[];

        *二维数组:1)int[][] y;2)int y[][];3)int[]y[]

        *例:int[] x,y[];? ?//定义了一维数组x,二维数组y

    122.返回值是引用类型时,子类的返回值类型要小于/等于父类的返回值类型

    123.子类的异常抛出的类型要小于/等于父类的抛出异常的类型

    124.子类重写父类的方法时,子类的方法可见范围要大于等于父类的方法的可见范围,

        比如父类方法是protected,子类可以是public。

    125.二维数组里面的一维数组长度可以不一样。

    126.数组的长度可以为0,比如String [] s=new String[0];

    127.String类重写了equlas(),默认比较的是值,如果值相同,则比较结果为true.而==比较的是两个对象的地址值。

    128.正则表达式的组件可以是单个的字符、字符集合、字符范围、字符间的选择或者所有这些组件的任意组合。

    129.FileOutputStream(String name) 创建一个向具有指定名称的文件中写入数据的输出文件流。

           FileOutputStream(File file) 创建一个向指定 File 对象表示的文件中写出数据的文件输出流。

           FileOutputStream(File file, boolean append)创建一个向指定 File 对象表示的文件中写入数据的文件输出流。

    130.代码块执行顺序是:静态代码块 > 构造代码块 > 构造方法。

    131.Java 中的字节流处理的最基本单位为 1 个字节,通常用来处理二进制数据,字节流操作的基本单元是字节

          字节流类 InputStream 和 OutputStream 类均为抽象类,代表了基本的输入字节流和输出字节流 ,

         Java 中的字符流处理的最基本的单元是 Unicode 代码单元(大小2字节),通常用来处理文本数据。

         字符流操作的基本单元是字符,字节流默认不使用缓冲区,字符流使用缓冲区

         按行处理、比较特定字符的时候一般会选择字符流;仅仅读写文件,不处理内容,一般选择字节流

    132.流都是单方向的,所以输入流只能用来读取数据,输出数据只能用输出流。

    133.Java编码顺序:

        1.)抽取共性形成类:如Phone/Student/Teacher,类名是大驼峰。

        2.)属性:成员变量,属性可以是基本类型变量,也可以是对象,私有属性可以封装,并提供公有set,get方法

        3.)静态代码块:类加载的时候加载,只加载一次,静态资源在类对象中是共享的

        4.)构造代码块:用于提取构造方法中的共性内容,如果有共性需要提取,可以写构造代码块。

        5.)构造方法:无参和含参,用于本类或子类创建对象用

        6.)普通方法/成员方法:完成一些业务功能。

        7.)局部代码块:要写在方法里,用一对花括号括起来,调用方法时才执行。

    134.面向对象三大特征:

        封装:private,私有标记

        继承:extends,子类继承父类的属性和方法,但是私有的属性和方法不可继承

        多态:向上转型/装箱,把子类对象看做父类类型-花木兰替父从军

        向下转型:(子类)多态对象

    135.多态最主要的作用是提供通用解决方案,统一调用标准。

    136.super可以理解为父类对象的一个引用,super()表示调用父类的构造方法,super(实参)调用父类含参

    137.静态资源只能调用静态资源,非静态可以调静态和非静态。

    138.重载和重写:

        重载:同一个类里,方法名相同,参数列表不同

        重写:父类和子类里,方法签名一致,方法体不同,子方法修饰符>=父方法修饰符。

    139.接口里没有成员变量,可以有常量,比如int a=10;

    140.接口不可以创建对象,一般用接口的实现类来创建对象。

    141.print方法默认会调用toString方法,该方法默认会打印对象的哈希码值整数,可以重写toString方法

    142.哈希码值可以是负数,同一个对象的哈希码值可以发生变化.

    143.==和equals的区别:

      1)对于==,如果作用于基本数据类型的变量,则直接比较其存储的 “值”是否相等;

        如果作用于引用类型的变量,则比较的是所指向的对象的地址;

      2)对于equals方法,注意:equals方法不能作用于基本数据类型的变量

        如果没有对equals方法进行重写,则比较的是引用类型的变量所指向的对象的地址;

        诸如String、Date等类对equals方法进行了重写的话,比较的是所指向的对象的内容。

    144.高效字符串StringBuffer和StringBuilder优化了String拼接的效率,时间利用效率比String快千倍。

    145.String s1="ab";String s2=new String("ab");String s3="a"+"b";String s4="a";s4+="b";

        创建字符串常量时,栈指向堆,堆指向方法区运行时常量池。

    146.String s1="ab";String s2=new String("ab");String s3="a"+"b";String s4="a";s4+="b";

        创建字符串常量时,栈指向堆,堆指向方法区运行时常量池。

    147.lang包无需导包也存在

    148.顶级父类Object中的常用方法:

        toString默认返回的是地址值,重写后是打印:类型+属性值。 

        hashCode返回哈希码值, 哈希码值是把地址转换为整数,不同对象的哈希码值不一样

        equals默认是比较地址值,重写后是比较属性值

    149.正则表达式,加了中括号[字符]表示字符取值范围,多选一/其中一个,横杠-表示从起点到终点,^表示取反或匹配行首,$匹配行尾,|表示或/并列,

        \w小写字母,\W表示排除小写字母,\d表示数字,\D表示排除数字,花括号{ }表示字符出现的次数,()括号表示分组。

        JS里面写正则表达式需要用//斜杠包起来。

    150.包装类Integer有高效的效果,高效的范围是(-128--127)在此范围内创建相同的数据的对象,

        只会存一次,后续再存都会使用之前的对象,超出范围就会重新创建对象,只有Integer有高效效果。

    151.BigDecimal的小数四则运算是精确的,普通的四则运算,遇到小数乘除会不精确

    152.BigDecimal bd1=new BigDecimal(d1+"");//用此种方式需要拼接空字符串“”否则会不精确。

    153.Stream:字节流,处理二进制数据,分为输入inputStream和输出OutputStream

        字符流:用于处理字符文件,分为输入Reader和输出Writer

        File:文件类,文件和目录(文件夹)路径名的抽象表示形式。

    154.字节流里面的读操作:int b;

                while((b=in2.read())!=-1){//这里是固定写法,表示读/赋值/判断同时进行,

                //这样才不会少读或者越界

                    char c=(char)b;

                    System.out.print(c+"*");

                }

    155.File不是抽象类,可以创建对象,比如File f=new File("path");//path可以是文件路径,

        或者不存在但要创建的路径,或者父级路径+文件名。

    156.字符读入流Reader和Writer是抽象类 不能直接new。

    157.字节流Stream也是抽象类,不能直接new

    158.字符流Reader和Writer读写复制文本文件有用,其他文件比如exe视频或者音乐图片等它搞不定

    159.字节流Stream可以读写复制二进制文件,只要是计算机的二进制文件都能读写和复制

    160.用IO流读写操作完之后,流资源必须关掉,关流是有顺序的,后创建的流先关闭

    161.FileWriter里面append参数可以加个true表示不覆盖原有数据

    162.序列化:ObjectOutputStream把对象序列化为二进制数据后输出保存到磁盘中。

        反序列化:ObjectInputStream读取磁盘中序列化的数据,并恢复为对象到程序中(内存)。

        可以用序列化和反序列化实现深拷贝.

        实际编码中用json格式序列化较多.

    163.类的对象需要如果要能序列化,必须要实现序列化的接口,implements serilizable。

    164.类属性里如果手动添加了固定的serialVersionUID,则可以多次反序列化

    165.类属性里如果没有添加serialVersionUID,则序列化和反序列化要成对每次匹配,一次序列化匹配一次反序列化。

    166.类里如果不手动添加serialVersionUID,修改类的属性(包括UID属性)之后要重新序列化,否则反序列化会报错。

    167.最后再补充两点, 哪些字段是不能被序列化的呢:

        static 修饰的, 因为序列化操作是对于堆区 ,而static的在全局区。

        transient 修饰的字段 ,在使用implements Serializable 的时候,也是避开序列化的。

    168.简单的问题用 数据结构可以解决,更难的问题需要数据结构+算法才能解决。

    169.字节流一次读一个字节,字符流一次读一个字符。

    170.泛型在编译后会被删除,所以在.class字节码文件中不存在泛型,泛型不影响JVM的运行。

    171.ArrayList底层是数组结构,查询快增删慢;LinkedList底层是链表结构增删快,查询慢。

       查询的快慢是指数据量大时的查询快慢。

    172.遍历是为了对单个元素进行处理。

    173.HashMap底层是一个Entry[ ]数组,当存放数据时,会根据hash算法来计算数据的存放位置

    算法:hash(key)%n ,

        n就是数组的长度,其实也就是集合的容量

    当计算的位置没有数据的时候,会直接存放数据

    当计算的位置,

        有数据时,会发生hash冲突/hash碰撞,解决的办法就是采用链表的结构,在对应的数据位置存放链表的头节点,

        对于这个链表来说,每次新加的节点会从头部位置开始加入,也就是说,数组中的永远是新节点.

    174.HashMap的底层结构:数组+链表(如果链表长度超过8会转成红黑树,低于6又退回链表)

    175.Hashmap的默认初始容量是16,增长因子(临界点Threshold)是0.75,比如长度达到12,也就是达到初始容量的75%

        就要扩容,每次扩容2倍,比如从16扩容成32,再扩容就是64。

    176.分时系统的线程有随机性,不分轻重缓急

    177.不同线程微观上是分时切换进行的,宏观上是同时进行的。

    178.线程的三种状态:就绪状态,运行状态,阻塞状态,终止。

        就绪相当于,乘客进了火车站候车室,运行相当于,乘客从候车室进了火车。

    179.StringBuffer或StringBuider是高效字符串里面有append(添加),reverse(逆序),insert(插入),

        replace(替换)等方法。

    180.Collection是单列集合的接口,Map是双列集合的接口,

        Collections是集合的工具类,里面有操作Collection集合的各种方法。

    180.ArrayList:线程不安全,每次增长1.5,如果无参构造,增长到10,再每次增长1.5倍,底层是可变数组

        Vector:线程安全,每次增长2倍,底层是可变数组

        HashSet:无序,单列数据,无索引,不可重复,每次增长2倍,底层是:数组+链表+红黑树

        TreeSet:有序,单列数据,数据不可重复,默认按照字典排序,元素对象需要实现Comparable接口

        HashMap:无序,双列键值对数据,不可重复,初始容量16,每次增长2倍,加载因子0.75(达到阈值就扩容),底层是:数组+链表+红黑树

        Properties:是HashTable的子类,并实现Map接口,Properties可以用于从.properties文件中读取数据并加载到对象中

    181.Comparable比较器不能用于基本数据类型的比较,基本数据类型需要转为包装类才可以比较,

        只能用于类对象的比较,需要明确比较的规则,才能比较。

    182.设计企业级散列表需要考虑的:hash冲突,空间,时间,线程安全,性能,高并发。

    183.继承Thread类

    优点: 编写简单,如果需要访问当前线程,无需使用Thread.currentThread()方法,

        直接使用this即可获得当前线程

    缺点: 自定义的线程类已继承了Thread类,所以后续无法再继承其他的类

        实现Runnable接口

    优点: 自定义的线程类只是实现了Runnable接口或Callable接口,后续还可以继承其他类,在这种方式下,

        多个线程可以共享同一个target对象,所以非常适合多个相同线程来处理同一份资源的情况,

        从而可以将CPU、代码、还有数据分开(解耦),形成清晰的模型,较好地体现了面向对象的思想

        缺点: 编程稍微复杂,如想访问当前线程,则需使用Thread.currentThread()方法

    184.如何判断程序有没有线程安全问题:

        多线程中,如果有静态共享资源,多个线程同时操作(写操作)静态共享资源,会产生线程安全问题(数据不同步导致)

    185.CPU:读取数据,数据寄存,计算,写出数据。

    186.程序:比如.exe文件,进程:进入内存的程序,线程:程序的最小单元。

    187.线程由OS操作系统调度。

    188.线程切换:保存旧线程,执行新线程,恢复旧线程。

    189.同步方法,如果一个方法里所有的代码都需要同步,那就在方法前加synchronized.

    190.同步代码块:synchronized(o){同步代码块(范围需要调试)},

        其中参数o是Object对象要在成员变量处申明。

    191.StringBuilder效率快,但是线程不安全,StringBuffer线程安全。

    192.创建线程池对象:ExecutorService pool= Executors.newFixedThreadPool(5);

        使用完线程池一定记得回收,否则跑着跑着就内存爆炸崩溃,方法:executor.shutdown();

    193.乐观锁把读和写分开,只对写操作加锁;常用的乐观锁,Lock,主要用于读操作多的场景,底层由加版本号和CAS实现.

        悲观锁,对读和写都加锁;常用的悲观锁:Sychronized,ReentrantLock,主要用于写操作多的场景.   

    194.元注解:注解语法与JAVA不同,不要套用Java语法

        @target(用在那里:类/方法/属性)描述注解存在的位置:

        ElementType.TYPE应用于类

        ElementType.METHOD应用于方法

        ElementType.FIELD应用于字段或属性

        ElementType.CONSTRUCTOR应用于构造方法

        @retention(生命周期:源文件/字节码文件)

    195.自定义注解:

        @retention

        @target

        @interface 注解名{  }

    196.给注解赋值:@Test(field=Num)

    197.线程锁:悲观锁,乐观锁,自旋锁(一个线程忙等待,消耗内存资源),

        CAS,偏向锁,轻量级锁,重量级锁(进队列等待,由操作系统实现)。

    198.同步:排队,同一时刻只有一个线程。异步:多线程抢占资源,并发。

    199.空对象null不能调用方法,否则会报空指针异常。

    200.暴力反射:getDeclaredField/Method....,获取私有的属性或者方法

    201.Function<T,U>表示函数式接口,有去有回,T是参数类型,U是返回值类型。

    202.+=,-=,*=,/=属于简写,而且在运算时会自动进行类型转换。

    203.&,|,^,与:都为1则为1,或:都为0则为0,异或:相同为0不同则为1

    204.流程控制:if else;switch case break default;for;for each;while;do while

    205.for循环里面开始条件只执行一次

    206.方法签名:方法名+参数列表,子类重写父类方法时,方法签名不能改。

    207.break:直接跳出本层循环,如果有多层循环只能跳出本层,不能全部跳出,可以指定标签。

    208.反射第一步获取字节码对象:

        方法1,Class.forName(类路径),

        方法2,类名.class,

        方法3,匿名对象.getClass,匿名对象:new 类名()

    209.反射可以把子类继承自父类的方法反射出来。

    210.外部类不能直接使用内部类的属性和方法,要用的话要在外部类里面先创建内部类的对象。

    211.创建内部类对象,要先创建外部类对象,

        例如,外部类.内部类 对象名=new 外部类()new 内部类()

    212.0b前缀表示二进制数,0x前缀表示十六进制数,0前缀表示八进制数

    213.a instancOf A:判断对象a是否属于A类

    214.静态代码块中不能使用this和super,因为静态资源优先于对象加载,静态加载时还无对象。

    215.匿名内部类通常与匿名对象一起使用,匿名对象只能使用一次。

    216.写软件就是靠思想,尤其是架构师,设计模式用得多。

    217.继承:高内聚,低耦合

    218.多态:统一调用标准,提高拓展性。

    219.MySQL数据库设置字符集为utf8要在建库时设置,如果在建表时设置或者建表后修改比较麻烦。

    220.数据库里面的删除操作要谨慎,不要轻易删除否则会承担法律责任,库/表/行/列记录不能随便删。

        删除数据库或者表用drop,删除行记录用delete。

    221.mysql中char与varchar的区别:

        char:长度固定,不足使用空格填充,效率高浪费存储空间,一般用于固定长度的表单提交数据存储如:身份证号/手机号/电话/密码等

        varchar:不定长,效率偏低

    223.mysql中主键列,序号不连续为正常现象,如果序号被删除,后面新增的不会补齐被删除的。

    224.innodb(支持事务,支持外键,支持行锁)一页有16kb,查询时先从磁盘读一页,减少磁盘IO次数,提高效率。

    225.innodb在插入数据时进行排序,降低了插入数据的效率,但是提高查询的效率

    226.mysql底层索引是B+树,其叶子节点(没有子节点的节点是叶子节点)包含双向指针,每一页作为一个叶子节点(leaf Page),提高查询效率。

    227.utf8字符集一个数字或一个字母占一个字节,一个汉字占3个字节。

    228.传统IO是面向流的,阻塞的,没有选择器,NIO(多路复用IO)是面向缓冲区的,不是阻塞的,有选择器。Netty封装了NIO并且解决了NIO空轮询的问题

    229.finally里面可以写throw语句 new一个异常

    230.Thread.sleep不会释放锁,wait是释放锁的。

    231.每个对象都有唯一的对象锁,而不是多个。

    232.通过数组名.length能获得数组的长度,注意length后面没有括号。

    233.线程的生命状态:

        新建状态new:创建一个线程

        就绪状态runable:此线程具备除了时间片外的所有资源

        运行状态running:抢占到时间片后进入运行期

        阻塞状态blacoking:由运行状态被阻塞

        死亡状态dead:线程结束。

    234.Java中没有引用传递,只有引用拷贝或值拷贝。

    235.如果某异常继承 RuntimeException,则该异常可以不被声明。

    236.sleep 是线程类(Thread)的方法,wait 是 Object 类的方法;

        sleep 不释放对象锁,wait 放弃对象锁。

        sleep 暂停线程、但监控状态仍然保持,结束后会自动恢复。

        sleep会引发程序中断异常

    237.sleep()方法使一个正在运行的线程处于睡眠状态,是一个静态方法,调用此方法时,

        需要捕捉InterruptedException异常。

    238.Synchronized声明不会被继承,如果一个用synchronized修饰的方法被子类覆盖,

        那么子类中这个方法不在保持同步,除非用synchronized修饰。

    239.反射有在运行中分析类的能力。

    240.Mysql数据库里面用having子句对group by分组后的数据进行排序。

    241.事务的四个特征:原子性,一致性,隔离性,持久性。

    242.事务用来管理 insert、update、delete 语句,因为这些操作才会“破坏”数据,

        查询select(读操作)语句是不会的。

    243.MYsql默认会开启事务,但是只针对单独的一条sql语句默认开启事务,如果要针对一堆

        SQL语句开启事务,需要手动开启事务。

    244.开启事务:start transaction,提交事务:commit,撤销修改就回滚:rollback。spring里面可以针对异常回滚:rollbackfor="异常名.class"

    245.Mysql里面有默认约束default(写上字段的默认值)和检查约束check(写上字段的约束条件)。

    246.Mysql中尽量不要用多表查询(三张表以下)因为多表查询会先生成笛卡尔积会占用内存消耗资源浪费时间。

    247.尽量不使用外键约束

    248.Mysql事务里多条Sql语句,要么全成功,要么全失败。

    249.Mysql里复合索引,一个索引包含多个字段。

    250.Mysql查询索引:show index from 表名;

        创建普通索引:create index 索引名 on 表名(字段名);索引列的值必须唯一。   

        创建唯一索引:alter table 表名 add unique(字段名);unique是唯一索引。

        创建主键索引:alter table 表名 add PRIMARY KEY(字段名);创建主键索引。

        创建复合索引:alter table 表名 add index 索引名 (字段1,字段2);

        删除索引;drop index 索引名 on 表名;

        查询sql语句执行的频率:show global status like 'com%';

        查询所有操作的频率:show global status like "com%";

        查询执行效率低的sql语句:show processlist;

        查询索引执行逻辑/计划:explain select ........,查询结果里的id控制查询的执行顺序,id相同的话自上而下,id不同的话,先执行id数值大的查询.

        复合索引有最左匹配原则:如果最左边的查询条件都不匹配那索引时效,无法通过该复合索引查询.

        如果在索引上执行了运算,那么索引会时效,比如对名称字符串截取子串等运算,字符串不加引号会导致索引失效.

        尽量使查询条件覆盖索引,如果不能覆盖,会导致回表查询,降低了效率.

        模糊查询时%百分号加在前面会导致索引时效.

        如果全表扫描比走索引更快那么就不会走索引.

        in会走索引,not in不走索引.

        is null 是否走索引 要看情况

        尽量使用复合索引,少使用单列索引.

        数据库底层会使用最优的索引(辨识度最高的索引)来使用,并不会使用全部索引.

        mysql explain 查询出来有哪些列:

        expain出来的信息有10列,分别是id、select_type、table、type、possible_keys、key、key_len、ref、rows、Extra,下面对这些字段出现的可能进行解释:

        id:  SQL执行的顺序的标识,SQL从ID大到ID小的执行

        select_type:每个select子句的类型

        table:这一行的数据是关于哪张表的

        type:表示MySQL在表中找到所需行的方式,又称“访问类型”

        常用的类型有: ALL, index,  range, ref, eq_ref, const, system, NULL(从左到右,性能从差到好)

        possible_keys:指出MySQL能够使用哪个索引在表中找到记录

        key列显示MySQL实际决定使用的索引

        key_len:表示索引中使用的字节数

        ref:表示上述表的连接匹配条件,即哪些列或常量被用于查找索引列上的值

        rows:表示MySQL根据表统计信息及索引选用情况,估算的找到所需的记录所需要读取的行数

        Extra:该列包含MySQL解决查询的详细信息

        select_Type: simple:简单查询,primary:主查询,subquery:子查询,derived:获得临时查询结果

        type: ref:非唯一索引扫描,range:范围类查询,index遍历索引树,all:遍历全表数据(全表扫描)

        sql优化只需要优化到 ref和range就行,需要扫描的行数越少越好.

        extra:using filesort(根据文件排序),using temporay(根据临时表查询),using index(使用索引),前两者效率比较低.

        查看有没有profile功能:select @@have_profiling;

        查看有没有开启profile功能:select @@profiling;如果结果为0就是没有开启.

        设置开启profile功能set profiling=1;

        使用profiles功能:show profiles;此操作可以看到每个操作的执行时间.(duration表示执行时间/持续时间)

        使用profiles功能查看具体查询的详细耗时时间:show profile for query id;(id表示query id 是一个数字表示查询的编号);

        optimizer_trace是MySQL 5.6引入的一项跟踪功能,它可以跟踪优化器做出的各种决策(比如访问表的方法、各种开销计算、各种转换等),

        并将跟踪结果记录到 INFORMATION_SCHEMA.OPTIMIZER_TRACE 表中。

        此功能默认关闭,开启后,可分析如下语句:

    SELECT,

    INSERT,

    REPLACE,

    UPDATE,

    DELETE,

    EXPLAIN,

    SET,

    DECLARE

    ,CASE,

    IF

    ,RETURN

    ,CALL

        sql优化器OPTIMIZER_TRACE的过程说明:

        以本处事例简要说明OPTIMIZER_TRACE的过程.

        查看OPTIMIZER_TRACE方法:

        set optimizer_trace='enabled=on';    --- 开启trace

        set optimizer_trace_max_mem_size=1000000;    --- 设置trace大小

        set end_markers_in_json=on;    --- 增加trace中json格式的注释

        select * from information_schema.optimizer_trace\G; 从系统表中查询trace优化器日志表.

    251.主键(一般是id)自带索引,而name一般不会自带索引,如果查询量大需要对name创建索引.

    252.Mysql视图:视图(缓存bufferpool)了上次查询的结果,下次再查直接从视图里面查。

        创建视图语句:create view 视图名称 as 一系列sql语句;

        视图作用:复杂的Sql语句只用写一次,提高Sql语句复用性,相当于模板。

    253.当我们创建一个联合索引(复合索引)的时候,如(k1,k2,k3),

        相当于创建了(k1)、(k1,k2)和(k1,k2,k3)三个索引(都包含k1),

        这就是最左匹配原则,也称为最左特性。

    254.oracle数据库密码不能破解,忘记密码就麻烦了

    255.Oracle里面没有数据库,只有用户-表-记录。

    256.Oracle数据库的分页,日期,存储过程非常麻烦。数据库从Oracle迁移到Mysql需要重写,耗费大量成本。

    257.Oracle里的序列sequence相当于mysql里面的主键,但是它可以设置主键每次增加多少。

    258.Oracle里面插入序列insert into 表名(字段名) values(序列名.nextval)。

    259.idea里导入jar包方式:创建工作空间-module-创建lib路径-导入jar包,

        然后file-projectStructure-libraries-+号:找到jar包,然后选择module应用。

    260.SQL注入:用户输入的密码有特殊字符比如#(#在sql里面表示注释)和SQL语句拼接,

        导致用户只需要输入用户名,不需要输入密码都能登录

        SQL注入攻击解决方案:不用statement改用conn.preparedStatement工具类

    261.笔试中:主业务60%,主技巧40%,面试中:主业务25%,主技巧75%。

    262.刷leetcode的时候要先刷主技巧的题,这样数据结构和算法会触类旁通。

    263.分布式算法:Paxsos算法,ZAB,RAFT,GOSSIP,请求负载均衡之RoundRobin

        请求负载均衡之随机轮询算法,请求负载均衡之加权随机轮询算法,

        请求负载均衡之Latency-Aware算法,路由寻径之距离矢量算法,分布式任务调度算法

        沙丁算法,分布式协调与同步算法,分布式计算之MR Stream Actor流水线

        布隆过滤算法/布谷鸟过滤算法  常见哈希及哈希碰撞问题

        漏桶算法  令牌桶  分布式ID生成算法 雪花LEAF  AES/RSA  分布式存储之Kademlia算法

        分布式存储之Crush算法  分布式存储之一致性哈希算法  pagerank  item/UserCF协同过滤

        倒排索引之TFID/MD25算分   机器学习算法  推荐系统算法

    264.Git常用操作:推送git add .(添加到当前目录下文件),

        提交git commit -m "remark",

        推送git push -u origin master

        从远程仓库拉取最新内容:git pull

         Git

    --1,概述

    是一个项目托管的平台

    --2,组成

    --工作空间:就是你的workspace

    --本地索引/暂存区:把工作空间的资源设置索引

    --本地仓库:从workspace里复制项目代码,放在本地仓库,再push给远程仓库

    --远程仓库:就是Git服务器,用来保存管理你发布的代码

    --3,Git的常用命令

    add: 从工作空间把代码提交到暂存区

    commit: 从暂存区提交到本地仓库(需要自己创建)

    push: 从本地仓库提交到远程仓库

    --4,使用过程

    --去码云注册一个账号

    --安装Git软件

    --准备本地仓库:在你的磁盘上创建的文件夹,将来会把这里的资源提交到远程仓库

    --准备远程仓库:在Gitee上创建,保存你提交的资源

    右上角加号-新建仓库-输入仓库名-选成公开的-创建

    --在本地仓库提交数据(需要执行Gitee自动生成的命令):

    git config --global user.name "cgblpx" #配置Git账户

    git config --global user.email "xxxxx@qq.com" #配置Git邮箱

    git config --list #查看配置信息

    git init  #初始化git

    git add .  #把当前文件夹里的所有资源都提交

    git commit -m "注释"  #把资源进行提交,并写注释

    git remote add origin ****.git #把本地仓库和远程仓库进行挂载连接

    git push -u origin master #第一次登录需要输入账号和密码

    --检查是否提交成功

    访问远程仓库,看看,有数据就行了.

    --下载远程仓库的资料

    git pull #下载到了本地仓库

       Git 中文乱码,配置如下相关设置基本解决

       设置显示 status 的编码

    git config --global core.quotepath false

    1

       设置图形界面的编码

    git config --global gui.encoding utf-8

    1

       设置提交信息的编码

    git config --global i18n.commit.encoding utf-8

    1

       

    设置输出 log 的编码

    git config --global i18n.logoutputencoding utf-8

    265.SQL优化:尽量用列名代替*,where过滤时,尽量把范围控制到最小

        尽量不使用or连接多个条件用in替代,不用not in因为不走索引

        不要用!=,where过滤时,like用来做模糊查询,尽量确定开始元素,比如where name like 'a%'

        索引单表建议最多5个,通常name列会加索引,因为数据多。

        用varchar代替char,因为varchar可以变长。

        尽量使用批量插入数据,批量提交:INSERT INTO student (id,NAME) VALUES(4,'齐雷'),(),(),();

        用group by实现分组,最好先用where对数据进行过滤到最少

        伪删除发起了update而不是delete,新增flag字段int(2),标记数据显示或隐藏的状态,值为0或1。

    266.html里面加载图片的路径:先找到和html所在目录同级(并列)的目录,再从该目录找到图片素材。比如:“img/a.jpg”

    267.Git clone 可以通过http 协议来访问:git clone http://www.kernel.org/pub/scm/git/git.git从而复制远程仓库到本地.

    268.html常用标签:h1-h6是标题标签,table表格标签,tr行,td列,input输入标签,div/span/p段落标签

        img/video/audio  图片/视频/音频标签  a超链接标签  width  height  bgcolor border cellspace

        align 位置,colspan列合并,css层叠样式表。

    269.css常用标签:选择器{属性}

    270.引入外部的css标签,rel用来指定文件的类型:rel="stylesheet"。

    271.html文件里的注释:<!--注释-->  css文件里的注释:/*注释*/。

    272.数据库查询:单行单列使用=,多行多列使用in或者exists,

        尽量用小表驱动大表来查询,提高效率,右表是小表用In,右表是大表用exists。

    273.Mysql里面去除空值用ifnull,oracle里面去除空值用nvl,nvl2(列名,不为空显示参数,为空显示参数)。

    274.Oracle里面的decode类似于java中的if else。

        使用格式:decode(列名,条件1,结果1,条件2,结果2)相当于mysql里面的case when then。

    275.oracle里面的rank函数会跳跃,dense_rank不会跳跃。

    276.Idea编程工具里面,代码与gitee远程仓库同步的步骤:

        创建工作空间A,VCS里面导入版本控制-创建本地仓库-选择空间A-在gitee里面创建同名的远程仓库A

        创建包--创建类--右键git--add--commit--repository下拉--选push提交-pull下载。

        提交代码一般是提交到自己的分支,一般不能提交到master主分支,如果核对没有问题再提交到master主分支。

    277.html里面<font>标签用来设置字体,文字颜色,字的大小。

    278.html里面设置边框border时需要加上边框粗细,颜色,虚实solid,否则无法显示。

    279.http协议:请求行,请求头,状态行,响应头。

    290.HTTP状态码:404资源不存在,500服务器内部错误,200请求成功,301被永久转移到其他url。

    291.前端排错非常困难,因为js如类型语言,写错没有报错,没有提示。

    292.Linux系统,mkdir-p批量创建或删除多层级文件夹,cp-R批量复制多层文件夹,scp:跨主机复制文件,rm删除文件夹,mv移动或改名文件夹。

        root用户:可读可写可执行, r:读,w:写,x:执行。其他用户权限受限。d:目录,-:文件,l:快捷方式,ls 列出文件,ls -a 列出所有文件包含隐藏文件.

        ll 列出文件并显示时间.

    293.权限设置:chmod:r4w2可读可写6,r4w2x1可读可写可执行7,chmod777+文件名

    294.内边距:padding,外边距:margin

    295.JS里面浏览器输入的数据默认是String字符串类型。

    296.Js里的函数可以有返回值,调用该函数时需要定义变量接收返回值。

    297.Js里的弹窗alert里面可以套一个函数调用,onclick点击时弹窗并执行函数。

       写法如下:οnclick=alert(func());

    298.Centos Linux7里面返回上级目录用 cd+空格.. 再回车

        查看文档 用nl-文件名,或more-文件名,或less-文件名,-向下查找?向上查找。

        退出文档输入q,保存文档输入:wq

    299.Linux里面ls表示列出目录,ll表示列出文件的访问权限,ln创建硬链接,

        ln -s 创建软链接(快捷方式),touch表示创建文件。

        lsof -i:8080查看端口占用情况,kill -9 杀掉进程.

    300.Linux向文件中写字符串,用echo

    301.Linux,Vim+文件名:创建vim文件或修改vim文件,输入i进入编辑模式,esc退出,:wq保存退出。

        :set nu,设置行号,ZZ不保存退出,n向下寻找,N向上寻找。

    302.Js里没有函数重载的概念,函数名字不能相同。

    303.Js里没有类的概念,但是有函数function相当于类,类的对象的属性可以边写边创建,不用先定义再创建。

        Js里类的定义方式:function 函数名/类名(参数列表){ 方法体 }

        创建类的对象,var 对象名=new 类名();

    304.JS里面的DOM模型:把整个html文件当做一个对象,常用API:通过ID获取元素,getElementById

        通过name获取元素,getElementByName,通过标签名获取元素,getElementByTagName

        通过类名获取元素,getElementByClassName,获取的是数组。

    305.Js的入口函数:函数和全局变量的声明不要写在入口函数window.οnlοad=function(){....}里,

        在页面一开始就需要执行的代码要写在window.οnlοad=function(){....}里。

    306.原生JS和Jquery的加载模式不同:原生JS会等DOM元素加载完毕,图片也加载完毕再执行

        Jquery会等到Dom元素加载完毕,但不会等到图片加载完毕再执行。

    307.原生JS只允许一个入口函数,如果写多个,后面的会覆盖前面的。

        Jquery可以有多个入口函数,后面的不会覆盖前面的,Juery相当于$。

    308.前端的代码如果出错的话,在开发工具里面是不容易找到错误原因的,要打开浏览器的console控制器查看错误

        需要执行代码打开浏览器按F12打开console会有错误提示。

    309.json对象--{"k":"v","k":"v","k":"v","k":"v"}

        json数组--[{"k":"v","k":"v","k":"v","k":"v"},{"k":"v","k":"v","k":"v","k":"v"},{"k":"v","k":"v","k":"v","k":"v"}]

    310.将Json字符串转化为JS对象用JSON.parse(字符串名字)

    311.Ajax.异步,回调 ,局部刷新

    312.Maven下载 安装 使用 管理jar包/依赖。POM模型-国外远程仓库-国内镜像仓库-本地仓库-依赖-坐标

        Maven坐标:存jar包的唯一定位的方式:

        groupId指定了jar包的组/公司id,

        artifactId,指定jar包的项目id

        version指定了jar包的版本号

        依赖的检查:先去本地仓库找,如果找不到就不能用,要去下载。

    313.Js对象的键是不用加引号的,加了就变成了字符串了,定义方法如下

        定义json对象:var user={ user:"Jason Wang",

    age:"34",

    sex:"男"

    };

    314.JSon是数据交互的王者,JSON.parse()和JSON.stringfy()

    315.重复代码太多就编写一个工具类封装重复的代码。

    316.创建SpringBoot工程;File-New-Project-Spring Initializ-输入项目ID-选JDK8-next-选择SpringWeb

        然后配置maven-设置-选择maven目录-选择xml设置文件-选择本地仓库

        找到自动生成的一个类,直接运行(启动服务器)。

    317.SpringMVC工作原理:前端控制器DispatcherServelet-处理器映射器HandlerMapping-

        处理器适配器HandlerAdaptor-视图解析器ViewResolver-视图渲染view。

    318.浏览器的Url地址是区分大小写的。

    319.服务器就像超市的管理者,客户端/浏览器就像逛超市的人。

    320.springboot项目启动提示8080端口被占用解决方法:

        netstat -o -n -a | findstr :8080

        taskkill /F /PID 7256(7256是PID号)

    321.http协议中get请求方式的用?号拼接url地址请求数据,在请求体中没有请求数据。

    322.两个相同的数异或操作等于0,0与任何数异或等于这个数本身,a⊕a=0,a⊕0=a;

    1. 归零律:

    2. 恒等律:

    3. 交换律:

    4. 结合律:;

    5. 自反:.

    323.前端POST提交,提交的数据不会显示在url地址上。

    324.SpringMVC常用注解;@SpringBootApplication,@RestController,@RequestMapping,@CrossOrigin(跨域),@PathVariable

    325.SpringMVC框架用GET提交数据,在Controller层直接用方法的参数列表匹配数据(属性名和参数名要一致)

        用restful提交,需要在参数里面加上Pathvariable注解,以及在方法上加上RequestMapping("url/{属性名1}/{属性名2}")

    326.IDEA里面要查找类或搜索源码双击shift

    327.SpringMVC常用的注解

    @Controller 标识是一个Controller,Spring包扫描创建实例,

    @RequestMapping 请求后的映射路径

       

    @PathVariable 标识接收单个参数,

    @ResponseBody 返回对象利用jackson工具类转换为json字符串

       

    @RequestParam 参数名和请求参数名称不同时使用,可以设置默认值

    328.IOC控制翻转:是指把创建对象(new),存储对象,对象依赖管理的过程交给Spring框架管理,也就是管理对象的生命周期。

    329.AOP面向切面编程,是一种思想。SOA:面向服务编程。

    330.@Autowired注解表示,用来创建属性对象,Di: dependency injection:依赖注入,依赖注入是依赖倒置(Dependency Inversion)的一个特殊情况.

    331.延迟加载=按需加载,lazy-init=true。

    332.java程序里的日期格式用import java.time.LocalDate包里的,这样前后端和数据库就不会出出错

        将日期插入数据库时这样处理:java.sql.Date.valueOf(日期变量)。

    333.Spring框架里使用@Component注解时,spring-configs.xml配置文件里要加上context标签,xmlns:context="Index of /schema/context"

        Index of /schema/context https://www.springframework.org/schema/context/spring-context.xsd

        <context:component-scan base-package="com.testioc.ioc"></context:component-scan>

        然后getBean方法参数里的name用类名但是首字母是小写

    334.Spring框架里使用@Autowired注解加在属性上, Di依赖注入,自动创建(new)类里成员属性对象

    335.SpringMVC:写controller接收客户端请求做出响应(Ioc控制反转),Spring:写service完成业务(底层是servlet),Mybatis:写Dao操作数据。

    336.Java里面方法可以传可变参数,比如public void method(int...args)其中三个点就表示可变参数,参数数量不固定.

        可以是1个参数,2个参数,3个参数等等。

    337.在反射获取方法或属性时 要先设置可见性setAccessable(true)

    338.Spring框架主要作用是IOC(管理对象生命周期)和DI(管理依赖)以及AOP(面向切面编程;Before,After,Around):

        通过预编译方式和运行期间动态代理实现程序功能的统一维护的一种技术。

    339.AOP面向切面编程:Aspect:切面(类) , PointCut:切点(类里的方法), Advice:通知(注解Before ,After,Around);

    339.spring框架的配置文件xml里写component标签时要先写左小于号<,然后会自动带出包扫描,写上包名然后再写上右尖括号会自动带出结束标签。

    340.Springboot比SpringMVC好多了,轻松搭建工程。

    341.常用注解@Component(组件放在类上,包扫描),@Autowired,@Resource,@Qualifier(value=""),@Nullable表示值可以为空,@Value(表示属性值)

    342.@Service加在service层的实现类而不是接口上,@Repository可以加在dao层/mapper

    343.Spring项目的xml配置文件可以用java配置类代替,配置类里加上@Configuration等注解,然后用annotationConfigContext获取容器。

    344.Springboot默认就是maven项目。

    345.MyISAM管理非事务表。它提供高速存储和检索,以及全文搜索能力。如果应用中需要执行大量的SELECT查询,那么MyISAM是更好的选择。--select

        而InnoDB用于事务处理应用程序,具有众多特性,包括ACID事务支持。如果应用中需要执行大量的INSERT或UPDATE操作,则应该使用InnoDB,这样可以提高多用户并发操作的性能。--insert,update

    346.InnoDB支持事务和高并发,MyISAM不支持事务和高并发,这一点是非常之重要。事务是一种高级的处理方式,如在一些列增删改中只要哪个出错还可以回滚还原,而MyISAM就不可以了。

    347.mysql里面的联合查询union自带去重,union all不去重。

    348.spring框架里要有切面类aspect, 切面方法(非业务功能拓展)(join point连接点)。

    349.spring框架里的xml配置文件里的bean标签默认调用无参构造,constructor-args默认调用含参构造。

    350.ORM映射:是指类和表的关系,是属性和字段值的关系,从数据库读写数据和类里的属性对应。

    351.Mybatis配置文件里,$不能拼接字符串,#可以拼接字符串。

    352.内存数据:断电即失。

    353.Eclipse里面的工作空间可以创建多个项目,每个项目是并列的,

        IDEA里面的工作空间是一个项目,里面是父子集项目,不是并列是包含关系。

    354.SpringMVC:接收用户提供的数据,返回服务器的数据。(**交互**)

    355.Spring作用:整合其他的第三方框架,可以让程序调用以一种统一的方式进行调用。(**整合**规则统一)

    356.Mybatis作用:整合JDBC方便用户与数据库进行交互。(**持久化**)

    357.SpringBoot作用:简化Spring等框架的操作,是框架的高级API。(**简化**)

    358.框架之间的关系:依赖关系

    359.容器:存储大量数据的Map集合,当程序加载key-value结构时,将数据保存到Map集合中(容器内部)

    360.利用Spel(springel)表达式,通过key,获取value,之后为属性赋值。

    361.了解技术和技术周边的知识。

    362.SpringBoot核心机制:开箱即用表示,只需要导入特定jar包的文件,则可以直接使用其中的功能,根本原因:springboot是对框架的简化。

    363.SpringBoot热部署:修改代码之后不用重启服务器,框架自动重启服务器,需要配置IDEA识别代码修改的功能。

    364.IDEA开启自动识别代码修改的快捷键:ctrl+alt+shift+/,选register,热部署是compiler.automake.allow.when.app.running。

    365.Lombok插件plugin作用,简化用户创建“pojo实体对象的过程”,@Data动态的生成get/set/toString方法,@NoArgsConstructor无参构造,@AllArgsConstructor全参构造

    366.mybatis映射配置文件属性与数据库中的字段一一对应时用resultType,属性与数据库字段不对应时用resultMap,一般单表查询使用resultType,多表联查使用resultMap;

        mapper映射文件里sql语句最好不要加分号结尾,因为分号在oracle数据库里无法解析。

    367.SSM三大框架整合时需要在启动类添加mapperScan或数据交互类添加mapper注解。

    368.Mybatis接口注解说明:实现数据查询时有2种Sql写法一:将所有的Sql语句都写到XML映射(mapper)文件中,方法二:可以将Sql注解写在方法上。

    369.Mybatis映射文件里如果对象中的属性与数据库表中的字段一一对映射时,使用resultType

        如果对象中的属性与数据库表中的字段不是一一映射时,使用resultMap

        一般条件下,单表查询一般使用resultType,多表关联查询时使用resultMap

        注意事项: 不能添加;号   版本冲突严重 mysql Oracle中。

    370.MybatisPlus简称MP

    371.mysql里面union 自带去重,union all 不去重,mysql里面的bigint类型相当于java里面的Long类型.

    372.Spring框架里,Aspect切面类,CutPoin(切点)切面方法(joinpoint连接点参数)

    373.Spring框架里,spring里的配置文件里的,

    bean标签默认会调用无参构造创建对象。

    constructor-args 标签默认会调用含参构造。

    374.jForum,Java论坛框架

    tomcat netty jetty spring

    源码阅读工具:

    源码阅读需要的基础,

    ooa,ood,设计模式,

        算法数据结构

    sequencediagram,diagram,类图工具

    spring:三级缓存,IOC,容器。

    375.技术赋能业务

    互联网三高:

    1.高性能

    降低响应时间,

    提升吞吐量,

    分库分表

    2.高可用

    3.高并发

    376.查询数据用get,有缓存,请求数据在URL里面可见。请求头:方式 地址 协议,

    修改提交数据用post(安全),有中文乱码

    请求方式不一致,

        错误码是405

    客户端异常,输入数据类型不对,错误码400

    浏览器和服务器的数据交互:

    HTTP,超文本传输协议

    Tomcat用Java编写,

        运行需要Java虚拟机

    web.xml可以保护servelet

    服务器相当于超市营业员,要处理客户的请求,

    http协议和tcp协议以及UDP协议不要混淆

        servlet里面只有service方法时可以处理post请求和get请求,如果只有doget方法或dopost方法,那么只能处理对应get和post的请求,

        如果service方法和dopost方法doget方法都有那么会优先执行service方法。

    springMVC底层就是servlet。

    377.哪些字段应该添加索引:1.主键自动创建唯一索引2.频繁查找的字段应该添加索引比如微信号/用户名/手机号3.与其他表关联的需要外键索引

        4.频繁更新的字段不适合创建索引。5.单键索引/复合索引的选择6.where条件里用不到的字段不创建索引。

        查看索引的使用情况 show status like 'Handler_read%'

    378.数据库的索的定义:数据库是一个多用户使用的共享资源。当多个用户并发地存取数据时,在数据库中就会产生多个事务同时存取同一数据的情况。

        若对并发操作不加控制就可能会读取和存储不正确的数据,破坏数据库的一致性。加锁是实现数据库并发控制的一个非常重要的技术。

        当事务在对某个数据对象进行操作前,先向系统发出请求,对其加锁。加锁后事务就对该数据对象有了一定的控制,

        在该事务释放锁之前,其他的事务不能对此数据对象进行更新操作。

        在数据库中有两种基本的锁类型:排它锁(Exclusive Locks,即X锁)和共享锁(Share Locks,即S锁)。

        当数据对象被加上排它锁时,其他的事务不能对它读取和修改。加了共享锁的数据对象可以被其他事务读取,但不能修改。数据库利用这两种基本的锁类型来对数据库的事务进行并发控制。

    379.*.frm是描抄述了表的结构,*.MYD保存了表的数据记录,*.MYI则是表的索引,.opt记录数据库的选项,数据库的字符集设置。

    380.#yml文件主要作用:编辑spring与第三方框架整合,业务数据如果写在这里会导致混乱,

        #yml文件是K-V结构,

        #key:value,冒号左边是key,冒号右边是value,不要写多余的空格,

        #yml文件有层级结构,缩进表示父子结构,

        #yml默认读写的字符集是utf8,中文不会乱码,

        #当spring启动时,该yml配置会被加载,

        #yml中的字符串默认不用加引号,

        #yml冒号之后要有空格。

    381.写程序要写一步测一步,不能写到底再测,这样的话测不出来。

    382.开发流程:设计数据库和表,技术选型,写代码,测试,部署运维上线。

    383.QueryWrapper是条件构造器用来拼接where条件。

    384.QueryWrapper(查询构造器),等于=eq,大于>gt,小于<lt,大于等于>=ge,小于等于<=le,不等于!=ne,UpdateWrapper(更新构造器)。不需要构造器时可以传null.

    385.Ajax里面data参数传递方法:1,以Js对象方式传递, 语法{ k1:value1,k2:value2,k3:value3 };2.拼接字符串"k1=value1&k2=value2&k3=value3"

    386.Ajax里面请求数据用get方式,提交数据用post方式。

    387.Ajax里面的回调函数名称是success。

    388.Js里面 用in遍历遍历的是索引/下标,for(index in data){console.log(data[index]) },用of遍历的是js对象,for(user of data){ console.log(data[user])}。

    389.Js模板字符串语法let str=`<tr><td>${user.id}</td><td>${user.name}</td><td>${user.age}</td><td>${user.sex}</td></tr>`。

    390.Js中var是申明全局变量,let是申明局部变量,局部变量作用范围在{ }代码块中,一般用在for循环的代码块中。定义常量用const。

    391.跨域问题出现在ajax请求上,在a标签提交和表单提交时不存在跨域问题。

    392.同源策略:请求协议://域名:端口,浏览器和服务器双方要一致,不一致就会产生跨域问题。

    393.http协议默认端口是80.

    394.CORS全称是跨域资源共享,只要服务器实现了CORS接口,就可以实现CORS。

    395.浏览器的网址与Ajax请求网址才存在跨域问题,A标签和FORM表单里的ACTION不存在跨域问题。

    396.Oracle里面&和&&的区别,&与&&的区别

        & 用来创建一个临时变量,每当遇到这个临时变量时,都会提示你输入一个值

        &&用来创建一个持久变量,当用&&命令引用这个变量时,不会每次遇到该变量就提示用户键入值,而只是在第一次遇到时提示一次。

    397.SQL中的truncate,当你不再需要该表时, 用 drop;当你仍要保留该表,但要删除所有记录时, 用 truncate;当你要删除部分记录时(always with a WHERE clause), 用 delete.

    398.Oracle里面的NVL相当于mysql里面的ifnull。

    399.CDN:CDN的全称是Content Delivery Network,即内容分发网络。CDN是构建在现有网络基础之上的智能虚拟网络,依靠部署在各地的边缘服务器,通过中心平台的负载均衡、内容分发、

        调度等功能模块,使用户就近获取所需内容,降低网络拥塞,提高用户访问响应速度和命中率。CDN的关键技术主要有内容存储和分发技术。CDN本质上网络缓存和分发。

    400.DML:data manipulation language 数据操作语言:

          insert、delete、update、merge

        DDL:data definition language   数据定义语言:

          create、alter、drop、truncate

        DCL:data control language    数据控制语言:

          grant、revoke

          truncate属于DDL语句。

    401.内连接 :内连接查询操作列出与连接条件匹配的数据行 外连接:返回到查询结果集合中的不仅包含符合连接条件的行,而且还包括左表(左连接)、右表(右 连接)或两个边接表(全外连接)中的所有数据行。

    402.truncate 不需要 rollback segment ,delete 需要 rollback segment ,TRUNCATE TABLE 语句:删除表中所有的数据并且释放表的存储空间,可以使用 DELETE 语句删除数据但不会释放表的存储空间,

        DELETE 产生 rollback segment,如果删除大数据量的表速度会很慢,同时会占用很多的 rollback segment

    403.Oracle中连接字符串使用"||"符号。

    404.Oracle里表空间和数据文件发生关系,数据文件是物理的,一个表空间可以包含多个数据文件, 而一个数据文件只能隶属一个表空间。

    405.JDBC中接口Statement中定义的execute方法返回值类型是boolean,其含义是判断有误ResultSet返回。

    406.JDBC的查询结果并不是一次性全拿到resultset中的,Oracle默认每次拿指定数量的结果,将指定数量的结果遍历完后,

        再拿下一个指定数量的结果。 否则,当查询海量数据的时候,内存会直接爆掉。

    407.@Component是通用注解,@Service是业务层实现类的组件注解。

    408.Spring依赖注入的两种方式是构造注入和设值注入。对于构造注入,Spring在创建Bean实例时,需要同时实例化其依赖的全部实例。对于复杂的依赖关系,若使用构造注入,会导致构造器过于臃肿。

        在bean元素中使用constructor-arg元素来设值属性值的构造函数注入,可以通过该元素的type属性指定参数类型,index属性指定该参数在构造函数参数列表中的索引位置。

    409.Spring框架有七个模块组成,分别是:Spring 核心容器(Core),Spring AOP, Spring ORM(对象和表的映射),Spring DAO,Spring WEB,Spring上下文(Context),Spring MVC。

    410.IOC具有三种注入方式,分别是构造函数注入、属性注入和接口注入。

    411.Vue框架代码里的data和methods之间的逗号不能少否则会报错。

    412.Spring IOP即“控制反转”,对象只是被动的接收依赖对象。

    413.Spring容器容器可以依据属性名称或者类型来完成自动装配,如果值为byName,容器会查找与属性名称一致的bean,并调用对应的set方法来完成注入。

    414.css块级元素:div、ul、li、dl、dt、dd、p、h1-h6、blockquote。

    415.JavaScript中的数据类型有: 字符串、数字、布尔、数组、对象、Null、Undefined Date是对象。

    416.UTF-8(8-bit Unicode Transformation Format)是一种针对Unicode的可变长度字符编码,又称万国码。UTF-8用1到6个字节编码UNICODE字符。

    417.一个数据库表只允许有一个主键,不能有两个主键,但是可以给多列设置一个主键。

    418.Mysql里面的select database();指查看已进入的库。

    419.Maven不自定义镜像仓库,默认从中央仓库下载jar包,Maven必须安装JDK(JRE),否则不能使用。

    420.varchar和text保存数据按数据的真实长度保存。

    421.电脑缓存是当cpu在读取数据的时候,先是从缓存文件中查找,然后找到之后会自动读取,再输入到cpu进行处理,当然如果没有在缓存中找到对应的缓存文件的话,那么就会从内存中读取并且传输给cpu来处理。

        当然这样的话需要一定的时间所以会很慢。等cpu处理之后,就很快把这个数据所在的数据块保存在缓存文件中,这样的话在以后读取这项数据的时候就直接在缓存中进行,不要重复在内存中调用并读取数据了。

    422.Vue里面的Computed计算属性有缓存机制,多次调用只执行一次。

    423.Vue常用7个属性:

    学习vue我们必须之到它的7个属性,8个 方法,以及7个指令。787原则

    el属性

    用来指示vue编译器从什么地方开始解析 vue的语法,可以说是一个占位符。

    data属性

    用来组织从view中抽象出来的属性,可以说将视图的数据抽象出来存放在data中。

    template属性

    用来设置模板,会替换页面元素,包括占位符。

    methods属性

    放置页面中的业务逻辑,js方法一般都放置在methods中

    render属性

    创建真正的Virtual Dom

    computed属性

    用来计算

    watch属性

    watch:function(new,old){}

    监听data中数据的变化

    两个参数,一个返回新值,一个返回旧值,

    424.用浏览器提交更新/插入数据时,同一个请求地址网页打开多次的话,数据会增删改多次。

    425.分布式思想:核心思想是解耦,按模块划分和按层级划分。

    426.架构师+压力测试+后台监控。

    427.组件化思想:保证组件之间不互相干扰,在组件内部创建html、css、js样式。

    428.重定向是服务器行为,重定向不能传递参数。

    429.Vue里面的children可以实现路由的嵌套,通过父子关系,实现子组件的渲染,在父组件的router-view中展现。

    430.Vue笔记:插值表达式{{}},v-text用于将数据填充到标签中,作用于插值表达式类似,但是没有闪动问题 ,

        v-cloak遮盖没解析完的插值表达式,v-html用来展现html元素,v-pre跳过解析

        v-once数据只解析一次,多次修改也只显示最初的效果,v-model前后端数据双向绑定,v-bind:绑定属性可以缩写为冒号+属性,

        v-on:click、@click绑定点击事件,@click.stop阻止事件向上冒泡,@click.prevent阻止浏览器默认行为

        按键访问修饰符:@keyup.enter回车触发,@keydown.space空格触发,@keydown.delete删除触发,@keydown.tab表单触发,

        分支结构:v-if,v-else-if,v-else,循环遍历:v-for,可以用来遍历数组v-for="elment in array",对象v-for="(key,value) in obj",集合v-for="obj in objLsit",

        v-model.number将用户输入的字符串转为数字,v-model.trim去除输入字符头和尾的空格,v-model.lazy懒加载,输入和显示不是同步更新,而是等输入完成,显示再更新。

        Vue共有8个钩子函数,created()表示实例创建完成,mounted()函数标志vue对象实例化成功。

        Vue数组操作:push从尾部添加,pop从尾部删除,shift从头部删除,unshift从头部添加,reverse反转,

        splice截取或者替换部分元素,splice参数中/*   arg1: 操作数据的起始位置 下标从0开始

       arg2: 操作的数量

       arg3: 替换后的值 可以有多个值

        axios请求方式:axios封装了promise对象,异步调用更简洁 常见请求类型:用来查询:get(查)/delete(删除),新增入库:post(新增)/put/(删除)

        axios.get请求传递参数需要加{params:参数},axios.post请求参数直接加在地址后面axios.post("",参数)

        axios.post请求,参数是js对象的json串,需要在后端代码里参数前加上@RequestBody,用来将json串转为对象。

        解构赋值:能否利用一个方法就直接将数据获取,简化2步调用,async和await要同时存在。

        定义Vue全局组件,Vue.component("组件名"{data(){return{返回值}},template:"#组件id"}),定义局部组件,let 组件名={data(){return{}},template:"#组件id"}

        VueRouter:路由,路由链接,路由填充位(显示组件),定义组件,创建路由对象,定义路由规则,将路由交给Vue对象管理。

        路由利用redirect实现路由重定向,利用children实现嵌套路由。

        Vue里面的Computed计算属性有缓存机制,多次调用只执行一次。

    431.前端里.vue文件是组件,vue数据结构:1页面主题内容 2.js样式 3.

    432.Vue脚手架,assets引入第三方图标,components表示组件在里面放页面,plugins引入UI工具,router设定路由。

    433.APP.VUE是表示默认页面index.html。main.js文件是脚手架核心js配置,用来控制脚手架运行的初始化js,一般用于设定全局变量。

    434.Java servlet是实现前后端交互的机制,含有request(请求数据)对象和response(响应数据)对象。

    435.dispatcherservlet前端控制器只负责请求的转发和响应。处理器适配器.

    436.将密码进行MD5加密处理时,同一个密码,用不同电脑产生的md5加密密码可能不一样。

    437.git创建本地分支命令:git branch (分支名称)

    438.git切换分支命令:git checkout (分支名称)

    439.git创建远程分支命令步骤:

        git branch ***(分支名称) 

        git push origin ***(分支名称)

    440.git给分支建立上游连接:git push -u origin (分支名称),-u 是 --set-upstream的简写。

    441.git查看分支:查看下当前分支:git branch    查看远程分支:git branch -r。

    442.单体;一个业务部署在一个服务器上

    ,集群;一个业务部署在多个服务器上

    ,分布式;一个业务拆分成多个子业务部署在多个服务器上。

        分布式的CAP原则;

    一致性,可用性,分区容错性

    ,分布式降低了维护成本/开发协作成本

    ,提高了管理和测试成本。

    微服务,把一个服务拆分成多个子服务,相互间可以调用。

        微服务从2019年开始变热门,是一种架构风格。

    互联网两大流派:lamp,spring+tomcat,

    lamp已经凉了。

    单体弊端;

    部署效率低,团队协作开发成本高。

       

    服务化;模块拆成独立的服务部署,

    微服务概念2014年提出

    微服务每个子服务可以用不同的编程语言来编写,也可以使用不同的数据库存储技术。

    每个服务运行在自己的进程中,可以自动化的部署。

       

    微服务特点;

    分散治理,去中心化治理,容错性设计

    产品不是项目,不容易外包 。

    微服务会带来组织架构的调整;

    团队由职能划分改为由模块业务划分。

        微服务是由一系列一部分模块构成。

    微服务优点;灵活,易于拓展,技术栈丰富,

    缺点;运维成本高,接口可能不匹配,架构复杂度高。

       

    微服务两大门派;

    springcloud(rest协议),dubbo(rpc协议)

    dubbo有中文文档,诞生于阿里巴巴

    ,springcloud迭代快速。

       

    443.线程池种类;

    固定数量线程池,

    单线程池,

    可缓存线程池,

    延时周期线程池,

    最佳线程数;

    CPU核心数*(1+平均等待时间/平均工作时间),

        通过设置maximumPoolSize,可以允许线程池容纳任意数量的并发任务

    只有在队列填满时才创建多于corePoolSize的线程,如果使用的是无界队列,那么线程数不会超过corePoolSize。

    444.

    Lambda表达式只能实现有且只有一个抽象方法的接口,Java称为函数式接口,jdk8提供的函数式接口位于java.util.function。

    445.网站登录原理,用ajax实现请求,表单封装username/password数据用post方式提交数据。

    446.java中的几种对象(PO,VO,DAO,BO,POJO),VO :(value object) ,表示值对象。

    447.用户登录成功之后,后端服务器会返回用户的token信息,前端需要保存该token,否则数据会销毁,

        服务器端数据应该保存到哪里?

    448.Session表示会话控制,session保存在支持cookie的浏览器中,session对象保存特点用户所需的属性及配置信息。在会话周期内session保存的数据有效。

        当会话结束(网页关闭)数据将失效,session是短时存储,页面关闭session保存的数据情况。

    449.cookie功能跟Session类似,但是数据保存更持久,数据暂存或永久保存在用户终端上,有持久cookie(持久存储)和会话cookie(浏览器关闭数据就销毁).

    450.OA系统用户登录信息保存在session中,财务系统登录信息保存在session中,手机银行登录信息保存在session里,为了信息安全,如果保存在cookie手机被盗,用户信息也被盗。

    451.腾讯视频会员:cookie存储。电商系统登录信息用session存储。

    452.Controller层里类的方法里如果返回有数据不为空,会执行success方法,要把数据对象(data)放在success里作为参数,返回success,如果data不传进去,浏览器不会显示数据。

    453.前端get请求传参方式:1.问号拼接,2.传对象,3.restful。

    454.mysql分页语法:select * from 表名 limit (n-1)*m,m。--其中n表示页数,m表示每页记录条数。

    455.Vue前端框架中,使用的是前端路由/客户端路由,页面是用组件component而不是html。

    456.前后端分离/前端服务器/后端服务器:前后端分离部署时,服务器A用于部署前端项目,称为前端服务器,服务器B用于部署后端项目,称为后端服务器。

        后端服务器通过开放API的方式,向前端服务器中的前端项目提供数据或数据操作接口,以此实现前端与后端的衔接。若受项目的成本限制,

        将前端项目与后端项目部署在同一服务器上也是可以的,可以通过nginx等反向代理服务器根据访问地址进行分发。

    457.前端路由是指:请求和页面(组件)的映射关系

    458.路由:router-link解析后变成a标签,to解析后变为href,router-view页面展示区。

    459.算法(algs)和性能(performance)影响用户体验。

    460.Mybatisplus可以随意切换数据库,而且有数据自动填充功能,有对外暴露数据自动填充的的接口MetaObjectHandle.

    461.swagger可以自动生成接口文档

    462.如果将大量的try catch代码写到程序中,导致业务代码混乱,Spring提供全局异常处理机制。

    463.直接操作数据库的删除语句delete无法回滚,容易导致失误删库,导致违法。

    464.设计模式:接口隔离原则,单一职责原则,依赖倒置原则,里氏替换原则(最少知道原则,只和直接朋友通信,

        直接朋友类型:成员变量+setter聚合,成员变量new组合,方法参数依赖,方法返回值类型),

        开闭原则-面向修改关闭面向拓展开放,合成复用原则:尽量使用聚合组合依赖来替代继承。

        组合:不可拆分的关系,如人与头的关系,聚合:可有可无的关系,比如人与手机。

    465.MultipartFile是springMVC专门针对文件上传开发的api。

    466.后端上传图片注意事项:

        //文件名要转为小写

        //需要验证图片的格式是否正确,用正则表达式验证文件名后缀,png/jpg/gif

        //验证图片是否有宽度和高度

        //文件分目录存储

        //防止文件重名,修改文件名称UUID

    467.网关gateway:网络通信的出口。

    468.要想使用桥接模式:桥接模式局域网其他主机可以访问虚拟机,桥接需要有物理设备-路由器(wifi)和交换机。NAT模式:只允许主机与虚拟机通信。

    469.反向代理机制:用户不清楚真实服务器地址,代理服务器位于用户和真实服务器之间,完成虚拟地址和真实地址的映射。

        用户由于某种原因,比如网络安全原因,不能直接访问服务器,所以需要代理服务器完成映射,接收请求后代理服务器根据映射文件,重新发起请求,访问真实的服务器,

        获取到资源后给代理服务器,然后再返回给用户,反向代理是服务器端代理,保护了服务器端。

        Nginx是主流的反向代理服务器/负载均衡服务器/电子邮件服务器,占用内存少(启动一个服务占用内存<2M),并发能力强。

        Nginx服务器并发能力3-5万次/每秒,Tomcat并发能力300-1000次/每秒,Nginx每次启动会启动2个进程(主进程-内存占用大和守护进程-内存占用小),如果重复启动则进程项会有多个。

        Ngnix启动start ngnix ,重启ngnix -s reload(无异常证明成功) ,停止ngnix -s stop

    470.正向代理:位于用户和目标服务器之间,用户非常清楚的知道自己访问的远程资源到底是谁,采用正向代理时一般都是为了实现网络通信。

        香港/台湾/vpn,用VPN访问真实的地址,比如境外的谷歌/脸谱等网址,正向代理是客户端代理,保护了客户端。

    471.HOSTS文件作用:主要在本机上 实现域名与ip地址(127.0.0.1)的映射。

    472.NFS(Network File System)即网络文件系统,它允许网络中的计算机之间通过TCP/IP网络共享资源。

        在NFS的应用中,本地NFS的客户端应用可以透明地读写位于远端NFS服务器上的文件,就像访问本地文件一样。

    473.linux参数

        defaults 使用默认设置

        sw 自动挂载的可读写分区

        noauto 设备(分区)只能手动挂载

        ro  挂载为只读权限

        rw  挂载为读写权限

    474.DOS是操作系统,不是文件系统

    475.Linux查找命令:ls只能找出当前目录下的文件,find 可以找出当前目录以及子目录下所有的文件。

    476.Nginx配置文件里,写图片反向代理的语法:

    server{

    listen 80;

    server_name image.jt.com;

    location  / {

    root   D:/software/img;

    }

    }

    477.F5硬件服务器,负载均衡,英文名称为Load Balance,其意思就是将负载(工作任务)进行平衡、分摊到多个操作单元上进行执行,例如Web服务器、FTP服务器、企业关键应用服务器和其它关键任务服务器等,从而共同完成工作任务。

    478.修改C:\Windows\System32\drivers\etc\hosts文件可以将域名和IP绑定,域名访问的是自己要求的ip地址。

    479.后端是没有页面的,只是返回数据给前端,要访问页面要加路径,不能只访问端口。

    480.如果web项目要发布,需要编译。

    481.编辑nginx配置文件的语法:

       #每个反向代理服务都是一个server

       

       server {

         #监听端口号 一般默认都是80

            listen       80;

           

       #拦截用户访问的路径

           

       server_name  localhost;

       #反向代理配置 location请求的路径 斜杠/ 表示拦截所有请求

    ,优先级最高的=表示精确拦截某请求比如/page,只访问page页面       

       location / {

            

       #root关键字   代表的是一个目录

               

       root   html;

               

       #index关键字代表页面  默认的欢迎页面

               

       index  index.html index.htm;

            }

          }

       proxy_pass代表代理的网址

    482.Robots文件是网站中蜘蛛抓取的第一个文件,是告诉搜索引擎蜘蛛网站中什么能抓取能访问,什么不能的文件。

        robots.txt文件是每一个搜索引擎蜘蛛到你的网站之后要寻找和访问的第一个文件(所以选B),必须存放在空间根目录(所以选A,不选D),告诉搜索引擎,这个网站有哪些是可以抓取的,哪些是不允许的抓取的,

        如果robots.txt不存在,搜索引擎蜘蛛将能够访问网站上所有未被口令保护的页面(所以选C);robots.txt是你对搜索引擎制定的一个如何索引你的网站的规则。

        通过该文件,搜索引擎就可以知道在你的网站中哪些文件是可以被索引的,哪些文件是被拒绝索引的,我们就可以很方便地控制搜索索引网站内容了;综上,所以答案选择ABC

    483.百度暂时不抓取或不能很好抓取的代码有javascript和flash

    484.搜索引擎按照信息收集方法不同可分为:目录式搜索引擎、机器人搜索引擎以及元搜索引擎。

    485.集群服务器:由多台服务器(tomcat占用内存200M+单台物理服务器要看内存多大决定支持多少tomcat)组成的一个物理结构,这些服务器可以提供

    486.负载均衡:Nginx代理服务器把请求分发给不同的后端集群服务器叫负载均衡。

        负载均衡机制:1.轮询机制,2.权重机制,加weight权重,性能好的服务器分配权重高。3.IP_HASH,由算法控制,写了它后其他策略不生效。

        IP_HASH,要素:IP地址 端口号,算法hash(ip:端口)%2

        高可用:服务器宕机,则程序可以实现故障的迁移,无需人为干预。Nginx策略:Nginx属性:down属性(标注down的话 Nginx永远不会访问该服务器),

        backup属性(备用机,正常情况下不提供服务,如果其他的设备宕机/遇忙才会访问该服务器。)

        不影响用户的情况下如何升级:

        1.将需要升级的服务器在nginx中标注为down属性,

        2.重启nginx,

        3.将新的jar包部署到服务器中,

        4.进行软件调试,如果测试无误再修改Nginx 服务器的down属性。

    487.服务器宕机之后可以重启,就跟电脑故障用重启解决一样。

    488.Nginx代理服务器实现高可用的配置:max_fails设置最大失败次数,fail_timeout设置最长失败时间(该时间之内不会再次访问)。

    489.后端项目打包,maven-install,一般打jar包。

    490.Linux里面根目录用斜杠/表示,绝对路径从根目录出发。

    491.Linux常用命令:

        hostnamectl set-hostname 主机名:设置主机名

        ctrl+C结束当前进程,ifconfig /ipaddr 查看ip地址,pwd 查看当前目录,tab自动补全代码etc,cd命令用于切换路径

        cd /回到根目录,cd ~用户主目录,cd ..返回到上一级目录,cd /usr/local/src/开发文件部署目录,

        ls –l 详细格式,文件权限,时间相当于ll;ls *.txt 查看所有的txt类型文档

        mkdir 创建目录

        mkdir a 创建 a目录

        mkdir -p a/b 创建 a目录,并在a目录里创建b目录,就是创建多层目录

        mkdir -m 777 c 创建一个权限为777的C目录

        rmdir  删除空目录(如果目录里有文件,则不能用此命令)

        mkdir --help查看当前命令的帮助

        vim a.txt 创建a.txt文件

        命令行:Esc退出编辑,切换到命令行模式。

        编辑模式:

        按i,在光标前开始编辑

        按a,在光标后开始编辑

        按o,在当前行的下一行开始编辑

        按u, 撤销之前的操作

        底行模式:按  shift+:冒号。

        :q! 不保存退出

        :wq 保存退出

        :set nu 设置行号

        :/world 从当前光标处,向上查找world关键字

        :?world 从当前光标处,向后查找world关键字

        rm a.txt提示再删除文件

        cp复制文件

        cp nginx.conf n.txt

        cp –R tomcat1 tomcat2   复制目录

        scp 跨主机复制,用于分布式

        mv 修改文件名,移动文件

        mv n.txt m.txt  修改文件名称

        mv n.txt adir/nn.txt  移到文件到某目录并改名,相当于剪切复制粘贴改名。

        tar -cvf a.tar ./*   打包当前目录所有文件 为a.tar文件

        tar -zcf b.tar.gz ./*   打包并压缩当前目录所有文件b.tar.gz文件

        tar -zxvf m.tar.gz    解压m.tar文件到当前目录

        Linux里修改jdk环境变量:

        vim /etc/profile

       

    export JAVA_HOME=/usr/local/src/jdk1.8

       

    export PATH=$JAVA_HOME/bin:$PATH

    export CLASSPATH=.:$JAVA_HOME/lib

        让JDK环境变量生效: source /etc/profile

        linux检查防火墙状态:firewall-cmd --state(需要root权限才能查看)

        linux通过命令手动将防火墙关闭

        关闭防火墙命令:

        1. systemctl stop firewalld.service

        开启防火墙命令:

        2. systemctl start firewalld.service

        Linux里修改文件权限为可读可写可执行的命令:

        chmod 777  文件或目录名

        Linux里修改文件权限为不可读不可写不可执行的命令:

        chmod -777  文件或目录名

        查看端口号占用情况:

        lsof -i : 8080(端口号)需要安装lsof

        Linux终端mobxtrem上传文件报错解决方案,先将文件上传到home里的用户文件夹再mv移动到目标文件夹。

        Linux mariadb数据库启动关闭操作:

        1.   启动命令    [root@localhost src]# systemctl  start  mariadb

        2.   重启命令    [root@localhost src]# systemctl  restart  mariadb

        3.   关闭命令    [root@localhost src]# systemctl  stop  mariadb

        4.   设定开机自起 [root@localhost src]# systemctl  enable mariadb

        5.   关闭开机自起 [root@localhost src]# systemctl  disable mariadb

        服务器上的数据库连接不上的原因:1数据库没有启动,2.防火墙封锁

        Linux 启动tomcat服务命令,java -jar 8082.jar & java -jar 8083.jar &

        检查linux上java程序是否正常运行:

        ps -ef 查看linux里系统所有进程项

        ps -ef|grep java ,|grep表示管道,竖线前后的命令同时执行,ps -ef | grep 服务名称,之前的结果作为后面的参数

        ps -aux

        jps 查看所有java服务项,结果比如 1522 jar,数字1522表示进程号。

        Linux 系统常规杀死进程命令,kill 1522 1523

        Linux 系统强硬杀死进程命令,kill -15 1522 1523 (加了-15)

        java项目在linux服务器后端启动之后终端是否关闭对程序运行没有影响,

        后端启动的命令是:nohup java -jar 8082.jar =>8082.log & nohup java -jar 8083.jar =>8083.log(&表示可以执行后续操作)

        cat 输出文件所有的内容

        more 输出文档所有的内容,分页输出,空格浏览下一屏,q退出

        less 用法和more相同,只是通过PgUp、PgOn键来控制

        tail 用于显示文件后几号,使用频繁

        tail -10 nginx.conf 查看nginx.conf的最后10行

        tail -10 8083.log 查看日志最后10行

        tail –f nginx.conf 动态查看日志,方便查看日志新增的信息

        nl 文件名:查看并显示行号。

        ctrl+c 结束查看

        find ./ -name "*hive-site.xml*":查找当前目录名称含有filename的文件目录     

        find ./ -name "*controller-manager*"

        linux系统目录挂载:mount -t nfs 192.168.232.129:/etc/nfs_data /etc/web_dir/

    492.Linux的脚本相当于外挂,脚本文件后缀.sh,是shell文件,用于批处理。

        创建脚本文件例子:vim  start.sh   首行,#!/bin/sh,其他行写要执行的脚本,比如

        nohup java -jar 8082.jar=> 8082.log &

        nohup java -jar 8083.jar=> 8083.log &

        运行脚本 sh start.sh

        nohup表示后台运行

    493.Nginx命令:

       

    windows系统:

        启动 start nginx

        重启 nginx -s reload

        停止 nginx -s stop

       

    Linux系统:

        目录: /usr/local/nginx/sbin

        启动 ./nginx

        重启 ./nginx -s reload

        停止 ./nginx -s stop

    494.Vue ui脚手架工具里点buil会创建前端程序打包文件dist。

    495.Linux里jar包红色,脚本是绿色,目录是蓝色,文件是白色。执行脚本的命令 ./脚本文件,相当于双击执行文件。

    496.spring-security安全框架可以在yml配置文件中配置密文密码,要加单引号'{bcrypt}..........'.

    497.maven依赖配置文件飘红原因:1.依赖没有下载完,2.版本号错误,3.网络不通,4.pom标签不完整.点击刷新按钮会重新下载依赖,如果项目没有在maven区展现,可以点击加号+把项目添加进来

    498.SpringSecurity的Bcrypt加密底层采用随机盐salt的方式加密,这牺牲了性能,可能导致访问慢.

    499.MD5加密已经不安全了,对相同的内容,加密结果都相同,并且不可逆.

    500.idea里面alt+enter自动生成对象.

    501.jdk1.8之后接口里可以有默认的有方法体的方法.

    502.常用的登录认证和授权框架:SpringSecurity 或Shiro

    503.SpringSecurity中常用的API有BcryptPasswordEncoder,DefaultAuthenticationFailureHandler,DefaultAuthenticationSuccessHandler.

    504.为什么要进行权限控制?防止非法用户破坏数据

    505.SpringSecurity进行权限控制额步骤:@EnableGlobalMethodSecurity,@PreAuthorize

    506.HTTP是超文本传输协议,是无状态协议.

    507.SpringSecurity依赖cookie

    508.单点登录系统:由nginx发通票(token令牌),可以访问分布式服务器,通过数据库存储会话状态这种方式中小型项目在用.

    509.单点登录系统的技术趋势是:将用户的登录状态信息都存储在客户端,服务端不记录任何状态,服务端只负责对客户端传递过来的

        状态信息进行解析,基于此方式进行用户登录状态的判断,这样的会话过程称之为无状态会话.

    510.JWT构成:header头部+payloader负载+signnature签名,由base64Url算法编码成这种形式:xxxx.yyyyy.zzzzzz.JWT是没有加密的,不能存放秘密信息.

    511.Spring项目的test单元测试的测试类一定要和启动类在同一个根目录下.

    512.Git乌龟,第一次是克隆远程仓库到本地,之后就是同步/提交/推送/拉取.如果出现版本冲突,乌龟会在源代码里加上小于号和等于号,需要人工处理冲突.

    513.JWT是什么?(一种规范的数据格式)JWT规范中的数据格式有几部分构成?(3部分,前2部分会进行Base64编码,最后部分会基于签名算法加密).

    514.单点登录,Single sign on 简称sso.

    515.UUID不能作为有效的登录令牌token,因为里面不含有用户的权限信息,无法实现单点登录sso/单点注销.

    516.Git版本控制的关键是:尽量不要让两个人同时修改一个文件.每个程序员负责一个包。

        程序员只提交自己负责的包,程序员不要提交公共文件夹,否则公共文件夹中的文件会发生冲突,

        公共文件由一个人负责,比如项目经理负责.

        项目经理第一次可以提交公共文件夹。如果代码冲突了 先下载代码,手动解决冲突。

        不能下载代码或不能上传代码,解决方法是重新clone项目.

    517.SpringSecurity里面的Filter过滤器在servelet之前,intercepter拦截器在servelet之后.

    518.Scala里var是变量,val是常量.能用常量的地方尽量不用变量.

    519.ObjectMapper是专门用来处理将对象转为json串的类,有writeValueAsString方法.

    520.分布式架构中认证方式如何实现:方式1.Session数据持久化2.客户端存储令牌,服务端解析令牌.

    521.认证服务器的令牌基于JWT规范,认证服务器作用:创建令牌,设置认证机制:登录成功/失败/无权限.

    522.SpringSecurity在认证服务和资源服务中的配置.

    523.导入数据表到mysql数据库的语句: source 数据源全路径比如D:\study\sql\jt_security.sql

    524.Idea里拷贝的资源需要右键rebuild重新编译.

    525.Gitee远程仓库克隆到本地的项目在idea里打开时需要右键添加到maven.

    526.资源服务器中的资源不是所有人都可以访问的,需要具备一定权限才可以,首先我们要判定是否登陆,然后判定登陆用户是否有权限,

        有访问权限才可以授权访问,这个操作可以放到spring mvc拦截器中进行实现.

    527.List转数组:list.toArray(new Integer[]{});list.toArray(new String[]{})

    528.数组转List:Arrays.asList(数组arr);

    529.SpringSecurity创建令牌和解析令牌时令牌里包含的用户名,密码,权限等信息的属性名要一致!

    530.maven工程写依赖的时候,先写<左小于号,然后会自动带出dependency的开始结束标签组id和项目id,写了项目id之后会自动带出组id.

    531.共性的代码可以提取到公共子项目中,然后作为依赖添加到其他子工程的依赖中.公共子工程可以没有启动类.

    532.SpringSecurity和JWT框架的SSO系统如果maven依赖错误可能导致前端页面错误,SpringSecurity框架里有默认的前端登录页面.

    533.Nacos在windows上的启动命令是:nacos的bin目录cmd,  .\startup.cmd -m standalone

        在Linux上的启动命令是:   ./startup.sh -m standalone

    534.前端和后端代码都可以加断点debug判断错误在哪里

    535.token令牌中的state和message的前后端写法要一致,authorities和token放入和取出属性名要一致

    536.Spring/微服务项目里,方法名如果大写编译时不会报错,但是运行时会出错,而且不会提示是大小写错误.

    537.Feign去调用远程服务时,不会死等,超时会报time out异常.

    538.市场上常用的注册中心:Google-Consul,Eureka,Alibaba-Nacos(每5秒一次心跳)-服务的注册/发现/配置/负载均衡.15秒没有检测到心跳会认为服务出问题,30秒没检测到心跳认为服务宕机.

    539.Spring项目中的依赖注入有@Autowired或@Resource注解方式进行装配.这两个注解的区别是:@Autowired默认按类型装配,@Resource默认按名称装配,当找不到名称匹配的bean时才会按类型装配.

    540.Spring里Bean的作用域:singleton,prototype,request,session,global-session,缺省的Spring bean 的作用域是Singleton(单例)

    541.yml等配置文件中的代码最好复制粘贴 自己手写很容易出错 而且没有任何错误提示,比如把config写出configure不会提示,但运行会报错!!!!

    542.写代码的话能复制粘贴的就不要手写,很容易出错.(单词错误,缩进错误,大小写错误,标点符号错误等)

    543.Log4j日志建议只使用四个级别,优先级从高到低分别是ERROR、WARN、INFO、DEBUG,并且,log4j默认的优先级为ERROR

        常用的日志级别是:debug,info,error.有些还有trace

    544.用Nacos做注册中心配置中心的项目,provider里的yml配置文件名称要写bootstrap.yml,配置中心的内容会把配置文件的内容覆盖!!!

    545.把配置写在配置中心的好处:配置修改时不用重启服务器.如果写在配置文件,那么配置修改,需要重启服务器.

        不会经常变化的内容一般写在配置文件而不是配置中心,比如服务器ip和端口,配置中心地址等

        经常变化的配置要写在配置中心比如nacos.

    546.服务启动后没有从配置中心获取我们的配置数据是什么原因:配置文件名是否正确?dataId是否正确?分组是否正确?配置的名字是否正确?

        缩进是否正确?假如是动态发布,是否有@RefreshScope注解?你项目中使用的日志规范是什么?(需要SLF4J日志对象)

    547.BeanFactory是工厂模式的实现,负责创建和管理bean.

        构造注入优点:构造期即创建一个完整、合法的对象,不需要写繁琐的set方法的,在构造函数中决定依赖关系的注入顺序

        在Spring中配置Bean的init-method在依赖注入之后执行

        SpringMVC 请求一个控制层资源时,可以在对应方法中直接使用参数变量接收参数数据,但参数变量的类型要为对象类型.

        在Controller方法中可以直接使用session对象向页面传值,@ModelAttribute注解在Controller方法的参数部分或Bean属性方法上使用

        BeanFactory的实现类的是ClassPathXmlApplicationContext,和FileSystemXmlApplicationContext

        Mybatis 的工作原理:SqlSessionFactory 根据 Mapper.xml 创建所有 statement,SqlSession 依据Mapper.xml 中的 id 找到并执行statement 中的方法

        Spring中配置Bean的id属性不是必须的,可以没有,id属性的值不可以重复

        mybatis核心配置文件中可以配置数据源和事务,映射文件应该和数据库中的表一一对应,当传入单个参数时,#{XXX} 名称可以是任意的

        SpringMVC和Spring说法正确的:SpringMVC是Spring的子级容器,SpringMVC中可以注入Spring容器的对象

        SpringMVC配置文件,配置文件有默认的名称,配置文件中需要配置视图解析器

        MyBatis实现一对多:

        是几个表联合查询,只查询一次,通过在resultMap里面配置collection节点配置一对多的类就可以完成。属于联合查询

        是先查一个表,根据这个表里面的结果的外键id,去再另外一个表里面查询数据,也是通过配置collection,但另外一个表的查询通过select节点配置。属于集合查询

        关于切入点的说法:是AOP中一系列连连接点的集合,在做AOP时定义切入点不是必须的,可以用正则表达式来定义切入点

        Spring中ApplicationContext能够用到的Bean的作用域:Singleton,Prototype,Session,GlobalSession,Request

        springmvc页面跳转:默认使用转发方式,如果Controller处理方法返回值是String,可使用"redirect:"前缀来重定向,

                          如果Controller处理方法返回值是ModelAndView,可使用RedirectView来重定向

        Spring的AOP的动态代理机制:CGLib库(继承父类),JDK动态代理(实现接口)

        IOC自动装载方法:byName,byType

        关于IOC的理解:控制反转,对象被动的接受依赖类

        Spring各模块之间关系:Spring各模块之间可以单独存在,Spring的核心模块是必须的,其他模块是基于核心模块

    548.AJAX缺陷是不能跨域.

    549.Sentinel:阿里开源的分布式系统的流量防卫兵.用于熔断限流,Sentinel控制台有缓存

        Sentinel启动命令:

        java -Dserver.port=8180 -Dcsp.sentinel.dashboard.server=localhost:8180 -Dproject.name=sentinel-dashboard -jar sentinel-dashboard-1.8.0.jar

        访问 http://localhost:8180/ 账号和密码都是sentinel

    550.QPS是每秒请求数量(query per second),流控编辑阈值,快速失败-生效后有Blocked by Sentinel (flow limiting)

    551.Sentinel限流措施:直接,关联,链路,降级

    552.小程序编码用的编程语言是JavaScript.其中页面跳转的标签是navigateTo.滚屏的标签是</scroll-view>

    553.常见的限流框架:sentinel,hystrix,常见的限流算法:计数,令牌桶,漏铜,滑动窗口.

    554.Sentinel的限流规则;QPS/线程数.

    555.Sentinel的限流模式:直接,关联,链路,降级

    556.当一个操作不是原子操作(可以拆分),被多个线程共享,那么就是线程不安全的.AtomicLong支持线程安全的自增操作.

    557.开发阶段不用集群,上线后才使用集群.服务器是不能轻易重启的.

    558.Url是Uri的子集,是uri的一种

    559.netty是最好的并发网络框架,网关gateway的核心是netty.网关可以实现负载均衡,把请求分配到不同的服务器上.

    560.Hadoop2.x组成:Common辅助工具,HDFS数据存储,Yarn资源调度,MapReduce计算.

        Yarn架构:ResourceManager资源管理器和NodeMangager节点管理器.

        MapReduce:Map并行处理输入数据(分),Reduce对Map阶段的数据进行汇总(和).

        Sqoop数据传递,Flume日志收集,Kafka消息队列,Hbase非关系型数据库,HDFS文件存储

        Spark Core内存计算(内存数据断电即失)

        Hive数据查询(sql),Mahout数据挖掘,Spark Mlib数据挖掘,SparkR数据分析,Spark Sql数据查询.SparkStreaming实时计算

        Flink对标Spark.

        Oozie任务调度,Azkaban任务调度(比前者简单).

    561.linux中/usr里的文件下是你安装linux系统时系统自带软件的安装目录。

        linux中/opt里的文件则是安装系统后用户自己安装的其他应用软件,一般是源码包的软件。

    562.DNS服务器:8.8.8.8是Google的公共DNS主服务器

       DNS为8.8.8.8是Google的DNS,用这个DNS不会被ISP的DNS劫持,心情不会被ISP弄坏,并且可访问的网页比ISP的DNS更多,但是正应为8.8.8.8是Google的DNS,而谷歌是国外的,所以用这个DNS,将8.8.8.8是Google的忍受网络龟速,8888解析的结果常将用户引导到较慢的网站。

       现在大中型网站目前都使用CDN做内容分发,确保用户就近接入而提高访问速度。同样的内容如taobao网页,深圳宽带用户访问的是taobao在广东的服务器,北京宽带用户访问的是taobao在北京的服务器。

       CDN是怎么做到就近接入的呢?关键就在于你用的DNS,你用哪个地方的DNS互联网公司基本认为你就是那个地方的宽带用户。如果你将DNS写错了,比如深圳宽带用户将DNS填写成北京的DNS,那么无论你访问taobao、sina你都被引导到北京去,网速自然慢了许多。所以说,DNS是流量牵引器,必须选合适的。

       说到这里,明白在国内使用8.8.8.8的坏处了吧?你将DNS填8.8.8.8,互联网公司都以为你是国外的用户,无法给你选出就近的服务器,随便给你个能用的就行了,你的网速自然慢了许多。 如果你无法忍受ISP的DNS劫持,又想访问一些用ISP的DNS无法访问的网页,那可以使用114.114.114.114,它在国内有几十个点,能引导你到最近的网站,没有8.8.8.8的弊端。

       虽然NDS填8.8.8.8,是有利弊,但是小编在这里建议你两个DNS都可以试试,那个快用那个。

       如果设置了NDS还是看高清卡的话,有可能是DNS服务器不稳定或被劫持。那你可以用用DNS优选。本应用是一款智能电视端绿色免费的专门用于上网优化DNS的工具。软件功能强大,操作简单。通过选取最优DNS解析服务器,来大大提高用户上网速度,让你的上网更加通畅。

    563.Linux重启网卡:service network restart

    564.Linux 跨主机拷贝文件方式: scp 当前文件路径  目标主机:文件路径

    565.Linux 跨主机递归拷贝文件夹方式: scp -r 当前文件路径  目标主机:文件路径

    566.Linux设置SSH无密码跨主机登录:ssh-keygen 再回车三下,每个主机上都要这样.

        cat id_rsa.pub >> authorized_keys

        scp authorized_keys slave2:~/.ssh

    567.Linux中找不到ifconfig命令的解决方法:yum install net-tools.x86_64 -y

    568.Gateway在互联网架构中的位置:F5->NGINX->GATEWAY->微服务.

    569.网关中的Predicate(断言)又称谓词,用于条件判断,只有断言结果都为真,才会真正的执行路由。断言其本质就是定义路由转发的条件.

        常用谓词逻辑:Path,Before,After,Ip,Cookie,Method,Head.可以自己定义谓词工厂.

    570.MONO是Spring WEBFLUX中的响应序列.

    571.idea复制粘贴项目时容易出现jdk编译版本不一致的问题,需要到file-settings-build-compiler-java compiler里修改jdk的版本.

    572.Idea里面指定jdk编译版本:

        <!--指定jdk编译版本-->

        <properties>

            <maven.compiler.source>8</maven.compiler.source>

            <maven.compiler.target>8</maven.compiler.target>

        </properties>

    573.Hadoop启动命令:

        格式化namenode :

        # bin/hdfs namenode -format

        启动hdfs :     

        # sbin/hadoop-daemon.sh start namenode

        # sbin/hadoop-daemon.sh start datanode

        启动后通过访问http://Ip地址:50070/判断是否启动成功

        启动Yarn集群:

        # sbin/start-yarn.sh

        一次性启动所有节点:sbin/sh start-all.sh,这个命令已经过时,新命令start-dfs.sh #启动hdfs  start-yarn.sh #启动yarn资源管理器

        一次性停止所有节点:sbin/sh stop-all.sh

        启动后通过访问http://Ip地址:8088/判断是否启动成功

        HDFS副本数: hdfs-site.xml里设置

        伪分布式安装HDFS,副本数只有一个

        集群安装HDFS,默认副本数是3个,可以修改参数:dfs.replication,官方也定义了最大副本数是512个,参数:dfs.replication.max。

        hadoop集群启动后datanode没有启动的原因:多次格式化namenode导致的namenode与datanode之间的不一致导致,停止集群,删除datanode存放的路径的curren数据.

    574.hadoop知识点:

        hdfs分布式存储,

        namenode管理节点和元数据,

        secondaryNameNode不是namenode的备份而是用于辅助namenode完成edits文件的滚动。

        namenode与secondarynamenode不要放在同一个节点:单节点内存大小有物理限制.

        datanode深层路径里保存的数据文件blk_1073741838类似这种格式的,一般是数据的源文件,可以编辑修改,但是不要修改,因为修改不会同步到其他节点.

        元数据保存在hadaoop.tmp.dir路径下

    元数据包含:文件存储路径,文件的权限,

    文件大小,区块大小,区块ID,区块对应的节点,副本数量。

        元数据存在内存(查询快)和磁盘中(备份用于奔溃恢复)

    元数据文件:edits记录写操作,

        fsimage镜像文件它记录元数据该数据落后于内存中元数据

    先把操作记录到edits_inprogress再执行内存元数据更新,

        fsimage更新时是将edits中的操作取出并执行到fsimage里,更新时会生成新的edits_inprogress文件,

        fsimage/edits更新滚动时机,空间:是当edits文件达到指定大小(64m,可以通过fs.checkpoint.size设置,在core里配置)时,

        时间:每隔1个小时滚动更新一次,时间可以通过fs.checkpoint.period更新,

        重启:namenode重启时也会更新,也可以强制滚动:Hadoop dfsadmin -rollEdits

    namenode

        在安全模式(safemode)只提供读服务

       

    datanode数据节点:

    默认一个block区块128M,dfs.blocksize可以改区块大小

    数据共保存3份,正本1份,副本2份.

       

    hdfs的根目录是/

    上传文件hadoop fs  -put 文件名 目录

       

    通过blockId确定区块顺序

    不同的block区块可以在同一个datanode上

    但是同一个block区块的副本不在同一个datanode节点上,

        不然备份无意义

    数据分片存储的原因:可以快速备份,化整为零,

        datanode会定期(每隔3秒可以延长比如1分钟一次)向namenode发送心跳,心跳通过RPC机制发送,

        心跳包含block信息和当前datanode的状态(预服役,服役,预退役),如果10分钟没有收到心跳,认为该节点lost,

        会将该节点数据备份到其他节点保证副本数量。如果等到了心跳则会对节点的数据进行校验,核对元数据是否一致,

        如果不一致会继续校验。

    集群内部上传,第一个副本在负责上传的节点上,集群外部上传,第一个副本在比较空闲的节点上。

        2.7版本之前第二个副本放在和第一个副本不同机架的节点上用于数据的安全保存。第三副本和第二副本在同一个机架节点上方便传输。

        2.7版本之后,第二和第三副本在不同机架节点上。更多副本,谁闲放谁上面。

        Hadoop有机架感知策略(不是物理机架是逻辑机架,本质是映射,不同物理机架可以映射到同一个逻辑机架),默认不开启,

        实际生产需要开启,用配置文件开启。实际过程中会将同一个物理机架的节点映射到同一个逻辑机架上。

        副本数量不能超过节点数,否则安全模式出不来。

        可以强制退出安全模式:

    Hadoop dfsadmin -safemod leave

    datanode用于存放block数据区块

    BlockPool区块池

       

    阿里云服务器节点数量5万左右

        查看hadoop的MapReduce计算的输出结果hadoop fs -ls output

        查看hadoop的MapReduce的wordcount计算的输出结果hadoop fs -ls wordcountoutput

        查看hadoop的MapReduce计算的输出结果详细信息:hadoop fs -cat output/fileName(结果文件名比如:part-r-00000)

        hadoop里创建input数据源路径:hdfs dfs -mkdir -p /user/root/input (具体路径要看自己的配置文件)

        将文件放入input数据源路径:hdfs dfs -put ./*.xml input

    575.开发阶段日志级别一般是debug 生产实际上线后日志级别是error.

    576.拿到项目先连接数据库再跑起来.

    577.Docker容器相当于光驱

    578.Hadoop集群宿主机账号root,密码自己的常用密码.

    579.linux里面sed批量修改操作:

        sed -i 's#${system:java.io.tmpdir}#/software/hive/tmp#g' hive-site.xml

        sed -i 就是直接对文本文件进行操作的:命令如下:

        sed -i 's/原字符串/新字符串/' /home/1.txt  (/home/1.txt表示要修改的目标文件,包含路径和文件名.)

        sed -i 's/原字符串/新字符串/g' /home/1.txt

    580.启动hive前要先启动hadoop:

        hive里的derby数据库初始化:

        mv metastore_db metastore_db.tmp

        schematool -initSchema -dbType derby

        关闭hdfs安全模式:hdfs dfsadmin -safemode leave

    581.docker指令区分大小写,docker常用指令:

        systemctl start docker:启动docker服务

        systemctl restart docker:重启docker服务

        systemctl enable docker:设定docker开机自启

        docker info:查看镜像配置

        docker --help:查看帮助

        docker pull 镜像名: 下载镜像

        docker images:查看所有镜像

        docker  ps  :查看已启动/正在运行的docker容器(可以看到容器ID 镜像名 命令 创建时间 状态 端口 容器名)

        docker ps –all:查看所有镜像,包含没有运行的镜像容器

        docker run -it 镜像名 (bash): 让镜像交互式运行

        docker run -d  镜像名: 让镜像在后台运行   

        docker stop 容器id :停止指定的docker容器

        docker restart 容器id :重启指定的docker容器

        docker image rm 服务名/服务id: 删除docker 镜像

        docker save 镜像名 | gzip>镜像名.tar.gz:  在当前目录保存并压缩镜像

        docker load < 镜像压缩包名:  在当前目录导入镜像

        docker load -i 镜像文件名:导入镜像

        docker container logs 容器ID: 查看容器日志

        假如镜像被占用着是不可以直接被删除的,需要先删除应用此镜像的容器:

        docker container rm 容器名或容器id

        docker container prune: 移除所有停止的容器

        docker volume create 数据卷名:创建数据卷,创建数据卷时会在宿主机默认的目录创建,也就是宿主机的目录不用指定,程序会自动指定宿主机目录.

        挂载数据卷的宿主机默认目录是 /var/lib/docker/volumes

        docker volume ls : 查看数据卷

        docker inspect 数据卷名:查看容器信息(里面的mounts是数据卷的挂载信息)

        docker: invalid reference format.错误提示说明docker命令没有写对,可能多了一个空格.

        docker run -it -v container-vol(数据卷名):/容器目录 centos:7(容器名) bash :挂载数据卷到容器目录(必须事先创建好数据卷,-v表示挂载数据卷或目录)

        docker run -it -v 宿主机目录:/容器目录 centos:7(容器名) bash :挂载容器目录到宿主机指定目录

        比如: docker run -it -v /usr/app:/opt/app centos:7 bash,容器里的目录相当于宿主机目录的快捷方式

        其中:

        1)/usr/app:为宿主机目录

        2)/opt/app: 为启动容器的一个目录

        3)-v 用于指定挂载目录,如果本地目录(宿主机目录)不存在, Docker 会自动为你按照挂载目录进行目录的创建。

        容器目录和宿主机目录的映射关系叫挂载.

        docker volume rm 数据卷名 :移除数据卷

        docker volume prune :清理无主数据卷.

        docker volume ls :查看数据卷 当数据卷的名字为乱码时 属于匿名数据卷

        docker  exec 容器名:进入正在运行的容器.

        docker exec -it mysql(容器名) bash:进入正在运行的容器

        docker history 镜像名:查看历史

        镜像由程序包+运行环境构成.所有镜像创建时都需要一个空的centos镜像

        Docker 镜像是一个特殊的文件系统,除了提供容器运行时所需的程序、库、资源、配置等文件外,   

        还包含了一些为运行时准备的一些配置参数(如匿名卷、环境变量、用户等)。镜像不包含任何动态数据,其内容在构建之后也不会被改变。

        镜像(Image)和容器(Container)的关系,就像是光盘和光驱(或者是类与对象),容器是镜像运行时的载体。

        容器可以被创建、启动、停止、删除、暂停等。

        容器的本质是进程,但与直接在宿主机执行的进程不同,容器进程运行于属于自己的独立的 命名空间。

        docker也是虚拟化技术,容器化技术,类似于迷你版虚拟机.

        docker镜像成为软件项目交付的标准.

        docker --link: 连接到某容器,相当于在容器内的hosts文件里增加了映射(现在已经不建议使用了)

    582.mobaxterm里面的路径进不去提示没有权限,可能是创建session时没有勾选specify username.

    583.Docker创建镜像步骤:centos:7镜像,程序压缩包,touch Dockerfile,

        配置Dockfile:

        FROM centos:7

        ADD jdk-8u51-linux-x64.tar.gz /usr/local/docker

        ENV JAVA_HOME=/usr/local/docker/jdk1.8.0_51 \

            PATH=/usr/local/docker/jdk1.8.0_51/bin:$PATH

        CMD [‘bash’]

        docker build -t jdk:8 .  (#不要丢掉这里的点): 用Dockfile构建镜像

        推送镜像到远程仓库的步骤: 共3步

        1.docker login(第一次登录或推送时需要)

        2.docker tag 镜像ID apespring(docker hub的账户名)/sp-eureka:v1(镜像名:版本号)

        3.docker push apespring(docker hub的账户名)/sp-eureka:v1(镜像名:版本号)

        指定端口运行容器举例: -d表示后台运行,一行一行的复制,不要复制整段,如果把换行复制了会报错.

        docker run -d   \

        -p 8180:8080 --name sentinel  \

        -v /usr/local/docker/sentinel/logs:/root/logs/csp sentinel:8  (-v表示挂载数据卷或目录--数据双向绑定)

        容器之间配置信息可以传递,数据卷的生命周期持续到没有容器使用它为止.

        挂载目录时可以不指定宿主机的目录,这样会挂载到默认目录这样属于匿名挂载容易导致数据找不到,一般不要使用.

        容器和宿主机的端口映射:8180是宿主机端口,对应的是8080是容器端口,宿主机的同一个端口只有一个,容器有多个.

        容器和宿主机的目录映射:宿主机目录/usr/local/docker/sentinel/logs; 对应的容器目录/root/logs/csp.

        指定端口和名字运行容器: docker run -p 80:80 --name nginx01  -d nginx

        如果没有做端口映射,是访问不了web界面的.

        查看容器在宿主机的默认挂载信息:docker inspect 容器名/容器id

        复制容器里文件资源到宿主机的目录:docker cp -a nginx01(容器名):/etc/nginx /usr/local/docker/nginx(宿主机目录)

        例如 docker cp -a 容器名:/etc/nginx(容器目录) /usr/local/docker/nginx(宿主机目录)

        复制宿主机文件到容器中 docker cp elasticsearch-analysis-ik-7.9.3.zip node1:/root/

        docker network create -d bridge netname:容器内创建虚拟网络

        docker network create -d bridge netname --subnet x.x.x.x --gateway x.x.x.x netname. 容器内创建网络(指定子网和网关)

        docker network ls :查看网络信息

        容器和容器之间如果不用虚拟网络通信的话,需要用宿主机的端口映射才能通信.

        docker search 镜像名 :搜索镜像,相当于去镜像市场docker hub搜索

        exit: 停止容器并退出

        ctrl+P+Q: 容器不停止情况下退出

        docker 运行时可以用 bin/sh -c 编写shell脚本

        docker commit -m 注释 -a 作者 容器id 镜像名:tag :提交自己的容器为镜像(相当于保存容器的状态/类似于虚拟机快照)

        docker rm -f $(docker ps -aq):清理所有容器

    584.JAVA在linux上运行带包的class文件:

        1,cd到Test.java(文件名)所在目录,运行javac Test.java

        2.cd 到目录外层执行java 包名.Test(类名)

    585.docker运行容器时 容器名字可以自己指定.同一个镜像可以用不同的名字运行多个容器.

    589.docker中的数据卷是保存在宿主机中,docker是内核级别的虚拟化技术.

    590.mysql命令行清屏: system clear

        mysql占用端口3306的进程是关不掉的,杀掉进程后会自动重启.

    591.linux查看某一端口使用情况的命令:lsof -i:端口号,根据PID关闭进程,使用命令:kill -9 进程号

        linux查看内核版本:cat /proc/version

    592.从redis容器进入redis数据库: redis-cli, 如果有密码需要加上 auth 密码

        进入redis集群: redis-cli -c

        查看集群节点:cluster nodes

        查看集群信息:cluster info

        连接远程redis: redis-cli -h 192.168.232.11 -p 6379  -a 123456(-a表示密码)

        redis查看版本 redis-cli -v  ,

        查看所有键: keys * ,查看m开头的所有键: keys m*

      对string的操作:

        set,设置值

        get,获取值

        setex 设置值和过期时间

        setnx:不存在则设置,如果存在则不设置(setIfAbsent或者setNx,很重要,用于分布式锁,redisson可以对锁续命)

        getset:如果存在,获取原来的值并设置新的值

        getrange,获取部分范围的值

        setrange,设置部分范围的值   

        数据库是由一个整数索引标识,而不是由一个数据库名称

        redis里的数据库,默认从索引0开始,查看其它数据库 用select id 库编号

        redis默认有16个库/索引,从0到15.

        redis 中的默认数据库数量为16个,但没有数据表,在配置文件中下面的参数来控制数据库总数:redis/redis.conf(配置文件)

        可以在配置文件中设置key的缓存时间,时间过了之后数据消失.

        进入redis容器不等于进入了redis系统

        redis里flushdb清空当前数据库,flushall清空所有数据库

        expire mykey 8:设置key的有效时长,单位秒.

        ttl mykey:查看剩余时间,返回-2表示键超时已经被删除.返回-1表示键存在但未设置时效时间.

        通过persist让对特定key设置的生效时长失效:

        语法:persist key

        pexpire 让key的生效时长以毫秒作为计量单位,可应用于秒杀场景:

        语法: pexpire key ,设置生存时间为毫秒,可以做到更精确的控制

        incr mykey :每次自增1

        incrby mykey 10:每次自增10,如果键时效之后再自增,就从0开始自增,时效的键还可以自增操作

        decrby mykey 10:每次自减10

        mset key1 v1 key2 v2 批量设置多个键值对

        mget key1 key2 批量获取多个值

        strlen mykey 统计key对应值的字符串长度(如果是中文的话 一个汉字是3个字节)set

      对map的存储

        hset mapname key value :在redis里存入hashmap对象,mapname是对象的名字,key是map里某个键,value是键对应的值.

        hget mapname key :获取hashmap对象键的值.

        hmset 批量设置,hmget 批量获取

        hgetall mapname :获取hashmap所有的值.

        hvals mapname :获取hashmap所有的值

        hkeys mapname:获取hashmap所有的键

        hincrby mapname key:增加某个键的值

        hdel mapname key: 删除键值

      对list的存储:

        lpush  最新一个放在最左边

        rpush  最新一个放在最右边

        lpop  listname count(移除元素的数量) 移除最左边的元素

        rpop  listname count(移除元素的数量) 移除最右边的元素

        lrange listname key1 key2 :取出索引范围内的值

        llen取出list长度

      对set的存储: 区别于zset有序的set   

        sadd setname value :给集合里添加元素(不可以重复的元素)

        smembers setname:获取集合元素

        sismember setname value:判断是否集合成员,是的话返回1,不是返回0

        lset listname key value: 设置集合某元素的值(相当于修改)

        l是左边相当于头部,r是右边相当于尾部

        lrem count element 从key对应list中删除count个和element相同的元素:

        count>0时,按从头到尾的顺序删除

        count<0时,按从尾到头的顺序删除,

        count=0时,删除全部

        scard: 获取集合中成员个数

        redis也可以实现单点登录,登录后将用户信息保存到redis里面

        RedisTemplate在使用时需要指定泛型,不然存入的数据会有乱码.

        redis数据持久化方式:   redis属于内存数据库

        数据持久化是指数据从内存写出到磁盘,内存的数据是断电即失的,如果不持久化到磁盘,数据丢失.

        主动持久化和被动持久化,rdb和aof,

        rdb方式是默认开启的,60秒,300秒,900秒或者自己设置,最新的rdb文件有最新的数据

        aof本质是操作日志,需要开启,才会使用这个持久化方式,这种方式会有io阻塞.

        save(阻塞式持久化,该方式会影响后续操作的进行):将当前 Redis 实例的所有数据快照(snapshot)以 RDB 文件的形式保存到硬盘。

        bgsave(异步持久化):BGSAVE 命令执行之后立即返回 OK ,然后 Redis fork 出一个新子进程,原来的 Redis 进程(父进程)继续处理客户端请求,而子进程则负责将数据保存到磁盘,然后退出

        shutdown

        redis进行事务控制时,通常是基于如下指令进行实现:

        multi 开启事务,如果没有开启监控,会阻塞进程,当前事务没有完毕,别的进程不能修改.

        exec 提交事务

        discard 取消事务

        watch 监控,如果监控的值发生变化,则提交事务时会失败

        unwatch 去掉监控

        redis-benchmark -c 100 -n 100000: redis的压力测试,-c表示客户端数量,-n表示请求数.

        flushall:清空全部数据库

        flushdb: 清空当前数据库

      对Zset有序集合的操作:

      对Geospatial地理位置的操作:

      Geoadd: 键 经度 维度 城市名称(经纬度数据如果超出范围会报错)

      Geodist:获取两个城市的举例:键 城市1 城市2

      Geohash:

      Getpos:获取指定城市的定位: 键 城市名

      Georadius:获取半径内的城市: 键  经度 维度 半径

      Georadiusbymember:

      对Hyperloglog类型的操作:

        PFadd

        PFcount

        PFmerge 合并去重

      对Bitmap位图的操作:

      setbit:

      getbit:

      bitcount:统计

      Redis其他数据类型:地理位置,基数统计/网络UV日志,位图

      主从复制集群架构:主节点master可读可写,从节点slave只能读, 从节点会备份主节点的数据.

      通过命令行设置主从关系:进入redis数据库之后,设置主从关系:slaveof 172.17.0.2 6379(ip:port),通过命令设置的主从关系是暂时的.

      也可以通过配置文件redis.conf设置主从关系,这种方式设置的主从关系是持久的.

      info replication:查看主从关系.

      主节点master如果设置了密码的话,那么从节点slave可能无法访问.

      通过命令行设置主从关系:主节点宕机的话,从节点不能写数据,这时的从节点还是连接到原来的主节点(还是保持主从关系),等主节点恢复时,从节点依旧可以读取到主节点写入的数据.

      如果主节点写数据时,从节点宕机的话,从节点不能保存主节点的数据,再重启从节点时,从节点默认是主节点,需要设置主从关系,才能变为从节点.

      只要变为从节点,那么主节点的数据会立即全量复制到从节点(第一次连接后全量复制).之后主节点数据更新时,数据会增量复制到从节点.

      主从关系有层层链路模式:就是 主--从--从--从这种模式(M-S-S-S),从节点后面还可以连接从节点,但是最前面的从节点属性还是从节点只能读不能写.

      主节点宕机之后,从节点可以设置slave of no one来变为主节点.

      单机的redis几乎不能达到QPS/秒,除非硬件性能非常好,要实现高并发就要用读写分离和主从架构.

      哨兵(Sentinel)是Redis的主从架构模式下,实现高可用性(high availability)的一种机制。

    由一个或多个Sentinel实例(instance)组成的Sentinel系统

     (system)可以监视任意多个主服务器,以及这些主服务器属下的所有从服务器,并在被监视的主服务器进入下线状态时,

      自动将下线主服务器属下的某个从服务器升级为新的主服务器,然后由新的主服务器代替已下线的主服务器继续处理命令请求。

      哨兵模式(自动选举主节点):主节点宕机,从节点会顶替主节点成为主节点,原来的主节点成为从节点,没有配置哨兵模式的主从复制架构没有这种功能.

      哨兵模式:基于主从复制,主从可以切换,故障可以转移,系统可用性较好.缺点:不方便在线扩容

      哨兵模式配置文件:sentinel.conf文件

      sentinel monitor redis6379 172.17.0.2 6379 1 (核心配置)

      如上指令表示要的监控的master, redis6379为服务名, 172.17.0.2和6379为master的ip和端口,1表示多少个sentinel认为一个master失效时,master才算真正失效.

      redis-sentinel sentinel.conf(启动哨兵模式)

    593.linux(或docker容器)安装vim失败(Unable to locate package vim)如何解决:

        apt-get update

        apt-get install vim

        或yum -y install vim*

    594.docker容器里的配置文件如果不能修改的话,要么在容器中安装vim编辑器,要么将容器里的配置文件挂载或者复制到宿主机

    595.docker里的创建数据卷相当于在宿主机指定目录里创建一个文件夹.数据卷代表宿主机的一个目录.

    596.分布式环境不会采用数据库 * 表中自带的自增策略-auto_increment

    597.java中 pom.xml中parent和dependency及dependencyManagement依赖的区别:

        通过<parent>引用的项目A,

        可以使用A项目中<dependency>中依赖的StringUtils的方法,

        但是不能调用A项目中自己定义的类和方法,

        C项目中通过<dependency>依赖的A,两者却都可以调用。

        parent:将需要依赖的jar包放到一个模块中,然后使用parent来标识依赖包,

        方便版本修改,只需要修改模块中版本,parent标记中可以不用版本号。

        有两个web项目A、B,一个java项目C

        它们都需要用到同一个jar包:common.jar。

        如果分别在三个项目的pom文件中定义各自对common.jar的依赖,

        那么当common.jar的版本发生变化时,

        三个项目的pom文件都要改,项目越多要改的地方就越多,很麻烦。

        这时候就需要用到parent标签, 我们创建一个parent项目,

        打包类型为pom,parent项目中不存放任何代码,

        只是管理多个项目之间公共的依赖。

        在parent项目的pom文件中定义对common.jar的依赖,

        ABC三个子项目中只需要定义<parent></parent>,

        parent标签中写上parent项目的pom坐标就可以引用到common.jar了

        如果<dependencies>和<dependencyManagement>中都对该jar做了依赖,

       以<dependencies>的为准,优先级高于<dependencyManagement>。

       若前者没有对其依赖,而后者对其有依赖,则以后者为准。<dependencyManagement>里只是声明依赖,并不实现引入.

    598.idea创建的maven工程里测试类和java源码类的包路径要一样,否则会报错.

    599.Test类的执行报错有可能是@Test注解的包引错了

    600.大数据时代的3V: 1海量volume,2.多样variety,3.实时velocity

        大数据时代的3高: 1.高并发,high concure 2高性能,high perfermance 2高可用high avaibility

    601.业务越来越完善,对开发的要求越来越高.

    601.指定端口运行java项目:java -jar item.jar --server.port:8001

    602.Feign通过集成ribbon已经默认实现负载均衡功能,也默认实现了重试功能.(单台服务器重试次数,更换服务器次数)

        ribbon.Connectout=1000毫秒,与后台服务器建立网络连接的超时时间

        ribbon.ReadTimeout=1000毫秒,发送请求后,超时等待最长时间

        ribbon默认只对Get请求开启重试

    603.Freemarker可以生成静态网页模板如商品详情,还可以生成sql等脚本

    604.IDEA里面搜索类用shift+shift,搜索备注和文件内容用ctrl+H

    605.UML类图里属性和方法可见性的表示方法:-private,+public,#protected,~波浪线表示package/default.

    606.Java.util.timer定时器类,timer.schedule(任务,延迟时间,周期)方法

    607.redis里的zset相当于有序的set,两列字段,一列存value,另一列存索引.

       zset的添加和移除的时间复杂度比较高,可以优化为list+zset,优先级高的放在linkedlist里面因为它增删快.

       优先级低的放在zset,zset里的数据可以定时刷新到list里面.

       redis的keys模糊匹配生产中会被禁用,因为cpu使用率高.

       用scan代替keys *的模糊查询.优化查询效率.

       redis里有管道pipeline支持命令批量执行,相当于多个操作共用一个连接请求,降低延时提高吞吐量.

       redis使用管道可以将执行时间缩减到原来的40分之一左右.

    608.数据库里longblob对应java的byte[],bigint相当于long.

    609.idea里的设置里的inspection可以设置序列化接口的UID,然后光标放在类名上,按住alt+Enter可以自动添加UID

    610.idea里面接口飘红的问题:设置里的inspection-spring-Autowired for Bean报错改成警告就行了.

    611.lombok注解:callSuper=false:不继承父类某方法.Version注解表示乐观锁,需要添加乐观锁的拦截器Bean(版本号自动维护,更新一次,版本号加一次)

    612.Spring声明式事务处理:加上@Transactional注解到方法上,如果有异常会回滚.

        事务不生效的原因:1.数据库表的引擎是MyIsam不支持事务,2.private/protected方法不支持事务.

        3.捕获了异常但是未向外抛出4.发生不检测的异常比如runtimeException类异常(空指针,索引越界,类转换异常等)无法回滚.

        4.如果想对非检测异常进行回滚,需要在@Transactional注解上指定rollbackfor="异常类型"

        5.@Transactional注解如果写到接口的方法上是不生效的,要写在实现类的方法上.

        6.Spring事务传播策略在内部方法调用时不生效,事务注解要加到直接调用的方法上.

        7.只读操作可以不开启事务.

    613.工具类BeanUtils.copyProperties()可以拷贝属性

    614.定时任务的方案:Timer或ScheduleExecutorService或者Spring-task加@Schedule注解和@EnableSchedule就行了.

    615.使用 cron 表达式来定义定时任务的执行时间策略:[秒] [分] [时] [日] [月] [周] [年]

        下面给出一些示例,可根据上面的解释进行练习解读:

        每隔 1 秒钟执行一次:*/1 * * * * ?

        每隔 1 分钟执行一次:0 */1 * * * ?

        每天 23 点执行一次:0 0 23 * * ?

        每月 1 号凌晨 1 点执行一次:0 0 1 1 * ?

        每月最后一天 23 点执行一次:0 0 23 L * ?

        每周星期天凌晨 1 点实行一次:0 0 1 ? * L

        在 26 分、29 分、33 分执行一次:0 26,29,33 * * * ?

    616.启动线程的方式:执行thread类的start方法.没有通过线程池创建的线程属于野线程,因为它缺乏管理.

        通过线程池创建线程可以实现线程的复用,减少资源的消耗.

    617.线程池submit里callable会返回执行结果,runable不返回执行结果.

        线程池对象的invokeAll方法可以批量执行一个任务list.

    618.阿里巴巴开发规范里线程池不允许使用Executors去创建,而是通过ThreadPoolExecutor的方式,这样的处理方法让写的人更加明确

        线程池的运行规则,Executors创建线程池对象的弊端有:

        固定数量线程池FixedThreadPool和SingleThreadPool允许请求的任务等待队列长度为Integer.MAX-Value

        可能会堆积大量的请求任务,从而导致OOM,内存溢出.

        可缓存线程池CachedThreadPool和ScheduleThreadPool允许创建的最大线程数是Integer.MAX-Value

        可能会创建大量的线程,从而导致OOM内存溢出.

        线程池参数不能胡乱的指定,否则影响性能.

        任务类型:1.IO密集型(线程数为CPU核数的两倍),2.CPU密集型(线程数等于CPU核数).

    619.SpringBoot默认情况下自动配置了ThreadPoolTaskExecutor到IOC容器,我们需要的时候直接加注解注入即可.

    620.SpringBoot里的给启动类加@EnableAsync注解,给方法加@Async("指定线程池")注解可以开启多线程.

    621.可以给线程添加日志,实现对线程的监控.

    622.zuul网关的功能:1.统一入口2.路由转发3.熔断降级4.负载均衡/重试(重试一般往后添加,不在前面加重试)

        5.安全认证(鉴权)6.日志监控.

        zuul有5个默认的过滤器.

        zuul默认集成了ribbon和hystrix.  hystrix日志聚合工具Turbine.

        Hystrix用于做容错降级和限流熔断(访问压力大就断开链路)

    623.springboot默认集成了logback日志框架,Lombok默认集成了SL4FJ日志接口.

    624.springboot里面有@Valid注解,用于对方法的参数进行校验,参数必须是对象,然后对象所属类里的属性要加

        @Max,@Size,@Null等注解,但是这些注解不能加在Pojo类上,因为这些类和数据库的表是对应的,如果加了会导致增删改查出现问题.

    625.安装rabbitmq镜像的步骤:

        #添加宿主机的配置目录和配置文件

        mkdir /etc/rabbitmq

        vim /etc/rabbitmq/rabbitmq.conf

        # 添加两行配置:

        default_user = admin

        default_pass = admin

        #运行容器,并指定端口,挂载目录

        docker run -d --name rabbit \

        -p 5672:5672 \

        -p 15672:15672 \

        -v /etc/rabbitmq/rabbitmq.conf:/etc/rabbitmq/rabbitmq.conf \

        -e RABBITMQ_CONFIG_FILE=/etc/rabbitmq/rabbitmq.conf \

        rabbitmq:management

        指定端口运行tomcat容器(--restart=always表示自动重启):

        docker run -d --name tomcat --restart=always \

        -p 8888:8080 \

        -v /opt/web:/usr/local/tomcat/webapps/ROOT \

        tomcat:latest

    626.中间件屏蔽底层操作系统的复杂性.中间件可以将不同语言开发的模块连接起来.中间件遵守一定的规范比如tcp/ip协议.小项目使用缓存和中间件.

    627.rabbitMq里面的queues是队列,里面的ready是准备发送消息,unacked是未确认回执的消息.State :当前的状态,running:运行中;idle:空闲.

    628.rabbitMq里面的队列不能覆盖,也就是说先后创建的队列名字不能一样,如果名字一样就是同一个队列;同一个名字的队列创建时是非持久化的再改为持久化的是不会成功的.

    629.rabbitmq里交换机的类型:1.direct2.fanout3.topic,群发消息用的交换机类型是fanout.(广播模式),消息发送者相当于广播电台,消息消费者相当于收音机(需要调到频道才能接收)

        队列不存在的话,投递消息不会成功,队列也不会自动创建,需要代码创建或在web管理后台上创建.

        fanout:会把所有发送到该交换器的消息都路由到所有与该交换器绑定的队列去。

        direct:精确匹配,会把消息路由到BindingKey(绑定键)与RoutingKey(路由键)匹配的队列中去.direct模式有性能损耗

        topic:模糊匹配,与direct类似,但是匹配规则有些不同。

        topic交换机路由匹配规则: #匹配零个/一级或多级,*匹配零个或一级.点号区分不同级.

        work模式自动应答:轮询分发消息,消息是平均分配到多个消费服务器上的,不会因为服务器的性能不同而分配不同数量的消息.

        work模式手动应答+basicQos(每次从队列取出多少条消息):公平轮询分发消息,消息是公平分配到多个消费服务器上的,会因为服务器的性能效率不同而分配不同数量的消息,多劳多得.

        basicQos要根据内存性能设置.basicQos(预抓取消息数量)

        交换机不保存消息,消息可以存到队列,消息如果无人接收就会被抛弃.

        生产环境中raabitmq里的消息应答/回执一般采取手动回执,不会采取自动回执.

        amqp协议是在tcp/ip协议上包裹了队列信息,交换机信息,通道信息等

        rabbitmq有默认的交换机,如果不指定交换机会绑定默认交换机,所以一般需要指定交换机.

        rabbitmq可以设置过期队列,也就是TTL队列,添加x-message-ttl属性值就可以设置队列里消息的过期时间.

        如果配置了死信策略,包括配置了死信交换机和死信队列,那么当消息过期,消息被拒绝,队列超出长度限制时(超出x-max-length),消息会进入死信队列.

        配置死信策略的方法,1.创建死信队列,2.创建死信交换机并绑定死信队列和路由键(如果死信交换机是fanout类型就不用配置路由键)

        3.将要处理死信的队列绑定死信交换机和死信路由键,那么当该队列产生死信就会死信就会进入死信队列.

        当rabbitmq的虚拟内存和磁盘空间超出设定的阈值时,队列的消息会处于阻塞blocking状态.

    630.可插拔性,解耦

    631.集群实现高可靠(故障率极低):主从节点,主从共享数据,主从同步(拷贝副本到从节点),主从转发,多主多从.

    632.命令行运行zipkin命令:java -jar zipkin-server-2.23.2-exec.jar --zipkin.collector.rabbitmq.uri=amqp://admin:admin@192.168.232.11:5672

        zipkin要搭配sleuth监听器使用;实现微服务的链路追踪,服务的调用关系,方便找到出现错误的服务,查看微服务的状态.

    633.Feign:用于远程调用,可以用dubbo代替,Bus是消息总线,bus的交换机是topic类型(模糊匹配)

    634.rabbimq能将请求延时到队列,降低服务器的压力,提高稳定性.

    635.mysql数据库如果导入sql失败可以尝试以下操作:

        set global max_allowed_packet=100000000;

        set global net_buffer_length=100000;

        SET GLOBAL  interactive_timeout=28800000;

        SET GLOBAL  wait_timeout=28800000

    636.idea里面批量查找替换代码快捷键:ctrl+F

    637.RabbitMq用erlang语言编写,erlang天生具备分布式特点.

    638.分布式事务:不同服务间保持数据的完整性和一致性.

    639.Feign实现了负载均衡和Rest调用的开源框架,openFeign封装了Ribbon(负载均衡/超时重试)和RestTemplate实现了WebService面向接口编程.

       Feign是一种声明式,模板化的HTTP客户端(仅在Consumer中使用),Feign旨在使编写JAVA HTTP客户端变得更加容易.

       Feign简化了RestTmeplate代码.使用Feign实现负载均衡是首选方案,只需要创建一个接口,在接口上添加注解即可.

       像调用本地方法一样调用远程方法.

       Fiegn的使用主要分为以下几个步骤:

       1.服务的消费方添加Feign依赖,一般添加openfeign

       2.创建业务层接口(复制需要调用的业务接口),添加@FeignClient("服务名"(注册中心注册的服务名))注解,声明需要调用的服务

       3.业务层抽象方法使用SpringMVC注解配置服务地址及参数,控制层注入需要调用的业务接口.

       4.启动类添加@EnableFeignClients(basePackage={"指定包"})注解激活Feign组件.

       5.在启动类或配置类注入负载均衡Bean对象实现负载均衡策略.(如果不注入策略,默认就是轮询策略)

       6.调用远程服务时可以开启Gzip压缩,减少传递数据的大小.

    640.HTTP连接需要3次握手,4次挥手.HTTPClient可以提高效率,提高健壮性和吞吐量.

    641.Zookeeper(Curator框架)可以实现分布式集群选主.(从节点备份数据,主节点如果宕机,从节点升级为主节点,实现高可用).

    642.@PostConstruct标注的方法会在依赖注入,也就是autowired之后执行.

    643.Spring里的amqp发送的消息默认是持久化的,amqp队列默认也是持久化的.

    644.Spring 中提供了一个 jdbc 脚本执行器,使用这个工具可以非常方便的运行一个 sql 脚本文件,下面是这个方法:

        ScriptUtils.executeSqlScript()

    645.@Service,@Repository不能写在接口上,需要写在接口的实现类上,@Autowired注入的时候,可以用接口注入,也可以用接口的实现类注入。

        @SpringBootApplication默认扫描的是所在包以及子包。

    646.分布式事务实现的方法ACID,AD用日志实现,CI用锁实现,用日志可以恢复数据,引入分布式事务协调者:1.彩排,反馈结果2.正确就提交,错误就回滚。

    647.tomcat,jvm,操作系统优化:Selector做IO处理,多线程做业务处理。数据库IO输入网络IO。

    648.JAVA的BIO就是传统的IO,也就是同步阻塞IO。

    649.递归就是方法调用自身,每调用一次,就会开辟一个方法内存区,当不断的开辟内存空间后,如果递归没有退出条件,会发生栈溢出异常.

    650.代码要有稳定性,不能随便改变量名,否则会影响调用.

    651.String字符串连接效率低,每个加号都会创建两个实例.改用StringBuilder可变字符串序列的append方法用来拼接字符串.

    652.BigDecimal用于精确的小数运算,BigInteger用于超大的整数运算.

    653.LinkedHashMap:结合链表实现的有序的散列表.ConcurrentHashMap:多线程下分段加锁的散列表.

    654.Idea里面在父工程里创建子module时要在父工程的路径下添加子目录,否则父工程的pom依赖会被打乱.

    656.spring项目的xml配置文件的文件格式后缀(.xml)如果不加上去会报500错误.

    657.Bean实例化(通过BeanFactory(defaultLisableBeanFactory)完成实例化):通过反射,在堆内存中开辟空间保存对象属性都是默认值;

        Bean初始化:完成对象的属性注入/调用具体的初始化方法.

    658.JDK动态代理虽然简单易用,但是其只能对接口进行代理。如果要代理的类为一个普通类、没有接口,那么Jdk动态代理就没法使用了要用CGLIB。

    659.Environment接口包括env和properties,将系统属性加载到标准环境中.

    670.观察者模式:监听器和监听事件,可以监督Bean的创建过程的进度.

    671.Spring源码中的refresh类有13个方法

    672.InitMessageSource:用于国际化.

    673.环境:本地环境,开发环境,测试环境,UAT环境,生产环境.

    674.Flink支持流处理和批处理,支持HDFS,Kafka,rabbitmq消息队列.

    675.Druid(不是指druid连接池):大数据实时查询和分析,高性能/高容错的分布式数据存储系统,能够实现聚合查询和分析的高并发系统.

       Druid的应用:点击分析,网络遥测分析,服务器指标存储,供应链分析,应用程序性能度量,数字营销/广告分析,商业智能/联机分析处理.

    676.TCC事务:第一阶段,Try预留资源、冻结数据、预演彩排,第二阶段,没有错误就Confirm确认/Commit提交,如果有错误就Cancel取消/Rollback回滚.

        TCC事务是用sql(写在xml里的sql)语句对数据库的操作实现的,用一个状态status表示数据的冻结和可用.

    677.微服务存在拆分和合并的情况.

    678.服务的注册中心相当于服务的通讯录.方便服务的发现和注册以及调用.

    679.消息队列的作用:

        流量削峰:MQ消息队列可以将超量请求暂存到消息队列,以便系统后期慢慢处理,避免系统被压垮.

        异步调用:同步调用会降低系统的吞吐量和并发度(因为下游没有响应时上游处于阻塞状态),且系统耦合度太高.异步调用则会解决这些问题,俗称异步解耦.

        数据收集:分布式数据实时和批量采集

    680.RocketMQ中的消费者数量应该小于等于订阅Topic的队列的数量,如果超出.则多余的消费者将不能消费消息,同一队列的同一消息不能被多个消费者共享.

        一个消费者组中的消费者必须订阅完全相同的Topic.一个消费者只能消费一个topic的消息.

        缺点:nameserver(类似于eureka,zk等注册中心)不能随便扩容.老版本的rocket使用zk注册

        消息生产者以轮询的方式向所有写队列发送消息,这些队列可能会分布在多个broker实例上

        一个消费组中的多个消费者,可以以负载均衡的方式来接收消息。

        一个队列的消息由一个消费者接收,除非消费者挂掉 才会换.

        单线程监听器:消费者消费消息时是单线程阻塞的,一个消息消费完才能到下一个.

        rocketmq需要启动两个服务: name server 和 broker, name server 默认配置JVM使用的内存是4g, broker默认配置JVM使用的内存是8g.

        开发环境中如果内存不足, 服务可能会无法启动, 可以通过降低两个服务的内存, 使服务可以正常启动, 也可以节省内存.

       

    681.Spring常用注解:@SpringBootApplication @Service @Component @Aspect @PointCut @Around @RestController @RquestMapping @GetMapping @PostMapping @PutMapping @Bean

        @Autowired @Resource @Configuration @RequestBody @RequestParam @PathVariable @Primary

    682.rocketmq的启动:

        启动nameserver:

        nohup sh bin/mqnamesrv &

        启动broker:

        nohup sh bin/mqbroker -n localhost:9876 &

        启动控制台: 

        cd 到控制台jar包所在目录

        nohup java -jar rocketmq-console-ng-1.0.1.jar --server.port=8080 --rocketmq.config.namesrvAddr=localhost:9876 &

        收发消息出现超时问题怎么解决:

        修改配置文件 :conf/broker.conf

        末尾添加指定ip:比如

        brokerIP1=192.168.64.141

        关闭 broker 服务:

        mqshutdown broker

        重新使用 broker.conf 配置启动 broker: cd 到bin的父级目录再操作:

        nohup sh bin/mqbroker -n localhost:9876 -c conf/broker.conf &

    683.写代码不是从上而下,是先写核心代码,再补充缺少的代码/补充缺少的细节.

    684.索引提高了查询效率,但是会降低增删改的效率.可以通过create 或者alter命令创建索引,通过drop删除索引.(索引不是越多越好)

        查询频率高,数据量大的字段适合添加索引.

    685.m叉(或m阶)的B树特点:树中的每个节点最多有m个孩子,除根节点以外,每个节点至少有m/2(向上取整)个孩子.

        B+树里面的叶子节点(没有子节点的节点)保存了数据信息和key,根节点和非叶子节点保存了索引.

        mysql数据库的叶子节点有双向指针链表.

    686.缓存穿透:用户传入恶意数据比如负数导致不断的查询数据库,解决办法,对传入的数据进行校验.比如用布隆过滤器

    687.redis集群一般至少6个节点,3主3从.或者3主6从.集群搭建完毕的标志: 16384哈希槽slots覆盖完毕才会完成集群的搭建.

    688.spring的配置文件可以写三份,开发环境:application-dev.yml,测试环境:application-test.yml,生产环境:application-prod.yml.

    689.Netty对JDK自带的NIO进行了封装,解决了Selector空轮询的问题.

    690.mysql里面的数据类型:字符,char,varchar,小数,float,double,numeric(5,2),decimal(5,2)整数:tinyint,int,bigint日期,date,time,datetime,timestamp.

    691.mysql中用limit做分页查询,0开始是第一页.分页查询的优化:如果起始页过大,要用where条件先筛选掉一部分.

    692.mysql数据库设置字符集要在建库时设置,建表时设置没有用.

        mysql数据库引擎是基于表的,建表时可以选择引擎,但是建库时不能选择引擎.

        实际开发中尽量少用多表联查,其根本原因就在这里,查询过程中,现在内存中构建一个大大的结果集,然后再进行数据的过滤。

        那这个构建过程,和所使用的内存资源,包括过滤时的判断,都是既耗费资源,又浪费时间。

        内连接:INNER JOIN两边都对应有记录的才展示,其他去掉

        左外连接:LEFT JOIN左边表中的数据都出现,右边没有数据以NULL填充

        右外连接:RIGHT JOIN右边表中的数据都出现,左边没有数据以NULL填充

        索引是一种排好序的快速查找的数据结构,它帮助数据库高效的进行数据的检索。

        在数据之外,数据库系统还维护着满足特定查找算法的数据结构(额外的存储空间),

        这些数据结构以某种方式指向数据,这样就可以在这些数据结构上实现高效的查找算法。这种数据结构就叫做索引。

        一般来说索引本身也很大,不可能全部存储在内存中,因此往往以索引文件的形式存放在磁盘中。目前大多数索引都采用BTree树方式构建。

       复合索引的最左特性:

       当我们创建一个联合索引(复合索引)的时候,如(k1,k2,k3),相当于创建了(k1)、(k1,k2)和(k1,k2,k3)三个索引,这就是最左匹配原则,也称为最左特性.

       在查询k1,或者k1,k2,或者k1,k2,k3时都可以用该索引.

       mysql里面 .frm存储表结构的文件, .ibd存储数据和索引的文件.

    693.java程序对数据库的CRUD操作如果不成功,在IDEA控制台里是很有可能看不到报错的,需要对增删改的代码进行try catch,才能看得到报错原因.

    694.数据表字段要有容错性设计,如果如字符类型,如果长度限制太死 要插入的字符多了一对引号,导致数据插入不进去就不好了.

    695.劣质的SQL语句会成为系统性能的瓶颈.随着数据量越来越大,因此需要对sql进行优化.

    696.Redis单独的主从复制架构是不能实现高可用的当主节点宕机后,从节点不会自动升级为主节点,需要搭配哨兵模式,才会实现主节点宕机从节点升级为主节点.

    697.ElasticSearch(分布式搜索引擎/Nosql数据库):在存储(analyzer)和搜索(search_analyzer)时使用的分词器可以不同,比如存储时用"ik_max_word",搜索时使用"ik_smart".

        核心概念:索引、分片、副本、映射.

       elastic-head里加粗的是正本

       _mapping映射是一种数据结构:包含字段名,数据类型,存储分词器/搜索分词器.

       -doc是默认文档类型._update是更新文档.

       PUT是指定id修改替换文档,POST是系统自动产生id添加文档,GET是查看文档,DELETE是删除文档.

       elasticSearch是数据库也是搜索引擎.

       shards:分片数量,replicas:副本数量

       -score:与搜索关键字相关度得分.

       hits:命中

       elasticSearch中的数据类型:

       Spring Data 的 Repository 接口提供了一种声明式的数据操作规范,无序编写任何代码,只需遵循 Spring Data 的方法定义规范即可完成数据的 CRUD 操作。

       

    ElasticsearchRepository 继承自 Repository,其中已经预定义了基本的 CURD 方法,我们可以通过继承 ElasticsearchRepository,添加自定义的数据操作方法。

       Elasticsearch可以设置搜索结果关键词高亮显示

       Elasticsearch自带分布式协调管理功能,不需要zokeeper

       Elasticsearch仅支持json文件格式

       solr搜索引擎支持json,xml,csv等格式,常用于电商搜索.

    698.缓存穿透(缓存里查不到):读请求优先去redis中查询,如果缓存没有再去mysql查询,如果mysql查不到会一直查询,导致mysql数据库奔溃,导致服务奔溃,最后导致整个系统奔溃.

       解决法办法:在控制层加布隆过滤器bloomFilter或者将null值缓存起来,对所有可能的查询参数以hash的形式存储,在控制层校验,不符合则丢弃,从而避免了对底层系统的查询压力.

       缓存击穿(缓存里查得到,但是查询量/并发量太大,缓存key快过期,最后查询的压力丢给数据库,并且回写缓存,导致数据库压力大而宕机)

       解决办法:①热点数据/热点key不设置缓存过期时间,或者通过随机数避免大量热点 key 同一时刻失效。②或者对热点Key用Redisson的setnx加分布式锁,每个key只有一个线程去查询后端,其余的线程等待.

       缓存雪崩:redis缓存宕机,比如故障宕机/断电,这时候所有的请求都会到达mysql存储层,如果并发量太大,会导致数据库宕机.

       解决办法:①采用redis主从复制哨兵集群高可用架构.②限流降级/流量削峰③数据预热,部署上线之前,对查询进行预演,对数据量大的key设置更长的过期时间.

    699.倒排索引:根据关键字找文档(存储分词/查询分词,确定关键字在文档的位置),普通索引:根据文档找关键字.

    700.ELK日志分析系统:E是指ElasticSearch(分布式开源全文检索引擎),L是指Logstash,K是指Kibana.

    701.Optional类型可以防止null值的空指针异常.

    702.多线程的CAS和ABA问题可以用原子操作或者加版本标记来解决.

        用AtomicStampedReference/AtomicMarkableReference(原子引用加上版本号)解决ABA问题.

    703.K83全自动容器部署工具,持续部署,谷歌开源的工具,开发运维一体化的标准化工具.K8S是Kubernetes的缩写,类似于i18N的简写.

        搭建K8S集群:用一键安装脚本/集群搭建开源工具比如GitHub - easzlab/kubeasz: 使用Ansible脚本安装K8S集群,介绍组件交互原理,方便直接,不受国内网络环境影响;也有手把手,手动安装方式但是不推荐.

        使用kubeasz容器

        ansible是新出现的自动化运维工具,基于Python开发,集合了众多运维工具(puppet、cfengine、chef、func、fabric)的优点,实现了批量系统配置、批量程序部署、批量运行命令等功能。

        K8S集群采用ETCD作为注册中心

        控制器:自动控制容器的部署和销毁,自动伸缩

        K8S组件:kubeadm,kubelet,kubectl

        pod容器:K8S对docker容器的封装对象,也可以用containerd容器

        pod是多进程的根容器,一个Pod里可以有多个容器,运行多个应用程序,pod为亲密性应用而存在.

        pod里的多个容器共享网络,共享存储.

        K8S集群里面的Service是不变的访问地址类似于springcloud里面的网关,调用service,然后service轮询负载均衡的调用其他容器.

        K8S集群分为,单master集群不需要负载均衡,多master集群(也称高可用集群,需要负载均衡).

        使用ansible 批量部署ssh免秘钥登录:yum install sshpass -y

        给ansible添加python网络地址组件:yum install python-netaddr -y

        RC老版的控制器,RS新版的控制器,用于伸缩,扩容,缩容,Daemon监控工具,JOB运行单次任务,CronJob运行定时任务.

        SERVICE:负载均衡,NodePort:对外暴露容器为服务,EndPoint:外部资源地址

        K8S配置代码自动补全:

        yum install -y bash-completion

        source <(kubectl completion bash)

        echo "source <(kubectl completion bash)" >> ~/.bashrc

        source ~/.bashrc

        查看K8S后端服务:kubectl get pod -A |grep kube-system

        K8S常用命令:

        kubectl get cs :查询组件状态,kubectl get ns 查询命名空间,

        kubectl get no 查询节点状态,kubectl get po查询容器状态,

        kubectl create -f通过配置文件创建容器,kubectl delete po删除容器

        kubectl create file.yml:根据yaml配置文件创建容器

        kubectl delete ns删除命名空间  kubectl delete all删除所有

        kubectl get rs :获取rs控制器

        kubectl apply -f 文件名.yaml:指定配置文件创建deployment控制器或服务service

        kubectl expose     

        Kubernetes 图形化管理工具:Kuboard或Rancher

        K8S集群部署工具:kubeasz或者kubeadm

        K8S的ETCD节点数量必须是奇数个1,3,5,7...

        linux最新稳定版4.19内核将nf_conntrack_ipv4更名为nf_conntrack,目前的kube-proxy不支持在4.19版本内核下开启ipvs.

        lsmod | grep -e ip_vs -e nf_conntrack_ipv4:查看module

        重启K8S:systemctl restart kubelet.service

        kubectl run kubia --image=luksa/kubia --port=8080:创建pod/kubia

        kubectl expose pod kubia --type=NodePort: 将pod对外暴露为Service

        kubectl get svc:获取服务

        kubectl api-resources:查看资源类型

        kubectl describe pod 容器名:查看pod容器详细信息

        kubectl describe svc kubia:查看服务详情

        kubectl create deployment nginx --image=nginx:创建deployment

        kubectl get deployment:查看deployment

        kubectl expose deployment nginx --port=80 --type=LoadBalancer:使用负载均衡模式发布服务

        kubectl describe service nginx:查看服务详情

        kubectl scale rc pod --replicas=3

        kubectl scale rs pod --replicas=3

        kubectl exec -it kubia bash:进入容器

        kubectl get po -o wide

        kubectl get pv:查看数据卷

        kubectl get pvc:查看持久数据卷

        kubectl create deployment 容器名 --image=镜像名:指定名称运行镜像容器

        kubectl delete deployment 容器名:删除控制器,控制器下面的pods也会被删除.

        kubectl delete pod pod名:删除pods.

        kubectl delete pv 数据卷:删除持久化数据卷

        kubectl describe pods pod名:查看pod详情.

        比如:kubectl create deployment tomcat --image=tomcat

        比如:kubectl create deployment nginx --image=nginx

        kubectl expose deployment tomcat --port=8080 --type=NodePort:暴露端口运行指定服务/容器,暴露完端口才有service

        tomcat的欢迎页面如果打不开,很有可能是默认的8080端口被占用,解决办法:1.恢复8080端口,2.修改server.xml文件65行的端口配置.

        kubectl exec -it tomcat-7d987c7694-lmrr6 bash:进入tomcat容器

        kubectl delete service tomcat:删除服务

        比如:kubectl expose deployment tomcat --port=8888 --type=NodePort

        比如:kubectl expose deployment nginx --port=30844 --type=NodePort

        curl http://nginx:访问其他容器

        宿主机磁盘挂载到容器:empty idr 在一个pod的多个docker容器之间交换数据、共享数据

        deployment用于部署和滚动升级,创建deployment时会默认创建Replicaset(简称RS),rs名称后面的一串数字不是随机的,是由镜像名称hash运算产生的.

        创建Deployment时,ReplicaSet资源会随之创建,实际Pod是由ReplicaSet创建和管理,而不是由Deployment直接管理

        K8S部署微服务的过程:1.项目打包2.制作Dockerfile,生成镜像3.kubectl create deployment myWeb --image=myImage创建容器4.暴露端口

        项目会以docker容器的方式运行在pod里面.

        容器化应用:把程序部署在docker里,比如springboot项目部署在docker里

        K8S里面如何部署容器化应用:1.项目打包2.生成Dockerfile3.创建镜像4.通过K8S部署这个镜像

        pod报错ErrImageNeverPull的原因:yml配置文件里的ImagePullPolicy镜像拉取政策错误:从Never改成Always

        pod重启后,里面的数据就没有了,需要数据持久化存储:

        办法1.nfs网络存储,需要yum安装nfs-utils,目录挂载mount -t nfs 192.168.232.129:/etc/nfs_data /etc/web_dir/

        NFS挂载时出现"access denied by server while mounting"的解决办法:

        1.权限设置有问题,其实文件夹权限都设为777了,权限上都没问题, 属主和所属组,是否正确

        2.hosts.deny和hosts.allow都保留默认设置。

        3.防火墙关关闭

        4.vim /etc/exports 里 ip地址范围不对。 172.16.2.0/24(rw,sync)

        K8S集群的优点:在master节点部署一个容器,也会在worker节点部署该容器,实现自动化部署.

        Accent on helpful side of your nature:强化你天性中有益的一面

        NFS:可以跨网络,跨主机访问文件夹,相当于windows的网络共享存储

        K8S的Command可以覆盖Docker的entrypoint,args可以覆盖Dockerfile的cmd

    704.软件,或者说计算机程序无一例外是由顺序结构、分支结构、循环结构和间接转移这几种行为组合而成的,无可增加,也缺一不可.

        软件的SOLID设计原则:

        1.SRP:单一职责原则,一个类或一个组件只干一件事,任何一个软件模块都应该只对某一类行为者负责,将服务不同行为者的代码进行切分

        2.OCP:开闭原则,面向功能拓展开放,面向功能修改关闭,设计良好的计算机软件应该易于扩展,同时抗拒修改,OCP是设计类与模块以及架构时的重要原则

        3.LSP:里氏替换原则,子类必须实现父类的抽象方法,但不得重写(覆盖)父类的非抽象(已实现)方法,最少知道原则,只和直接朋友通信.

        4.ISP:接口隔离原则,一个类对另外一个类的依赖性应当是建立在最小的接口上的一个接口代表一个角色,不应当将不同的角色都交给一个接口。没有关系的接口合并在一起,形成一个臃肿的大接口,这是对角色和接口的污染。

        5.DIP:依赖反转原则.高层策略性的代码不应该依赖实现底层细节的代码,具体应该依赖抽象,而不是相反. 

    705.Spring的单例对象的初始化主要分为三步;第一步.实例化,第二步.属性注入,第三步.初始化.循环依赖主要发生在第一、第二步,也就是构造器循环依赖(这种没法解决)和field属性的循环依赖。

        解决循环引用也应该从初始化过程着手,对于单例来说,在Spring容器整个生命周期内,有且只有一个对象,所以很容易想到这个对象应该存在Cache中,

        Spring为了解决单例的循环依赖问题,使用了三级缓存.

    706.JVM双亲委派机制:加载器收到请求不会自己先加载,先委托父类加载器,如果父类加载器还存在父类加载器,则会进一步向上委托,依次递归.

        如何父类加载器可以完成类加载,就成功返回,倘若父类无法完成加载任务,子加载器才会尝试自己去加载,这就是双亲委派模式.

       

        引导类加载器

             V

        拓展类加载器

             V

        系统类加载器

        双亲委派机制的作用:1.避免类的重复加载;2.保护程序的安全,防止核心API被恶意篡改.(沙箱安全机制)

    707.电商里面SPU + 颜色 + 尺码,就是一个SKU,SKU是从属于SPU的关系

        订单超时自动处理:秒杀订单付款超时,正常订单付款超时,确认收货超时,评价超时等

        用定时任务执行订单超时自动处理.解决方案:SpringTask 核心注解@Schedule(cron表达式* * * * * ?),问号表示放弃值,比如星期几和一个月的第几天不能同时设置,会冲突.

    708.大数据:5V,大量,高速,多样,低价值度低,实时,Hbase数据库:列式存储

        Flume数据清洗:Hive可以清洗,Flink也可以清洗,清洗的含义:把没用的数据清洗掉,去除噪音,取出信号.

        离线数据处理:Mapreduce,hive,SparkSQL,FlinkDataSet,流式数据处理;Flink高效.Storm(快速,亚秒级,过时的框架),SparkStream:速度没有storm快但是吞吐量高.

    709.Hashmp知识点:底层:数组,链表,红黑树,红黑树是二叉树,平衡树,初始长度16,加载因子0.75,每次扩容2倍,每个位置是一个桶bucket,线程不安全.

        ConcurrentHashmap底层是:Hashmp+分段锁,线程是安全的.

        CAS:Compare And Swap先比较再保存,多线程的安全写方式,

        AtomicMarkableReference解决 ABA的问题,作用:比较当前引用和期望值是否相等,标识是否相同,如果相同就进行更新,不相同就不更新.

        HashEntry:键值对,节点

        Segment继承自ReEnrenLock:一个Segment(分段锁)就是一个ReentrantLock

    710.Java虚拟机:类加载子系统;虚拟机栈,本地方法栈,程序计数器,堆,方法区(非堆),字节码执行引擎.

        线程私有:程序计数器,虚拟机栈,本地方法栈(在其中为方法开辟内存空间).

        线程共享:堆,方法区.

        堆中保存对象,堆分为新生代区:伊甸园区-幸存者区,老生代区:保存重量级对象.

        对象的分代年龄达到15会成为老生代对象.

        Java的指令都是根据栈来设计的.

        JVM调优工具:Arthas,由阿里巴巴出品.

        1.先用nohup后台运行java程序:

        2.curl -O https://alibaba.github.io/arthas/arthas-boot.jar

        3.java -jar arthas-boot.jar

        4.输入程序选项比如1回车 进入监控

        5.dashboard

        6.Thread 线程ID

        7.Arthas常用命令:jad 全路径包名+类名, trace ,thread, watch等.

        GC调优的目的:

        减少STW(stop the world)的时间,避免垃圾对象进入老生代区,减少Full GC

        垃圾回收95%集中在堆区进行,GC优先清理游离的不被引用的对象.

        5%在方法区进行,栈没有垃圾回收功能因为不需要,PC程序计数器没有垃圾回收功能.

        栈帧中的局部变量表是重要的垃圾回收根节点,只要是被局部变量表中直接或间接引用的对象都不会被垃圾回收.

        栈顶缓存:将栈顶元素全部缓存在物理CPU的寄存器中,以此降低内存的读/写次数,提升执行引擎的执行效率.

        任何时刻一个线程都只有一个方法在执行,也就是所谓的当前方法.

        JVM的线程和操作系统的线程是一一对应的,操作系统负责线程调度,给线程分配CPU资源.

        JVM虚拟机的调优:设置XMX和XMS参数

        栈是先进后出FILO,一个方法对应一个栈帧,栈帧之间是互相独立的.

    711.数据库的底层逻辑:用分治(分而治之)+索引来避免全量扫描,内存比磁盘快十万倍,索引也是数据但是占用空间小得多,内存维护索引树的主干.

        索引能提高查询效率,但是会降低增删改的效率

        mysql数据库一行的数据是连续的,不同的字段数据类型不同偏移量不同.

        Redis是纯内存的数据库,单进程的,可保存数据类型丰富,弊端:内存有限,成本比较高.Redis没有磁盘IO,适合保存热点数据比如秒杀库存和商品前三页.

        Redis处理用户事务是单线程的,不用加锁,串行.

        SAP-HANNA数据库:内存关系型数据库,服务器内存1TB,服务器+数据库+ERP单台售价1亿,包含冗余的设计:多电源+UPS不间断电源.

    712.秒杀订单产生的垃圾对象模拟:  系统压力评估: 

        假设一个订单对象占1kb,根据数据类型不同,订单对象大小不同.

        每秒300个订单:下单涉及其他对象如库存,优惠群,积分等,放大20倍,大概每秒有300KB*20/秒对象生成,

        可能还有其他操作比如订单查询,放大10倍,大概会300*20*10/秒,每秒产生60M的对象放入堆内存伊甸园区,1秒后都变为垃圾对象.

        JVM虚拟机优化参数设置:

        ●堆大小设置:

        幸存者区放不下的话对象可能进入老生代区

        java-Xms3G-Xmx3G-Xss1M-xx:MetaSpaceSize=512M

        -Xms: 最小堆的大小,也就是当你的JVM虚拟机启动后,就会分配这么大的堆内存给你

        -Xmx: 最大堆的大小 ,此值可以设置与-Xms相同,以避免每次垃圾回收完成后JVM重新分配内存

        -Xmn:设置年轻代堆区大小

        -Xss1M: 设置每个线程的堆栈大小

        当最小堆-Xms占满后,会尝试进行GC,如果GC之后还不能得到足够的内存,分配新的对象,那么就会扩展堆,

        如果-Xmx设置的太小,扩展堆就会失败,导致OOM错误提示。

        整个JVM内存大小=年轻代大小 + 年老代大小 + 持久代大小

        ●垃圾回收器选择

        JVM给了三种选择:串行收集器、并行收集器、并发收集器,但是串行收集器只适用于小数据量的情况,

        所以这里的选择主要针对并行收集器和并发收集器。

        吞吐量优先的并行收集器: -XX:+UseParallelGC并行收集器主要以到达一定的吞吐量为目标,适用于科学技术和后台处理等.

        响应时间优先的并发收集器: -XX:+UseConcMarkSweepGC并发收集器主要是保证系统的响应时间,减少垃圾收集时的停顿时间。适用于应用服务器、电信领域.

    713.java有字节码分析工具 jclasslib,可以在Idea中安装.

    714.BIO以流的方式处理数据,

        NIO以块的方式处理数据,块比流的效率高得多.NIO中的Buffer是双向的,可以读写切换.

        一个channel对应一个Buffer

        write和read会调用操作系统的内核函数

        将Buffer里的数据写入到channel: channel.write(Buffer),卸货

        将channel数据读入到Buffer: channel.read(Buffer),装货

        一个Selector(选择器)对应一个线程,一个线程对应多个channel

       程序切换到哪个channel由事件Event决定.Selector会根据不同的事件,在各个通道上切换.

       Buffer就是一个内存块或者容器(包含数组),底层是一个数组,Buffer是双向的,可以读可以写,通过flip切换,channel也是双向的.

       HTTP2.0能够处理的并发请求比HTTP1.0大几个数量级.

       Buffer:包含ByteBuffer(用的最多的),IntBuffer,FloatBuffer,DoubleBuffer等.

       MappedByteBuffer可以让文件直接在内存(堆外内存)修改,操作系统不需要拷贝一次.

       Buffer属性;Capacity,Limit,Position,Mark

       Netty:设计优雅,开发效率高,解决了NIO的bug,零拷贝(数据从直接内存到JVM堆内存没有拷贝),

       DirectByteBuffer是直接内存不是虚拟机的堆内存.HeapByteBuffer是堆内存.

       Unsafe后面类里面有方法可以直接操控内存和线程.不建议在生产环境中使用这个后门类.

       NEtty适用于多线程长连接的消息应用

    715.网络分层模型:5层,应用层可以拆分为会话层+展示层+应用层.

        应用层(HTTP,DNS,SSH,FTP),HTTP是无状态协议不保存用户的信息,通过TCP协议传输,通过请求/应答方式运行.HTTP状态码

        传输层(TCP/UDP),

        网络层(IPV4,IPV6),

        数据链路层(以太网协议,WLAN协议),

        物理层(光纤,双绞线电缆,无线设备),

    716.面试关键知识点整理;

       1.Java基础

       2.数据库/缓存/消息队列

       3.Spring框架

       4.算法数据结构:令牌桶算法(没有令牌可以等,拿到了令牌就执行业务,谷歌guava的RateLimiter用于限流+防止超卖),漏斗算法(抛弃请求,只恒定过滤少部分)

       5.前端和网络

       6.项目解说

       项目的行业,系统架构,开发周期,模块需求,参与的模块开发,遇到的问题,使用到的技术

       用密钥隐藏秒杀接口,防止脚本攻击,控制单个用户下单频率(超出频率抛弃请求)

    717.hive不支持行级别的增删改,优势在于高吞吐.

    718.synchronize是jvm单进程悲观锁,在分布式环境下,synchronize和reentrantLock(可重入锁)是juc(java.util.concurrent)本地锁只能锁当前进程,不能锁其他JVM的进程.

        分布式锁:用于分布式环境(多个JVM进程),互斥性,

        常见的分布式锁解决方案:

        1数据库分布式锁,数据库加一条记录比如版本号,锁表.

        2.zokeeper分布式锁(不适用于互联网三高)

        3.Redis的Set nx原子命令,Redisson提供了分布式锁的实现,用一个后台线程监控另一个线程是否超时,如果超时可以对锁续命.锁的粒度越小越好.(同一种商品的库存可以分段)

        Redisson的读写锁,保证总能读到最新数据,读完才能写,写完才能读.写锁没释放,读锁就必须等待.写锁是独享锁,读锁是共享锁.

        Redisson的闭锁,所有线程走完了,才能闭锁.

        锁的名字决定锁的粒度,比如11号商品加锁:product-11-lock,不能把全部商品用一把锁.

        wait和notify可以实现线程之间的通信.

    719.接口幂等性:方案,雪花算法生成全局ID,乐观锁+版本号,分布式锁.

    720.接口限流:高并发时,如果不做接口限流,会影响数据库稳定性.秒杀系统会独立部署.

    721.锁优化:互联网是读多写少场景:区分操作是读还是写

    722.模拟压力测试工具:JMeter和LoadRunner

    723.IDEA里面的Edit Configuration的VM Option可以修改JVM虚拟机的调优参数比如Xmx,Xms,Xmn等.

    724.SpringBoot2.0以后默认使用Lettuce作为redis客户端,但是有bug.Lettuce使用netty通信,吞吐量大.

        Spring的RedisTemplate默认封装了jedis和lettuce.

    725.缓存和数据库数据如何保持一致性:常用的是双写模式(会产生脏数据)或者失效模式(写了数据库再删缓存),经常修改的数据应该直接读数据库.

        1.加分布式读写锁2.缓存数据+过期时间3.使用canal(在里开源的中间件)订阅mysql的binlog(mysql的二进制日志).


    灵活和变通是为了坚持和实现目标而不是更换目标,

    不能因为挫折和困难就更换目标,频繁更换目标会导致走偏迷失自己,

    更多相关内容
  • 并发编程笔记

    2020-08-04 19:32:01
    并发编程笔记
  • 编程笔记:记录笔记的网站
  • C语言编程笔记

    2018-03-30 16:53:27
    C语言笔记, C编程
  • 网络编程笔记

    2018-12-16 19:00:57
    网络对计算机来说有多么重要就不再多说了,想学好网络编程也是不容易的,其中好的笔记就是不错的选择,能是你的学习效率达到事半功倍的效果,不要犹豫了,学好网络编程将是你在程序员路上的一大优势,带来意想不到的...
  • python编程笔记

    2018-01-21 15:59:46
    python编程笔记python编程笔记python编程笔记python编程笔记python编程笔记
  • 网络编程学习笔记.md

    2021-05-08 09:22:22
    网络编程 (狂神说Java)学习笔记 + 自己的一些理解
  • win32编程笔记.docx
  • linux系统编程笔记
  • Java并发编程相关笔记,描述了Java并发编程相关及Java线程模型相关知识点
  • 超全的多线程与高并发的编程笔记,从JVM&JMM角度讲多线程,synchronized优化原理,AQS和线程池等等,需要的童鞋请自行下载!
  • SimplIQ编程笔记.doc

    2021-03-21 11:08:01
    SimplIQ编程笔记
  • linux socket编程笔记.rar

    2021-05-12 22:19:56
    linux socket编程笔记
  • Java并发编程笔记.7z

    2022-07-06 09:32:12
    Java并发编程笔记.7z
  • 这是我的shell编程笔记,我有很多自己的学习笔记,供我以及大家复习使用,还有其他的哦 C语言笔记,java笔记,网页笔记,javaweb笔记,gcc笔记,等,我会慢慢传
  • 推荐使用的网络编程笔记模板
  • Shell编程笔记,有很多关于Shell编程的干货,适合学习
  • linux管道专题编程笔记
  • juc-study编程笔记.md

    2021-07-06 01:45:19
    学习狂神说的juc编程笔记
  • linux信号量专题编程笔记
  • linux共享内存专题编程笔记
  • linux消息队列专题编程笔记
  • 编程笔记.zip

    2019-10-30 00:16:47
    总结的编程相关知识点,暂时没有python的,先暂时用着吧
  • C++编程笔记

    2018-08-28 21:46:13
    C++学习总结(真正的思考总结),包含面向对象思想的理解、模板编程与其他小窍门(有涉及C++11新特性)
  • linux系统编程笔记

    2014-08-13 14:21:06
    linux系统 编程 开发 笔记 如果 大家 需要 可以 下载 看看 啊 希望 对你 linux 系统学习 有一定的 帮助 啊
  • 数控加工中心编程笔记.doc
  • Python非常详细编程笔记.doc
  • 网络编程笔记.c

    2021-09-01 10:46:28
    网络编程笔记.c
  • C语言的网络编程笔记

    2018-07-09 16:24:55
    C语言的网络编程笔记,包含网络编程常用函数的解释和实例代码
  • 黑马程序员并发编程笔记(一)

    千次阅读 2022-01-21 19:10:53
    1.聊聊线程和进程 1.1.进程和线程的概念 什么是进程? 可以理解为,进程就是存储在静态资源(磁盘)里的程序(指令和数据)运行时的一种状态,通俗的理解,进程就是运行时的程序。 注释:程序由数据和指令组成,...

    1.聊聊线程和进程

    1.1.进程和线程的概念

    什么是进程?

    可以理解为,进程就是存储在静态资源(磁盘)里的程序(指令和数据)运行时的一种状态,通俗的理解,进程就是运行时的程序。

    注释:程序由数据和指令组成,这些指令要读写,就必须把指令加载到cpu,数据加载到内存 。进程就是来加载指令,管理内存,管理io的

    注意:内存一般指的是运行内存,因为小时候不准确的概念,我们常常将内存和磁盘存储相关联,但二者不相同。

    当一个程序被调用时,它就作为一个进程,从磁盘加载到内存之中。一个程序可以有多个进程(记事本)也可以只有一个进程(网易云音乐)。

    线程的简单概述

    一个进程中可以分配多个线程。

    线程是一个指令流,将指令流中的一条条指令交给cpu运行。

    java中线程是最小的调度,进程时资源分配的最小单位。在windows中不活动,而作为线程的容器。

    对比

    • 进程是独立的,而线程存在于进程中,是它的一个子集。
    • 进程拥有共享的资源,如内存空间等,供其内部的线程共享·进程间通信较为复杂
    • 同一台计算机的进程通信称为IPC ( lnter-process communication )
      不同计算机之间的进程通信,需要通过网络,并遵守共同的协议,例如HTTP
    • 线程通信相对简单,因为它们共享进程内的内存,一个例子是多个线程可以访问同一个共享变量·线程更轻量,线程上下文切换成本一般上要比进程上下文切换低

    关于上下文切换

    简单来说就是把不用的进程/线程 kill掉,防止它们占用不必要的内存。

    2.并发和并行

    2.1.并发

    单核 cpu 下,线程实际还是 串行执行 的。操作系统中有一个组件叫做任务调度器,将 cpu 的时间片(windows下时间片最小约为 15 毫秒)分给不同的程序使用,只是由于 cpu 在线程间(时间片很短)的切换非常快,人类感觉是 同时运行的 。总结为一句话就是: 微观串行,宏观并行 ,

    一般会将这种 线程轮流使用 CPU 的做法称为并发, concurrent

    通俗理解:一个核心轮流调用各个线程。

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fjCRK2Wy-1642763425871)(https://static01.imgkr.com/temp/5d859f6d95c343e89689cdce92d8fa44.png)]

    2.2.并行

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-SoE125yS-1642763425872)(https://static01.imgkr.com/temp/b5d0319a9e174b9da93062ab047b64ea.png)]

    通俗来讲:就是多个核心在一个时间里执行不同的线程。

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QOb920Rq-1642763425873)(https://static01.imgkr.com/temp/11a9e64b03c84d4abac13191dae6ad3a.png)]

    2.3.同步和异步

    同步和异步的概念

    以调用方的角度讲,如果需要等待结果返回才能继续运行的话就是同步,如果不需要等待就是异步

    同步等待

    QQ截图20220121094639

    异步等待

    QQ截图20220121094648

    1) 设计

    多线程可以使方法的执行变成异步的,比如说读取磁盘文件时,假设读取操作花费了5秒,如果没有线程的调度机制,这么cpu只能等5秒,啥都不能做。

    2) 结论

    • 比如在项目中,视频文件需要转换格式等操作比较费时,这时开一个新线程处理视频转换,避免阻塞主线程
    • tomcat 的异步 servlet 也是类似的目的,让用户线程处理耗时较长的操作,避免阻塞 tomcat 的工作线程
    • ui 程序中,开线程进行其他操作,避免阻塞 ui 线程

    3.java进程的基本操作

    3.1.创建进程

    方法一,直接使用 Thread

    // 构造方法的参数是给线程指定名字,,推荐给线程起个名字(用setName()也可以)
    Thread t1 = new Thread("t1") {
     @Override
     // run 方法内实现了要执行的任务
     public void run() {
     log.debug("hello");
     }
    };
    t1.start();
    

    方法二,使用 Runnable 配合 Thread

    把【线程】和【任务】(要执行的代码)分开,Thread 代表线程,Runnable 可运行的任务(线程要执行的代码)Test2.java

    // 创建任务对象
    Runnable task2 = new Runnable() {
     @Override
     public void run() {
     log.debug("hello");
     }
    };
    // 参数1 是任务对象; 参数2 是线程名字,推荐给线程起个名字
    Thread t2 = new Thread(task2, "t2");
    t2.start();
    

    1.8后用lambda表达式来简化写法

    QQ截图20220121101957

    // 创建任务对象
    Runnable task2 = () -> log.debug("hello");
    // 参数1 是任务对象; 参数2 是线程名字,推荐
    Thread t2 = neaw Thread(task2, "t2");
    t2.start();
    
    

    也可以更简略一点

    // 参数1 是任务对象; 参数2 是线程名字,推荐
    Thread t2 = neaw Thread(() -> log.debug("hello"), "t2");
    t2.start();
    
    

    idea里 lamba表达式简化快捷键: alt +enter

    小结

    方法1 是把线程和任务合并在了一起,方法2 是把线程和任务分开了,用 Runnable 更容易与线程池等高级 API 配合,用 Runnable 让任务类脱离了 Thread 继承体系,更灵活。通过查看源码可以发现,方法二其实到底还是通过方法一执行的!

    需要注意的是:

    • 如果直接运行Thread的run()方法,则是主线程调用

    方法三,FutureTask 配合 Thread

    FutureTask 能够接收 Callable 类型的参数,用来处理有返回结果的情况 Test3.java

        public static void main(String[] args) throws ExecutionException, InterruptedException {
            // 实现多线程的第三种方法可以返回数据也可以抛出异常,返回的数据需要用get接收
            FutureTask futureTask = new FutureTask<>(new Callable<Integer>() {
                @Override
                public Integer call() throws Exception {
                    log.debug("多线程任务");
                    Thread.sleep(100);
                    return 100;
                }
            });
            
      
            new Thread(futureTask,"我的名字").start();
            log.debug("主线程");
            //{}表示占位,实际值是后买你的参数,获取结果。必要时可以通过get方法获取执行结果,该方法会阻塞直到任务返回结果。
            log.debug("{}",futureTask.get());
        }
    

    Future就是对于具体的Runnable或者Callable任务的执行结果进行取消、查询是否完成。

    public interface Future<V> {
        boolean cancel(boolean mayInterruptIfRunning);
        boolean isCancelled();
        boolean isDone();
        V get() throws InterruptedException, ExecutionException;
        V get(long timeout, TimeUnit unit)
            throws InterruptedException, ExecutionException, TimeoutException;
    }
    

    Future提供了三种功能:

    1. 判断任务是否完成;
    2. 能够中断任务;
    3. 能够获取任务执行结果。

    3.3 查看进程线程的方法

    windows

    任务管理器可以查看进程和线程数,也可以用来杀死进程
    
    tasklist 查看进程
    
    taskkill 杀死进程
    
    tasklist | findstr java 查看所有的java线程
    

    linux

    ps -fe 查看所有进程
    
    ps -fT -p <PID> 查看某个进程(PID)的所有线程
    
    kill 杀死进程
    
    top 按大写 H 切换是否显示线程
    
    top -H -p <PID> 查看某个进程(PID)的所有线程
    
    ps -fe | grep java 查看所有的java进程
    

    Java

    jps 命令查看所有 Java 进程
    
    jstack <PID> 查看某个 Java 进程(PID)的所有线程状态
    
    jconsole 来查看某个 Java 进程中线程的运行情况(图形界面)
    

    jconsole 远程监控配置

    需要以如下方式运行你的 java 类

    java -Djava.rmi.server.hostname=`ip地址` -Dcom.sun.management.jmxremote -
    Dcom.sun.management.jmxremote.port=`连接端口` -Dcom.sun.management.jmxremote.ssl=是否安全连接 -
    Dcom.sun.management.jmxremote.authenticate=是否认证 java类
    

    修改 /etc/hosts 文件将 127.0.0.1 映射至主机名

    如果要认证访问,还需要做如下步骤

    复制 jmxremote.password 文件

    修改 jmxremote.password 和 jmxremote.access 文件的权限为 600 即文件所有者可读写

    连接时填入 controlRole(用户名),R&D(密码)

    例子:

    QQ截图20220121153824

    QQ截图20220121153952

    3.2 线程运行原理

    3.2.1.虚拟机栈与栈帧

    QQ截图20220121155442

    拟机栈描述的是Java方法执行的内存模型:每个方法被执行的时候都会同时创建一个栈帧(stack frame)用于存储局部变量表、操作数栈、动态链接、方法出口等信息,是属于线程的私有的。当java中使用多线程时,每个线程都会维护它自己的栈帧!每个线程只能有一个活动栈帧,对应着当前正在执行的那个方法

    3.2.2.线程上下文切换(Thread Context Switch)

    因为以下一些原因导致 cpu 不再执行当前的线程,转而执行另一个线程的代码

    • 线程的 cpu 时间片用完(每个线程轮流执行,看前面并行的概念)
    • 垃圾回收
    • 有更高优先级的线程需要运行
    • 线程自己调用了 sleepyieldwaitjoinparksynchronizedlock 等方法

    当 Context Switch 发生时,需要由操作系统保存当前线程的状态,并恢复另一个线程的状态,Java 中对应的概念 就是程序计数器(Program Counter Register),它的作用是记住下一条 jvm 指令的执行地址,是线程私有的.

    3.3 Thread的常见方法

    20200306114615-258720

    QQ截图20220121184804

    3.3.1 start 与 run

    调用start

        public static void main(String[] args) {
            Thread thread = new Thread(){
              @Override
              public void run(){
                  log.debug("我是一个新建的线程正在运行中");
                  FileReader.read(fileName);
              }
            };
            thread.setName("新建线程");
            thread.start();
            log.debug("主线程");
        }
    

    输出:程序在 t1 线程运行, run()方法里面内容的调用是异步的 Test4.java

    11:59:40.711 [main] DEBUG com.concurrent.test.Test4 - 主线程
    11:59:40.711 [新建线程] DEBUG com.concurrent.test.Test4 - 我是一个新建的线程正在运行中
    11:59:40.732 [新建线程] DEBUG com.concurrent.test.FileReader - read [test] start ...
    11:59:40.735 [新建线程] DEBUG com.concurrent.test.FileReader - read [test] end ... cost: 3 ms
    

    调用run

    将上面代码的thread.start();改为 thread.run();输出结果如下:程序仍在 main 线程运行, run()方法里面内容的调用还是同步的

    12:03:46.711 [main] DEBUG com.concurrent.test.Test4 - 我是一个新建的线程正在运行中
    12:03:46.727 [main] DEBUG com.concurrent.test.FileReader - read [test] start ...
    12:03:46.729 [main] DEBUG com.concurrent.test.FileReader - read [test] end ... cost: 2 ms
    12:03:46.730 [main] DEBUG com.concurrent.test.Test4 - 主线程
    

    小结

    直接调用 run() 是在主线程中执行了 run(),没有启动新的线程使用的是main线程, 使用 start() 是启动新的线程,通过新的线程间接执行 run()方法 中的代码

    3.3.2 sleep 与 yield

    sleep

    QQ截图20220121161549

    1. 调用 sleep 会让当前线程从 Running 进入 Timed Waiting 状态(阻塞)
    2. 其它线程可以使用 interrupt 方法打断正在睡眠的线程,那么被打断的线程这时就会抛出 InterruptedException异常【注意:这里打断的是正在休眠的线程,而不是其它状态的线程】
    3. 睡眠结束后的线程未必会立刻得到执行(需要分配到cpu时间片)
    4. 建议用 TimeUnit 的 sleep() 代替 Thread 的 sleep()来获得更好的可读性
    展开全文

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 472,876
精华内容 189,150
关键字:

编程笔记