github: https://github.com/devernay/cminpack

主页: http://devernay.github.io/cminpack/

使用手册: http://devernay.github.io/cminpack/man.html

CMinpack配置

从github中clone下来源文件,进入目录后新建build,使用cmake对上一层目录内容进行编译configure->generate。

命令行不熟练可以使用cmake-gui指令,需要选中examples选项才会对样例进行编译。

完成后进入build/examples目录,执行make命令,可以看到已经生成可执行文件,运行其中任意程序进行测试。

再进入到build/cmake目录,执行make命令和make install命令,将cminpack.pc安装到指定目录(我的电脑上安装到了/usr/local/lib64/pkgconfig),最后将这个目录通过/etc/profile添加到pkg的路径当中(别忘了source运行一下)。

在命令行中输入pkg-config opencv –libs –cflags ,如果能够显示路径则成功。

[NOTE] 我对pkg-config的使用并不是很了解,是模仿着opencv进行配置的。

CMake相关详解

[NOTE] 因此自己对CMake使用还很不熟练,因此找机会对CMakeList.txt进行学习。

${CMINPACK_SOURCE_DIR}/CMakeList.txt

# 因为Markdown没有支持CMakeList.txt的高亮,因此用Makefile的高亮将就一下。

# The name of our project is "CMINPACK". CMakeLists files in this project can
# refer to the root source directory of the project as ${CMINPACK_SOURCE_DIR} and
# to the root binary directory of the project as ${CMINPACK_BINARY_DIR}.
# CMINPACK_SOURCE_DIR: CMinpack源代码的根目录
# CMINPACK_BINARY_DIR: CMinpack二进制文件的根目录 # 要求的最小CMake版本号
cmake_minimum_required (VERSION 2.6) # 项目名称:CMINPACK
project (CMINPACK) # PROJECT_NAME: CMINPACK
# PROJECT_NAME_LOWER: cminpack
string(TOLOWER ${PROJECT_NAME} PROJECT_NAME_LOWER) # include其他CMake命令
# 在cminpack_utils.cmake这个文件中定义了GET_OS_INFO和DISSECT_VERSION两个宏指令,后面进行详细介绍。
include(${PROJECT_SOURCE_DIR}/cmake/cminpack_utils.cmake)
# Set version and OS-specific settings
# CACHE: 缓存到本地文件
set(CMINPACK_VERSION 1.3.6 CACHE STRING "CMinpack version")
set(CMINPACK_SOVERSION 1 CACHE STRING "CMinpack API version")
# 在cminpack_utils.cmake中定义的两个宏
DISSECT_VERSION()
GET_OS_INFO() # Add an "uninstall" target
# CONFIGURE_FILE: 让普通文件也能使用CMake中的变量
# 输入文件: uninstall_target.cmake.in
# 输出文件: uninstall_target.cmake
# IMMEDIATE: 暂时没找到意思
# @ONLY: 限制只替换被@VAR@引用的变量(${VAR}格式的变量不会被替换)
CONFIGURE_FILE ("${PROJECT_SOURCE_DIR}/cmake/uninstall_target.cmake.in" "${PROJECT_BINARY_DIR}/uninstall_target.cmake" IMMEDIATE @ONLY) # ADD_CUSTOM_TARGET: 增加一个没有输出的目标,使得它总是被构建
# CMAKE_COMMAND: 指向CMake可执行文件的完整路径
ADD_CUSTOM_TARGET (uninstall "${CMAKE_COMMAND}" -P "${PROJECT_BINARY_DIR}/uninstall_target.cmake") # 需要注意,ctest期望在build目录下找到测试文件。
enable_testing() if (OS_LINUX OR ${CMAKE_SYSTEM_NAME} STREQUAL "FreeBSD")
option (USE_FPIC "Use the -fPIC compiler flag." ON)
else (OS_LINUX)
option (USE_FPIC "Use the -fPIC compiler flag." OFF)
endif (OS_LINUX) # 生成SHARED库的选项
option (BUILD_SHARED_LIBS "Build shared libraries instead of static." OFF)
if (BUILD_SHARED_LIBS)
message (STATUS "Building shared libraries.")
else ()
message (STATUS "Building static libraries.")
set(CMAKE_RELEASE_POSTFIX _s)
set(CMAKE_RELWITHDEBINFO_POSTFIX _s)
set(CMAKE_DEBUG_POSTFIX _s)
set(CMAKE_MINSIZEREL_POSTFIX _s)
if(WIN32)
add_definitions(-DCMINPACK_NO_DLL)
endif(WIN32)
endif () option(USE_BLAS "Compile cminpack using a blas library if possible" ON) #set(CMAKE_INSTALL_PREFIX ${PROJECT_SOURCE_DIR}/../build) # 添加头文件目录
if(NOT "${CMAKE_PREFIX_PATH}" STREQUAL "")
include_directories(${CMAKE_PREFIX_PATH}/include)
endif() # cminpack_srcs: 源代码文件
set (cminpack_srcs
cminpack.h cminpackP.h
chkder.c enorm.c hybrd1.c hybrj.c lmdif1.c lmstr1.c qrfac.c r1updt.c
dogleg.c fdjac1.c hybrd.c lmder1.c lmdif.c lmstr.c qrsolv.c rwupdt.c
dpmpar.c fdjac2.c hybrj1.c lmder.c lmpar.c qform.c r1mpyq.c covar.c covar1.c
minpack.h
chkder_.c enorm_.c hybrd1_.c hybrj_.c lmdif1_.c lmstr1_.c qrfac_.c r1updt_.c
dogleg_.c fdjac1_.c hybrd_.c lmder1_.c lmdif_.c lmstr_.c qrsolv_.c rwupdt_.c
dpmpar_.c fdjac2_.c hybrj1_.c lmder_.c lmpar_.c qform_.c r1mpyq_.c covar_.c
)
# cminpack_hdrs: 头文件
set (cminpack_hdrs
cminpack.h minpack.h) # 添加一个名为cminpack的库
add_library (cminpack ${cminpack_srcs}) if (${CMAKE_SYSTEM_NAME} STREQUAL "FreeBSD")
TARGET_LINK_LIBRARIES(cminpack m)
endif() # Link with a BLAS library if requested
if (USE_BLAS)
if (NOT BUILD_SHARED_LIBS)
set(BLA_STATIC True)
endif()
find_package(BLAS)
if (BLAS_FOUND)
target_link_libraries(cminpack PUBLIC ${BLAS_LIBRARIES})
set_target_properties(cminpack PROPERTIES LINK_FLAGS "${BLAS_LINKER_FLAGS}")
target_compile_definitions(cminpack PUBLIC -DUSE_CBLAS)
endif()
endif() # install: 为工程生成安装规则
# TARGETS版本的install命令
install (TARGETS cminpack
# 模块库
LIBRARY DESTINATION ${CMINPACK_LIB_INSTALL_DIR} COMPONENT library
# 静态链接的库文件
ARCHIVE DESTINATION ${CMINPACK_LIB_INSTALL_DIR} COMPONENT library
# 动态库
RUNTIME DESTINATION bin COMPONENT library)
# FILES版本的install命令
# 以相对路径方式给出的文件名是相对当前源代码路径而言的,默认具有OWNER_WRITE, OWNER_READ, GROUP_READ和WORLD_READ权限
install (FILES ${cminpack_hdrs} DESTINATION ${CMINPACK_INCLUDE_INSTALL_DIR}
COMPONENT cminpack_hdrs) if (USE_FPIC AND NOT BUILD_SHARED_LIBS)
set_target_properties (cminpack PROPERTIES COMPILE_FLAGS -fPIC)
endif () set_target_properties(cminpack PROPERTIES VERSION ${CMINPACK_VERSION} SOVERSION ${CMINPACK_SOVERSION}) # add_subdirectory: 添加子项目
add_subdirectory (cmake)
add_subdirectory (examples)

