
Go 调用 C 写的动态库完整例子(Linux版) 弄完了 Go 语言如何调用动态库,又开始琢磨起 Python 怎么调用动态库,首先仍然是以前一篇中的 C 实现为例,C 函数为原型为
char * Add(char* src, int n), 由于用符号直接定位函数,所以无需 C 的头文件。本文仍然是以 Linux 平台为例,GCC 编译为动态库 so 文件。并实验了两个例子,一个为基本的类型,char* 和 int, 再一个就是在 C 中使用到了结构体指针和无类型指针(void*) 时,如何在 Python 进行调用。测试环境为:
- Linux Ubuntu 20.04
- gcc: gcc (Ubuntu 9.3.0-17ubuntu1~20.04) 9.3.0
- Python: 3.8.10
PM 2 是什么,官网上 https://pm2.keymetrics.io/ 是说 PM2(Process Manager 2) 是 Node JS 的高级的,产品级的进程管理工具。为什么叫做 PM2,那有没有 PM 或 PM 1 呢,没有,它起步就是 2. PM2 相对于 Node JS 有点类似于 Gunicorn 和 Python Web 应用的关系。 但 PM2 比 Gunicorn 功能更强大, 其实 PM2 还能用来管理其他任何进程,不局限于 Node JS 的。
最好的入门学习教程是官方的 Quick Start。从中我们可以大概看到 PM2 的主要应用:- 对进程的管理与监控
- 多种进程重启策略
- 日志的管理
- 使用配置文件
- 集群模式
- 用作静态 Web 服务
- 进行应用部署
- 使用环境变量
PM2 是 Node JS 应用,所以它是跨平台的。 Read More
本文为 Java 注册 classpath 协议读取文件的目的就是要让下面的代码能工作起来1String text = IOUtils.toString(new URL("classpath:/db.properties"), "UTF-8"); 2System.out.println(text);
假设在 classpath 下有个文件 db.properties, 比如在 Maven 项目的 src/main/resources 目录中,或是在某个 jar 包的根位置。如果我们直接执行上面的代码将会得到异常Exception in thread "main" java.net.MalformedURLException: unknown protocol: classpath
说是不认识的 classpath 协议。
at java.net.URL.<init>(URL.java:617)
at java.net.URL.<init>(URL.java:507)
前面代码是有实际用途的,比如说我们使用 XML 时就能支持远程协议1Document document = DocumentBuilderFactory.newInstance().newDocumentBuilder() 2 .parse("https://www.w3schools.com/xml/note.xml"); 3System.out.println(document.getDocumentElement().getTagName());
Read More
前面尝试过用 Java 转换 Apache Avro 数据为 Parquet 格式,本文用 Python 来做同样的事情,并且加入 logicalType: date 类型的支持。本测试中的 Avro 数据也是由 Python 代码生成的。
重复一句 Avro 与 Parquet 的最粗略的区别:Avro 广泛的应用于数据的序列化,如 Kafka,它是基于行的格式,可被流式处理,而 Parquet 是列式存储格式的,适合于基于列的查询。
第一步,生成 Avro 数据文件 user.avro, 须先安装 fastavropip install fastavro
生成 user.avro 的代码
Read More
Java 单元测试最趁手的 Mock 组件当属 Mockito,虽然它最初是基于继承来实现 Mock 的,所以对私有方法,私有属性,静态方法, final 类,final 方法,构造函数无能为力。于是有时不得不引入 JMockit 或 PowerMockit 来辅助。不过现在的 Mockito 功力有所增强。
首先是 Mockito 2.1.0 开始可以 Mock final 类和 final 方法,要在 classpath 下创建个文件mockito-extensions/org.mockito.plugins.MockMaker, 内容为mock-maker-inline。 之前写过一篇介绍:Mockto 也能 Mock final 类和 final 方法了,其中也探索了它的实现细节,使用到了 ByteBuddy 修改字节码。
从 Mockito 3.4.0 通过类似的 mockto-extensions 扩展的方式,实现了对静态方法的 Mock。所有使用到的接口是 org.mockito.MockedStatic, 它当前在 Mockito 3.7.7 中还是一个试验性方法 @Incubating,能拿来用就行。 Read More
在 Python 使用用json.dumps(data)时突然发现特别慢,data本身不大,但是一个包含很多元素的列表,所以促使本人寻找一个替代的 JSON 处理库。大概对比了一个 ujson(UtltraJSON), python-rapidjson(RapidJSON) 和 Python 自带的 json 库。还有一个 simplejson 是为兼容 Python 2.6 以前用的(json 是 Python 2.6 新加入的 API),性能有些差。
基本上姜还是老的辣,想要收获更好的性能,还得仰赖传统的 C/C++ 语言,ujson 是用纯 C 写的,RapidJSON 是 C++ 写的,后者还是十美分的开源产品。json, ujson, rapidjson 三者loads()方法的性能差别不太明显,但dumps()大对象时 Python 自带的 json 库就要考验用户的耐心了。
注:最开始本来认定了 ujson 为最佳选择, 所以先从 usjon 和 rapidjson 切入的,后来写作本文的过程中,从 usjon 的自我介绍中发现了 Rust 写的 orjson 很显眼,才加入了 orjson 的测试,看来 orjson 更值得拥有。
Read More- 一年半以前写了关于 Python 包管理及虚拟环境系列
其中历数了virtualenv,python3 -m venv,pipenv, 并提到了 pyenv 和 conda。但对 pyenv 和 conda 未作介绍,其中 conda 似乎不该错过。 Anaconda 着力于为数据分析提供支撑,并与 Jupyter Notebook 有更完美的结合,而且 PyCharm 中对它也有很好支持。因此本文来了解一下 conda 以及 Anaconda。
首先 Anaconda 是什么,它是一个用于科学计算的,跨平台的包管理与 Python 环境的工具,它方便的解决了多版本 Python 并存,切换及第三方包安装的问题。所以 Anaconda 不只是像venv,pipenv那样的创建管理 Python 虚拟环境,还承担了系统软件的安装管理,像 Mac 下的brew那样的功能。一般来说我们没有必要安装 Anaconda, 只需要安装 Miniconda 获得conda这个命令行工具即可。 Read More
在去年的一篇 Python 多线程编程 中学习了 Python 中如何使用多线程来调度任务,工作中也不时从自己的博客中找来参考。在运用当中不时的碰到内存消耗殆尽情况,直接把命令行窗口打死,不得不强行关窗口或杀进程。之前一直未意识到问题所在,只知任务太多就必死无疑,现在要用 Python 来处理大量任务了,必须着手来解决一下它。其实原因很简单,和 Java 的 ThreadPoolExecutor 一样(看它们用的类名都是一样的)。Java 的 ThreadPoolExecutor 内部使用了一个Integer.MAX_VALUE的 LinkedBlockingQueue 来存放提交的待处理的任务,所以基本上就是一个无底洞,自然解决办法也是类似的,需要一个 Bounded Queue 来存放任务列表。
在解决该问题之前自己也不妨来温习一下 Python 中使用线程池的基本模式,下面的模板代码曾经是我的最爱:1import time 2from concurrent.futures import ThreadPoolExecutor 3 4def perform(x): 5 time.sleep(2) 6 print(f'process {x}') 7 return x + 1 8 9with ThreadPoolExecutor(5) as executor: 10 for i in range(3): 11 executor.submit(perform, i) 12 13 executor.shutdown(wait=True) 14 15print('done')
在上面的with上下文中会进行以下几步 Read More
想要配置好 Apache + mod_wsgi + Flask 问题真是太多了,随便换一个 Linux 发行版,或者不同的 Python 版本就得让 Google 排很多温室气体。Nginx 可以使用 uWSGI 和 Flask 串联起来,配置起来第一直觉好像也不容易,所以打算换一种方式,直接用一个 Python 的 WSGI HTTP Server, 必要的话再往前面加一个反向代理的 Nginx。这里就来试下 Nginx + Gunicorn + Flask 的完整配置。
在 Flask 的官方网站 Deployment Options 提到了各种生产环境下的部署办法,与 Gunicorn 类似的工具还有 uWSGI, Gevent, Twited Web, Hypercorn, Uvicorn, Daphne(来自于 django) Read More
在 Python 常用日期处理 -- 内置模块 datetime 探讨了 Python 如何使用 datetime, 如果是一个跨时区的应用(Web 应用都是),就不能只存储一个时间而不带时区,如此,全球用户将会看到一个相同的时间字符串,白天黑夜就错乱了。比说用户信息的更新时间存储为 2020-07-07 13:46:08, 上海的用户和芝加哥的用户看到的是同一个时间字符串,实质上却相差好多个小时。
我们可以这么做,在服务端只存储一个 Timestamp 长整型值或 UTC 时间,Timestamp 是无关乎时区的,它总是相对于一个 UTC 时间的偏移值; 然后由客户端根据本地时区来显示当地时间。不过在服务端存储为 Timestamp 或 UTC 可读性就不强了,打开文件看到 Timestamp 整形值,大脑是无法直接转换为日期,UTC 时间略好一些。
另一种做法可在服务端存储为开发者便于理解的带时区的时间,如 2020-07-07T13:46:08.342+08:00, 客户获得该时间,因为带有时区信息也就能转换为客户端本地时间。
客户端请求时还可以把本地的时区信息传送给服务端,由服务端转换为相应的本地时间发送给客户端,但 HTTP 头信息默认不带时区信息,客户端必须主动发送它。 Read More