LEADTOOLS 入门教程: 使用 AWS Lambda 转换文档 - C# .NET Core

news2025/7/15 3:40:12

LEADTOOLS 是一个综合工具包的集合,用于将识别、文档、医疗、成像和多媒体技术整合到桌面、服务器、平板电脑、网络和移动解决方案中,是一项企业级文档自动化解决方案,有捕捉,OCR,OMR,表单识别和处理,PDF,打印捕获,归档,注释和显示功能。利用业界领先的图像处理技术,能够智能识别文件,可以用来识别任何类型的扫描或传真形式的图像。

LEADTOOLS 最新下载https://www.evget.com/product/782/download

本教程展示了如何配置和运行 .NET Core 文档服务。

概括本教程介绍如何设置 AWS Lambda 以与 LEADTOOLS SDK 一起使用以及如何使用 .NET Core 转换文档。
完成时间60分钟
平台下载教程项目 (774 KB)
IDEVisual Studio 2019、2022、AWS Lambda Visual Studio 扩展
开发许可证下载 LEADTOOLS

在学习从 LEADDocument中添加和删除页面 - C# .NET Core 教程之前,通过查看添加引用和设置许可教程来熟悉创建项目的基本步骤。

完成 Visual Studio 的 AWS 设置;

要设置开发环境以在 Visual Studio 中使用 AWS,请完成来自 Amazon 的以下 2 个教程:

  • 在 AWS Toolkit for Visual Studio 中使用 AWS Lambda 模板
  • 在 AWS Toolkit for Visual Studio 中使用 AWS Lambda 项目

完成这些教程后,应安装适用于 Visual Studio 的 AWS 工具包,并基本了解如何为 .NET Core 创建新的 AWS Lambda 项目并发布到 AWS。

创建一个空函数

