-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsearch.xml
132 lines (132 loc) · 45.2 KB
/
search.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
<?xml version="1.0" encoding="utf-8"?>
<search>
<entry>
<title><![CDATA[牛客网上周题目整理(20190701-20190707)]]></title>
<url>%2F2019%2F07%2F07%2F%E7%89%9B%E5%AE%A2%E7%BD%91%E4%B8%8A%E5%91%A8%E9%A2%98%E7%9B%AE%E6%95%B4%E7%90%86(20190701-20190707)%2F</url>
<content type="text"><![CDATA[写在开始整理一下上周(2019/07/07-2019/07/07)收藏的值得研究的题目一、枚举(enum)是一种新的类型,允许用常量来表示特定的数据片段,而且全部都以类型安全的形式来表示,是特殊的类,可以拥有成员变量和方法1枚举类前面几乎没怎么用过,所以放在后面进行一个大的总结; 八、枚举类详细分析与测试 二、下面程序的输出结果:123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103 public class Test_2019_07_07{ public static void main(String[] args) { Chinese obj1 = Chinese.getInstance(); Chinese obj2 = Chinese.getInstance(); System.out.println(obj1==obj2); } } class Chinese{ private static Chinese objref = new Chinese(); // 构造方法私有,单例模式 private Chinese(){} public static Chinese getInstance(){return objref;} } 结果是:true 解析:饿汉式单例模式,在类创建时,就已经实例化完成,在调用Chinese.getInstance()时,直接获取静态对象扩展: 设计模式:懒汉式单例、饿汉式单例、登记式单例 (1)、懒汉式单例,在第一次调用(getInstance方法)的时候实例化自己: public class Single{ private Single(){} private static Single single=null; // 静态工厂方法 public static Singletonn getInstance(){ if(single == null){ single = new Single(); } return single; } } 在并发的情况下存在多个Single实例导致线程不安全的情况 解决:(1)加同步synchronized (2)加双重锁定,先判空,实例是否为空 (3)静态内部类-> public class Single{ private static class LazyHolder{ private static final Singleton INSTANCE = new Single(); } private Singleton (){} public static final Single getInstance(){ return LazyHolder.INSTANCE } } (2)、饿汉式单例,在类初始化时已经自行实例化: public class SingletonHungry{ private SingletonHungry(){} private static final SingletonHungry single = new SingletonHungry(); // 静态工厂方法 public static SingletonHungry getInstance(){ return single; } } 饿汉式在类创建的同时就已经创建好一个静态的对象供系统使用,以后不再改变,所以天生是线程安全的 (3)、登记单例 public class RegisterSingleton { private static Map<String,RegisterSingleton> map = new HashMap<String,RegisterSingleton>(); static{ RegisterSingleton singleton = new RegisterSingleton(); map.put(singleton.getClass().getName(), singleton); } // 保护的默认构造方法 protected RegisterSingleton(){} // 静态工厂方法,返还此类唯一的实例 public static RegisterSingleton getInstance(String name){ if(name == null){ name = RegisterSingleton.class.getName(); System.out.println("name == null"+"--->name="+name); } if(map.get(name) == null){ try{ map.put(name,(RegisterSingleton)Class.forName(name).newInstance()); // 通过反射来拿到动态的构造 }catch(Exception e){ e.printStackTrace(); } } return map.get(name); } // 一个示意性的商业方法 public String about(){ return "Hello,I am RegSingleton."; } public static void main(String[] args) { RegisterSingleton registerSingleton = RegisterSingleton.getInstance(null); System.out.println(registerSingleton.about()); } } 懒汉式和饿汉式的区别: 1.饿汉式类一旦加载,就把单例初始化完成,保证getInstance的时候,单例是已经存在的了 2.懒汉式较懒,只有当调用getInstance的时候,才回去初始化这个单例 三、有关cgi1234567891011CGI(Common Gateway Interface 公共网关接口) -> 概念:是HTTP服务器与你的或其它机器上的程序进行"交谈"的一种工具,其程序必须运行在网络服务器上 功能:用来解释处理来自表单的输入信息,并在服务器产生相应的处理,或将相应的信息反馈给浏览器。CGI程序使网页具有交互功能 运行环境:CGI程序在UNIX操作系统上CERN或NCSA格式的服务器上运行。在其它操作系统(如:windows NT及windows95等)的服务器上 也广泛地使用CGI程序,同时它也适用于各种类型机器。 处理步骤: (1)通过Internet把用户请求送到服务器 (2)服务器接收用户请求并交给CGI程序处理 (3)CGI程序把处理结果传送给服务器 (4)服务器把结果送回给用户 其不可移植 四、强制转型:  经过强制类型转换以后,变量a, b的值分别为( )short a = 128; byte b = (byte) a;12345678910111213141516171819202122232425262728293031321、Java中用补码形式表示2、第一位正负位,1表示负,0表示正。3、原码:一个数的二进制表示。 3的原码00000011 -3的 原码 100000114、反码:负数原码按位取反(符号位不变)。正数原码本身。 3的反码00000011 -3的反码111111005、补码:正数是原码本身。负数反码加1。 3的补码是00000011 -3的补码是11111101-------------------------------------------------------------------------------int占4个字节,32位byte占1个字节,8位所以强转时会截断。前24位---------------------------------------------------------------------------在内存中表示形式( 注意java中是以补码表示一个数,所以表示形式是补码,不是原码! ):int a = 3 00000000 00000000 00000000 00000011 (强转byte时前面24个0被截断)byte b = 3 00000011int a = -3 11111111 11111111 11111111 11111101 (强转byte时前面24个1被截断)byte b = -3 11111101----------------------------------------------------------------------------已知负数的补码,求负数:补码-1=反码,反码按位取反=该负数绝对值已知负数,求负数的补码:1、负数原码除了符号位,按位取反(不含符号位),加1。2、负数绝对值的补码(也就是原码),按位取反(含符号位),加1-------------------------------------------------------------------------------例子:java int 128转为byte,值:128为正数,补码为10000000(前面24个0省略),变成byte,只剩下10000000(byte为1个字节),因为开头是1,所以为负数。即1个负数的补码是10000000。反码是01111111,原码是1000000。是128.因为是负数,所以是-128。 五、堆区的划分: 六、有关transient1transient与序列化(方便在网络间进行传输数据)相关,将transient加在属性的前面可不用进行序列化 七、程序能否通过编译,如果通过的话输出结果是:123456789101112131415161718192021222324class HasStatic{ private static int x = 100; public static void main(String args[ ]){ HasStatic hs1 = new HasStatic(); hs1.x++; HasStatic hs2 = new HasStatic(); hs2.x++; hs1=new HasStatic(); hs1.x++; HasStatic.x--; System.out.println( "x=" +x); }}结果:程序通过编译,输出结果为:x=102解析: 因为x的 修饰符为 static 所以x为类变量,即对于所有的实例来说,他们访问的x为同一个x,类变量存储在方法区,不属于每个实例的私有, 刚开始x=100 调用hs1.x++ x为101; 调用hs2.x++ x为102; 调用hs1.x++ x为103 (此时hs1指向了一个新的HasStatic实例,但是依然访问的是同一个X) 调用HasStatic.x-- x为102 所以结果为102 八、枚举类详细分析与测试123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134package nowcoder;/*** @author 作者 Joker青* @version 创建时间:2019年7月7日 下午2:06:20 *//* * 一、自己定义 * 二、使用enum关键字定义枚举类 * 1.常用的方法 * 2.如何让枚举类实现接口 * * */public class Test_2019_07_07_TestSeason { public static void main(String[] args) { // 1.values() 的用法 返回所有的枚举类的对象 SeasonEnum[] values = SeasonEnum.values(); for (int i = 0; i < values.length; i++) { values[i].showMe(); } //2.valueOf(String name):要求传入的形参name是枚举类对象的名字, //否则,报java.lang.IllegalArgumentException异常 String str = "SUMMER"; SeasonEnum season= SeasonEnum.valueOf(str); season.showMe(); System.out.println(season); //3.getDeclaringClass()这个方法得到枚举常量所属枚举类型的Class对象 //可以用它来判断两个枚举常量是否属于同一个枚举类型 System.out.println(season.getDeclaringClass()); //4.ordinal() 得到当前枚举常量的次序 System.out.println(season.ordinal()); //toString()方法 可以重写,使结果更好看 //equals()在枚举类型中可以直接使用“==”来比较两个枚举常量是否相等。Enum提供的这个equals()方法, //也是直接使用“==”实现的。它的存在是为了在Set、List和Map中使用。注意,equals()是不可变的。 //hashcode Enum实现了hashCode()来和equals保持一致。它也是不可变的。 //compareTo 枚举类型实现了comparable 接口,这样可以比较两个枚举常量的大小(按照声明的顺序排列) //clone 枚举类型不能被clone。为了防止子类实现克隆方法,enum实现了一个仅抛出clonenotsupportedexception异常的不变clone(). } }class Season{ // 1.提供类的属性,声明为private final private final String seasonName; private final String seasonDesc; // 2.声明为final的属性,在构造器中初始化 private Season(String seasonName,String seasonDesc){ this.seasonName = seasonName; this.seasonDesc = seasonDesc; } // 3.通过公共的方法来调属性 public String getSeasonName() { return seasonName; } public String getSeasonDesc() { return seasonDesc; } // 4.创建枚举类的对象 public static final Season SPRING = new Season("spring","春暖花开"); public static final Season SUMMER = new Season("summer","夏日炎炎"); public static final Season AUTUMN = new Season("autumn","秋高气爽"); public static final Season WINTER = new Season("winter","白雪皑皑"); @Override public String toString() { return "Season [seasonName=" + seasonName + ", seasonDesc=" + seasonDesc + "]"; } public void show(){ System.out.println("这是一个季节"); } }// 泛型类 要实现的接口interface Info{ void showMe();}// 泛型类,这个是系统提供enum SeasonEnum implements Info{ // 放在第一行 SPRING("spring","出暖花开"){ public void showMe(){ System.out.println("我叫春天"); } }, SUMMER("summer","夏日炎炎"){ public void showMe(){ System.out.println("我叫夏天"); } }, AUTUMN("autumn","秋高气爽"){ public void showMe(){ System.out.println("我叫秋天"); } }, WINTER("winter","白雪皑皑"){ public void showMe(){ System.out.println("我叫冬天"); } }; private final String seasonName; private final String seasonDesc; private SeasonEnum(String seasonName,String seasonDesc){ this.seasonDesc = seasonDesc; this.seasonName = seasonName; } public String getSeasonName() { return seasonName; } public String getSeasonDesc() { return seasonDesc; } @Override public String toString() { return this.getSeasonName()+":"+this.getSeasonDesc(); } public void showMe() { } }]]></content>
<categories>
<category>nowcoder</category>
</categories>
<tags>
<tag>nowcoder</tag>
</tags>
</entry>
<entry>
<title><![CDATA[牛客网上周题目整理(20190624-20190630)]]></title>
<url>%2F2019%2F06%2F30%2F%E7%89%9B%E5%AE%A2%E7%BD%91%E4%B8%8A%E5%91%A8%E9%A2%98%E7%9B%AE%E6%95%B4%E7%90%86(20190624-20190630)%2F</url>
<content type="text"><![CDATA[写在开始整理一下上周(2019/06/24-2019/06/30)收藏的值得研究的题目   一、当我们需要所有线程都执行到某一处,才进行后面的代码执行时我们可以使用:CountDownLatch    [ Java主线程等待所有子线程执行完毕再执行 ]这个需求其实我们在工作中经常会用到,比如用户下单一个产品,后台会做一系列的处理,为了提高效率,每个处理都可以用一个线程来执行,所有处理完成之后才会返回给用户下单成功。 并发工具类等待多线程完成的CountDownLatch:其不可能重新初始化或者修改CountDownLatch对象内部计数器的值,一个线程调用countdown方法happen-before另外一个线程调用await方法 1234567891011121314151617181920public class test{ public static void main(String[] args) throws InterruptedException{ final CountDownLatch latch = new CountDownLatch(5); for(int i=0;i<5;i++){ new Thread(new Runnable(){ public void run(){ try{ Thread.sleep(1000); }catch(Exception e){ e.printStackTrace(); } System.out.println("子线程执行!!"); latch.countDown(); // 让latch中的数值减1 } }).start(); } latch.await(); // 阻塞当前线程直到latch中的值为0 System.out.println("主线程执行!"); }} 同步屏障CyclicBarrier 123456789101112131415161718192021222324public class test{ public static void main(String[] args) throws InterruptedException,BrokenBarrierException{ final CyclicBarrier barrier = new CyclicBarrier(5); for(int i=0;i<4;i++){ new Thread(new Runnable(){ public void run(){ try{ Thread.sleep(1000); }catch(Exception e){ e.printStackTrace(); } System.out.println("子线程执行!!"); try{ barrier.await(); // 到达屏障 }catch(Exception e){ e.printStackTrace(); } } }).start(); } barrier.await(); // 阻塞当前线程直到latch中的值为0 System.out.println("主线程执行!"); }} 两者区别(CountDownLatch和CyclicBarrier)1countDownLatch只能使用一次,而CyclicBarrier方法可以使用reset()方法重置,所以CyclicBarrier方法可以能处理更为复杂的业务场景    二、一道题不知道为啥:123String str ="";System.out.print(str.split(",").length());   结果输出为1  why?    三、关于引用传递和值传递:123456引用数据类型是引用传递,基本数据类型是值传递值传递不可以改变原变量的内容和地址:因为Java方法的形参传递都是原变量的副本,在方法中改变的是副本的值;而不适合原变量的引用传递不可以改变原变量的地址,但可以改变原变量的内容:当副本的引用改变的时候,原变量的引用并没有变化,当副本改变内容时,由于副本引用指向的是原变量的地址空间,所以原变量的内容发生变化结论: 1.值传递不可以改变原变量的内容和地址; 2.引用传递不可以改变原变量的地址,但可以改变原变量的内容;    四、下面输出结果为false的是:1234Integer i01=59;int i02=59;Integer i03=Integer.valueOf(59);Integer i04=new Integer(59); 解析一: 解析二:123456789101112131415161718192021222324252627282930313233343536373839首先常量池这个概念,原来以为只要是一个整型,都会放进到常量池,比如,0,1,12222222等。查找后发现,Byte,Short,Integer,Long,Character这5种整型的包装类也只是在对应值小于等于127并且大于等于-128时才可使用常量池,因为他们至占用一个字节(-128~127);再者Integer.valueOf方法中也有判断,如果传递的整型变量>= -128并且小于127时会返回IntegerCache类中一个静态数组中的某一个对象, 否则会返回一个新的Integer对象,代码如下public static Integer valueOf(int i) { assert IntegerCache.high >= 127; if (i >= IntegerCache.low && i <= IntegerCache.high) return IntegerCache.cache[i + (-IntegerCache.low)]; return new Integer(i);}所以如果你测试如下代码public static void main(String[] args) { Integer a = 127; Integer b = 127; Integer c = 128; Integer d = 128; System.out.println(a == b); System.out.println(c == d);}结合自动封装、常量池以及Integer.valueOf方法就不难得出,答案时 true和false; 再看本题:Integer i01=59;int i02=59;Integer i03=Integer.valueOf(59);Integer i04=new Integer(59);第一行:由于59在-128~127范围之内,所以在自动装箱的时候,会返回IntegerCache[59 - (-128)];第三行:同第一行第四行:因为有new关键字,所以在heap中开辟了一块新内存放置值为59的Integer对象。System.out.println(i01==i02);//正确System.out.println(i01==i03);//正确,都指向IntegerCache[59-(-128)]对象System.out.println(i03==i04);//错误,引用指向的对象地址不同System.out.println(i02==i04);//正确    五、假设 a 是一个由线程 1 和线程 2 共享的初始值为 0 的全局变量,则线程 1 和线程 2 同时执行下面的代码,最终 a 的结果不可能是():1234567boolean isOdd = false;for(int i=1;i<=2;++i){ if(i%2==1)isOdd = true; else isOdd = false; a+=i*(isOdd?1:-1);} 解析:如图:1234易知:每个线程对a 均做了两次读写操作,分别是 “ +1 ” 和 “ -2 ”而题目问了是最终a 的结果,所以 a 的结果取决于各自线程对 a 的先后读写的顺序结论:a的可能取值为-1、0、-2]]></content>
<categories>
<category>nowcoder</category>
</categories>
<tags>
<tag>nowcoder</tag>
</tags>
</entry>
<entry>
<title><![CDATA[牛客网上周题目整理(20190609-20190616)]]></title>
<url>%2F2019%2F06%2F16%2F%E7%89%9B%E5%AE%A2%E7%BD%9120190609-20190616%E9%A2%98%E7%9B%AE%E6%95%B4%E7%90%86%2F</url>
<content type="text"><![CDATA[写在开始整理一下上周(2019/06/09-2019/06/16)收藏的值得研究的题目 数据类型转换1以下b的值是:byte b = (byte)129 基础  byte,一个字节,一个字节有8位的二进制数,它的可表示范围是[128-127],来看一下计算过程:首先在计算机中它只认识0和1,在计算方面是以补码的形式呈现; 123在一串二进制数中,最高为表示符号的正负,0为整数,1为负数; 对于正整数而言,原码、反码和补码都是一样的; 12345678910举个例子:如127 符号位 数值位 源码表示 0 1111111 反码表示 0 1111111 补码表示 0 1111111我们可以得到 127 这个整数在计算机中的存在形式以及表现的补码为 01111111我们再回过来可以验证一下: 1*2^0+1*2^1+1*2^2+1*2^3+1*2^4+1*2^5+1*2^6+0*2^7 = 1+2+4+8+16+32+64+0=127 12对于负整数而言,反码表示为原码的最高位置不变,其它位全部取反 补码为反码的值加1 123456789举个例子:如-127 符号位 数值位 源码表示 1 1111111 反码表示 1 0000000 补码表示 1 0000001验证一下: -1*2^7+1*2^0=-127 byte的最大值和最小值12345678910111213最大值: 最高位为整数,其它为1,得到01111111 经过等比公式计算得到值为:127 max=127最小值: 对于负整数-0,二进制表示为100000000(补码) 10000000(原码) 由于正整数0和负整数-0相等,但是它们的二进制表示形式却不一样并且-0还是9位二进制表示的,所以为了解决这个问题,就让10000000表示为-128即 min=-128 123456789所以我们能得到: 每个数据都是由8位二进制表示,每一位都有2种可能(0或者1),所以8位二进制可以组合的数据个数为: sum = 2^8=256 正整数从0~127共sum1=128个,负整数从-1~-128共128个 sum1 + sum2 =sum即从这个角度也可以说明最小范围为-128,最大范围为127。 分析上述题目  首先知道129补码的二进制形式为:00000000 00000000 00000000 10000001   又知道正数的补码和原码相同   我们截取出来10000001,很明显这是一个负数,补码-1=反码   得到反码:10000000,反码转原码得到(符号位不变):111111111   现在我们得到的原码是11111111再经过转反码求补码得到123456符号位 数值位 源码表示 1 1111111 反码表示 1 0000000 补码表示 1 0000001最后的结果:-1*2^7+1*2^0=-127 关于JVM的内存 12345678910111213141516171819202122232425运行时数据区包括:虚拟机栈区、堆区、方法区、本地方法栈、程序计数器虚拟机栈区:常说的栈区,线程私有,存放基本类型,对象的引用和returnAddress,在编译期间完成分配堆区:Java堆,也称GC堆,所有线程共享,存放对象的实例和数组,Java堆是垃圾收集器管理的主要区域方法区:所有线程共享,存储已被虚拟机加载的类信息,常量,静态变量,即时编译器编译后的代码等数据。这个区域的内存回收目标主要是针对常量池的对象的回收和对类型的卸载程序计数器:线程私有,每个线程都有自己独立的程序计数器,用来指示下一条指令的地址运行流程: 程序(非多线程)开始运行的时候,在系统中会自动分配一个栈,这个时候程序计数器就开始起到作用了,它会指示jvm对编译之后的字节码的执行方向,同时在执行一个方法的时候就会在栈中分配一个属于方法一个栈帧,方法的局部变量都会存放在这个栈帧中,其生命周期随着方法的结束而释放,这里强调一点的是先进后出的逻辑,堆中的数据当没有对象引用的时候就成了孤立数据,此时就会被GC垃圾回收器对其进行内存释放。 方法区包含了常量池:存放类信息、常量、静态变量、即时编译器编译后的代码等。其中静态成员变量在类装载的时候就进行了创建,在整个程序结束时按序销毁。 静态成员变量在类装载的时候就进行了创建,在整个程序结束时按序销毁。 实例变量在类实例化对象时候创建,在对象销毁的时候销毁。 局部变量在局部范围使用时创建,跳出局部范围销毁。 关于编译期和运行期: 编译期:就是将源码编译成二进制的.class字节码文件,并将文件放到了磁盘中, 编译期相当于只是做了一个翻译的过程 运行期:这块就是我们java解释器将二进制.class字节码解释成程序能识别的程序(将磁盘中的代码放到内存中就是类加载过程 线程12345678910111213 public class Bground extends Thread{ public static void main(String argv[]){ Bground b = new Bground(); b.run(); } public void start(){ for(int i=0;i<10;i++){ System.out.println("Value of i = "+i); } } }运行这段代码得到什么结果? 1234567891011分析: 开启线程的方法是start()方法:让线程从new变成runnable,run()方法是执行体的入口 这里的run方法使用的是父类的方法,需要有target这个对象,但很明显这里并没有初始化,所以运行这段代码什么也不会发生 @Override public void run() { if (target != null) { target.run(); } } 12345678910111213141516线程创建: 1.子类(ExtendsThread)继承Thread,子类开启start() // 启动线程 - 创建子类对象,调用子类对象的start方法 ExtendsThread extendsThread = new ExtendsThread(); extendsThread.start(); 2.类ImplRunnable实现Runnable,创建代理对象 // 创建实现类对象// ImplRunnable implRunnable = new ImplRunnable();// // 创建代理类对象// Thread thread = new Thread(implRunnable);// thread.start(); // 一个对象只使用一次则可以使用匿名类 - 可以不用申明引用 new Thread(new ImplRunnable()).start();; 分析代码123456789101112131415161718192021222324252627282930package Test;public class Test { private static void test(int[] arr) { for (int i = 0; i < arr.length; i++) { try { if (arr[i] % 2 == 0) { throw new NullPointerException(); } else { System.out.print(i); } } finally { System.out.print("e"); } } } public static void main(String[]args) { try { test(new int[] {0, 1, 2, 3, 4, 5}); } catch (Exception e) { System.out.print("E"); } } }分析: 由于arr[0] =0,所以在进入 test()方法里面会在第一个if 上抛出一个 NullPointerException,接着会执行 finally 的语句, (finally语句先于 return 和 throw语句执行), 输出一个'e,然后回到 main方法中,由于捕捉到异常,所以进入到catch语句中,然后打印一个'E',所以最终结果为"eE"]]></content>
<categories>
<category>nowcoder</category>
</categories>
<tags>
<tag>nowcoder</tag>
</tags>
</entry>
<entry>
<title><![CDATA[ss科学上网]]></title>
<url>%2F2019%2F06%2F09%2Fss%E4%B8%80%E9%94%AE%E6%90%AD%E5%BB%BA%2F</url>
<content type="text"><![CDATA[只是记录一下 1234567891011121314先安装git yum -y install git克隆项目 git clone -b master https://github.com/flyzy2005/ss-fly设置密码和端口 ss-fly/ss-fly.sh -i flyzy2005.com 1024加速 ss-fly/ss-fly.sh –bbr查看是否启动加速 sysctl net.ipv4.tcp_available_congestion_control]]></content>
<categories>
<category>科学上网</category>
</categories>
<tags>
<tag>ss</tag>
<tag>ladder</tag>
</tags>
</entry>
<entry>
<title><![CDATA[魃]]></title>
<url>%2F2019%2F06%2F07%2F%E9%AD%83%2F</url>
<content type="text"><![CDATA[待更新 写在开始]]></content>
<categories>
<category>数据结构与算法</category>
</categories>
<tags>
<tag>数据结构与算法</tag>
</tags>
</entry>
<entry>
<title><![CDATA[图和递归]]></title>
<url>%2F2019%2F06%2F02%2F%E5%9B%BE%E5%92%8C%E9%80%92%E5%BD%92%2F</url>
<content type="text"><![CDATA[图的相关知识以及用递归实现的一些算法 写在开始本周共实现算法:温故而知新1234数组的二分查找 矩形递归 二分查找实现旋转数组的最小值 - 两种实现方式 非递归方式的二叉树的层次遍历以及中序遍历        现在渐渐开始养成了每天都往仓库提交点什么,无论提交的是理论的知识还是实现的代码,总归是记录成长的见证。 场景我们小时候玩的迷宫,走到死胡同返回再去寻找有出路的新节点,尝试新的路径,往复循环直到找到出口,那么它是怎么记录下来路径,又是怎么去寻找到新节点的?微博和微信,用户之间能够互相关注和互相添加好友;抖音等系统机制能给你推荐你的好友,以及地图的最远和最近等机制怎么实现的? 图上周认识到了图这种数据结构,发现这种数据结构真的是好啊。然后我越来越真切地感受到,很多知识都是基于生活演变而来,仔细一想很多知识不就是为了解决生活中问题的么。 什么是图?图由顶点集合与描述各顶点之间边组成的一种数据结构图分为有向和无向如下图是有向图和无向图两种:我们都知道在使用的地图(无论是百度地图还是高德地图)它们都有帮我识别远近的,以及推荐最优解的功能那是怎么实现的?事实上,这里引入了一个概念带权图:在每个顶点之间的边上都会有一个权重(weight),通过它的和,会知道那条路径会更短以及用时最快 图的储存图存储方式有链表+数组和邻接矩阵储存的过程如上图,需要求解时间最少,距离最短,权值最小的最短路径通过一种算法:狄克斯特拉算法上图中共有8个地方,初始用如下方法记录 - 暂且认为从起点到v2-v8的距离均为-1(无穷大)12345678910S数组 v1T数组 v2 v3 v4 v5 v6 v7 v8前一个节点 当前节点 权重 v2 -1 v3 -1 v4 -1 v5 -1 v6 -1 v7 -1 v8 -1 经过最终的运算得到如下数组:12345678910111213141516s数组 v1 v2 v3 v4 v6 v7 v5 v8t数组前一个节点 当前节点 权重 v1 v2 3 v2 v3 4 v3 v4 5 v6 v5 8 v3 v6 6 v6 v7 7 v7 v8 12最短路径路线 v1 v2 v3 v6 v7 v8 12 3 1 2 1 5下面的数字代表的是:各个节点之间的距离 【最终结果表】 从上面那种表可以看出来,我们能够得到从v1到v2、v3等各个点之间的最短距离;狄克斯特拉算法实现过程:首先是:v1节点到最近的三个节点v2、v3、v4以及他们的权重是否大于初始值(-1)。如果大于则进行更新,所以得到如下:123456789101112131415161718192021222324252627v1节点: 前一个节点 当前节点 权重 上一个节点到当前节点的权重值 v1 v2 -1 3 v1 v3 -1 5 v1 v4 -1 6 v5 -1 v6 -1 v7 -1 v8 -1更新完了之后:将原本的`-1`替换掉最新的权重值, 如果[权重小于原本的权重]则进行替换 前一个节点 当前节点 权重 v1 v2 3 v1 v3 5 v1 v4 6 v5 -1 v6 -1 v7 -1 v8 -1数组表一: s数组 v1 v2 t数组 v3 v4 v5 v6 v7 v8 【表格一】 然后接下来,在【上一个节点到当前节点的权重值】这一栏中找到最小的值,即[3] - 对应当前节点最小的值:v2 ,得到【表格一】中的数组表一;1v1能到达的顶点已经走完了,现在看v2的能到达的顶点路径 1234567891011121314151617181920212223242526272829v2节点 - 能到最近节点的图 - (v5、v6、v3) - 则路径为[v1-v2-v3]、[v1-v2-v5]、[v1-v2-v6] 前一个节点 当前节点 权重 上一个节点到当前节点的权重值 v1 v2 3 v1 v3 5 1 v1 v4 6 v5 -1 v6 -1 7 v7 -1 4 v8 -1 更新完了之后:将原本的`-1`替换掉最新的权重值,如果[权重小于原本的权重]则进行替换,以及[前一个节点的名称] 前一个节点 当前节点 权重 v1 v2 3 v2 v3 1+3 v1 v4 6 v2 v5 7+3 v2 v6 4+3 v7 -1 v8 -1 数组表二: s数组 v1 v2 v3 t数组 v4 v5 v6 v7 v8 【表格二】 接下来就是循环前面的操作,直到走完v1-v8的所有路径,得到最终结果表详情可以了解 b站上面尚学堂的数据结构与算法 申明文章中的图片均非本人的原创,转自极客时间-王争专栏的图,若有打扰请联系本人进行删除;]]></content>
<categories>
<category>数据结构与算法</category>
</categories>
<tags>
<tag>sc数据结构与算法hedule</tag>
</tags>
</entry>
<entry>
<title><![CDATA[递归]]></title>
<url>%2F2019%2F05%2F26%2F%E9%80%92%E5%BD%92%2F</url>
<content type="text"><![CDATA[递归出口在哪? 写在开始本周有一个需求:就是需要完成一颗树结构递归呐,递归]]></content>
<categories>
<category>数据结构与算法</category>
</categories>
<tags>
<tag>数据结构与算法</tag>
</tags>
</entry>
<entry>
<title><![CDATA[常见算法复杂度分析和算法实现]]></title>
<url>%2F2019%2F05%2F19%2F%E5%B8%B8%E8%A7%81%E7%AE%97%E6%B3%95%E5%A4%8D%E6%9D%82%E5%BA%A6%E5%88%86%E6%9E%90%E5%92%8C%E7%AE%97%E6%B3%95%E5%AE%9E%E7%8E%B0%2F</url>
<content type="text"><![CDATA[常见算法的时间复杂度分析和栈实现队列、队列实现栈 写在开始刷题和sql在以后就只记录一些有意思的题目或分析;如:关于几个常见算法的时间复杂度分析案例:12345678(1).交换i和j的内容 sum=0; (一次) for(int i=0;i<=n;i++>){ (n次) for(j=1;j<=n;j++>){ (n^2次) sum++; (n^2次) } }则时间复杂度T(n) = 1+n+2*n^2 取最高次的影响则为 T(n) = O(n^2) 1234567(2). for (i=1;i<n;i++){ y=y+1; ① for (j=0;j<=(2*n);j++) (因为j能取到2n所以为:2n+1) x++; ② } ① 的时间复杂度是(n-1)、② 的时间复杂度是(n-1)(2n+1) 则时间复杂度为T(n) = O(n-1)+(n-1)(2n+1) = O(n^2) 12345678(3). a=0; b=1; ① (1次) for(i=1;i<=n;i++){ ② (n+1次) s=a+b; ③ (n次) b=a; ④ (n次) a=s; ⑤ (n次) } 则时间复杂度为:T(n) = 4n = O(n) 为线性的函数 123456(4). i=1; ① 1 while(i<=n>){ i=i*2; ② 2^f(n)<=n;f(n)<=log2n } T(n)=O(log2n) 这里频次本身是一个函数,则可求得函数本身f(n)的值 本周实现算法 1.用两个栈实现队列 - 完成基本的出队和入队的功能 123456789101112131415161718192021222324252627282930313233343536373839404142/*基本分析:由于栈和队列的两种结构是完全相反的*/ public class ImplQueueByStack{ // 定义两个栈 Stack<Integer> stackA = new Stack<Integer>(); Stack<Integer> stackB = new Stack<Integer>(); // 定义入队的方法 public void push(int node){ // 将栈A当作队列的入口 stackA.push(node); } // 队列的出队方法 public int pop() throws Exception{ if(stackA.isEmpty() && stackB.isEmpty()){ throw new Exception("队列为空"); } // 将栈B当作队列的出口,拿到栈A中的最后一个元素进行出栈 if(stackB.isEmpty()){ // 如果栈B为空的话,遍历栈A往栈B中添加元素 while(!stackA.isEmpty()){ stackB.push(stackA.pop()); } } // 添加返回值 return stackB.pop(); } // 测试方法 public static void main(String[] args) throws Exception { ImplQueueByStack implQueueByStack = new ImplQueueByStack(); implQueueByStack.push(2); implQueueByStack.push(4); implQueueByStack.push(0); System.out.println(implQueueByStack.pop()); implQueueByStack.push(10); implQueueByStack.push(20); System.out.println(implQueueByStack.pop()); } } 2.用两个队列实现栈 - 完成基本的出队和入队的功能 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253 public class ImplStackByQueue{ // 定义两个队列 Queue<Integer> queueA = new Queue<Integer>(); Queue<Integer> queueB = new Queue<Integer>(); //定义队列的入队方法 public void push(int node){ // 如果队列A为空,则队列B Push if(queueA.isEmpty()){ queueB.push(node); } if(queueB.isEmpty()){ queueA.push(node); } // 如果两个队列均为空的话,使用队列A优先 if(queueA.isEmpty() && queueB.isEmpty()){ queueA.push(node); } } // 定义出队的方法 public int pop() throws Exception{ if(queueA.isEmpty() && queueB.isEmpty()){ throw new Exception("栈为空"); }// 如果queueA为空,queueB不为空,将queueB的元素依次放入queueA,直到queueB中最后一个元素弹出 if(!queueA.isEmpty()){ while(queueB.size()>1){ queueA.add(queueB.poll()); } return queueB.poll(); } if(!queueB.isEmpty()){ while(queueA.size()>1){ queueB.add(queueA.poll()); } return queueA.poll(); } } public static void main(String[] args) throws Exception { ImplStackByQueue implStackByQueue = new ImplStackByQueue(); ImplStackByQueue.push(2); ImplStackByQueue.push(4); ImplStackByQueue.push(0); System.out.println(ImplStackByQueue.pop()); ImplStackByQueue.push(10); ImplStackByQueue.push(20); System.out.println(ImplStackByQueue.pop()); } }]]></content>
<categories>
<category>数据结构与算法</category>
</categories>
<tags>
<tag>数据结构与算法</tag>
</tags>
</entry>
<entry>
<title><![CDATA[刷题]]></title>
<url>%2F2019%2F05%2F12%2F%E5%88%B7%E9%A2%98%2F</url>
<content type="text"><![CDATA[做一个执行者而不是计划者 Beginning从上周开始写博客开始,我就开始计划了我后面每天要做的事情;目前已经开始执行了一周,然后到了周天的总结时间; 牛客网刷题首先是每天早上在公交上刷Java基础题目,每天,很惨呐😭;可以看出来Java的基础真的很差劲,但是目前的阶段主要在补充一些数据结构与算法的知识,所以就每天早上挤公交的时候刷刷题,到下阶段着重看Java;总结:关于Java基础,我相信很多人和我一样,面象google编程;再就是看了源码但过了一段时间又忘记了,所以我选择了每天刷点题,着重提高对数据结构与算法的认知,希望几个月后我能得到自己的肯定; 数据结构与算法这里刷的是剑指offer,虽然很多不懂,走的很慢,但慢慢磨总归是可以磨出来的;这周主要做了两道算法题目:一道是:输入一个链表,按链表值从尾到头的顺序返回一个ArrayList,另一道是:输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回。;其中链表的那道题目:给我印象最深的就是通过栈结构来实现的,这里充分地利用了栈结构先入后出的特性;以及递归方法,这也让我再次体会到了递归的强大;12345678910111213// 3.使用栈public ArrayList<Integer> printListFromTailToHeadStack(ListNode listNode){ Stack<Integer> stack = new Stack<>(); while(listNode != null){ stack.add(listNode.val); listNode = listNode.next; } ArrayList<Integer> ret = new ArrayList<>(); while(!stack.isEmpty()){ ret.add(stack.pop()); } return ret;} 12345678910111213// 递归实现 - 把后面未遍历的当成一个整体,然后调用自己的方法,这样理解起来就很方便了LinkedList<Integer> linkedList = new LinkedList<Integer>(); public ArrayList<Integer> printListFromTailToHead(ListNode listNode) { ArrayList<Integer> ret = new ArrayList<>(); if(listNode != null){ ret.addAll(printListFromTailToHead(listNode.next)); ret.add(listNode.val); //System.out.println(ret); } System.out.println(ret); return ret; } 然后关于树:学习了树的结构以及二叉树深度优先遍历和广度有限遍历,其中前序遍历,中序遍历,后序遍历三种深度遍历的方式。当然我自己根据题目给出的前两种遍历结构试着自己画了一下二叉树的结构,结果就是很容易把左边的树画出来,而右边的怎么都感觉不对劲;后面看了别人的思路也觉得画的有问题😚;可能还没有理解透彻,需要被再多折磨一下;总结:虽然算法在很多时候自己可能写不出来,但是硬着头皮去啃坚持一个阶段下来即使不能达到自己能随手写出来那种地步也会对整体的结构有一个比较清晰的脉络,值得深究; 关于SQL同样是在下午吃完饭回来进行练习,SQL的练习要比我想象中进展的快:计划是每周5道左右,目前来看貌似已经超两倍的完成;感觉牛客的SQL练习不大能起效果:就目前练习的来看基本都是两张表带点简单的条件以及排个序没有达到我想要的效果,可也能没做到后面的题目;改善:针对次可能需要进行改变一下,增加数据结构与算法的看书时间,先看算法书再练习SQL; 阶段总结目前来看,周一到周五基本能够完成上述的任务;周六周天主要写小程序和写文章、看书等任务周六和周天尚欠缺自制力,不能最大化的利用时间;希望能够有所改进;]]></content>
<categories>
<category>数据结构与算法</category>
</categories>
<tags>
<tag>数据结构与算法</tag>
</tags>
</entry>
<entry>
<title><![CDATA[hexo个人博客从0到1]]></title>
<url>%2F2019%2F05%2F02%2Fhexo%E4%B8%AA%E4%BA%BA%E5%8D%9A%E5%AE%A2%E4%BB%8E0%E5%88%B01%2F</url>
<content type="text"><![CDATA[写在开始这篇文章主要记录这两天倒腾的hexo个人博客系统从0到1的过程。 平台虽说是基于windows平台的搭建,但是很多命令都是一样的,所以想在Linux里面尝试的不妨倒腾两手 正文 Git的安装git是个好工具,和svn一样主要用于版本控制,我们需要在 git bush里面进行命令行的操作。有关git的相关知识可以到廖雪峰的网站进行学习; NodeJS的安装NodeJS也是个好东西,这玩意儿居然能写js的后端,一句话流批。NodeJS主要是用来管理和配置npm包的,安装完成需要配置一下环境变量,然后打开cmd,输入会有对应的版本号 12node -vnpm -v hexo的安装安装好工具之后开始操作:首先建立一个hexo文件的目录;例如在D盘根目录新建hexo文件夹,然后cd到该目录下,开始安装。 1234567$ cd D:hexo/ #换成你的目录$ npm install -g hexo-cli #安装hexo脚手架$ hexo init #Hexo自动在当前文件夹下下载搭建网站所需的所有文件$ npm install #安装依赖包$ hexo g #完整命令为hexo generate,生成静态文件$ hexo s #完整命令为hexo server,启动服务器,用来本地预览 然后localhost:4000(默认开启4000端口)就能看到自己的静态资源站了 调整相关hexo样式这里一般就是先选好自己想用哪个主题样式用npm包clone下来,然后在主题文件夹下的配置文件改。如:日期啊,分页啊,用哪种样式等等,这里就不一一介绍了。这里可以参考hexo官网,看看它的目录结构以及受欢迎的主题。我看很多人用的Next主题,简洁而不简单 蛮不错的。 到这里应该都能访问到本机服务上的博客了。接下来主要做的就是将本地代码部署到远端GitHub上去。 部署到GitHub上并解析自己的域名 建立仓库值得注意的是,这里命名规则是账号名.github.io这个是后面你访问的域名(如果不绑定自己的域名的话) 设置git的名字和邮箱设置命令 1git config --global user.name '账号名' 查看是否设置成功的命令 1git config --global user.name 邮箱同理 1git config --global user.email '邮箱' 配置SSH密匙配置密匙命令 1ssh-keygen -t rsa -C '邮箱名' 查看是否设置成功 1ssh -T [email protected] 打开生成好密匙的文件id_rsa.pub,进入GitHubsetting-->SSH and GPG keys-->New SSH key复制粘贴保存 部署打开D:\hexo,用sublime或者VS code打开根目录下的_config.yml文件,文件最后可以看到 12deploy: type: 修改其配置 1234deploy: type: git repository: [email protected]:yourname/yourname.github.io.git #发布到github branch: master 然后就是一套,你可以选择将它们写到bat脚本执行文件里面去 123$ hexo clean$ hexo g$ hexo d 当然这里如果你没有安装部署的命令的话需要如下操作 1$ npm install hexo-deployer-git --save 这时,你就可以在浏览器里面输入https://yourname.github.io来进行访问你的博客了; 将域名解析到对应的GitHub仓库地址(可选)如果你有自己的域名的话或者你想拿自己的域名做链接的话,你需要到对应的云平台域名解析设置两条www和@的解析设置,其中记录类型为CNAME和记录值为账号名.github.io。进入{yourname}.github.io仓库-->Settings->GitHub Pages保存好域名即可。到D:\hexo\sourse目录下(即你安装hexo的目录下的sourse目录下)新建文件CNAME,用Sublime或者VS code打开,填入你的域名,如jokerq.com,保存。然后到D:\hexo目录下用sublime打开_config.yml,ctrl+f查找skip_render,然后改为 123skip_render: - README.md - CNAME 最后就是执行你的bat文件,大功告成!]]></content>
<categories>
<category>前端</category>
</categories>
<tags>
<tag>hexo</tag>
<tag>静态博客系统</tag>
</tags>
</entry>
<entry>
<title><![CDATA[Hello World]]></title>
<url>%2F2019%2F05%2F02%2Fhello-world%2F</url>
<content type="text"><![CDATA[Welcome to Hexo! This is your very first post. Check documentation for more info. If you get any problems when using Hexo, you can find the answer in troubleshooting or you can ask me on GitHub. Quick StartCreate a new post1$ hexo new "My New Post" More info: Writing Run server1$ hexo server More info: Server Generate static files1$ hexo generate More info: Generating Deploy to remote sites1$ hexo deploy More info: Deployment]]></content>
</entry>
<entry>
<title><![CDATA[逍惆]]></title>
<url>%2F2019%2F04%2F28%2Fmarkdown%E5%9F%BA%E6%9C%AC%E8%AF%AD%E6%B3%95%E7%9A%84%E4%BD%BF%E7%94%A8%2F</url>
<content type="text"><![CDATA[小丑的世界逍惆的第一篇blog 列表1 列表2 a 子列表 b 子列表 列表3 小丑的世界 字体变斜 字体加粗 <html></html> 12345678<html> <head> <title>我是代码片段</title> </head> <body> conole.log(我是打印的函数); </body></html> 引用别人的代码]]></content>
<categories>
<category>前端</category>
</categories>
<tags>
<tag>导航</tag>
<tag>分享</tag>
</tags>
</entry>
</search>