1.在大学想要学习编程,源码可以通过哪些途径进行学习?
2.深入分析堆外内存 DirectByteBuffer & MappedByteBuffer
3.初试AutoML(TPOT)解决 回归问题
4.2022·合辑Python量化从入门到精通
在大学想要学习编程,源码可以通过哪些途径进行学习?
一、源码先知道编程能帮我们干什么编程,源码其实已经不仅仅是源码“编写程序”这么狭义了,通过写代码让计算机帮我们做事都可以看作“编程”。源码福昕源码这也是源码为什么,在注重高效率的源码今天,社会越来越推崇“少儿编程”与“全民编程”。源码
并且,源码现在的源码语言工具(比如python)已经降低了不少编程工作的复杂度,让我们在不了解编译过程的源码情况下,也能通过几行简洁的源码代码很棒地完成工作。
因此,源码我在这里总结一下,源码编程能帮我们做什么,已经做这个工作需要懂计算机到什么程度:
1. 日常办公、处理表格:
一是excel的功能已经够直观便捷、够强大了;二是0基础入门python,肯定要涉及到学习一些数据结构的相关知识,有这个时间,还不如好好看看excel有哪些强大功能。
2. 科学计算(运筹/机器学习/数值分析):
现在科学计算几乎难以与“编程”二字分家。做科学计算的人都是很聪明、学习能力很强的人,但其编程能力往往参差不齐,我这里划了三个档次:
- 2.1 不需要太多编程能力,重点在于结果而非编程: 很多朋友只是用用仿真软件、用R语言做做统计分析、用matlab做做拟合,他们的工作重点在于输出的结果,而非“编程”这个过程,那很显然,这类同学往往是类似物理、管理、社会学这类学科的从业者,都是很聪明能干的人,我认为在过程中学习,多看看前辈们的工作方式与工具,注重文件管理与编程规范(不要乱起文件/变量名字,android ndk 源码也不要乱放文件…),学学github检索与使用,熟能生巧就好。
- 2.2 需要一定编程功底,如CV/NLP等ML/DL/OR从业者: 计算机视觉、自然语言处理、深度学习、机器学习、运筹学、线性求解器、启发式算法……这类研究是一定要拿计算机做实验的,并且用编程实现算法的入门并不简单。对于这类同学来讲,数学、数据结构是重点中的重点,“会用”python这类语言的同时,最好也掌握一下“面向对象的思想”与“函数式编程”,方便我们阅读框架源码;注重自己的编程习惯,配置一个好点的编辑器,持续学习(比如你了解jupyter notebook的快捷键与自动补全吗),咱也不能一直当个“调包侠”呀。有余力则应该去系统地学学计算机课程。
- 2.3 大神,我们用python调用的很开心的深度学习框架TensorFlow其实核心都是用c/c++写的哦!为什么用c/c++呢?我估计是为了更好的性能、对计算机算力更充分的利用。我们知道,c/c++是有指针的语言,这增加了编程难度,却也让开发者可以更好地对系统的虚拟空间进行管理。很多主流语言,比如java、python为了降低开发者编程难度,便取消了指针机制。这类人计算机功底必须极其扎实。
3. 软件工程师/开发者:
前端、后端、PC端、移动端、商铺交易 源码Web平台、全栈、网络安全、测试、运维、游戏等等,就是我们常说的“程序员”,工种其实太多了!自学编程的孩子如果是想成为这类工程师,那当然需要系统学习软件专业与计算机专业的专业课;但是我们大部分孩子只是想学学计算机,了解一下而已,因此第3条我们不展开讨论。
4. 其他很有趣的事:
日常生活中我们离不开手机、计算机,因此如果能写个“程序”,让计算机“自动”做一些工作,便蛮有趣的。比如,编程爱好者Sarthak agarwal[2]就写了许多python脚本文件,这其中有用自动下载、自动管理文件、自动发邮件的。这里,我不得不点明一个误区:虽然人们常说python很方便、强大,但只会python是远远不够做这些有趣的事的。比如,用python下载听起来很美好,但是不懂url、不懂网页布局,怎么可能做到呢?python说白了,只是一个方便的工具而已嘛。
二、再明确自己要拿编程做什么
编程能做什么,要学到什么程度,其实我在上文说的已经比较明白了。
自学编程大概两个阶段:
打基础,至少学懂一门语言,推荐拿C/C++入门(为了学到一些指针与面向对象的dz 发贴源码知识),拿Python入门也可,但你会发现面向对象在Python教学中可能不被强调,因为Python自带的工具已经很强大;
不推荐拿Java入门,因为Java实在是开发者用的语言,其魅力在于接口、程序设计,想拿Java入门,不如拿C/C++入门;
编程之理,一通百通。第二个阶段,就是多多实践、持续学习,在自己的领域探索下去:
如果你要搞数据科学、打数据比赛,就去多用熟悉python中的pandas、sklearn库等等;
如果想做线性求解,先找几个简单的java+线性求解器例子动手复现下来,读懂每行代码的作用,在过程中积累;
深入分析堆外内存 DirectByteBuffer & MappedByteBuffer
大家好,我是大明哥,一个专注于「死磕 Java」系列创作的硬核程序员。本文内容已收录在我的技术网站:。
ByteBuffer有两种特殊类:DirectByteBuffer和MappedByteBuffer,它们的原理都是基于内存文件映射的。
ByteBuffer分为直接和间接两种。
我们先了解几个基本概念。
操作系统为什么要区分真实内存(物理内存)和虚拟内存呢?这是因为如果我们只使用物理内存会有很多问题。
对于常用的Linux操作系统而言,虚拟内存一般是4G,其中1G为系统内存,3G为应用程序内存。
进程使用的是虚拟内存,但我们数据还是存储在物理内存上,那么虚拟内存是怎样和物理内存对应起来的呢?答案是页表,虚拟内存和物理内存建立对应关系采用的是页表页映射的方式。
页表记录了虚拟内存每个页和物理内存之间的对应关系,具体如下:
它有两个栏位:有效位和路径。
当CPU寻址时,它有三种状态:
CPU访问虚拟内存地址过程如下:
下面是tinyhttpd源码解析Linux进程的虚拟内存结构:
注意其中一块区域“Memory mapped region for shared libraries”,这块区域就是内存映射文件时将某一段虚拟地址和文件对象的某一部分建立映射关系,此时并没有拷贝数据到内存中,而是当进程代码第一次引用这段代码内的虚拟地址时,触发了缺页异常,这时候OS根据映射关系直接将文件的相关部分数据拷贝到进程的用户私有空间中去,当有操作第N页数据的时候重复这样的OS页面调度程序操作。这样就减少了文件拷贝到内核空间,再拷贝到用户空间,效率比标准IO高。
接下来,我们分析MappedByteBuffer和DirectByteBuffer的类图:
MappedByteBuffer是一个抽象类,DirectByteBuffer则是它的子类。
MappedByteBuffer作为抽象类,其实它本身还是非常简单的。定义如下:
在父类Buffer中有一个非常重要的属性address,这个属性表示分配堆外内存的地址,是为了在JNI调用GetDirectBufferAddress时提升它调用的速率。这个属性我们在后面会经常用到,到时候再分析。
MappedByteBuffer作为ByteBuffer的子类,它同时也是一个抽象类,相比ByteBuffer,它新增了三个方法:
与传统IO性能对比:
相比传统IO,MappedByteBuffer只有一个字,快!!!它之所以快,在于它采用了direct buffer(内存映射)的方式来读取文件内容。这种方式是直接调动系统底层的缓存,没有JVM,少了内核空间和用户空间之间的复制操作,所以效率大大提高了。那么它相比传统IO快了多少呢?下面我们来做个小实验。
通过更改size的数字,我们可以生成k,1M,M,M,1G五个文件,我们就这两个文件来对比MappedByteBuffer和传统IO读取文件内容的性能。
大明哥电脑是GB的MacBook Pro,对k,1M,M,M,1G五个文件的测试结果如下:
绿色是传统IO读取文件的,蓝色是使用MappedByteBuffer来读取文件的,从图中我们可以看出,文件越大,两者读取速度差距越大,所以MappedByteBuffer一般适用于大文件的读取。
父类MappedByteBuffer做了基本的介绍,且与传统IO做了一个对比,这里就不对DirectByteBuffer做介绍了,咱们直接撸源码,撸了源码后我相信你对堆外内存会有更加深入的了解。
DirectByteBuffer是包访问级别,其定义如下:
DirectByteBuffer可以通过ByteBuffer.allocateDirect(int capacity)进行构造。
调用DirectByteBuffer构造函数:
这段代码中有三个方法非常重要:
下面就来逐个分析这三段代码。
这段代码有两个作用
maxMemory=VM.maxDirectMemory(),获取JVM允许申请的最大DirectByteBuffer的大小,该参数可通过XX:MaxDirectMemorySize来设置。这里需要注意的是-XX:MaxDirectMemorySize限制的是总cap,而不是真实的内存使用量,因为在页对齐的情况下,真实内存使用量和总cap是不同的。
tryReserveMemory()可以统计DirectByteBuffer占用总内存的大小,如果发现堆外内存无法再次分配DirectByteBuffer则会返回false,这个时候会调用jlra.tryHandlePendingReference()来进行会触发一次非堵塞的Reference#tryHandlePending(false),通过注释我们了解了该方法主要还是协助ReferenceHandler内部线程进行下一次pending的处理,内部主要是希望遇到Cleaner,然后调用Cleaner#clean()进行堆外内存的释放。
如果还不行的话那就只能调用System.gc();了,但是我们需要注意的是,调用System.gc();并不能马上就可以执行full gc,所以就有了下面的代码,下面代码的核心意思是,尝试9次,如果依然没有足够的堆外内存来进行分配的话,则会抛出异常OutOfMemoryError("Direct buffer memory")。每次尝试之前都会Thread.sleep(sleepTime),给系统足够的时间来进行full gc。
总体来说Bits.reserveMemory(size, cap)就是用来统计系统中DirectByteBuffer到底占用了多少,同时通过进行GC操作来保证有足够的内存空间来创建本次的DirectByteBuffer对象。所以对于堆外内存DirectByteBuffer我们依然可以不需要手动去释放内存,直接交给系统就可以了。还有一点需要注意的是,别设置-XX:+DisableExplicitGC,否则System.gc();就无效了。
到了这段代码我们就知道了,我们有足够的空间来创建DirectByteBuffer对象了.unsafe.allocateMemory(size)是一个native方法,它是在堆外内存(C_HEAP)中分配一块内存空间,并返回堆外内存的基地址。
这段代码其实就是创建一个Cleaner对象,该对象用于对DirectByteBuffer占用的堆外内存进行清理,调用create()来创建Cleaner对象,该对象接受两个参数:
调用Cleaner#clean()进行清理,该方法其实就是调用thunk#run(),也就是Deallocator#run():
方法很简单就是调用unsafe.freeMemory()释放指定堆外内存地址的内存空间,然后重新统计系统中DirectByteBuffer的大小情况。
Cleaner是PhantomReference的子类,PhantomReference是虚引用,熟悉JVM的小伙伴应该知道虚引用的作用是跟踪垃圾回收器收集对象的活动,当该对象被收集器回收时收到一个系统通知,所以Cleaner的作用就是能够保证JVM在回收DirectByteBuffer对象时,能够保证相对应的堆外内存也释放。
在创建DirectByteBuffer对象的时候,会new一个Cleaner对象,该对象是PhantomReference的子类,PhantomReference为虚引用,它的作用在于跟踪垃圾回收过程,并不会对对象的垃圾回收过程造成任何的影响。
当DirectByteBuffer对象从pending状态->enqueue状态,它会触发Cleaner#clean()。
在clean()方法中其实就是调用thunk.run(),该方法有DirectByteBuffer的内部类Deallocator来实现:
直接用unsafe.freeMemory()释放堆外内存了,这个address就是分配堆外内存的内存地址。
关于堆外内存DirectByteBuffer就介绍到这里,我相信小伙伴们一定有所收获。下面大明哥介绍堆内内存:HeapByteBuffer。
初试AutoML(TPOT)解决 回归问题
在Data Castle的一项比赛中,我尝试了Auto ML工具TPOT来解决回归问题,挑战是预测小分子在人体内的清除率,数据来自chembl数据库,分为8:2的训练集和测试集,测试集又分为A和B两部分,B榜成绩决定最终排名。
我对Auto ML有了兴趣,特别是TPOT,它能自动对比多个模型,通过迭代优化,生成一个经过调优的模型。TPOT易于集成sklearn,我选择它是因为其兼容性。安装和调试过程略过,通过官方示例就能理解基本流程,比如波士顿房价预测。
实际操作中,我处理的数据是维的特征向量,包含整形、布尔和浮点型特征,分布复杂。为简化问题,我舍弃了大部分布尔特征,最终数据降为维。在Jupyter notebook中,我构建了回归模型,生成的tpot_medical_pipeline_fenlie1.py文件保存了模型。
在test.py中,我用模型预测了测试集,并提交了结果,但未见实时反馈。源代码和数据集已上传,可供感兴趣的人参考。感谢阅读,希望本文对你有所帮助。
·合辑Python量化从入门到精通
引言 公众号“Python金融量化”历经四年,累计万+关注,依然坚持文字输出,这背后离不开广大读者的支持,特别是知识星球圈友的贡献,累计付费人数已达+。公众号以原创内容为动力,今年的一大成就在于基于公众号沉淀和网上资源开发了qstock量化分析包,包括数据获取、可视化、选股和量化回测四大模块。qstock面向读者开源,直接通过“pip install qstock”进行安装,或通过“pip install –upgrade qstock”进行更新,部分策略功能仅对知识星球会员开放。 学习是一个逐步积累的过程,通过梳理过去四年发布的多篇原创文章,形成四大框架:Python入门篇、金融数据篇、量化分析篇和策略回测篇。以下将详细介绍各部分内容。Python入门篇
这一部分主要围绕Python金融量化入门学习路径、量化资源,以及numpy、pandas、matplotlib等量化常用库的入门和应用。推荐使用Anaconda作为编译软件,内置Jupyter notebook和Spyder,其中Jupyter在交互式编程与数据分析上功能强大。公众号文章皆基于Jupyter编写。1.1 Python金融量化入门
1.2 Python量化资源大合集
1.3 NumPy入门与应用
1.4 Pandas数据处理详解
1.5 Matplotlib与Seaborn可视化
1.6 Sklearn机器学习基础
1.7 Pyecharts股票可视化分析
金融数据篇
本部分涉及使用Python获取股票行情、上市公司基本面、宏观经济以及财经新闻等数据,进行可视化分析。使用Postgresql搭建本地量化分析数据库,介绍qstock免费开源库在线获取行情数据、板块资金流数据、宏观基本面和财经新闻数据。2.1 Python获取交易数据
2.2 上市公司数据概览
2.3 Python量化选股初探
2.4 财经十大关键词解析
2.5 Python财经数据可视化
2.6 文本挖掘与财经分析
2.7 Python量化财经新闻分析
2.8 自建量化分析数据库
2.9 Python面向对象编程与股票数据管理
量化分析篇
本部分深入探讨A股市场分析、金融统计、蒙特卡洛模拟、时间序列建模、TA-Lib技术分析、投资组合、多因子模型、基本面量化分析等。内容涵盖数据探索性分析、时间序列专题、技术分析、投资组合分析、多因子模型、债券与期权分析、比特币量化、基本面量化等。3.1 股票分析入门
3.2 A股指数图谱分析
3.3 A股沉浮启示录
3.4 股市趋势与拐点研究
3.5 A股数据挖掘案例
3.6 机器学习分析股票市场结构
3.7 股票涨停板探索性分析
3.8 时间序列日期处理
3.9 时间序列自相关性与平稳性
3. 金融时间序列模型
3. ARCH与GARCH模型应用
3. 机器学习预测效果与非平稳性
3. Markov区制转换模型分析
3. 统计套利量化
3. 股市牛熊分析
3. TA-Lib技术分析
3. TA-Lib技术分析案例
3. 量价关系分析
3. Python量化股票情绪指标
3. 动量指标量化回测
3. Python量化强势股寻找
3. Python量价形态选股
3. 牛股价量分析
3. Heikin Ashi蜡烛图可视化
3. 趋势预测方法
3. 价格噪音量化应用
3. 交易系统与市场分析
3. 多因子量化选股模型
3. 单因子测试框架
3. 量化回测
3. 固定收益与衍生品分析
3. 债券与期权定价分析
3. 比特币交易者分析
3. 股票财务指标打分系统
3. 高管增持股价影响
3. 领涨板块与题材龙头股
策略回测篇
本部分聚焦于量化策略的评价指标、指数定投、机器学习、海龟交易法、均值回归策略等,以及backtrader回测系统的运用和qstock量化回测。4.1 量化投资方法论
4.2 量化策略评价与风险指标
4.3 证券收益分析
4.4 事件驱动量化回测
4.5 Pyfolio量化回测图表
4.6 指数定投策略分析
4.7 如何实现基金定投收益最大化
4.8 使用Logistic回归预测指数涨跌
4.9 RNN深度学习预测股票价格
4. 均值回归策略回测
4. 海龟交易法则应用
4. 月份效应与A股择时策略
4. 北向资金预测大盘涨跌
4. ADX和MACD趋势策略回测
4. 龙虎榜个股交易策略
4. qstock量化回测应用
4. 均线排列价格动量策略
4. 价格动量策略回测
4. 机器学习预测交易信号
4. 神经网络构建量化交易策略
4. backtrader入门与使用
4. backtrader进阶指南
4. backtrader高级应用
4. 回测股票因子数据
4. 股票组合量化回测
4. 海龟交易策略回测
4. 回测技术指标自定义
4. Ichimoku云图策略回测
4. 隔夜持仓与日内交易比较
结语
回顾过去,展望未来,曾国藩的“物来顺应,未来不迎,当时不杂,既过不恋”作为结语,寄予读者以智慧与启示。公众号“Python金融量化”致力于分享Python金融量化应用知识,提供丰富资源、视频资料、PDF文档、文章源码以及与博主交流的平台。加入知识星球,获取更多内容,与作者互动交流。