1.1下载sdk运行

百度离线人脸识别sdk的使用

1.2配置环境

添加至项目,可以拖动复制或者以类库形式添加
face-resource此文件夹 放到根目录上一层

激活文件与所有dll引用放到根目录
嫌麻烦可以将sdk的根目录所有文件直接拖动至项目的根目录

1.3 使用
百度离线人脸识别sdk只支持Release方式运行,所以项目的配置也改为此方式(不然会提示baiduapi…….一系列dll找不到)
sdk使用OpenCvSharp3-AnyCPU的引用

  static class Program
{
/// <summary>
/// 应用程序的主入口点。
/// </summary> [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
delegate void FaceCallback(IntPtr bytes, int size, String res);
// sdk初始化
[DllImport("BaiduFaceApi.dll", EntryPoint = "sdk_init", CharSet = CharSet.Ansi
, CallingConvention = CallingConvention.Cdecl)]
private static extern int sdk_init(bool id_card);
// 是否授权
[DllImport("BaiduFaceApi.dll", EntryPoint = "is_auth", CharSet = CharSet.Ansi
, CallingConvention = CallingConvention.Cdecl)]
private static extern bool is_auth();
// 获取设备指纹
[DllImport("BaiduFaceApi.dll", EntryPoint = "get_device_id", CharSet = CharSet.Ansi
, CallingConvention = CallingConvention.Cdecl)]
private static extern IntPtr get_device_id();
// sdk销毁
[DllImport("BaiduFaceApi.dll", EntryPoint = "sdk_destroy", CharSet = CharSet.Ansi
, CallingConvention = CallingConvention.Cdecl)]
private static extern void sdk_destroy(); // 测试获取设备指纹device_id
public static void test_get_device_id()
{
IntPtr ptr = get_device_id();
string buf = Marshal.PtrToStringAnsi(ptr);
Console.WriteLine("device id is:" + buf);
} [STAThread]
static void Main()
{
bool id = false; int n = sdk_init(id);
if (n != 0)
{
Console.WriteLine("auth result is {0:D}", n);
Console.ReadLine();
} // 测试是否授权
bool authed = is_auth();
Console.WriteLine("authed res is:" + authed);
test_get_device_id(); Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
}

使用时将Program类修改,不然无法使用人脸检测接口 错误报告为参数非法回传 -1

1.3.1 人脸图片检测方法

[DllImport("BaiduFaceApi.dll", EntryPoint = "track", CharSet = CharSet.Ansi
, CallingConvention = CallingConvention.Cdecl)]
private static extern IntPtr track(string file_name, int max_track_num);
public void test_track()
{
// 传入图片文件绝对路径
string file_name = "d:\\kehu2.jpg";
int max_track_num = 1; // 设置最多检测人数(多人脸检测),默认为1,最多可设为10
IntPtr ptr = track(file_name, max_track_num);
string buf = Marshal.PtrToStringAnsi(ptr);
Console.WriteLine("track res is:" + buf);
}

人脸检测接口,此方法需要在d盘根目录放一张名为“kehu2.jpg”的图片来检测是否含有人脸。

1.3.2 人脸摄像头实时检测方法

public void usb_csharp_track_face(int dev)
{
using (var window = new Window("face"))
using (VideoCapture cap = VideoCapture.FromCamera(dev))
{
if (!cap.IsOpened())
{
Console.WriteLine("open camera error");
return;
}
// Frame image buffer
Mat image = new Mat();
// When the movie playback reaches end, Mat.data becomes NULL.
while (true)
{
RotatedRect box;
cap.Read(image); // same as cvQueryFrame
if (!image.Empty())
{
int ilen = 2;//传入的人脸数
TrackFaceInfo[] track_info = new TrackFaceInfo[ilen];
for (int i = 0; i < ilen; i++)
{
track_info[i] = new TrackFaceInfo();
track_info[i].landmarks = new int[144];
track_info[i].headPose = new float[3];
track_info[i].face_id = 0;
track_info[i].score = 0;
}
int sizeTrack = Marshal.SizeOf(typeof(TrackFaceInfo));
IntPtr ptT = Marshal.AllocHGlobal(sizeTrack* ilen);
//Marshal.Copy(ptTrack, 0, ptT, ilen);
// FaceInfo[] face_info = new FaceInfo[ilen];
// face_info = new FaceInfo(0.0F,0.0F,0.0F,0.0F,0.0F); //Cv2.ImWrite("usb_track_Cv2.jpg", image);
/* trackMat
* 传入参数: maxTrackObjNum:检测到的最大人脸数,传入外部分配人脸数,需要分配对应的内存大小。
* 传出检测到的最大人脸数
* 返回值: 传入的人脸数 和 检测到的人脸数 中的最小值,实际返回的人脸。
****/
int faceSize = ilen;//返回人脸数 分配人脸数和检测到人脸数的最小值
int curSize = ilen;//当前人脸数 输入分配的人脸数,输出实际检测到的人脸数
faceSize = track_mat(ptT, image.CvPtr, ref curSize);
for (int index = 0; index < faceSize; index++)
{
IntPtr ptr = new IntPtr();
if( 8 == IntPtr.Size)
{
ptr = (IntPtr)(ptT.ToInt64() + sizeTrack * index);
}
else if(4 == IntPtr.Size)
{
ptr = (IntPtr)(ptT.ToInt32() + sizeTrack * index);
} track_info[index] = (TrackFaceInfo)Marshal.PtrToStructure(ptr, typeof(TrackFaceInfo));
//face_info[index] = (FaceInfo)Marshal.PtrToStructure(info_ptr, typeof(FaceInfo));
Console.WriteLine("in Liveness::usb_track face_id is {0}:",track_info[index].face_id);
Console.WriteLine("in Liveness::usb_track landmarks is:");
for (int k = 0; k < 1; k ++)
{
Console.WriteLine("{0},{1},{2},{3},{4},{5},{6},{7},{8},{9},",
track_info[index].landmarks[k], track_info[index].landmarks[k+1],
track_info[index].landmarks[k+2], track_info[index].landmarks[k + 3],
track_info[index].landmarks[k+4], track_info[index].landmarks[k + 5],
track_info[index].landmarks[k+6], track_info[index].landmarks[k + 7],
track_info[index].landmarks[k+8], track_info[index].landmarks[k + 9]
);
} for (int k = 0; k < track_info[index].headPose.Length; k++)
{
Console.WriteLine("in Liveness::usb_track angle is:{0:f}", track_info[index].headPose[k]);
}
Console.WriteLine("in Liveness::usb_track score is:{0:f}", track_info[index].score);
// 角度
Console.WriteLine("in Liveness::usb_track mAngle is:{0:f}", track_info[index].box.mAngle);
// 人脸宽度
Console.WriteLine("in Liveness::usb_track mWidth is:{0:f}", track_info[index].box.mWidth);
// 中心点X,Y坐标
Console.WriteLine("in Liveness::usb_track mCenter_x is:{0:f}", track_info[index].box.mCenter_x);
Console.WriteLine("in Liveness::usb_track mCenter_y is:{0:f}", track_info[index].box.mCenter_y);
画人脸框
box = bounding_box(track_info[index].landmarks, track_info[index].landmarks.Length);
draw_rotated_box(ref image, ref box, new Scalar(0, 255, 0));
// 实时检测人脸属性和质量可能会视频卡顿,若一定必要可考虑跳帧检测
// 获取人脸属性(通过传入人脸信息)
//IntPtr ptrAttr = FaceAttr.face_attr_by_face(image.CvPtr, ref track_info[index]);
//string buf = Marshal.PtrToStringAnsi(ptrAttr);
//Console.WriteLine("attr res is:" + buf);
获取人脸质量(通过传入人脸信息)
//IntPtr ptrQua = FaceQuality.face_quality_by_face(image.CvPtr, ref track_info[index]);
//buf = Marshal.PtrToStringAnsi(ptrQua);
//Console.WriteLine("quality res is:" + buf);
实时检测人脸特征值可能会视频卡顿,若一定必要可考虑跳帧检测
//float[] feature = new float[512];
//IntPtr ptrfea = new IntPtr();
//int count = FaceCompare.get_face_feature_by_face(image.CvPtr, ref track_info[index], ref ptrfea);
返回值为512表示取到了特征值
//if(ptrfea == IntPtr.Zero)
//{
// Console.WriteLine("Get feature failed!");
// continue;
//}
//if (count == 512)
//{
// for (int i = 0; i < count; i++)
// {
// IntPtr floptr = new IntPtr();
// if ( 8 == IntPtr.Size)
// {
// floptr = (IntPtr)(ptrfea.ToInt64() + i * count * Marshal.SizeOf(typeof(float)));
// }
// else if( 4 == IntPtr.Size)
// {
// floptr = (IntPtr)(ptrfea.ToInt32() + i * count * Marshal.SizeOf(typeof(float)));
// } // feature[i] = (float)Marshal.PtrToStructure(floptr, typeof(float));
// Console.WriteLine("feature {0} is: {1:e8}", i, feature[i]);
// }
// Console.WriteLine("feature count is:{0}", count);
//}
}
Marshal.FreeHGlobal(ptT);
window.ShowImage(image);
Cv2.WaitKey(1);
Console.WriteLine("mat not empty");
}
else
{
Console.WriteLine("mat is empty");
}
}
image.Release();
}
}

以上为原sdk方法;
只可检测人脸 不可活体检测;