在 Visual Studio 中,创建一个新的AWS Lambda 项目(.NET Core - C#)项目。为项目命名和位置,然后单击创建

选择一个空函数并单击确定

添加 LEADTOOLS 参考

所需的参考取决于项目的目的。对于这个项目,需要以下 NuGet 包:

  • Leadtools.Document.Sdk

在解决方案资源管理器中右键单击 C# 项目,然后选择管理 NuGet 包...。

浏览LEADTOOLS,然后选择Leadtools.Document.SdkNuGet 包并安装它。接受 LEAD 的最终用户许可协议。

有关特定格式所需的编解码器 DLL 的完整列表,请参阅文件格式支持。

添加 LEADRequest.cs 类

右键单击 C# 项目并选择Add,然后选择Class。为其命名LEADRequest.cs并单击添加

将以下内容添加到using块中:

【C#】

using Leadtools.Document.Writer;

【C#】

public class LEADRequest
{
public string InputUrl { get; set; }
public DocumentFormat DocumentFormat { get; set; }
public LEADRequest()
{
}
}

添加 LEADLambdaHandler 类

右键单击 C# 项目并选择Add,然后选择Class。为其命名LEADLambdaHandler.cs并单击添加。

在新类中,将以下内容添加到using块中:

【C#】

using System;
using System.Diagnostics;
using System.IO;
using System.Net.Http;
using Amazon.Lambda.Core;
using Leadtools;
using Leadtools.Document;
using Leadtools.Document.Converter;
using Leadtools.Document.Writer;
using Leadtools.Ocr;

复制下面的代码以将所需的功能添加到类中:

【C#】

public class LEADLambdaHandler
{
// Global Variables
IOcrEngine ocrEngine;
DocumentConverter documentConverter;
static HttpClient httpClient = new HttpClient();

// Constructor which handles all initialization to make sure the function is as fast as possible once it is warmed up
public LEADLambdaHandler()
{
InitEnvironment();

Platform.LibraryPath = "/opt/native-runtimes/";

InitLEADTOOLS();
}

// Method which initializes the Lambda environment for use by the LEADTOOLS SDK
void InitEnvironment()
{
// Set the LD_LIBRARY_PATH in function console to include:
// /var/lang/lib:/lib64:/usr/lib64:/var/runtime:/var/runtime/lib:/var/task:/var/task/lib:/opt/lib:/tmp

ExecuteBashCommand("ln -s /lib64/libdl.so.2 /tmp/libdl.so");
}

// Initialize the LEADTOOLS SDK Classes
void InitLEADTOOLS()
{
SetLicense();

RasterDefaults.TemporaryDirectory = "/tmp";

RasterDefaults.SetResourceDirectory(LEADResourceDirectory.Fonts, "/opt/ShadowFonts");

ocrEngine = OcrEngineManager.CreateEngine(OcrEngineType.LEAD);
ocrEngine.Startup(null, null, "/tmp", "/opt/OcrLEADRuntime");

documentConverter = new DocumentConverter();
documentConverter.SetOcrEngineInstance(ocrEngine, true);
}

// Helper method for executing shell scripts in the Lambda environment
string ExecuteBashCommand(string command)
{
command = command.Replace("\"", "\"\"");

var proc = new Process
{
StartInfo = new ProcessStartInfo
{
FileName = "/bin/bash",
Arguments = "-c \"" + command + "\"",
UseShellExecute = false,
RedirectStandardOutput = true,
CreateNoWindow = true
}
};

proc.Start();
proc.WaitForExit();

return proc.StandardOutput.ReadToEnd();
}

// Set license code TODO: Replace the licString and developerKey with a valid license and key
void SetLicense()
{
string licString = "[License]\n" + "License = <doc><ver>2.0</ver>`ADD LICENSE HERE`</doc>";
string developerKey = "ADD DEVELOPMENT KEY HERE";
byte[] licBytes = System.Text.Encoding.UTF8.GetBytes(licString);
RasterSupport.SetLicense(licBytes, developerKey);
}

// Main conversion function
public string ConvertDocument(LEADRequest request, StringWriter sw)
{
var isUrl = Uri.IsWellFormedUriString(request.InputUrl, UriKind.RelativeOrAbsolute);

if (isUrl)
{
var response = httpClient.GetAsync(request.InputUrl).Result;
if (response.IsSuccessStatusCode)
{
var stream = response.Content.ReadAsStreamAsync().Result;

using (var document = DocumentFactory.LoadFromStream(stream, new LoadDocumentOptions()))
{
string ext = DocumentWriter.GetFormatFileExtension(request.DocumentFormat);
string fileName = Path.Combine("/tmp", Path.ChangeExtension(Path.GetFileName(request.InputUrl), ext));
DocumentConverterJobData jobData = DocumentConverterJobs.CreateJobData(document, fileName, request.DocumentFormat);
DocumentConverterJob job = documentConverter.Jobs.CreateJob(jobData);
documentConverter.Jobs.RunJob(job);

if (job.Errors.Count > 0)
foreach (var error in job.Errors)
sw.WriteLine($"Error during conversion: {error.Error.Message} {error.Error.StackTrace}");
else
return fileName;
}
}
else
sw.WriteLine("Download of URL is not successful");
}
else
sw.WriteLine("Url is invalid.");

return null;
}
}

设置许可文件

许可证解锁项目所需的功能。它必须在调用任何工具包函数之前设置。有关详细信息,包括针对不同平台的教程,请参阅设置运行时许可证。

有两种类型的运行时许可证:

  • 评估许可证,在下载评估工具包时获得。它允许评估工具包。
  • 部署许可证。如果需要部署许可证文件和开发人员密钥,请参阅获取许可证。

笔记

添加 LEADTOOLS NuGet 和本地引用以及设置许可证在添加引用和设置许可证教程 中有更详细的介绍。

更新 FunctionHandler

当触发 AWS Lambda 函数时,将FunctionHandler调用该方法。Function函数首次启动时,将在此之前调用全局类中的所有内容。当容器处于warm状态时,它只会调用该FunctionHandler方法,直到执行上下文发生变化。

为了利用此功能,大部分初始化代码都在构造函数中完成,以便在容器处于LEADLambdaHandler状态时尽可能快地调用每个函数。

打开Function.cs作为项目一部分包含的文件,并将以下内容添加到using其余 using 语句下的块中。

【C#】

using System.IO;

将以下全局变量添加到Function类中:

【C#】

public LEADLambdaHandler LEADHandler = new LEADLambdaHandler();

将该方法替换为FunctionHandler以下方法以接受 aLEADRequest作为输入而不是字符串输入,然后调用该LEADHandler.ConvertDocument方法:

【C#】

public string FunctionHandler(LEADRequest request, ILambdaContext context)
{
StringWriter sw = new StringWriter();
try
{
string outputFile = LEADHandler.ConvertDocument(request, sw);

if (outputFile != null)
sw.WriteLine($"Successfully saved to {outputFile}.");
else
sw.WriteLine("Error occurred. Output file not saved.");
}
catch (Exception ex)
{
sw.WriteLine(ex.Message);
sw.WriteLine(ex.StackTrace);
if (ex.InnerException != null)
{
sw.WriteLine(ex.InnerException.Message);
sw.WriteLine(ex.InnerException.StackTrace);
}
}
return sw.ToString();
}

添加所有代码后,构建项目以确保一切都按预期工作。

收集所需的 Lambda 依赖项

笔记

如果需要,可以跳过此步骤。此项目中包含的 ZIP 已包含所需的 Lambda 依赖项。

LEADTOOLS SDK 需要在 Linux 机器上安装某些依赖项才能正常运行。有关完整列表,请参阅LEADTOOLS Linux 库和演示项目入门。

AWS Lambda 提供了一个包含相同 Linux 发行版的 Docker 镜像,以便在部署到 Lambda 之前测试功能。这也可用于安装所需的依赖项并创建部署包。这需要安装Docker Desktop

  • 打开 Windows PowerShell
  • 跑docker pull amazonlinux
  • 在主机上的某个位置创建本地卷,例如C:\temp\docker
  • 跑docker run -it -v C:\temp\docker:/var/task amazonlinux:latest
  • 使用以下 2 个命令在 VM 中安装 .NET Core 3.1:
    • rpm -Uvh https://packages.microsoft.com/config/centos/7/packages-microsoft-prod.rpm
    • yum -y install dotnet-sdk-3.1
  • 安装 LEADTOOLS 第 3 方依赖项:
    • yum -y install uuid-devel uuidd gcc gcc-c++ glibc-devel kernel-devel kernel-headers libX11 libXt libX11-devel libXt-devel sqlite sqlite-devel freetype fontconfig
  • 发布 Lambda 项目
    • 导航到之前创建的项目的位置
    • 在该位置打开CMDcsproj
    • 跑dotnet publish
  • 导航到发布文件夹并将文件复制<PROJECT-DIR>\bin\Debug\netcoreapp3.1\publish\runtimes\linux-x64\nativeassets\netcoreapp到C:\temp\docker
  • 在该C:\temp\docker目录中,创建一个新的文本文件并复制并粘贴以下 shell 脚本并将其另存为CopyDeps.sh:
indir="/var/task/"
outdir="/var/task/lib/"
ldcache=$(ldconfig -p)

mkdir -p $outdir

for i in $(ls ${indir}/*.so); do
deps=$(ldd $i | grep "=>" | grep -v "liblt")

while IFS= read -r line; do
result=""
list=( $line )

dep=$(echo $ldcache | grep "${list[0]}")

if [ ! -z "$dep" ] ; then
cp -vL "${list[2]}" $outdir 2> /dev/null
fi

done <<< "$deps"
done
  • 运行 shell 脚本以创建具有所需依赖项的 lib 文件夹:sh /var/task/CopyDeps.sh
  • shell 脚本完成后,在主机上转到C:\temp\docker\lib这将包含所有依赖项
  • 删除以下内容,因为它们已安装在 Lambda 环境中:
    • liddl.so.2
    • libexpat.so.1
    • libz.so.1

创建 Lambda 层

LEADTOOLS SDK 需要在 Lambda 函数中安装环境依赖项。为了保持包的小和灵活,使用了 Lambda 层。有关层是什么的更多信息,请参阅AWS Lambda 层。

LEADTOOLS SDK OCR 引擎需要依赖项包含在任何 OCR 部署中。有关所需内容的更多信息,请参见LEADTOOLS OCR 模块 - LEAD 引擎运行时文件。

由于需要 AWS Lambda 环境,因此还需要 Shadow Fonts。有关 Shadow Fonts 的更多信息,请访问LEADTOOLS Drawing Engine and Multi-Platform Consideration。

  • 创建一个名为的新文件夹lead-deps-layer
  • 将lib文件夹从复制C:\temp\docker\lib到lead-deps-layer
  • lead-deps-layer在命名中创建一个新文件夹native-runtimes
  • 发布 Lambda 项目
    • 导航到之前创建的项目的位置
    • 在该位置打开CMDcsproj
    • 跑dotnet publish
  • 转到发布文件夹的 linux 本机依赖项<PROJECT-DIR>\bin\Debug\netcoreapp3.1\publish\runtimes\linux-x64\nativeassets\netcoreapp\
  • 将所有.so文件复制到lead-deps-layer\native-runtimes文件夹
  • 将C:\temp\docker\lib文件夹复制到lead-deps-layer
  • 将ShadowFonts文件夹从复制<INSTALL_DIR>\LEADTOOLS22\Bin\Common\ShadowFonts到lead-deps-layer
  • 将OcrLEADRuntime文件夹从复制<INSTALL_DIR>\LEADTOOLS22\Bin\Common\OcrLEADRuntime到lead-deps-layer
    • 此文件夹包含 LEADTOOLS 支持的各种 OCR 语言的字典和拼写检查引擎。如果只需要某些语言,请删除不需要的语言以最小化文件夹大小。有关语言文件的更多信息,请参见LEADTOOLS OCR 模块 - LEAD 引擎运行时文件
  • 文件夹中现在应该有 4 个子目录lead-deps-layer:lib、native-runtimes、ShadowFonts和OcrLEADRuntime
  • 压缩lead-deps-layer文件夹的内容。确保 ziplead-deps-layer.zip不包含同名的子文件夹,并且 zip 结构类似于以下屏幕截图:

上传图层 Zip 文件

创建层 zip 后,需要将其上传到 AWS Lambda。

  • 导航到AWS Lambda 控制台并登录
  • 在左侧面板上,选择图层
  • 在主窗口中,选择创建图层
  • 第一个上传的将是lead-deps-layer
    • 命名图层lead-deps-layer
    • 给它一个描述
    • 点击上传并选择lead-deps-layer.zip
    • 运行时下拉列表中,选择.NET Core 3.1 (C#/PowerShell)
    • 单击创建以创建图层

将 Lambda 函数发布到 AWS

该层完成后,现在可以将函数发布到 AWS。

  • 打开之前在 Visual Studio 中创建的 Lambda 项目。
  • 右键单击项目名称并选择发布到 AWS Lambda
    • 如果这是第一次发布 Lambda,则需要将帐户配置文件与 AWS 的访问密钥一起使用。有关这方面的更多信息,请参阅管理 IAM 用户的访问密钥
  • 选择要使用的帐户资料地区
  • 确保语言运行时设置为.NET Core v3.1
  • 填写Function Name,点击Next
  • 将内存 (MB)更改为 2048
  • 从下拉列表中选择角色名称,然后单击上传

这将dotnet publish在项目上运行,然后压缩文件和依赖项并将其上传到 Lambda。

减小封装尺寸

在上一步中创建的包会很大,因为它包含许多添加到层的依赖项。为了减小体积,zip 包将需要修改并手动上传到 Lambda。

  • 进入<PROJECT-DIR>\bin\Release\netcoreapp3.1\publish目录
  • 删除LEADTOOLS包含已添加到的 OCRRuntimes 的文件夹lead-deps-layer
  • <function-name>.zip将发布目录的内容压缩到一个名为覆盖自动创建的 zip 文件中
  • 导航回AWS Lambda 控制台并登录
  • 在左侧面板上,选择功能
  • 选择<function-name>打开功能
  • 在函数的配置中,在函数代码部分下,选择上传以上传缩小尺寸的 zip
  • 从中选择 zip <PROJECT-DIR>\bin\Release\netcoreapp3.1\publish\<function-name>.zip,点击确定,然后点击右上角的保存

这将更新功能包,使其尽可能小。

更改设置

上传包后,LD_LIBRARY_PATH需要更新函数的环境变量以正确加载依赖项。

  • 在控制台的功能页面中,向下滚动到环境变量部分
  • 单击管理环境变量以打开编辑环境变量屏幕
  • 点击添加环境变量
  • 对于,输入LD_LIBRARY_PATH和输入 
  • /var/lang/lib:/lib64:/usr/lib64:/var/runtime:/var/runtime/lib:/var/task:/var/task/lib:/opt/lib:/tmp
  • 单击保存以保存这些更改

设置环境变量后,需要将层添加到函数中。

  • 在控制台的功能页面,展开Designer
  • 选择图层
  • 在底部现在打开的图层部分中,选择添加图层
  • 选择从运行时兼容层列表中选择单选按钮
  • 名称下拉列表中,选择lead-deps-layer
  • 版本下拉列表中,选择最新的版本号
  • 单击添加将此图层添加到函数中

确保函数的内存设置为 2048 MB:

  • 在控制台的功能页面中,向下滚动到基本设置部分
  • 单击编辑
  • 内存 (MB)滑块拖动到2048 MB
  • 单击保存以保存更改

测试功能

完成上一步后,该功能就可以进行测试了。

  • 在控制台的功能页面,选择右上角的 测试
    • 这将打开配置测试事件对话框
  • 选择hello-world 活动模板
  • 填写活动名称
{
"InputUrl": "https://demo.leadtools.com/images/tiff/ocr1.tif",
"DocumentFormat": 1
}
  • 单击创建以创建测试事件

如果一切设置正确,执行结果应该返回succeeded并类似于:

以上便是 使用 AWS Lambda 转换文档 ,如果您还有其他疑问,欢迎咨询我们或者加入我们官方技术交流群。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/8795.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

SSM框架真没那么难,这份阿里大佬的进阶实战笔记真给讲透了!

SSM框架&#xff1a; SSM框架是spring MVC &#xff0c;spring和mybatis框架的整合&#xff0c;是标准的MVC模式&#xff0c;将整个系统划分为表现层&#xff0c;controller层&#xff0c;service层&#xff0c;DAO层四层 使用spring MVC负责请求的转发和视图管理 spring实现…

Docker学习笔记

1.docker比vm快的原因: docker有着比虚拟机更少的抽象层,不需要实现硬件资源的虚拟化运行,运行在docker上的程序使用的都是物理机的资源. dicker利用的是宿主机的内核,不需要加载操作系统的os内核. 2.docker帮助文档docker help 具体到某一个命令是使用 docker run --help即可…

【JMeter】Jmeter分布式压测教程

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录一、原理二、环境搭建2.1 环境准备2.2 slave机器配置2.3 master机器配置三、脚本及执行3.1 参数化问题3.2 GUI启动测试3.3 命令行启动测试总结一、原理 Jmeter分布式…

【深入理解Kotlin协程】CoroutineScope.launch源码追踪扒皮

lifecycleScope、viewModelScope、GlobalScope、MainScope的上下文 协程最重要的就是协程上下文对象&#xff0c;因为通过上下文可以获取到协程相关的任何东西(Job、Dispatcher、Interceptor、Name、ExceptionHandler)&#xff0c;所以有必要了解清楚常用的协程作用域对象中cor…

asp.net+sqlserver汽车4s店销售网站系统c#项目

数据项 管理员信息表&#xff5b;用户编号&#xff0c;用户名称&#xff0c;用户密码&#xff5d; 新闻信息表&#xff5b;编号&#xff0c;标题&#xff0c;内容&#xff0c;添加时间&#xff5d; 汽车信息表&#xff5b;编号&#xff0c;汽车名称&#xff0c;汽车价格&#x…

制造业行业现状及智能生产管理系统一体化解决方案

前言&#xff1a; 《中国制造2025》作为我国实施制造强国战略第一个十年的行动纲领。它重点提出了坚持&#xff1a;创新驱动、质量为先、绿色发展、结构优化、人才为本的基本方针。坚持&#xff1a;市场主导、政策引导&#xff0c;立足当前、着眼长远&#xff0c;整体推进、重…

Selenium实现原理

Selenium 是目前主流的用于Web应用程序测试的工具&#xff0c;可以直接运行在浏览器中&#xff0c;就像真正的用户在操作一样。 selenium的实现原理是这样的&#xff1a; 1.运行代码&#xff0c;启动浏览器后&#xff0c;webdriver会将浏览器绑定到特定端口&#xff0c;作为we…

[go学习笔记.第十五章.反射] 1.反射的基本介绍以及实践

一.反射的引入以及基本介绍 1.看两个问题 (1).对于结构体的序列化和反序列化&#xff0c;看一段代码 package mainimport("fmt" "encoding/josn" )type Monster struct {Name string json:"monsterName"Age int json:"monsterAge&quo…

deque容器(20221115)

1、基本概念 功能&#xff1a;双端数组&#xff0c;可以对头端进行插入删除元素 deque与vector的区别&#xff1a; vector对应头部的插入删除效率低&#xff0c;数据量越大&#xff0c;效率越低 deque对头部的插入删除速度比vector快 vector访问元素速度比deque快 deque内…

sanic 教程

sanic 教程 在Sanic的生命周期流程大致如下&#xff1a; http请求——Sanic解析request——匹配路由——请求中间件——视图函数——响应中间件——http响应 依赖库 sanic21.3.4 sanic-jwt1.7.0 sanic-openapi21.12.0 gunicorn20.1.0 PyMySQL1.0.2 aiomysql0.1.1 DBUtils1.3…

WPS(WSC)中M1 到M8 图解

背景 之前实习的时候就学了Wifi p2p相关的东西&#xff0c;当时找M1到M8的功能把我累惨了&#xff0c;找到的还全是千篇一律的东西&#xff0c;讲的不是很清楚&#xff08;当然原版出书的那个前辈肯定是懂的&#xff09;&#xff0c;但是对我等小白不友好&#xff0c;就萌生了这…

3.线性代数-矩阵

矩阵和Tensor1. Tensor2.矩阵3.线性代数正确打开方式3.1 行视图3.2 列视图4.线性相关和线性无关5. Span、基和子空间(Subspace)6.四个基本的子空间6.1 列空间6.2 零空间6.3 行空间6.4 左零空间6.5 四个基本子空间的关系7.可逆矩阵8.方阵的特征值与特征向量9.特征分解9.1一般矩阵…

【Pytorch with fastai】第 7 章 :训练SOTA的模型

&#x1f50e;大家好&#xff0c;我是Sonhhxg_柒&#xff0c;希望你看完之后&#xff0c;能对你有所帮助&#xff0c;不足请指正&#xff01;共同学习交流&#x1f50e; &#x1f4dd;个人主页&#xff0d;Sonhhxg_柒的博客_CSDN博客 &#x1f4c3; &#x1f381;欢迎各位→点赞…

Nginx优化方案

目录 一、Nginx返回错误页面 1、HTTP常见状态代码列表 二、Nginx状态页面 1、安装status模块 2、激活status 三、优化并发连接数 1、压力测试软件ab&#xff08;http-tools&#xff09; 2、优化并发连接数 2.1、修改nginx并发数 2.2、修改内核最大文件数量 四、Nginx…

吉莱斯皮随机模拟算法(SSA)(Matlab代码实现)

&#x1f468;‍&#x1f393;个人主页&#xff1a;研学社的博客 &#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜…

【K8S系列】第十讲:Knative 简介

目录 一、 Serverless介绍 二、Knative 介绍 2.1 Knative 的定位 2.2 Knative的组成 2.2.1 Build 构建系统 2.2.2 Serving&#xff1a;服务系统 2.2.3 Eventing&#xff1a;事件系统 补充&#xff1a; 三、总结&#xff1a; 一、 Serverless介绍 在讲Knative之前&a…

【毕业设计】机器视觉手势检测和识别系统 - python 深度学习

文章目录0 前言1 实现效果2 技术原理2.1 手部检测2.1.1 基于肤色空间的手势检测方法2.1.2 基于运动的手势检测方法2.1.3 基于边缘的手势检测方法2.1.4 基于模板的手势检测方法2.1.5 基于机器学习的手势检测方法3 手部识别3.1 SSD网络3.2 数据集3.3 最终改进的网络结构4 最后0 前…

线程池源码解析 2.工作原理与内部结构

线程池源码解析—工作原理与内部结构 工作原理 概述 线程池是线程的池子&#xff0c;本质上是通过单个线程执行多个并发任务&#xff0c;使得尽量少的创建线程&#xff0c;减少开销。在线程池内部&#xff0c;是没有区分核心线程和非核心线程的&#xff0c;是通过 Set 集合的…

拒绝内卷,阿里架构师整理的这份Java核心手册,堪称最强

2022年注定是不寻常的一年&#xff0c;在今年因为疫情以及各大大厂纷纷传来裁员的消息&#xff0c;引得整个互联网圈动荡不堪。腾讯裁员30%、京东、百度、字节等大厂都在纷纷裁员&#xff0c;引的这些中厂和小厂也跟风裁员。 这个时候外部的各种变化愈发证明一个重要的一点&am…

2022.11.7-11.13 AI行业周刊(第123期):技术人员的职业发展在哪里?

篇章一&#xff1a;技术人员的职业发展 上周和大学时的舍友聊天&#xff0c;交流当前大家的生活状态。 我们已经本科毕业将近10年了&#xff0c;他目前也有两个孩子&#xff0c;在湖北的一个地级市中&#xff0c;从事的是通信行业。 不过随着工作的时间越久&#xff0c;他发…