${CMINPACK_SOURCE_DIR}/cmake/cminpack_utils.cmake

# 获取系统信息,设置安装位置
macro(GET_OS_INFO)
# string(REGEX MATCH 正则表达 输出变量 )
string(REGEX MATCH "Linux" OS_LINUX ${CMAKE_SYSTEM_NAME})
string(REGEX MATCH "BSD" OS_BSD ${CMAKE_SYSTEM_NAME})
if(WIN32)
set(OS_WIN TRUE)
endif(WIN32) if(NOT DEFINED CMINPACK_LIB_INSTALL_DIR)
set(CMINPACK_LIB_INSTALL_DIR "lib")
if(OS_LINUX)
if(${CMAKE_SYSTEM_PROCESSOR} STREQUAL "x86_64")
set(CMINPACK_LIB_INSTALL_DIR "lib64")
else(${CMAKE_SYSTEM_PROCESSOR} STREQUAL "x86_64")
set(CMINPACK_LIB_INSTALL_DIR "lib")
endif(${CMAKE_SYSTEM_PROCESSOR} STREQUAL "x86_64")
message (STATUS "Operating system is Linux")
elseif(OS_BSD)
message (STATUS "Operating system is BSD")
elseif(OS_WIN)
message (STATUS "Operating system is Windows")
else(OS_LINUX)
message (STATUS "Operating system is generic Unix")
endif(OS_LINUX)
endif(NOT DEFINED CMINPACK_LIB_INSTALL_DIR)
# 比如/usr/local/include/cminpack-1
set(CMINPACK_INCLUDE_INSTALL_DIR "include/${PROJECT_NAME_LOWER}-${CMINPACK_MAJOR_VERSION}")
endmacro(GET_OS_INFO) # 解剖CMinpack版本号
macro(DISSECT_VERSION)
# Find version components
string(REGEX REPLACE "^([0-9]+).*" "\\1"
CMINPACK_MAJOR_VERSION "${CMINPACK_VERSION}")
string(REGEX REPLACE "^[0-9]+\\.([0-9]+).*" "\\1"
CMINPACK_MINOR_VERSION "${CMINPACK_VERSION}")
string(REGEX REPLACE "^[0-9]+\\.[0-9]+\\.([0-9]+)" "\\1"
CMINPACK_REVISION_VERSION ${CMINPACK_VERSION})
string(REGEX REPLACE "^[0-9]+\\.[0-9]+\\.[0-9]+(.*)" "\\1"
CMINPACK_CANDIDATE_VERSION ${CMINPACK_VERSION})
endmacro(DISSECT_VERSION)

