Community Day 深圳站社区嘉年华,诚邀对技术抱有高度热忱的你!报名戳 了解详情
写点什么

全方位对比:Python、Julia、MATLAB、IDL 和 Java (2019 版)

  • 2019-10-11
  • 本文字数:7789 字

    阅读完需:约 26 分钟

全方位对比:Python、Julia、MATLAB、IDL 和 Java (2019 版)

引言

我们使用简单的测试用例来对各种高级编程语言进行比较。我们是从新手程序员的角度来实现测试用例,假设这个新手程序员不熟悉语言中可用的优化技术。我们的目的是突出每一种语言的优缺点,而不是宣称一种语言比其他语言更优越。计时结果以秒为单位,精确到四位数,任何小于 0.0001 的值将被视为 0 秒。


本文提供的测试是在 Intel Xeon Haswell 处理器节点上进行的,每个节点有 28 核(每核 2.6GHz)和 128GB 的可用内存。Python、Java 和 Scala 测试运行在一台 Mac 计算上,该计算机配备了 Intel i7-7700HQ(4 核,每核 2.8GHz),16GB 可用内存,以便与 Xeon 节点进行比较。我们考虑这些语言使用如下版本:


语言 版本号 是否开源
Python3.7
Julia0.6.2
Java10.0.2
Scala2.13.0
IDL8.5
R3.6.1
MatlabR2017b
GNU Compilers9.1
Intel Compilers18.0.5.274


GNU 和 Intel 编译器用于 C 和 Fortran。包含这些语言是为了作为基准,这就是为什么它们的测试也带有优化版本(-O3、-Ofast)的原因。


测试用例分为四类:


  • 循环和向量化

  • 字符串操作

  • 数值计算

  • 输入 / 输出


每个测试都足够“简单”,可以用任何一种语言快速编写,旨在解决以下问题:


  • 非连续内存位置的访问

  • 递归函数的使用

  • 循环或向量化的利用

  • 海量文件的打开

  • 任意长度的字符串的操作

  • 矩阵的乘积

  • 迭代求解的使用

  • 等等


源文件包含在以下目录中:


C\  Fortran\  IDL\  Java\  Julia\  Matlab\  Python\  R\  Scala\
复制代码


还有一个目录:


Data\
复制代码


它包含一个 Python 脚本,该脚本在读取大量文件时生成测试用例所需的 NetCDF4 文件。它还有用于“计算文件中唯一单词”测试用例的示例文本文件。


备注:在下面显示的结果中,我们使用了较旧版本的 Julia,因为在 Xeon Haswell 节点上安装最新版本的 Julia(1.1.1) 时我们遇到了困难。此外,Python 实验并不包括 Numba,因为我们有权访问的 Haswell 节点使用的是较旧版本的操作系统,妨碍了 Numba 的正确安装。

循环与向量化

  • 复制多维数组


给定任意 n x n x 3 矩阵 A,我们将执行以下操作:


A(i, j, 1) = A(i, j, 2)A(i, j, 3) = A(i, j, 1)A(i, j, 2) = A(i, j, 3)   
复制代码


循环和向量化的使用。该测试用例旨在测量语言访问连续内存位置的速度,并查看每种语言如何处理循环和向量化。


表 CPA-1.0:在 Xeon 节点上使用循环复制矩阵元素所用的时间。


语言 选项 n=5000n=7000n=9000
Python16.216431.786752.5485
Julia0.07220.14450.2359
Java0.18100.32300.5390
Scala0.27500.48100.7320
IDL6.466111.906819.4499
R22.951044.976074.3480
Matlab0.28490.52030.8461
Fortrangfortran0.17600.34800.5720
gfortran -O30.06800.17200.2240
ifort0.06800.13600.2240
ifort -O30.06800.13600.2800
Cgcc0.17000.34000.5600
gcc -Ofast0.09000.18000.3100
icc0.10000.18000.3000
icc -Ofast0.10000.18000.3000