  static VideoCapture camera1 = null;
static VideoCapture camera2 = null;
public bool usb_csharp_track_face(int dev)
{
string buf = "";
int faceSize = 0;
int faceNum = 2;//传入的人脸数
int face_size = faceNum;//当前传入人脸数,传出人脸数
//VideoCapture cap = VideoCapture.FromCamera(dev);
//Mat image = new Mat();
long ir_time = 0;
// 序号0为电脑识别的usb摄像头编号,本demo中0为ir红外摄像头
// 不同摄像头和电脑识别可能有区别
// 编号一般从0-10 */
int device = select_usb_device_id();
camera1 = VideoCapture.FromCamera(device);
if (!camera1.IsOpened())
{
Console.WriteLine("camera1 open error");
return false;
}
camera1.Set(CaptureProperty.FrameWidth, 1440);
camera1.Set(CaptureProperty.FrameHeight, 1080);
camera2 = VideoCapture.FromCamera(device + 1);
if (!camera2.IsOpened())
{
Console.WriteLine("camera2 open error");
return false;
} RotatedRect box;
Mat frame1 = new Mat();
Mat frame2 = new Mat();
Mat rgb_mat = new Mat();
Mat ir_mat = new Mat();
//var window_ir = new Window("ir_face");
//var window_rgb = new Window("rgb_face");
if (!camera1.IsOpened())
{
return false;
}
#region 尝试
while (true)
{ //Thread.Sleep(1000); camera1.Read(frame1);
camera2.Read(frame2); if (!frame1.Empty() && !frame2.Empty())
{
int ilen = 2;//传入的人脸数
TrackFaceInfo[] track_info = new TrackFaceInfo[ilen];
for (int i = 0; i < ilen; i++)
{
track_info[i] = new TrackFaceInfo();
track_info[i].landmarks = new int[144];
track_info[i].headPose = new float[3];
track_info[i].face_id = 0;
track_info[i].score = 0;
}
int sizeTrack = Marshal.SizeOf(typeof(TrackFaceInfo));
IntPtr ptT = Marshal.AllocHGlobal(sizeTrack * ilen);
#region 原
if (frame1.Size(0) > frame2.Size(0))
{
rgb_mat = frame1;
ir_mat = frame2;
}
else
{
rgb_mat = frame2;
ir_mat = frame1;
}
#endregion
float rgb_score = 0;
float ir_score = 0;
//Marshal.Copy(ptTrack, 0, ptT, ilen);
//FaceInfo[] face_info = new FaceInfo[ilen];
//face_info = new FaceInfo(0.0F,0.0F,0.0F,0.0F,0.0F);
//Cv2.ImWrite("usb_track_Cv2.jpg", image);
/* trackMat
* 传入参数: maxTrackObjNum:检测到的最大人脸数,传入外部分配人脸数,需要分配对应的内存大小。
* 传出检测到的最大人脸数
* 返回值: 传入的人脸数 和 检测到的人脸数 中的最小值,实际返回的人脸。
****/
faceSize = ilen;//返回人脸数 分配人脸数和检测到人脸数的最小值
int curSize = ilen;//当前人脸数 输入分配的人脸数,输出实际检测到的人脸数
faceSize = track_mat(ptT, frame1.CvPtr, ref curSize);
IntPtr ptr1 = rgb_ir_liveness_check_faceinfo(rgb_mat.CvPtr, ir_mat.CvPtr, ref rgb_score, ref ir_score, ref faceSize, ref ir_time, ptT);
curSize = ilen;
faceSize = track_mat(ptT, frame1.CvPtr, ref curSize);
//Console.WriteLine(rgb_score.ToString());
//Console.WriteLine(ir_score.ToString());
//textBox1.Text = faceSize.ToString();
for (int index = 0; index < faceSize; index++)
{
IntPtr ptr = new IntPtr();
if (8 == IntPtr.Size)
{
ptr = (IntPtr)(ptT.ToInt64() + sizeTrack * index);
}
else if (4 == IntPtr.Size)
{
ptr = (IntPtr)(ptT.ToInt32() + sizeTrack * index);
}
track_info[index] = (TrackFaceInfo)Marshal.PtrToStructure(ptr, typeof(TrackFaceInfo));
IntPtr ptrQua = FaceQuality.face_quality_by_face(frame1.CvPtr, ref track_info[index]);
buf = Marshal.PtrToStringAnsi(ptrQua);
}
textBox2.Text = buf.ToString();
Marshal.FreeHGlobal(ptT);
//window.ShowImage(image);
pictureBox1.Image = frame1.ToBitmap();
Cv2.WaitKey(1);
#region 测试
if (rgb_score != 0 && ir_score != 0)
{
if (faceSize >= 1)
{ JObject jObject = (JObject)JsonConvert.DeserializeObject(buf);
var json = (JObject)JsonConvert.DeserializeObject(jObject["data"].ToString()); string result = json["result"].ToString();
// textBox1.Text = json["result"].ToString();
var json1 = (JObject)JsonConvert.DeserializeObject(result);
if (double.Parse(json1["bluriness"].ToString()) <= 0.00001 && double.Parse(json1["occl_r_eye"].ToString()) < 0.1 && double.Parse(json1["occl_l_eye"].ToString()) < 0.1 &&
double.Parse(json1["occl_mouth"].ToString()) <= 0 && double.Parse(json1["occl_nose"].ToString()) < 0.11 && double.Parse(json1["occl_r_contour"].ToString()) < 0.1
&& double.Parse(json1["occl_chin"].ToString()) <= 0 && double.Parse(json1["occl_l_contour"].ToString()) < 0.1)
{
string fileName = DateTime.Now.ToString("yyyyMMdd") + ".jpg";
string path = AppDomain.CurrentDomain.BaseDirectory;
string picture = path + @"img" + "\\" + fileName; frame1.SaveImage(picture);
falnem = picture;
if (Sdistinguish() != "0")
{
Class1 c = new Class1();
Thread.Sleep(2000);
dtTo = new TimeSpan(0, 0, 2);
camera2.Release();
camera2.Release();
thread.Abort();
return true; }
else
{
Thread.Sleep(2000);
dtTo = new TimeSpan(0, 0, 2);
camera2.Release();
camera2.Release();
thread.Abort();
//msg2 msg2 = new msg2();
//msg2.Show();
return true;
this.Close();
} Thread.Sleep(2000); thread.Abort();
//msg2 msg2 = new msg2();
//msg2.Show();
this.Close();
//window.Close(); }
} } #endregion //return faceSize;
}
else
{
Console.WriteLine("mat is empty");
}
}
#endregion frame1.Release(); return false;
//usb_csharp_track_face(1);
}

以上为我修改后的;

  private string distinguish()
{
dz = "1";
//string fileName = DateTime.Now.ToString("yyyyMMddHH") + ".jpg";
string fileName = falnem; //string fileName = "" + ".jpg";
//SavePicture(fileName);
FaceCompare faceCompare = new FaceCompare();
JObject jObject = (JObject)JsonConvert.DeserializeObject(faceCompare.test_identify(fileName, "group", "")); // JObject jObject = (JObject)JsonConvert.DeserializeObject(faceCompare.test_identify("d:\\4.jpg", "test_group", "u1"));
var json = (JObject)JsonConvert.DeserializeObject(jObject["data"].ToString());
var json1 = (JObject)JsonConvert.DeserializeObject(json["result"].ToString());
var json1 = (JArray)json["result"].ToString();
textBox1.Text = "对比值:" + json1["score"].ToString() +"/r用户:"+json1["user_id"].ToString() ;
textBox1.Text= faceCompare.test_identify("d:\\4.jpg", "test_group", "test_user"); string result = json["result"].ToString().Substring(1, json["result"].ToString().Length - 2);
// textBox1.Text = json["result"].ToString();
var json1 = (JObject)JsonConvert.DeserializeObject(result);
//textBox2.Text = "对比值:" + json1["score"].ToString() + "\r\n用户:" + json1["user_id"].ToString();
string user = json1["user_id"].ToString(); string lockes = "0";
#region 查询数据库
using (var db = new ces(dbPath))
{
//List<TestFaceDB> testFaces = db.testFaces.Where(x => x.User == json1["user_id"].ToString()).ToList();
var testFaces = db.testFaces.Where(x => x.User == user).ToList();
//string testFaces = db.testFaces.Select(*).Where(x => x.User == json1["user_id"].ToString()).ToString();
//this.Text = $"{DateTime.Now}, 查到{books.Count}条记录";
lockes = testFaces[0].Locks;
} int lo = int.Parse(lockes);
if (int.Parse(lockes) > 100)
{
int d = 0;
while (lo > 100)
{
lo -= 100;
d++;
}
int z = 1;
for (int i = 0; i < d - 1; i++)
{
z = z * 2;
};
dz = "0" + z.ToString();
}
#endregion double score = double.Parse(json1["score"].ToString()); lockes = lo.ToString(); if (score > 80)
{
if (int.Parse(lockes) < 10) lockes = "0" + lockes;
return lockes;
}
else
{
return lockes;
} }
//1:N比较
public /*void*/string test_identify(string str, string usr_grp, string usr_id)
{
string file1 = str;//"d:\\6.jpg";
string user_group = usr_grp;//"test_group";
string user_id = usr_id;//"test_user";
IntPtr ptr = identify(file1, user_group, user_id);
string buf = Marshal.PtrToStringAnsi(ptr);
//Console.WriteLine("identify res is:" + buf);
return buf;
}

distinguish()方法为识别后在数据库中寻找匹配人脸数据;
将活体实时检测与人脸实时检测合并为一个方法,关闭了window显示窗口,修改为pictureBox控件 通过线程调用(不然死循环会崩溃);关闭摄像头为 Release();方法

数据均为json数据 ;
具体数据参数见百度文档
根据需求修改判断条件是否符合项目中的人脸标准;
识别流程为
启动线程->打开摄像头->检测到人脸->将人脸图片保存->用图片传入调用人脸对比方法;

1.3.3 人脸注册方法

string user_id = User.Text;
string group_id = "group";
string file_name = falnem;
string lockse = group.Text;
string user_info = info.Text;
string zc = faceManager.test_user_add(user_id, group_id, file_name, user_info);
JObject jObjectzc = (JObject)JsonConvert.DeserializeObject(zc);
if(jObjectzc["msg"].ToString()== "success")
{
List<TestFaceDB> testFaceDBs = new List<TestFaceDB>()
{
new TestFaceDB() {User = user_id,Locks = lockse,Phone = user_info}
};
textBox1.Text = dbPath;
using (var db = new ces(dbPath))
{
int count = db.InsertAll(testFaceDBs);
//this.Text = $"{DateTime.Now}, 插入{count}条记录";
}
msg msg = new msg();
msg.ShowDialog();
Thread.Sleep(5000); dtTo = new TimeSpan(0, 0, 2);
camera1.Release();
camera2.Release(); return true;
}
Thread.Sleep(3000);

同上的方法 先检测摄像头中是否使活体人脸并存图片文件,保存后调用人脸注册

public /*void*/ string test_user_add(string uid,string gid,string fil,string uin)
{
//人脸注册
//string user_id = "test_user";
//string group_id = "test_group";
//string file_name = "d:\\2.jpg";
//string user_info = "user_info";
string user_id = uid;
string group_id = gid;
string file_name = fil;
string user_info = uin;
IntPtr ptr = user_add(user_id, group_id, file_name, user_info);
string buf = Marshal.PtrToStringAnsi(ptr);
return buf;
}

这个我修改添加了参数;

因sdk带的SQLite数据库字段比较少,并且我也没有花心思想办法去修改它创建的数据库,所以创建个新的和sdk中数据库以一个字段相连,就当扩展数据库了;
在注册的时候顺带存新数据库一份就可以,要什么字段看自己需求;
当查找数据库中数据的时候查到就取那个字段,然后去新数据库中查找对应的其他字段。

1.4 打包

打包简单方法直接将根目录数据放到一个文件夹然后添加到Application Folder文件夹,然后在同目录将face-resource放进去就可以了,在安装的时候不能安装到系统盘 不然接口会出问题;不知道什么原因
安装到一个电脑的时候需要使用百度离线识别的sdk序列号激活不然不可使用;因为百度离线人脸识别sdk 是通过电脑指纹判断是否激活,如果遇到LicenseTool.exe打不开弹出缺少系统dll组件请去网络下载,或许因为电脑系统为盗版系统组件未安装齐
也可以在百度下载激活的压缩文件;
在添加输出的时候将sdk作为本地化资源输出,项目作为主输出,输出类型为Release;

「码农_半只龙虾」  也是我  ————————————————

版权声明:本文为csdn博主「码农_半只龙虾」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
csdn链接:https://blog.csdn.net/weixin_44986330/article/details/106297549

 

百度离线人脸识别sdk的使用的更多相关文章

  1. Java离线人脸识别SDK 支持arcface 2.0 最新版

    虹软人脸识别SDK之Java版,支持SDK 1.1+,以及当前最新版本2.0,滴滴,抓紧上车! JDK SDK Win release license status 前言 由于业务需求,最近跟人脸识别 ...

  2. windows下百度离线人脸识别本地部署与使用(nodejs做客户端,c++做服务端,socket做通信)

    1.离线人脸识别本地部署 详情请阅读百度人脸识别官网 2.nodejs做socket通信的客户端 为什么不直接通过调用c++编译的exe获得人脸识别结果? 原因:exe运行时会加载很多模型而消耗很多时 ...

  3. 虹软人脸识别SDK接入Milvus实现海量人脸快速检索

    一.背景 人脸识别是近年来最热门的计算机视觉领域的应用之一,而且现在已经出现了非常多的人脸识别算法,如:DeepID.FaceNet.DeepFace等等.人脸识别被广泛应用于景区.客运.酒店.办公室 ...

  4. Java版 人脸识别SDK demo

    虹软人脸识别SDK之Java版,支持SDK 1.1+,以及当前最新版本2.0,滴滴,抓紧上车! 前言 由于业务需求,最近跟人脸识别杠上了,本以为虹软提供的SDK是那种面向开发语言的,结果是一堆dll· ...

  5. Java版 人脸识别SDK dem

    虹软人脸识别SDK之Java版,支持SDK 1.1+,以及2.0版本,滴滴,抓紧上车! 前言由于业务需求,最近跟人脸识别杠上了,本以为虹软提供的SDK是那种面向开发语言的,结果是一堆dll······ ...

  6. 人脸识别SDK小结

    Face++人脸识别 进入官网 Face++ 致力于研发世界最好的人脸技术,提供免费的API和SDK供企业和开发者调用,更有灵活的定制化服务满足不同需求.已有多家公司使用Face++技术服务,完成包括 ...

  7. 基于百度AI人脸识别技术的Demo

    编写demo之前首先浏览官方API:http://ai.baidu.com/docs#/Face-API/top 下面是源码: package com.examsafety.test; import ...

  8. 虹软人脸识别SDK在网络摄像头中的实际应用

    目前在人脸识别领域中,网络摄像头的使用很普遍,但接入网络摄像头和人脸识别SDK有一定门槛,在此篇中介绍过虹软人脸识别SDK的接入流程,本文着重介绍网络摄像头获取视频流并处理的流程(红色框内),以下内容 ...

  9. AI人脸识别SDK接入 — 参数优化篇(虹软)

    引言 使用了虹软公司免费的人脸识别算法,感觉还是很不错的,当然,如果是初次接触的话会对一些接口的参数有些疑问的.这里分享一下我对一些参数的验证结果(这里以windows版本为例,linux.andro ...

随机推荐

  1. 11 Java的方法 递归

    6.递归 A方法调用B方法,我们很容易理解! 递归就是:A方法调用A方法!就是自己调用自己 利用递归可以用简单的程序来解决一些复杂的问题. 它通常把一个大型复杂的问题层层转化为一个与原问题相似的规模较 ...

  2. 基于Drone+Gogs流水线-全面认识轻量级云原生CI引擎Drone

    1. 介绍 Drone by Harness 是一个基于Docker容器技术的可扩展的持续集成引擎,用于自动化测试.构建.发布.每个构建都在一个临时的Docker容器中执行,使开发人员能够完全控制其构 ...

  3. 使用数据库、Redis、ZK分别实现分布式锁!

    分布式锁三种实现方式: 基于数据库实现分布式锁: 基于缓存(Redis等)实现分布式锁: 基于Zookeeper实现分布式锁: 基于数据库实现分布式锁 悲观锁 利用select - where - f ...

  4. pycharm远程调试、开发(详细操作)

    如果仅是远程开发,新建 ssh Interpreter 并 apply tools -> deployment -> browser remote host 即可 1.服务器侧准备 准备调 ...

  5. 4月8日 python学习总结 模块与包

    一.包 #官网解释 Packages are a way of structuring Python's module namespace by using "dotted module n ...

  6. json.dumps参数之解

    宝藏参数,懂的都懂^-^ 说明:编译后print()打印内容,此内容以字符串紧凑输出,且无顺序,中文不可读..   应用:使用pycharm做接口测试时,print()打印出的接口下行,如下图:   ...

  7. 100行代码实现HarmonyOS“画图”应用,eTS开发走起!

    本期我们给大家带来的是"画图"应用开发者Rick的分享,希望能给你的HarmonyOS开发之旅带来启发~ 介绍 2021年的华为开发者大会(HDC2021)上,HarmonyOS ...

  8. 垃圾收集器G1和CMS ,以及老年代和新生代的比例设置

    首先 1.G1是包括年轻代和年老代的GC 2.CMS是年老代GC 3.二者在某些时候都需要FullGC(serial old GC)的辅助 ###CMS收集器:CMS(ConCurrent Mark ...

  9. java常见字节大小存储问题

    JAVA中默认的编码方式 转:http://blog.csdn.net/scyatcs/article/details/31356823 编码问题存在两个方面:JVM之内和JVM之外.1.Java文件 ...

  10. 转载:STL常用容器的底层数据结构实现

    转载至:https://blog.csdn.net/qq_28584889/article/details/88763090 vector :底层数据结构为数组,支持快速随机访问 list:底层数据结 ...