leetcode的一道字符串题目:最长不重复的子字符串长度

找出最长的不重复的子字符串

首先一拿到这个题目的时候想到利用set集合来存储子字符串,当发现含有重复的字符的时候就将这个set清零。这个做法有一个明显的缺点就是当子字符串中的某一个字符和后面的重复的话,那么后面不行同的也会被清楚:例如dfvfab,在这个里面vfab应该是最短的子字符串,但是这时候这个方法会输出错误的值。

思路:

自己想不到解法之后就参考了Solution2,这个方法想了下也挺好的,遂记录下:
该方法是设置两个游标,一个在前,一个在后(定义为i,j),当前面的一个发现在set集合中含有重复的字符,那此时停止i,然后j自增,当发现在set集合中已经将重复的那个字符剔除之后,此时在i自增

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
public int lengthOfLongestSubstring(String s) {
//错误的思路,以为存入set就可以
// if (s == null || s.length() == 0){
// return 0;
// }
// Set<Character> set =new HashSet<>();
// int max=0;
// for (int i =0 ;i< s.length() ;i++){
// char c = s.charAt(i);
// if (set.contains(c)){
// set.clear();
// }
// set.add(c);
// if (set.size() > max){
// max = set.size();
// }
// }
// return max;
if(s == null || s.length() ==0){
return 0;
}
Set<Character> set =new HashSet<>();
int i=0,j=0,result=0,n=s.length();
while(i < n && j <n){
if(!set.contains(s.charAt(j))){
set.add(s.charAt(j++));
result=Math.max(result,j-i);
}else{
set.remove(s.charAt(i++));
}
}
return result;
}
阅读更多

Java通过反射用指定构造器初始化

Java通过反射用指定构造器初始化

首先, 一般来讲在Java中初始化一个类是通过new来操作的, 但是有一种情况却不适合这种new操作,那就是通过配置文件来进行实例化操作。

例如,在Spring中,需要加载配置文件中的类,这是比较常见的配置。 那么在Spring启动类中如何将这个类加载进容器中呢,显然进行new操作是不太现实的。 这时候就需要Java的反射操作了,Java的反射操作一般来讲有两种:分别是Class.forName()classLoader.loadCLass() 最后都是通过newInstance() 来进行初始化,但是在这里却发现假设反射的类中含有带参数的构造器,那么此时这个newInstance()就会抛NoSuchMethodException ,这是因为newInstance()因为不加参数所以调用的是默认构造器,而反射类中已经包含了带参数的构造器,所以无不带参数构造器,遂抛出异常。

但是此时newInstance()是加不了参数的,所以若需要通过制定构造器来进行反射的话需要一个类叫Constructor,

新建一个实体类:

阅读更多

记一次springboot-mybatis找不到dao层的错误

写了三个多月的Python,今天再写一个springboot-mybatis的项目的时候好多东西都忘记了,尤其是在今天下午遇到了一个关于mybatis的错误:

1
2
3
4
5
6
7
8
Description:

Field peopleDao in com.example.serviceImpl.PeopleServiceImpl required a bean of type 'com.example.dao.PeopleDao' that could not be found.


Action:

Consider defining a bean of type 'com.example.dao.PeopleDao' in your configuration

很明显就是dao层无法被扫描到,在一下午的尝试中,首先检查了包结构,如下:
com
—example
——controller
————XXX.java
——dao
————XXX.java
——–***
——Application.java

也就是说这个包结构是完全符合springboot的规范的,也就表示在启动类上面的注解是完全可以扫描到dao包下面的那个接口的。所以注解不存在问题。

然后尝试了第二种方法。修改启动类的扫描结构:

阅读更多

关于Java线程的一些思考

消费者和生产者的模型:

今天在看《现代操作系统》P73页的一个关于多线程的竞态条件的时候书中说到了唤醒等待位方法,这个方法使我突然想起联想到以前在Java多线程中sleep()方法会清除中断状态的一些类似之处:
树上的代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#definde N 100
int count =0;
void producer(void){
int item;
while(True){
item=producer_item();
if (count == N) sleep();
insert_item(item);
count=count+1;
if (count == 1 )wakeup(consumer);
}
}

void consumer(void){
int item;
while(true){
if (count == 0)sleep();
item =remove_item();
count=count -1;
if (count == N-1) wakeup(producer);
consumer_item()
}
}

在书中提到过一个情况就是:当消费者判断count==0的时候是会睡眠的,但是此时由于某种情况(线程的sleep()方法还没被执行完),而恰巧生产者又生产了一个item,导致此时count加一为1,而当count为1的时候生产者是会发出一个wakeup信号给消费者的,此时,由于消费者并没有睡眠因此会忽略掉该信号,而当消费者真正睡眠之后又由于生产者再不会进行通知,导致队列被生产者塞满,从而该模型阻塞。
那么为了解决该方法,书中引入了唤醒等待位方法,该方法就是在生产者发出信号给消费者的时候添加一个中断状态,而当该线程需要进行睡眠的时候会先判断状态,若是wakeup则不进行睡眠

Java多线程中的引用:

阅读更多

pandas的transform和apply

q区别

transform是Pandas里面Groupby的一个方法,主要作用是对groupby之后的dataframe进行处理,接收的参数一个是一个Series

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
In [18]: df = pd.DataFrame({'B': ['one', 'one', 'two', 'three','two', 'two', 'one', 'three'],
...: 'C': [1,2,3,4,5,6,7,8], 'D': [11,12,13,14,15,16,17,18]})