${CMINPACK_SOURCE_DIR}/examples/CMakeLists.txt

# 可选项
# option (选项名 "选项注释" 默认内容)
option (BUILD_EXAMPLES "Build the examples and tests." ON)
option (BUILD_EXAMPLES_FORTRAN "Build the FORTRAN examples and tests." OFF) if (BUILD_EXAMPLES)
# Make sure the compiler can find include files from our cminpack library.
include_directories (${CMINPACK_SOURCE_DIR}) # Make sure the linker can find the cminpack library once it is built.
link_directories (${CMINPACK_BINARY_DIR}) # 设置变量内容
# set(变量 内容)
set (FPGM tchkder thybrd thybrd1 thybrj thybrj1 tlmder tlmder1 tlmdif tlmdif1 tlmstr tlmstr1)
set (CPGM ${FPGM} tfdjac2) # cmpfile: 用于一行行地比较两个文件的异同
# cmpfiles could be used by runtest.cmake... for now it's unused
# add_executable(可执行文件名称 源文件)
add_executable (cmpfiles cmpfiles.c) # inspired by http://www.netlib.org/clapack/clapack-3.2.1-CMAKE/TESTING/CMakeLists.txt
# except that here we have to compare the output to a reference
# 测试部分跳过不看
macro(add_minpack_test testname reference)
set(TEST_OUTPUT "${CMINPACK_BINARY_DIR}/examples/${testname}.out")
set(TEST_REFERENCE "${CMINPACK_SOURCE_DIR}/examples/ref/${reference}.ref")
get_target_property(TEST_LOC ${testname} LOCATION)
add_test(${testname} "${CMAKE_COMMAND}"
-DTEST=${TEST_LOC}
-DOUTPUT=${TEST_OUTPUT}
-DREFERENCE=${TEST_REFERENCE}
-DINTDIR=${CMAKE_CFG_INTDIR}
-P "${CMINPACK_SOURCE_DIR}/examples/runtest.cmake")
endmacro(add_minpack_test) # 遍历处理每一个目标文件
foreach (source ${CPGM})
add_executable (${source}_ ${source}_.c)
target_link_libraries (${source}_ cminpack)
if (OS_LINUX)
target_link_libraries (${source}_ m)
endif (OS_LINUX)
add_minpack_test(${source}_ ${source}c)
add_executable (${source}c ${source}c.c)
target_link_libraries (${source}c cminpack)
if (OS_LINUX)
target_link_libraries (${source}c m)
endif (OS_LINUX)
add_minpack_test(${source}c ${source}c)
endforeach(source)
endif (BUILD_EXAMPLES) # FORTRAN部分跳过不看