表 CPA-1.1:在 i7 Mac 上使用循环复制矩阵元素所用的时间。


语言n=5000n=7000n=9000
Python18.667536.404660.2338
Python (Numba)0.33980.30600.3693
Java0.12600.24200.4190
Scala0.20400.34500.5150


表 CPA-2.0:在 Xeon 节点上使用向量化复制矩阵元素所用的时间。


语言选项n=5000n=7000n=9000
Python0.49560.97391.6078
Julia0.31730.55750.9191
IDL0.39000.76411.2643
R3.52906.935011.4400
Matlab0.28620.55910.9188
Fortrangfortran0.09600.25200.3240
gfortran -O30.09600.24400.3120
ifort0.14000.22800.3840
ifort -O30.12000.23600.4560


表 CPA-2.1:在 i7 Mac 上使用向量化复制矩阵元素所用的时间。


语言n=5000n=7000n=9000
Python0.56021.08321.8077
Python (Numba)0.85071.36502.0739

字符串操作

  • 外观数列


外观数列(Look and Say Sequence)读取一个整数。在后续的每个项中,前一个项中每个整数出现的次数连接到该整数的前面。如,一个项 1223,接下来将会是 112213 ,或“一个 1,两个 2,一个 3”。这里,我们从数字开始: 1223334444 ,并确定 n 项(随 n 不同)的外观数列,这个测试用例突出显示了语言如何操作操纵任意长度的字符串。


表 LKS-1.0:在 Xeon 节点上查找 n 项的外观数列所用的时间。


语言选项n=40n=45n=48
Python2.089044.4155251.1905
Java0.06940.08990.1211
Scala0.04700.12700.2170
IDL20.2926304.50491612.4277
Matlab423.22416292.7255exceeded time limit
Fortrangfortran0.00800.01200.0120
gfortran -O30.00800.01200.0120
ifort0.00400.01600.0120
ifort -O30.00800.00400.0080
Cgcc0.06000.19000.4300
gcc -Ofast0.04000.18000.4000
icc0.06000.19000.4100
icc -Ofast0.05000.19000.4100


表 LKS-1.1:在 i7 Mac 上查找 n 项的外观数列所用的时间。


语言n=40n=45n=48
Python1.733122.3870126.0252
Java0.06650.09120.1543
Scala0.04900.09700.2040


  • 文件中的唯一单词


我们打开一个任意文件,并计算其中唯一单词的数量,假设单词如下:


ab   Ab   aB   a&*(-b:   17;A#~!b
复制代码


数量是相同的(在这样的情况下,大小写、特殊字符和数字将被忽略)。在我们的测试中,使用了四个文件:


world192.txt、plrabn12.txt、bible.txt、book1.txt
复制代码


这些文件取自 Canterbury 语料库


表 UQW-1.0:在 Xeon 节点上计算文件中的唯一单词所用的时间。


语言world192.txt (19626 个单词)plrabn12.txt (9408 个单词)bible.txt (12605 个单词)book1.txt (12427 个单词)
Python (dictionary method)0.50020.10900.88690.1850
Python (set method)0.38140.08730.75480.1458
Julia0.21900.03540.32390.0615
Java0.56240.22991.01350.2901
Scala0.46000.21500.69300.2190
R104.58208.644033.821017.6720
Matlab3.02700.96576.03481.0390


表 UQW-1.1:在 i7 Mac 上计算文件中唯一单词所用的时间。


语言world192.txt (19626 个单词)plrabn12.txt (9408 个单词)bible.txt (12605 个单词)book1.txt (12427 个单词)
Python (dictionary method)0.35410.08660.73460.1448
Python (set method)0.36850.08200.71970.1417
Java0.51290.25300.91830.3220
Scala0.58100.15400.66500.2330

数值计算

  • 斐波那契数列


斐波那契数列是一个数字序列,其中每个连续的数字是它前面两个数字的和:



它的第一项是:



斐波那契数列在经济学、计算机科学、生物学、组合学等领域都有广泛的应用。我们在计算第 n 个斐波那契数列时测量所用的时间。迭代计算和递归计算都需要计算时间。


表 FBC-1.0:在 Xeon 节点上迭代查找斐波那契数列所用的时间。


语言选项n=25n=35n=45
Python000
Julia000
Java000
Scala000
IDL000
R0.03300.03200.0320
Matlab0.00260.00340.0038
Fortrangfortran000
gfortran -O3000
ifort000
ifort -O3000
Cgcc000
gcc -Ofast000
icc000
icc -Ofast000


表 FBC-1.1:在 i7 Mac 上迭代查找斐波那契数列所用的时间。


语言n=25n=35n=45
Python000
Python (Numba)0.11000.10950.1099
Java000
Scala000


表 FBC-2.0:在 Xeon 节点上递归查找斐波那契数列所用的时间。


语言选项n=25n=35n=45
Python0.05937.0291847.9716
Julia0.00030.03083.787
Java0.00110.04104.8192
Scala0.00100.05605.1400
IDL0.02382.5692304.2198
R0.00900.01000.0100
Matlab0.01421.2631149.9634
Fortrangfortran00.084010.4327
gfortran -O3000
ifort000
ifort -O3000
Cgcc00.04005.0600
gcc -Ofast00.02002.2000
icc00.03003.1400
icc -Ofast00.02003.2800


表 FBC-2.1:在 i7 Mac 上递归查找斐波那契数列所用的时间。


语言n=25n=35n=45
Python0.05196.4022800.0381
Python (Numba)0.417243.76045951.6544
Java0.00300.04425.0130
Scala0.00100.04705.7720


  • 矩阵乘法


将两个随机生成的 n x n 矩阵 AB 相乘。测量执行乘法的时间。这个问题说明了利用每种语言中可用的内置库的重要性。


表 MXM-1.0:在 Xeon 节点上进行矩阵相乘所用的时间。


语言选项n=1500n=1750n=2000
Pythonintrinsic0.15600.24300.3457
Juliaintrinsic0.14970.23980.3507
Javaloop13.861017.860032.3370
Scalaloop9.838019.145032.1310
Rintrinsic0.16000.24600.3620
Matlabintrinsic1.36721.39510.4917
IDLintrinsic0.18940.23090.3258
Fortrangfortran (loop)17.437131.466062.1079
gfortran -O3 (loop)3.32825.300312.1648
gfortran (matmul)0.38400.61600.9241
gfortran -O3 (matmul)0.38800.61600.9161
ifort (loop)1.14011.81612.9282
ifort -O3 (loop)1.14811.80812.9802
ifort (matmul)1.14411.81212.9242
ifort -O3 (matmul)0.51600.82811.2441
ifort (DGEMM)0.21600.23600.3320
Cgcc (loop)13.200020.980031.4400
gcc -Ofast (loop)1.45002.36004.0400
icc (loop)1.23002.15004.0500
icc -Ofast (loop)1.15001.75002.5900


表 MXM-1.1:在 i7 Mac 上进行矩阵相乘所用的时间。


语言选项n=1500n=1750n=2000
Pythonintrinsic0.09060.11040.1611
Numba (loop)9.259520.201235.3174
Javaloop32.508047.768082.2810
Scalaloop23.054038.911060.3180


  • 置信传播算法


置信传播是一种用于推理的算法,通常用于人工智能、语音识别、计算机视觉、图像处理、医学诊断、奇偶校验码等领域。我们用 5000x5000 元素矩阵来测量算法进行 n 次迭代所用的时间。在 Justin Domke 的博客(Domke 2012)中展示了 MATLAB、C 和 Julia 的代码,该博客指出,这个算法是“矩阵乘法的重复序列,然后进行归一化”。


表 BFP-1.0:在 Xeon 节点上执行置信传播算法所用的时间。


语言选项n=250n=500n=1000
Python3.70767.082413.8950
Julia4.02807.822015.1210
Java63.9240123.3840246.5820
Scala53.5170106.4950212.3550
IDL16.960933.208665.7071
R23.415045.416089.7680
Matlab1.97603.80877.4036
Fortrangfortran21.001341.010687.6815
gfortran -O34.49238.256517.5731
ifort4.73639.108617.8651
ifort -O34.73639.108621.1973
Cgcc2.64005.290010.5800
gcc -Ofast2.42004.85009.7100
icc2.16004.32008.6500
icc -Ofast2.18004.34008.7100


表 BFP-1.1:在 i7 Mac 上执行置信传播算法所用的时间。


语言n=250n=500n=1000
Python2.41214.54228.7730
Java55.3400107.7890214.7900
Scala47.956095.3040189.8340


  • 梅特罗波利斯 - 黑斯廷斯(Metropolis-Hastings)算法


梅特罗波利斯 - 黑斯廷斯算法是一种用于从概率分布中提取随机样本的算法。该实现使用二维分布(Domke 2012),并测量迭代 n 次所用的时间。


表 MTH-1.0:在 Xeon 节点上执行梅特罗波利斯 - 黑斯廷斯算法所用的时间。


语言选项n=5000n=10000n=15000
Python0.04040.08050.1195
Julia0.00020.00040.0006
Java0.00400.00500.0060
Scala0.00800.00900.0100
IDL0.01340.01050.0157
R0.07600.15000.2230
Matlab0.01830.02110.0263
Fortrangfortran000
gfortran -O3000
ifort0.004000
ifort -O30.00400.00400
Cgcc000
gcc -Ofast000
icc000
icc -Ofast000


表 MTH-1.1:在 i7 Mac 上执行梅特罗波利斯 - 黑斯廷斯算法所用的时间。


语言n=5000n=10000n=15000
Python0.03460.06380.0989
Java0.00600.00400.0060
Scala0.00900.01000.0130


  • 快速傅里叶变换


我们创建一个 n x n 矩阵 M ,其中包含随机复值。我们计算了 M 的快速傅里叶变换和结果的绝对值。快速傅里叶变换算法广泛用于各种科学和工程领域的信号处理和图像处理。


表 FFT-1.0:在 Xeon 节点上计算快速傅里叶变换所用的时间。


语言选项n=10000n=15000n=20000
Pythonintrinsic8.079719.635734.7400
Juliaintrinsic3.97911.49020.751
IDLintrinsic16.669938.985770.8142
Rintrinsic58.2550150.1260261.5460
Matlabintrinsic2.62436.001010.66232


表 FFT-1.1:在 i7 Mac 上计算快速傅里叶变换所用的时间。


语言选项n=10000n=15000n=20000
Pythonintrinsic7.953821.535555.9375


  • 迭代求解器


我们使用雅克比法迭代求解器(Jacobi iterative solver)数值逼近二维拉布拉斯方程(Laplace equation)的解,该解用四阶紧致格式离散(Gupta,1984)。随着网络点数量的变化,我们记录所用的时间。


表 ITS-1.0:在 Xeon 节点上迭代计算近似解所用的时间。


语言选项n=100n=150n=200
Python158.2056786.34252437.8560
Julia1.03085.187016.1651
Java0.41301.89505.2220
Scala0.5402.10305.7380
IDL73.2353364.13291127.1094
R157.1490774.70802414.1030
Matlab2.81635.05438.6276
Fortrangfortran0.82403.732010.7290
gfortran -O30.66803.07208.8930
ifort0.54002.47207.1560
ifort -O30.54002.46807.1560
Cgcc0.50002.42007.7200
gcc -Ofast0.22001.05003.1900
icc0.46002.23006.7800
icc -Ofast0.33001.60004.8700


表 ITS-1.2:在 i7 Mac 上迭代计算近似解所用的时间。


语言n=100n=150n=200
Python174.7663865.12032666.3496
Python (Numba)1.32265.032415.1793
Java0.46001.76904.7530
Scala0.59702.09505.2830


表 ITS-2.0:在 Xeon 节点上使用向量化计算近似解所用的时间。


语言选项n=100n=150n=200
Python2.627214.650540.2124
Julia2.458313.191841.0302
IDL1.711928.684128.0683
R25.2150121.9870340.4990
Matlab3.32917.648615.9766
Fortrangfortran0.86804.204011.5410
gfortran -O30.36001.80405.0880
ifort0.28001.53604.4560
ifort -O30.28001.56004.4160


表 ITS-2.1:在 i7 Mac 上使用向量化计算近似解所用的时间。


语言n=100n=150n=200
Python1.70517.457222.0945
Python (Numba)2.44518.509421.7833


  • 矩阵的平方根


给定 n x n 矩阵 A,我们寻找这样的矩阵 B,使得:


B * B = A


B 就是平方根。在我们的计算中,我们考虑对角线上为 6,别处为 1 的矩阵 A。


表 SQM-1.0:在 Xeon 节点上计算矩阵的平方根所用的时间。


语言n=1000n=2000n=4000
Python1.01015.237644.4574
Julia0.42072.508019.0140
R0.56503.066019.2660
Matlab0.35711.65522.6250


表 SQM-1.1:在 i7 Mac 上计算矩阵的平方根所用的时间。


语言n=1000n=2000n=4000
Python0.56533.396325.9180


  • 高斯求积


高斯求积(Gauss-Legendre Quadrature)是逼近定积分的一种数值方法。它使用被积函数的 n 个值的加权和。如果被积函数是 0 到 2 n - 1 次多项式,则结果是精确的。这里我们考虑区间 [-3, 3] 上的指数函数,并记录当 n 变化时执行积分所用的时间。


表 GLQ-1.0:在 Xeon 节点上计算积分近似值所用的时间。


语言选项n=50n=75n=100
Python0.00790.00950.0098
Julia0.00020.00040.0007
IDL0.00430.00090.0014
R0.02600.02400.0250
Matlab0.74760.07310.4982
Fortrangfortran00.00400.0080
gfortran -O300.01200.0120
ifort0.00800.00800.0080
ifort -O30.00800.00400.0080


表 GLQ-1.1:在 i7 Mac 上计算积分近似值所用的时间。


语言n=50n=75n=100
Python0.01400.00350.0077


  • 三角函数


我们在 n 元素值列表上迭代计算三角函数,然后在同一列表上计算反三角函数。当 n 发生变化时,测量完整全部操作所用的时间。


表 TRG-1.0:在 Xeon 节点上计算三角函数所用的时间。


语言选项n=80000n=90000n=100000
Python14.689116.508423.6273
Julia55.392062.949069.2560
IDL37.441341.969535.2387
R91.5250102.8720113.8600
Matlab5.27945.86496.3699
Scala357.3730401.8960446.7080
Java689.6560774.9110865.057
Fortrangfortran53.483360.031766.6921
gfortran -O349.927156.023562.1678
ifort18.641120.957323.2654
ifort -O318.645120.957323.2694
Cgcc107.4400120.7300134.0900
gcc -Ofast93.0400104.5700116.0600
icc76.260085.790095.3100
icc -Ofast48.840054.960061.0600


表 TRG-1.1:在 i7 Mac 上计算三角函数所用的时间。


语言n=80000n=90000n=100000
Python3.53996.19846.9207


  • Munchausen 数


Munchausen 数 是一个自然数,等于其自身幂次的位数之和。在以 10 为基数的情况下,有 4 个这样的数字:0、1、3435 和 438579088。我们来确定找到这些数字需要多久。


表 MCH-1.0:在 Xeon 节点上查找 Munchausen 数所用的时间。


语言选项所用时间
Python1130.6220
Julia102.7760
Java4.9008
Scala72.9170
Rexceeded time limit
IDLexceeded time limit
Matlab373.9109
Fortrangfortran39.7545
gfortran -O321.3933
ifort29.6458
ifort -O329.52184
Cgcc157.3500
gcc -Ofast126.7900
icc228.2300
icc -Ofast228.1900


表 MCH-1.1:在 i7 Mac 上查找 Munchausen 数所用的时间。


语言所用时间
Python1013.5649
Java4.7434
Scala64.1800

输入 / 输出

  • 读取大量文件


我们有一套涵盖 20 年的每日 NetCDF 文件(7305)。给定年份的文件位于一个标记为 YYYY 的子目录中(例如,Y1990、Y1991、Y1992 等)。我们希望编写一个脚本,打开每个文件,读取一个三维变量(经度 / 维度 / 级别)并对其进行操作。脚本的伪代码如下:


    Loop over the years        Obtain the list of NetCDF files        Loop over the files            Read the variable (longitude/latitude/level)            Compute the zonal mean average (new array of latitude/level)            Extract the column array at latitude 86 degree South            Append the column array to a "master" array (or matrix)
复制代码


目标是能够生成三维数组(年份 / 级别 / 值)并执行等高线图。这是我们支持的典型用户面临的问题类型:需要对数千个文件进行操作以提取所需信息的集合。拥有能够从文件中快速读取数据(如 NetCDF、HDF4、HDF5、grib 等格式)的工具对我们的工作至关重要。


表 RCF-1.0:在 Xeon 节点上处理 NetCDF 文件所用的时间。


语言所用时间
Python660.8084
Julia787.4500
IDL711.2615
R1220.222
Matlab848.5086


表 RCF-1.1:在 i7 Mac 上处理 NetCDF 文件所用的时间。


语言所用时间
Python89.1922


表 RCF-2.0:在 Xeon 节点上利用多核处理器使用 Python 处理 NetCDF 文件所用的时间。


所用时间
1570.9791
2317.6108
4225.4647
8147.4527
1684.0102
2459.7646
2851.2191


表 RCF-2.1:在 i7 Mac 上利用多核处理器使用 Python 处理 NetCDF 文件所用的时间。


所用时间
184.1032
263.5322
456.6156


图表总结


在下面的图中,我们通过使用 GCC 获得的计时数字(仅在最后一列,即最大问题的大小)作为参考,总结上述计时结果。




研究结果


概述:


  • 没有任何一种语言在所有测试中都优于其他语言。

  • 通过仅在必要时创建变量以及“清空”不再使用的变量来减少内存占用非常重要。

  • 对于相同的任务,使用内置函数会比内联代码带来更高的性能。

  • Julia 和 R 提供了简单的基准测试工具。我们编写了一个简单的 Python 工具,允许我们随心所欲地多次运行 Python 测试用例。


循环和向量化:


  • 与使用循环相比,Python(和 NumPy)、IDL 和 R 在向量化时运行速度更快。

  • 在使用 Numba 时,只要使用 NumPy 数组,Python 就可以更快地处理循环。

  • 对于 Julia,循环比向量化代码运行得更快。

  • 在不涉及计算的情况下,使用循环与向量化相比,MATLAB 在性能上似乎没有显著变化。当进行计算时,向量化 MATLAB 代码要比迭代代码更快。


字符串操作:


  • 与其他语言相比,Java 和 Scala 在操作大型字符串时,似乎具有显著的性能。


数值计算:


  • 与其他语言相比,R 在使用递归时似乎具有显著的性能。

  • 语言在数值计算中相对于其他语言的性能表现取决于具体的任务。

  • MATLAB 的内置快速傅里叶变换函数似乎运行速度最快。


输入 / 输出:


  • 虽然有些语言运行测试的速度比其他语言快,但在本地 Mac 上而不是处理器节点上运行测试的话,可以获得最大的性能提升。因为处理器节点使用机械硬盘,而 Mac 用的是固态硬盘。这表明硬件对 I/O 性能的影响比所使用的语言更大。

参考资料

  1. Julia, Matlab and C,Justin Domke 著,2012 年 9 月 17 日

  2. 四阶泊松求解器,《计算物理学杂志》,55(1):166-172,Murli M. Gupta 著,1984 年


原文链接:


Basic Comparison of Python, Julia, Matlab, IDL and Java (2019 Edition)


2019-10-11 13:526216
用户头像

发布了 501 篇内容, 共 203.1 次阅读, 收获喜欢 1493 次。

关注

评论 1 条评论

发布
用户头像
原文都没写不能转正,翻译后却写了....这是洗稿最高水平了吧
2019-10-21 09:52
回复
没有更多了
发现更多内容

Zookeeper选举机制

tunsuy

zookeeper 开源 源码分析 分布式协同

从“成为作者”到“立即创作”:开启你的“写作极客”生活

岛乾坤

写作

管理信息系统课程基础知识

小匚

idea+spring4+springmvc+mybatis+maven实现简单增删改查CRUD

虚拟世界的懒猫

spring mybatis ssm springmvc java8

容器日志采集利器:Filebeat深度剖析与实践

傅轶

Kubernetes 容器 云原生 日志 Filebeat

万字破解云原生可观测性

谭建

云原生 APM 可观测性 链路追踪 Skywalking

消息队列Kafka - Kafka中的选举

Java收录阁

kafka

当 Redis 发生高延迟时,到底发生了什么

程序员历小冰

redis Linux 延迟

Hadoop集群搭建-01前期准备

虚拟世界的懒猫

hadoop hdfs mapreduce zookeeper centos

Hadoop集群搭建-04安装配置HDFS

虚拟世界的懒猫

hadoop

以物理学思维破解分布式系统的本质

常平

分布式

为什么开源是基础软件的未来

顾钧

开源 基础软件

机器学习中常用的处理手段

子夜2104

学习

centos6搭建NEXUSphp pt私人种子站

虚拟世界的懒猫

centos nexusphp pt bt

Hadoop集群搭建-02安装配置Zookeeper

虚拟世界的懒猫

hadoop zookeeper centos7

Hadoop集群搭建-05安装配置YARN

虚拟世界的懒猫

hadoop

OKR实践中的痛点(3):破3旧,迎3新!

大叔杨

OKR Scrum 敏捷 敏捷开发 绩效

重要:Kafka第3篇之一条消息如何被存储到Broker上

z小赵

kafka

如何成为一个靠谱的人

熊斌

个人成长 团队协作

为什么最该祝自己劳动节快乐

石君

劳动 劳动节 励志

张小龙 的 22 年和微信的 8 年

池建强

微信 张小龙

如何无缝的将Flutter引入现有应用?

稻子

flutter ios android 开源 移动应用

做好仓储控制系统(WCS)的关键

申扬科技

仓储控制系统 WCS

思考如何节省时间,节省出时间进行思考

伯薇

思考 时间管理 思考力 工作效率 提升效率

【终于解决】ubuntu19安装nvidia驱动后屏幕亮度默认最亮不可调节

虚拟世界的懒猫

ubuntu 英伟达

Java并发编程系列——常用并发工具类

孙苏勇

Java Java并发 并发编程 多线程

程序员陪娃漫画系列——喂药

孙苏勇

程序员 生活 陪伴 漫画

1分钟就能学会的时间管理大法

小匚

时间分配 时间管理

Hadoop集群搭建-03编译安装hadoop

虚拟世界的懒猫

hadoop centos7

游戏夜读 | 2020周记(4.10-4.17)

game1night

配置微软Azure大数据HDInsight云集群

虚拟世界的懒猫

microsoft 大数据 微软 azure hdinsght

全方位对比:Python、Julia、MATLAB、IDL 和 Java (2019 版)_语言 & 开发_Alexander Medema_InfoQ精选文章