python代码阅读技巧_Python源码阅读技巧
原标题:Python源码阅读技巧
刚参加⼯作那会,没想过去读源码,更没想过去改框架的源码;总想着别⼈的框架应该是完美的、万能的,应该不需要改;另外即使我改了源码,怎么样让我的改动⽣效了?项⽬中引⽤的不还是没改的jar包吗。回想起来觉得那时候的想法确实挺……
⼯作了⼀年多之后准备跳槽了,开始了⼀轮的⾯试,其中有⼏个⾯试官就问到了相关的源码问题:ArrayList、HashMap的底层实
现,spring、mybatis的相关源码。问源码的⾯试⼀般就是回去等消息,然后就没然后了。
那时候开始意识到,源码这东西在之前的⼯作的中感受不到,但是在⾯试中好像⾯的还挺频繁的,从此有意识的开始了jdk部分源码的阅读(主要是集合)。⼀开始看源码,看的特别糙,知道个⼤概,知道ArrayList的底层实现是数组,HashMap的底层是散列表(数组+链表);更深⼊⼀点的扩容、hash碰撞等等就不知道了。
读spring源码起于⼯作中遇到了⼀个问题(spring jdbcTemplate事务,各种诡异,包你醍醐灌顶!),排查⼀段时间最终是解决了,但过程让我⾮常难受,各种上⽹查资料、各种尝试,感觉就像⼤海捞针⼀样,
遥遥⽆期。我下定决⼼,我要看⼀看spring的源码,于是我买了⼀本《spring源码深度解析》,结合着这本书、打开着eclipse,开始了spring的源码阅读之旅。⾄此,读源码成了习惯,源码已经进⼊了我的⼼⾥。
后来,springboot的⽕热,让我也想蹭上⼀蹭,于是有了springboot的启动源码系列,虽然还在进⾏中,但是我相信我能将其完成;⼯作中⽤到了shiro,我⼜结合着《跟我学shiro》将shiro的源码看了个⼤概,有了shiro源码系列博⽂,还差⼀篇认证与授权(应该很快就能⾯世),shiro源码系列就封笔了。最近在搭建⾃⼰的后台管理系统,⽤到了quartz,集成的过程也遇到了⼀些问题,因此有了quartz的两篇⽂章。
慢慢的,从⼀味的⽹上资料变成了很多时候会从源码中答案。不求能读太多的源码,但愿⾃⼰接触的技术都能读上⼀读,路漫漫其修远兮,吾将上下⽽求索!
我为什么读源码
很多⼈⼀定和我⼀样的感受:源码在⼯作中有⽤吗?⽤处⼤吗?很长⼀段时间内我也有这样的疑问,认为哪些有事没事扯源码的⼈就是在装,只是为了提⾼他们的逼格⽽已。
那为什么我还要读源码呢?⼀刚开始为了⾯试,后来为了解决⼯作中的问题,再后来就是个⼈喜好了。
说的好听点是有匠⼈精神;说的委婉点是好奇(底层是怎么实现的);说的不⾃信点是对⿊盒的东西我⽤的没底,怕⽤错;说的简单直⽩点是提升⾃我价值,为了更⾼的薪资待遇(这⾥对真正的技术迷说声抱歉)。
源码中我们可以学到很多东西,学习别⼈⾼效的代码书写、学习别⼈对设计模式的熟练使⽤、学习别⼈对整个架构的布局,等等。如果你还能出其中的不⾜,那么恭喜你,你要飞升了!会使⽤固然重要,但知道为什么这么使⽤同样重要。从模仿中学习,从模仿中创新。
读源码不像围城(外⾯的⼈想进来,⾥⾯的⼈想出去),它是外⾯的⼈不想进来,⾥⾯的⼈不想出去;当我们跨进城内,你会发现(还是城外好,⽪!)城内风光⽆限,源码的海洋任我们遨游!
我是怎么样读源码的
内容了解
word文本框边框怎么去掉⾸先我们要对我们的⽬标有所了解,知道她有什么特点,有些什么功能。对对⽅都还不了解,就想着进⼊别⼈的内⼼世界,那不是臭不要脸嘛,我们要做⼀个有着流氓⼼的绅⼠;对她有个⼤致的了解了,就可以发起攻势,⼀举拿下。四组随机
那么怎么样了解了,⽅式有很多,我这⾥提供⼏种,仅供参考
最好的⽅式就是官⽅参考指南,亲⽣⽗母往往对孩⼦是最了解的,对孩⼦的描述也是最详细的;⽐如Spring Boot Reference Guide就是对springboot最详细的描述,怎么样使⽤springboot、springboot特性等等,通过此指南,springboot在你⾯前⼀览⽆遗;
但是,springboot毕竟是外国⼈的孩⼦,如果英语不好,估计读起来有点头疼了,不过我们有google翻译呀,咬咬⽛也是能看的。源码世界的丈母娘、⽼岳丈是⾮常慷慨的!
其次是书籍,国外优秀的有很多,国内也不乏好书,⽐较推荐此⽅式,⾃成体系,让我们掌握的知识点不⾄于太散。这就是好⽐是源码的闺蜜,对源码⾮常了解,重点是挺⼤⽅,会尽全⼒帮助我们了解源码。
再次就是博客,虽然可能觉得知识点⽐较散,但是针对某个知识点却特别的细,对彻底掌握⾮常有帮助,园⼦内就有很多技术⼤⽜,写的博客⾃然也是⾮常棒,⾮常具有学习价值。当然还有社区、论坛、github、码云等等。这就是源码的朋友圈,我们从中也能获取到⾮常多关于源码的信息。
设计模式的了解
优秀的框架、技术从不乏设计模式;jdk源码中就应⽤了很多设计模式,⽐如IO流中的适配器模式与装饰模式、GUI的观察者模式、集合中的迭代器模式等等;spring源码中也是⽤到了⼤量的设计模式。设计模式有什么优点、各适⽤于什么场景,不是本⽂的内容,需要我们⼤家⾃⾏去了解。
我们只需要对⼀些常⽤的设计模式有个⼤致了解,再去读源码是⽐较好的;不需要将23种设计模式都通读,也不需要将常⽤设计模式完全理解透;对于全部通读,我们时间有限,另外有些模式确实不太好理解、⽤的少,性价⽐不⾼,没必要全部都读。
推荐书籍:《Head First Design Patterns》(中⽂版:《Head First 设计模式》)、《Java与模式》;
另外我⽐较推荐的⼀种学习设计模式的⽅式是读别⼈博客:java_my_life,刘伟技术博客,chenssy的设计模式;
设计模式之于源码,就好⽐逛街购物之于⼥⼈,想顺利勾搭源码,我们需要好好掌握设计模式这个套路。
配合ide进⾏断点追踪
我们通过源码的圈⼦对源码的了解终究只是停在表⾯,终究还是没有⾛进她的内⼼,接下来我就和⼤家分享下,我是如何⾛进她的内⼼的!
相信看过我的源码博客的⼩伙伴都知道,我⾮常喜欢通过idea断点来进⾏源码追踪,断点追踪源码是我⾮常推荐的⼀种⽅式。断点不仅可以⽤来调试我们的代码,也可以⽤来调试我们⽤到的框架源码。
⾯对未知的、茫茫多的源码,我们往往没有⾜够的时间、经历和耐⼼去通读所有源码,我们只需要去读我们关注的部分即可(有⼈可能会说我都不关⼼,这…)。那为什么要⽤断掉调试的⽅式来跟源码,⽽不是直接从源代码⼊⼿去跟我们关注的部分呢?
尝试过的⼩伙伴应该知道,如果我们对源码不熟悉,直接通过源码的⽅式去跟,⼀⽅⾯很容易迷路(多态,会有很多⼦类实现),不知道接下来跟哪⼀个,另⼀⽅⾯也很容易跟丢,当我们跟⼊的很深的时候,很有可能就忘记上⼀步跟到哪了。
下⾯我会举例来说明我是如何进⾏断点追踪的,以spring-boot-2.0.3之quartz集成,不是你想的那样哦!和 spring-boot-2.0.3之quartz 集成,数据源问题,源码探究 为背景来讲,需要搞清楚两个点:springboot是如何向quartz注⼊数据源的,quartz是如何操作数据库的
springboot向quartz注⼊数据源
QuartzAutoConfiguration是springboot⾃动配置quartz的⼊⼝
将quartz的配置属性设置给SchedulerFactoryBean;将数据源设置给SchedulerFactoryBean:如果有@QuartzDataSource修饰的数据源,则将@QuartzDataSource修饰的数据源设置给SchedulerFactoryBean,否则将应⽤的数据源(druid数据源)设置给SchedulerFactoryBean,显然我们
的应⽤中没有@QuartzDataSource修饰的数据源,那么SchedulerFactoryBean中的数据源就是应⽤的数据源;将事务管理器设置给SchedulerFactoryBean。SchedulerFactoryBean,负责创建和配置quartz Scheduler,并将其注册到spring容器中。SchedulerFactoryBean实现InitializingBean的afterPropertiesSet⽅法,⾥⾯有可以设置数据源的过程
可以看到通过org.quartz.jobStore.dataSource设置的dsName(值为quartzDs)最后会被替换成springTxDataSource.加scheduler实例名(我们的应⽤中是:springTxDataSource.quartzScheduler)。springboot会注册两个ConnectionProvider给quartz:⼀个dsName 叫springTxDataSource.quartzScheduler,有事务;⼀个dsName叫springNonTxDataSource.quartzScheduler,没事务。
quartz如何操作数据库
我们通过停⽌定时任务来跟下quartz对数据库的操作
发现quartz⽤如下⽅式获取connection
conn = Instance().getConnection(getDataSource());复制代码
那么我们的job中就可以按如下⽅式操作数据库了
public class FetchDataJob extends QuartzJobBean {
// private String dataSourceName = "quartzDs"; // ⽤此会不到
// private String dataSourceName = "springNonTxDataSource.quartzScheduler"; // 不⽀持事务
// private String dataSourceName = "springTxDataSource.quartzScheduler"; // ⽀持事务
private final String insertSql = "INSERT INTO tbl_sys_user(name, age) VALUES(?,?) ";
private String schedulerInstanceName = "quartzScheduler"; // 可通过jobDataMap注⼊进来
sql递归函数的例子@Override
protected void executeInternal(JobExecutionContext context) throws JobExecutionException {
String dsName = LocalDataSourceJobStore.NON_TX_DATA_SOURCE_PREFIX
+ schedulerInstanceName; // 不⽀持事务
//String dsName = LocalDataSourceJobStore.TX_DATA_SOURCE_PREFIX + schedulerInstanceName; // ⽀持事务
和java有关的小说
try {
Connection connection = Instance().getConnection(dsName);
PreparedStatement ps = connection.prepareStatement(insertSql);
ps.setString(1, "张三");
ps.setInt(2, 25);
ps.close();
connection.close(); // 将连接归还给连接池
System.out.println("插⼊成功");
} catch (SQLException e) {
e.printStackTrace();
}
}
public void setSchedulerInstanceName(String schedulerInstanceName) {
this.schedulerInstanceName = schedulerInstanceName;
}
}复制代码
明确我们的⽬的,到合适的切⼊点,进⼊断点调试追踪也就容易了。
任我说的天花乱坠,你仍⽆动于衷,那也只是我⼀厢情愿,只有局中⼈才能体会到其中的奥妙!
总结与感悟
从上⾄下全部通读的⽅式,个⼈不太推荐,这是建⽴在很熟悉的基础上的,当我们对某个框架已经⽐较熟悉了,再从上⾄下进⾏通读,彻底了解,这是我认为正确的⽅式;但是从不熟悉到熟悉这个过程,个⼈不推荐全部通读,⽽是推荐上⾯我推荐的⽅式 - 断点局部追踪。
很多时候,我们的博⽂都只是授之以鱼,⽽我们也只是从中得到鱼;⽽这篇的⽬的则是授之以渔,我希望⼤家从中学到捕鱼的⽅法,⽽不是⼀味的等待别⼈的鱼;希望⼤家能够⾃给⾃⾜,也能把鱼和渔都授予其他⼈。返回搜狐,查看更多
android 游戏开发和应用开发责任编辑:
python基础代码实例
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论