第一个CMinpack程序

根据我们阅读给出的测试样例的CMake相关文件,我们可以开始动手写自己的第一个CMinpack程序。

新建目录,目录下放着我们要运行的使用了CMinpack的程序my-cminpack-demo.c。

开始编写CMakeLists.txt文件,首先提取出我们需要的内容:

project(my-cminpack-demo)
cmake_minimum_required (VERSION 2.6) include_directories (${CMINPACK_SOURCE_DIR})
link_directories (${CMINPACK_BINARY_DIR}) add_executable (my-cminpack-demo my-cminpack-demo.c)
target_link_libraries (my-cminpack-demo cminpack)
if (OS_LINUX)
target_link_libraries (my-cminpack-demo m)
endif (OS_LINUX)

然后新建build目录,在build目录下运行cmake ..

发现会跳出找不到sqrt函数的错误,这个我们能够一下子联想到是Linux系统下没有连接到m库文件的原因。虽然我不知道这个判断为什么无法执行,但是我们已知在Linux环境下,把它去掉。

得到最终的CMakeLists.txt:

project(my-cminpack-demo)
cmake_minimum_required (VERSION 2.6) include_directories (${CMINPACK_SOURCE_DIR})
link_directories (${CMINPACK_BINARY_DIR}) add_executable (my-cminpack-demo my-cminpack-demo.c)
target_link_libraries (my-cminpack-demo cminpack)
target_link_libraries (my-cminpack-demo m)

虽然我们make得到可执行文件,运行后查看结果(图中我使用了tlmdif_.c作为测试)

LMDIF使用说明

官方英文介绍:http://devernay.github.io/cminpack/lmdif_.html

包括函数名

lmdif, lmdif1_ - 最小化非线性函数平方和

函数概要

include <minpack.h>
void lmdif1_(void (*fcn)(int *m, int *n, double *x, double *fvec, int *iflag),
int *m, int *n, double *x, double *fvec,
double *tol, int *info, int *iwa, double *wa, int *lwa); void lmdif_(void (*fcn)(int *m, int *n, double *x, double *fvec, int *iflag),
int *m, int *n, double *x, double *fvec,
double *ftol, double *xtol, double *gtol, int *maxfev, double *epsfcn, double *diag,
int *mode, double *factor, int *nprint, int *info, int *nfev, double *fjac,
int *ldfjac, int *ipvt, double *qtf,
double *wa1, double *wa2, double *wa3, double *wa4 );

详细描述