In [19]: df
Out[19]:
B C D
0 one 1 11
1 one 2 12
2 two 3 13
3 three 4 14
4 two 5 15
5 two 6 16
6 one 7 17
7 three 8 18

那么需要对其groupby之后求C的平均值怎么办

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
n [23]: df.groupby('B').transform(lambda x : x.mean())
Out[23]:
C D
0 3 13
1 3 13
2 4 14
3 6 16
4 4 14
5 4 14
6 3 13
7 6 16

In [24]: df.groupby('B').apply(lambda x : x.mean())
Out[24]:
C D
B
one 3.333333 13.333333
three 6.000000 16.000000
two 4.666667 14.666667

阅读更多

pandas的操作使用

pandas读取csv文件

在pandas读里面包含了几个函数分别用来读取csv或者excel文件:
read_csv方法用来读取一个csv文件一般常用参数是path:用于指定一个文件及其目录
sep表示读取该csv文件的时候是以什么制表符读取的,一般是’,’
usecols表示需要读取csv的多少列,这是一个绝对索引,0代表的是第一列,参数为一个list

Pandas的结构:

pandas经常使用的结构一般是dataframe和series,DataFrame类似于二维数组,或者sql里面的一张表,若在创建的时候为指定索引的话则默认从0开始一次递增为索引:

1
2
3
4
5
6
7
8
9
10
11
12
import pandas as pd
In [15]: df_2=pd.DataFrame(data=['a','b','c'])

In [16]: df_2
Out[16]:
0
0 a
1 b
2 c
用上述方式创建的时候是不需要指定index的,但是用标量创建的时候是需要指定index的:
pd.DataFrame({'a':'A','b':'B'})
ValueError: If using all scalar values, you must pass an index
阅读更多

关于流和多态的一些记录

流的读取问题

read()方法

read()方法经常用于读取一个byte数组或者char数组,其内部的方法如下:

1
2
3
public final int read(byte b[]) throws IOException {
return in.read(b, 0, b.length);
}

首先在读取字节流的时候是所有的字节流的顶级类的是InputStream抽象类,而继承自Inputstream的类都是带有read方法,每一个类几乎丢重写了自己的read方法,而这就是多态的一种体现。

阅读更多

关于Java的HashMap

Map接口:

  1. 在map接口中的存在一个主接口:public interface Map 和一个内部接口:interface Entry
  2. 其中Map接口主要功能是提供map的一些基本的操作,例如put,inEmpty,get等,而Entry接口则主要是负责遍历操作时的一些方法,例如getKey(),getValue(),setValue

#HashMap实现类:

  1. 在HaspMap这个类里面其实包含了很多的内部类:如下图:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    Node
    HashMap
    KeySet
    KeySpliterator
    EntrySet
    Values
    HashIterator
    KeyIterator
    ValueIterator
    EntryIterator
    HashMapSpliterator
    ValueSpliterator
    EntrySpliterator
    TreeNode

    TreeNode类: TreeNode类是一个红黑树:里面包含的是一些红黑树的操作;

    EntrySet类: EntrySet类是提供一个HashMap的遍历方式的一个类,EntrySet类里面有iterator方法,其作用在于map的一种遍历方式:

    1
    2
    3
    4
    5
    Iterator iterator =map.entrySet().iterator();
    while (iterator.hasNext()){
    Map.Entry<Object,Object> map1 = (Map.Entry<Object, Object>) iterator.next();
    System.out.println(map1.getKey());
    }
    这里涉及的知识是EntrySet是继承了AbstractSet间接实现了Set接口,而map.entrySet()方法返回的是一个Set<Map.Entry<K,V>>这个实例。

    其他的暂时还不知道有什么用

关于HashMap的其他细节

阅读更多

关于ArrayList的所见所想

关于ArrrayList扩容:

今天在面试的时候面试官提到过ArrayList扩容是原来的1.5倍加一,但是我看jdk1.8的时候是显示为1.5倍

查看源码:

1
2
3
4
5
6
7
8
9
10
11
12
//Java1.8的扩容方法
private void grow(int minCapacity) {
// overflow-conscious code
int oldCapacity = elementData.length;
int newCapacity = oldCapacity + (oldCapacity >> 1);
if (newCapacity - minCapacity < 0)
newCapacity = minCapacity;
if (newCapacity - MAX_ARRAY_SIZE > 0)
newCapacity = hugeCapacity(minCapacity);
// minCapacity is usually close to size, so this is a win:
elementData = Arrays.copyOf(elementData, newCapacity);
}

那么ArrayList会是扩充1.5倍之后加一呢?

阅读更多

安装hexo的一些注意事项

安装步骤:

  1. 首先安装npm —
  2. 然后安装hexo npm install hexo-cli -g
  3. 初始化一个hexo项目 hexo init blog
  4. 添加配置文件 pm install --save hexo-renderer-jade hexo-renderer-scss hexo-generator-feed hexo-generator-sitemap hexo-browsersync hexo-generator-archive
  5. 安装 npm install

添加主题文件:

  • 在github上找出自己喜欢的一个主题
  • 用git命令clone下来
  • 将文件放到themes文件夹,然后修改hexo文件的_config.yml
  • 将themes文件夹里面的那个主题名称添加到theme这个标签之后
  • 可以在theme文件夹里面修改_config.yml这个文件来获得想要的效果