ARTS (第1周)
ARTS 高效学习是左耳听风发起的一个高效学习方法,一个需要持续坚持的方法。ARTS 包含四块的内容(作者原话):
- Algorithm。主要是为了编程训练和学习。每周至少做一个 leetcode 的算法题(先从Easy开始,然后再Medium,最后才Hard)。进行编程训练,如果不训练你看再多的算法书,你依然不会做算法题,看完书后,你需要训练。关于做Leetcode的的优势,你可以看一下我在coolshell上的文章 Leetcode 编程训练 - 酷 壳 - CoolShell(一个小时以内);
- Review:主要是为了学习英文,如果你的英文不行,你基本上无缘技术高手。所以,需要你阅读并点评至少一篇英文技术文章,我个人最喜欢去的地方是 Medium(需要梯子,其他的可以社区的官方文档以及论文学习)以及各个公司的技术blog,如Netflix的(30min);
- Tip:主要是为了总结和归纳你在是常工作中所遇到的知识点。学习至少一个技术技巧。你在工作中遇到的问题,踩过的坑,学习的点滴知识(也可以学习【极客时间】上的实用课程);
- Share:主要是为了建立你的影响力,能够输出价值观。分享一篇有观点和思考的技术文章,也可以是技术总结的文章。
Algorithm 算法
LeetCode 三数之和
https://leetcode-cn.com/problems/3sum/submissions/
题目描述
给定一个包含 n 个整数的数组 nums
,判断 nums
中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?找出所有满足条件且不重复的三元组。
注意:答案中不可以包含重复的三元组。
例如, 给定数组 nums = [-1, 0, 1, 2, -1, -4],
满足要求的三元组集合为:
[
[-1, 0, 1],
[-1, -1, 2]
]
思路:
关于这题,我最首先的做法是最繁杂的做法,先找出所有符合的数组,然后在添加到结果集合的时候判断是否重复(使用集合的container方法),进行去重。结果做成了四重循环的模式(因为container方法里就是一个循环,加上外层的三重循环,合起来四重),效率极低,上传到LeetCode,就直接返回说答案超时。
随后进行了修改,先排序,然后每个循环开始的时候,进行判断,判断当前是否和前一个数字相同。相同的话就跳过,在判断的同时进行排序,大大减少了去重的开销。但结果依然是超时,如下图。
1 | public List<List<Integer>> threeSum3(int[] nums) { |
在这个时候,我隐隐感觉到了这个题目,如果循环还是这么多重,多半答案都是超时。
1 | public static List<List<Integer>> threeSum5(int[] nums) { |
这边的思路就是先排序,从小到大,并且这题的要求是3数之和是0 因此要么三个数值都是0,要么必定有一个数字小于0, 因此,在从小到大排序的时候,如果第一个数字大于0,就可以结束了。
至于内层循环的判断,首先也是重复数字的跳过判断,然后则是从数组的最左端(最小数)和最右段(最大数)的坐标开始进行双端同时进行查找,将剩余数组里的最大数和最小数与外层循环的数字进行相加,若结果大于0,则集合的最大数字的坐标进行减一位的操作(减小),若大于0,则进行最左边左边的扩大一位的操作。等于0,则符合条件。
Review 英文文章
nginx 1.8.0 的文档
https://www.nginx.com/blog/nginx-unit-1-8-0-now-available/
该文档讲述了nginx 1.8.0的各类配置的使用
Tip 技巧
1、本周学会了hexo+GitHub搭建博客的技巧 也就是当前的博客。
参考链接https://www.cnblogs.com/liuxianan/p/build-blog-website-by-hexo-github.html
2、本周学会了spring boot方面的知识:
以下内容学习自尚硅谷
(1)yml语句的语法
1、基础语法
k:(空格)v:表示一对键值对(空格必须有);
以空格的缩进来控制层级关系;只要是左对齐的一列数据,都是同一个层级的
1 | server: |
ps:属性和值也是大小写敏感;
2、值的写法
字面量:普通的值(数字,字符串,布尔)
k: v:字面直接来写;
字符串默认不用加上单引号或者双引号;
“”:双引号;不会转义字符串里面的特殊字符;特殊字符会作为本身想表示的意思
name: “zhangsan \n lisi”:输出;zhangsan 换行 lisi
‘’:单引号;会转义特殊字符,特殊字符最终只是一个普通的字符串数据
name: ‘zhangsan \n lisi’:输出;zhangsan \n lisi
3、对象、Map(属性和值)(键值对):
k: v:在下一行来写对象的属性和值的关系;注意缩进
对象还是k: v的方式
1 | user: |
行内写法:
1 | user: {lastName: test,age: 18} |
4、数组(List、Set):
用- 值表示数组中的一个元素
1 | users: |
行内写法
1 | users: [toms,mike] |
(2)多Profile文件
我们在主配置文件编写的时候,可以配置多Profile,方便不同环境下的修改、测试、运行
spring 默认使用application.properties的配置;
例如:如果使用profile,文件名可以是 application-dev.properties/yml (格式为application-{profile}.properties/yml),在配置文件中指定 spring.profiles.active=dev,那么就可以指定使用 application-dev.properties/yml 的配置
(3)配置文件的优先级
配置文件在spring boot里 分为jar包内 和jar包外的配置
在指定了外部配置的情况下,外部配置的优先级大于内部。
在jar包内的配置文件如下
spring 默认使用application.properties/yml 为文件名的配置;
优先级由高到底,高优先级的配置会覆盖低优先级的配置;
优先级路径如下:
–file:./config/
–file:./
–classpath:/config/
–classpath:/
spring boot还提供外部引入配置
例如在命令行参数里指定端口:java -jar xxx.jar –server.port=8087
官方文档的配置外部文件优先级(这里就不一一细说了)
- Devtools global settings properties on your home directory (
~/.spring-boot-devtools.properties
when devtools is active). @TestPropertySource
annotations on your tests.@SpringBootTest#properties
annotation attribute on your tests.- Command line arguments.
- Properties from
SPRING_APPLICATION_JSON
(inline JSON embedded in an environment variable or system property) ServletConfig
init parameters.ServletContext
init parameters.- JNDI attributes from
java:comp/env
. - Java System properties (
System.getProperties()
). - OS environment variables.
- A
RandomValuePropertySource
that only has properties inrandom.*
. - Profile-specific application properties outside of your packaged jar (
application-{profile}.properties
and YAML variants) - Profile-specific application properties packaged inside your jar (
application-{profile}.properties
and YAML variants) - Application properties outside of your packaged jar (
application.properties
and YAML variants). - Application properties packaged inside your jar (
application.properties
and YAML variants). @PropertySource
annotations on your@Configuration
classes.- Default properties (specified using
SpringApplication.setDefaultProperties
).
(4)Spring boot 的自动装配原理初识
部分注解
1 | "xxxxx") //将配置文件中配置的每一个属性的值,映射到这个组件中 例如类person(属性有name,age) 引入的prefix 为self.person 配置文件有self.person.name: tom ,self.person.age:18 ,那么就会在spring容器里注册进一个person的bean 其name属性为tom,age属性为18 (prefix = |
SpringFactoriesLoader会扫描所有jar包类路径下 META-INF/spring.factories
把扫描到的这些文件的内容包装成properties对象
从properties中获取到EnableAutoConfiguration.class类(类名)对应的值,然后把他们添加在容器中。并且这些类一般都以xxxxAutoConfiguration命名。
例如
1 | //表示这是一个配置类 |
上面是一个redis的自动配置类,首先redis自动配置类 会进行环境的判断判断当前环境中是否有自己需要的类,如果有则其注解@conConfiguration生效,表明这是一个配置类,随后该类将会根据配置在容器中添加配置类RedisProperties,同时也会注册LettuceConnectionConfiguration、JedisConnectionConfiguration2个类。
随后会开始下一步的具体的bean配置 该方法会进入redisClient()方法,该方法会先判断环境中是否有RedisClient类的bean,若有(例如:用户自定义了该bean的情况),则不会继续注册这个bean,若没有该指定的bean,则会进行注册。
(5)利用自动配置进行组件的切换
SpringBoot底层是Spring框架,Spring框架默认日志框架是用JCL,而spring boot的默认的日志配置则是slf4j+logback。
如果我们需要修改slf4j+log4j的方式,则仅需要去除slf4j+log4j的依赖,然后引入slf4j-log4j12的依赖即可。
因为spring boot有自动装配的功能,会自动判断环境,进行指定组件的注册,并不需要程序员进行太多的操作。
1 | <dependency> |
PS:其它的组件切换也类似:例如tomcat切换成netty ,只需要将tomcat的依赖去掉,并加上netty 的依赖,即完成操作。
Share 分享
适时的总结,可以帮助我们梳理知识。
在我写完这篇总结的过程中,我发现了有几个隐藏的知识点未曾注意到,也发现了几个知识点还未理解透彻,这也可以帮助我们发现自己的不足。
做事情不要浮躁、每一个成功的人都是一点一滴积累起来的。将自己积累起来了,未来自己的选择也将更多更好。
有好的想法就去尝试。任何事情如果都是光想不做,结果都是会失败。成功都是一点一点的积累起来。