lmdif_的目的是最小化m个n元非线性方程的平方和,使用的方法是LM算法的改进。用户需要提供计算方程的子程序。Jacobian矩阵会通过一个前向差分(forward-difference)近似计算得到。

lmdif1_是相同的目的,但是调用方法更简单一些。

语言备注

这些函数是通过FORTRAN写的,如果从C调用,需要记住以下几点:

  • 名称重编:

    • 2.95/3.0版本的g77下,所有函数以下划线结尾,后续版本可能会更改;
  • 使用g77编译:
    • 即使你的程序全部用C语言写成,你也需要使用gcc进行链接,因为这样它会自动导入FORTRAN库。只使用g77进行编译是最方便的(它处理C语言也是OK的);
  • 通过引用调用:
    • 所有函数参数都是指针;
  • 列优先数组:
    • z( i , j ) = z[ ( i - 1 ) + ( j - 1 ) * n
    • fcn是用户提供用于计算函数的子程序。在C语言当中fcn需要如下定义:
void fcn(int m, int n, double *x, double *fvec, int *iflag) {
/* 计算函数在x点的值,通过fvec返回。*/
}

iflag的值不能被fcn所修改,除非用户想要终止lmdif/lmdif1_。在这个例子中iflag设置为负整数。

lmdif_和lmdif1_的共同参数

m:函数个数;

n:变量个数(n<=m)

x:长度为n的数组,设置为初始的估计解向量。输出的时候x内容为最终估计的解向量。

fvec:输出长度为m的数组,内容为最终输出x计算得到的函数解。

lmdif1_的参数

tol:作为输入,非负数。用于函数终止的条件判断:

  • 平方和小于tol;
  • x之间的相对误差小于tol;

info:作为输出。如果用户终止了函数的执行,info将被设置为iflag的值(负数)(详细见fcn的描述),否则,info的值如下几种情况:

  • 0:输入参数不合适;
  • 1:平方和的相对误差小于tol;
  • 2:x之间的相对误差小于tol;
  • 3:1/2两种情况同时符合;
  • 4: fvec is orthogonal to the columns of the Jacobian to machine precision(这个情况是什么暂时不是很清楚)
  • 5:调用fcn的次数达到了200*(n+1)次;
  • 6:tol设置过小,平方和无法达到那么小;
  • 7:tol设置过小,x的近似解无法优化到误差达到那么小。

iwa:长度n的工作数组;

wa:长度lwa的工作数组;

lwa:作为输入,整数,不能小于mn+5n+m;

[NOTE] 这三个输入我也不知道作用,从样例来看不需要初始化。

lmdif_的参数

暂时不用这部分,跳过。

官方样例解读

源码: https://github.com/devernay/cminpack/blob/d1f5f5a273862ca1bbcf58394e4ac060d9e22c76/examples/tlmdif1_.c

/*     lmdif1 例子. */
#include <stdio.h>
#include <math.h>
#include <assert.h>
#include <minpack.h>
#define real __minpack_real__ // 用户自定义的函数f()
// real -> __cminpack_real__ -> 浮点数(double)
void fcn(const int *m, const int *n, const real *x, real *fvec, int *iflag); int main()
{
int j, m, n, info, lwa, iwa[3], one=1;
real tol, fnorm, x[3], fvec[15], wa[75]; // 函数个数15; 变量数3
m = 15;
n = 3; // 初始位置做粗略估计
// 1.e0 = 1.0e0 = 1.0
x[0] = 1.e0;
x[1] = 1.e0;
x[2] = 1.e0; // 为什么要设置75?
lwa = 75; /* set tol to the square root of the machine precision. unless high
precision solutions are required, this is the recommended
setting. */
// (建议打印一下看值是多少) tol = sqrt(__minpack_func__(dpmpar)(&one)); // 需要注意指针
__minpack_func__(lmdif1)(&fcn, &m, &n, x, fvec, &tol, &info, iwa, wa, &lwa); // 最终的2范数(即平方和开根号)
fnorm = __minpack_func__(enorm)(&m, fvec);
printf(" final l2 norm of the residuals%15.7g\n\n", (double)fnorm);
printf(" exit parameter %10i\n\n", info);
printf(" final approximate solution\n");
for (j=1; j<=n; j++) {
printf("%s%15.7g", j%3==1?"\n ":"", (double)x[j-1]);
}
printf("\n");
return 0;
} // The problem is to determine the values of x(1), x(2), and x(3)
// which provide the best fit (in the least squares sense) of
// x(1) + u(i)/(v(i)*x(2) + w(i)*x(3)), i = 1, 15
// to the data
// y = (0.14,0.18,0.22,0.25,0.29,0.32,0.35,0.39,
// 0.37,0.58,0.73,0.96,1.34,2.10,4.39),
// where u(i) = i, v(i) = 16 - i, and w(i) = min(u(i),v(i)). The
// i-th component of FVEC is thus defined by
// y(i) - (x(1) + u(i)/(v(i)*x(2) + w(i)*x(3))). void fcn(const int *m, const int *n, const real *x, real *fvec, int *iflag)
{
/* function fcn for lmdif1 example */ int i;
real tmp1,tmp2,tmp3; // 实际的y值
real y[15]={1.4e-1,1.8e-1,2.2e-1,2.5e-1,2.9e-1,3.2e-1,3.5e-1,3.9e-1,
3.7e-1,5.8e-1,7.3e-1,9.6e-1,1.34e0,2.1e0,4.39e0};
assert(*m == 15 && *n == 3); if (*iflag == 0) {
/* insert print statements here when nprint is positive. */
/* if the nprint parameter to lmder is positive, the function is
called every nprint iterations with iflag=0, so that the
function may perform special operations, such as printing
residuals. */
// 这段没有很看懂,在??情况下打印信息
return;
} /* compute residuals */ for (i=0; i<15; i++) {
tmp1 = i+1;
tmp2 = 15 - i;
tmp3 = tmp1;
if (i >= 8) {
tmp3 = tmp2;
}
fvec[i] = y[i] - (x[0] + tmp1/(x[1]*tmp2 + x[2]*tmp3));
}
}

[NOTE] 其他内容有待更新

CMinpack使用介绍的更多相关文章

  1. CSS3 background-image背景图片相关介绍

    这里将会介绍如何通过background-image设置背景图片,以及背景图片的平铺.拉伸.偏移.设置大小等操作. 1. 背景图片样式分类 CSS中设置元素背景图片及其背景图片样式的属性主要以下几个: ...

  2. MySQL高级知识- MySQL的架构介绍

    [TOC] 1.MySQL 简介 概述 MySQL是一个关系型数据库管理系统,由瑞典MySQL AB公司开发,目前属于Oracle公司. MySQL是一种关联数据库管理系统,将数据保存在不同的表中,而 ...

  3. Windows Server 2012 NIC Teaming介绍及注意事项

    Windows Server 2012 NIC Teaming介绍及注意事项 转载自:http://www.it165.net/os/html/201303/4799.html Windows Ser ...

  4. Linux下服务器端开发流程及相关工具介绍(C++)

    去年刚毕业来公司后,做为新人,发现很多东西都没有文档,各种工具和地址都是口口相传的,而且很多时候都是不知道有哪些工具可以使用,所以当时就想把自己接触到的这些东西记录下来,为后来者提供参考,相当于一个路 ...

  5. JavaScript var关键字、变量的状态、异常处理、命名规范等介绍

    本篇主要介绍var关键字.变量的undefined和null状态.异常处理.命名规范. 目录 1. var 关键字:介绍var关键字的使用. 2. 变量的状态:介绍变量的未定义.已定义未赋值.已定义已 ...

  6. HTML DOM 介绍

    本篇主要介绍DOM内容.DOM 节点.节点属性以及获取HTML元素的方法. 目录 1. 介绍 DOM:介绍DOM,以及对DOM分类和功能的说明. 2. DOM 节点:介绍DOM节点分类和节点层次. 3 ...

  7. HTML 事件(一) 事件的介绍

    本篇主要介绍HTML中的事件知识:事件相关术语.DOM事件规范.事件对象. 其他事件文章 1. HTML 事件(一) 事件的介绍 2. HTML 事件(二) 事件的注册与注销 3. HTML 事件(三 ...

  8. HTML5 介绍

    本篇主要介绍HTML5规范的内容和页面上的架构变动. 目录 1. HTML5介绍 1.1 介绍 1.2 内容 1.3 浏览器支持情况 2. 创建HTML5页面 2.1 <!DOCTYPE> ...

  9. ExtJS 4.2 介绍

    本篇介绍ExtJS相关知识,是以ExtJS4.2.1版本为基础进行说明,包括:ExtJS的特点.MVC模式.4.2.1GPL版本资源的下载和说明以及4种主题的演示. 目录 1. 介绍 1.1 说明 1 ...

随机推荐

  1. HTTP协议解析(格式和举例十分清楚)

    掌握HTTP虽然不是必须的,但是如果你知道它的工作原理,那么在学习JSP开发中的某些知识就可以易如反掌了. 一,HTTP协议详解之URL篇 http(超文本传输协议)是一个基于请求与响应模式的.无状态 ...

  2. CRS-2800: Cannot start resource 'ora.asm' as it is already in the INTERMEDIATE state on server ‘RAC02’

    在安装ORACLE RAC的Grid Infrastructure时,在节点1运行/u01/app/11.2.0/grid/root.sh正常,当在节点2运行/u01/app/11.2.0/grid/ ...

  3. HTTP通信过程原理

    HTTP协议 通信过程介绍 HTTP协议介绍 Http(Hypertext Transfer Protocol)超文本传输协议. Http是应用层协议,当你上网浏览网页的时候,浏览器和服务器之间就会通 ...

  4. DIOCP3 DEMO的编译(去掉VCL前缀)

    总有些朋友问我,关于DEMO编译的一些问题,每次都回答大概都差不多,我想还是写篇说明书给大家,关于DEMO编译的步骤. [环境设定] 1.将DIOCP3\source路径添加到Delphi的搜索路径, ...

  5. 做个知识回顾目录,打算每日更新一下ios的基础知识

    一.基础技能列表:   01 面向对象特性       类与方法封装       通过继承扩展类       抽象类与方法覆盖       多态.动态类型和动态绑定       分类和协议       ...

  6. Ruby元编程:动态添加类属性及其实际应用

    上个星期测试道的Monkey老师和我聊到测试用例参数过多的问题,其实这样的问题在我这里也同样经历过.比如我的测试用例必须面对不同的测试环境,每个环境有无数的参数,开发的最初阶段,因为参数少,所以就放在 ...

  7. jmeter报告分析工具

    一直以来做性能测试都是用jmeter和LR,当然还有一些自己写测试脚本,LR不用说,分析结果那个组件杠杠的!但是jmeter毕竟是开源的,所以分析查看结果不像LR那样自带图形神马的,虽然可以自己写脚本 ...

  8. 阿里云部署Redis服务器远程连接问题

    昨天在阿里云免费领了一个月的云服务器,就着最近学的SpringBoot,准备做一个SpringBoot与Redis的整合. 因为以前用的Redis都是安装在本地的,使用过程中没遇到什么大问题,可是一旦 ...

  9. Laravel --- 要点笔记

    一.路由: // 常规用法 Route::get('/',function(){ return 'get'; }) // 匹配多个 Route::match(['get','post'],'/',fu ...

  10. Java内存区域(运行时数据区域)和内存模型(JMM)

    Java 内存区域和内存模型是不一样的东西,内存区域是指 Jvm 运行时将数据分区域存储,强调对内存空间的划分. 而内存模型(Java Memory Model,简称 JMM )是定义了线程和主内存之 ...