2024年11月

需求介绍

很多用户使用了
SpreadJS
的数据填报功能。大致用法为:设计模板,填充数据源。在这个过程中,可能会出现模板中设置了公式,而在数据源填充时,公式没有携带下来的问题。

比如我们定义一个模板:

接下来使用setDataSpurce()填充数据源,填充后,发现只有一行有公式值,其他行无数据

那么,我们该做一些什么操作呢?或者有哪些方案呢?
目前有四种方案,分别
fillAuto

copyTo

clipboardPaste

setColumnDataFormula

我们分别看一下这四种方案的具体使用用法及性能。

我们先获取下table区域,定义baseRow ,baseCol

 let row = table.range().row
        let baseRow = row + 1;
        let baseCol = 4
        let rowCount = 0

然后在setDataSource后,修改rowCount值

        document.getElementById('btn6').addEventListener('click', function () {
            sheet.setDataSource(new GC.Spread.Sheets.Bindings.CellBindingSource(data2))
            rowCount = table.range().rowCount
        })

一、方案

1、fillAuto

let start = new GC.Spread.Sheets.Range(baseRow, baseCol, 1, 1)
            let end = new GC.Spread.Sheets.Range(baseRow, baseCol, rowCount - 1, 1)
            sheet.fillAuto(start, end, {
                fillType: GC.Spread.Sheets.Fill.FillType.auto,
                series: 0,
                direction: GC.Spread.Sheets.Fill.FillDirection.down
            });

2、copyTo

 for (let r = baseRow + 1; r < row + rowCount; r++) {
                sheet.copyTo(baseRow, baseCol, r, baseCol, 1, 1, GC.Spread.Sheets.CopyToOptions.formula)
            }

3、clipboardPaste

 let fromRanges = [new GC.Spread.Sheets.Range(baseRow, baseCol, 1, 1)]
            let pastedRanges = [new GC.Spread.Sheets.Range(baseRow + 1, baseCol, rowCount - 2, 1)]
            spread.commandManager().execute({
                cmd: "clipboardPaste",
                sheetName: sheet.name(),
                fromSheet: sheet,
                fromRanges,
                pastedRanges,
                isCutting: false,
                clipboardText: "",
                pasteOption: GC.Spread.Sheets.ClipboardPasteOptions.formulas
            });

4、setColumnDataFormula

table.setColumnDataFormula(baseCol, sheet.getFormula(baseRow, baseCol));

上述四种方案均能实现公式填充,结果如下:

二、性能对比

1、100条
那么,我们接下来看下这四种方案的性能吧,首先我们设置100条数据源,

 let sales = [], dataLength = 100
        for (let i = 0; i < dataLength; i++) {
            sales.push({orderDate: '1/6/2013', item: 'book', units: '95', quantity: 1.99})
        }
        sheet.setRowCount(dataLength + 1)

然后设置一个按钮,在每一种方案执行后,用来清除数据。

  document.getElementById('btn5').addEventListener('click', function () {
            sheet.clear(2, 4, sheet.getRowCount(), 1,GC.Spread.Sheets.SheetArea.viewport,GC.Spread.Sheets.StorageType.data);
        })

结果如下:

100条数据的情况下,四种方案的性能都相差不大。

2、1000条
接下来,我们设置10000条数据,将dataLength 改为1000
结果如下:

3、10000条
接下来,我们设置10000条数据,将dataLength 改为10000
结果如下:

观察上图,我们发现setColumnDataFormula与clipboardPaste性能较好,而fillAuto性能最差。

4、10000条
我们接下来将数据量改为
10万
条数据,观察setColumnDataFormula与clipboardPaste性能

汇总以下这些数据:

总结

由上面的内容可以看出,在数据量不大的情况下,四种方式差不多,但在数据量较大的情况下,建议使用setColumnDataFormula方式填充公式。

扩展链接:

【干货放送】财务报表勾稽分析要点,一文读尽!

为什么你的财务报表不出色?推荐你了解这四个设计要点和!

纯前端类 Excel 表格控件在报表勾稽分析领域的应用场景解析

本文是对公开论文的核心提炼,而非直接翻译,旨在进行学术交流。如有任何侵权问题,请及时联系号主以便删除。

来源:晓飞的算法工程笔记 公众号,转载请注明出处

论文: Can OOD Object Detectors Learn from Foundation Models?

创新点


  • 研究并发掘在大规模开放集数据上训练的文本到图像生成模型在目标检测任务中合成
    OOD
    对象的潜力。
  • 引入一种自动化的数据整理过程以获取可控的、带注释的场景级合成
    OOD
    图像,用于
    OOD
    目标检测。该过程利用大型语言模型(
    LLMs
    )进行新对象发现,并使用视觉基础模型进行数据注释和过滤。
  • 发现在保持
    ID
    /
    OOD
    图像上下文的一致性以及获得更准确的
    OOD
    注释边界框,对合成数据在
    OOD
    目标检测中的有效性至关重要。
  • 在多个基准上的全面实验证明了该方法的有效性,在使用最少合成数据的情况下显著超越了现有的最先进方法。

内容概述


分布外(
OOD
)目标检测是一项具有挑战性的任务,因为缺乏开放集的
OOD
数据。受到近期在文本到图像生成模型方面的进展的启发,例如
Stable Diffusion
,论文研究了基于大规模开放集数据训练的生成模型合成
OOD
样本的潜力,从而增强
OOD
目标检测。

论文提出了
SyncOOD
,这是一种简单的数据策划方法。该方法利用大型基础模型的能力,从文本到图像的生成模型中自动提取有意义的
OOD
数据,使得模型能够访问包含在现成基础模型中的开放世界知识。合成的
OOD
样本随后被用于增强一个轻量级、即插即用的
OOD
检测器的训练,从而有效地优化了在分布内(
ID
)/
OOD
的决策边界。

在多个基准上进行的广泛实验表明,
SyncOOD
在性能上显著优于现有方法,凭借最少的合成数据使用,建立了新的最先进性能。

SyncOOD


异常合成管道包括两个部分:

  1. 合成一组有效的照片真实感场景级
    OOD
    图像
    \(\textbf{x}^{\text{edit}}\)
    ,记为
    \(\mathcal{D}_{\text{edit}} = \left\{(\textbf{x}^{\text{edit}}, \textbf{b}^{\text{edit}})\right\}\)
    ,该图像包含新颖对象及其相应的标注框
    \(\textbf{b}^{\text{edit}}\)
    ,这一过程基于从
    \(\mathcal{D}_{\text{id}}\)
    进行全自动化的区域级编辑。
  2. 选择和使用高效的合成数据,为训练
    OOD
    对象检测器提供伪
    OOD
    监督,与训练集中
    ID
    样本一起使用。

合成新语义对象

  • 从分布内对象想象新概念对象

如图 (a) 所示,基于训练集
\(\mathcal{D}_{\text{id}}\)
中的
ID
标签
\(\mathcal{Y}_{\text{id}}\)
,利用大型语言模型
LLM
(如
GPT-4
)广泛的知识和推理能力来检查视觉相似度和上下文兼容性,为每个
ID
对象标签设想了一组新颖对象,记为
\(\mathcal{Y}_{\text{novel}}\)
,同时保持了想象对象与
ID
对象之间的语义可分性。这能够关联
ID
对象,并通过使用包含上下文示例的提示来促进可能的新对象的概念化,以替换现有的
ID
对象。

  • 在指定区域内编辑对象

为了生成包含新概念
\(y_j \in \textbf{y}^{\text{novel}}_i\)
的新图像,选择替换现有图像中标签为
\(y_i^{\text{id}}\)
的现有
ID
对象,而不是寻找新的位置或从头生成图像。通过这样做,可以确保上下文兼容性,并消除场景上下文中的干扰,因为上下文得以保留。

如图 (b) 所示,使用稳定扩散修复(
Stable-Diffusion-Inpainting
)对
ID
图像进行区域级编辑,得到包含新对象的编辑图像
\(\textbf{x}^{\text{edit}}\)
为:

\[\begin{equation}
\textbf{x}^{\text{edit}}=\text{SDI}(\textbf{x}^{\text{id}},\textbf{b}^{\text{id}},\textbf{y}^{\text{novel}}).
\label{eq:sdi}
\end{equation}
\]

  • 细化新对象的注释框

由于扩散模型中的随机性,编辑对象的属性,如质量、体积和定位,可能与原始对象框不匹配。为了解决这个问题,如图 (c) 所示,设计一个基于
SAM
的高效、有效的细化器,以获取新对象的精确边界框。

使用从
\(\textbf{b}^{\text{id}}\)
扩展出的填充区域作为提示,并使用
SAM
输出该区域中新对象的最高置信度实例掩码
\(\textbf{m}^{\text{SAM}}\)

\[\begin{equation}
\textbf{m}^{\text{SAM}}=\text{SAM}(\textbf{x}^{\text{edit}};\text{padding}(\textbf{b}^{\text{id}}, e)),
\label{eq:sam}
\end{equation}
\]

将获得的掩码
\(\textbf{m}^{\text{SAM}}\)
转换为边界框
\(\textbf{b}^{\text{SAM}}\)
,并计算
\(\textbf{b}^{\text{SAM}}\)
与相应的
\(\textbf{b}^{\text{id}}\)
之间的交并比(
IoU
),以过滤出在尺度上变化较大的新对象:

\[\begin{equation}
\left\{\textbf{b}^{\text{edit}}\right\}=\left\{\left.\textbf{b}^{\text{SAM}}\middle|\right.\text{IoU}(\textbf{b}^{\text{SAM}},\textbf{b}^{\text{id}})>\gamma\right\},
\label{eq:iou}
\end{equation}
\]

发掘难OOD样本以及模型训练

  • Mining Hard OOD Objects with High Visual Similarities for Training

最可能被目标检测器混淆为原始
ID
对象的新对象视为最有效。因此,基于预训练目标检测器的潜在空间中的成对相似性,寻找最容易被混淆为
ID
的合成
OOD
样本。

对于一个现成的目标检测器
\(\mathcal{F}_\text{det}\)
,为每一对提取潜在特征
\(\textbf{z}^{\text{edit}}\)

\(\textbf{z}^{\text{id}}\)
,根据相似性进行过滤,以提供伪
OOD
监督:

\[\begin{equation}
\textbf{z}^{\text{edit}},\textbf{z}^{\text{id}}=\mathcal{F}_\text{det}(\textbf{b}^{\text{edit}};\textbf{x}^{\text{edit}}),\mathcal{F}_\text{det}(\textbf{b}^{\text{id}};\textbf{x}^{\text{id}}).
\label{eq:extract}
\end{equation}
\]

\[\begin{equation}
\left\{\textbf{z}^{\text{ood}}\right\}=\left\{\left.\textbf{z}^{\text{edit}}\middle|\right.\epsilon_{\textit{low}}<\text{sim}(\textbf{z}^{\text{edit}},\textbf{z}^{\text{id}})<\epsilon_{\textit{up}}\right\},
\label{eq:sim}
\end{equation}
\]

  • 通过合成样本优化
    ID
    /
    OOD
    决策边界

一旦获得了
ID
和合成
OOD
对象,使用一个轻量级的多层感知器(
MLP

\(\mathcal{F}_\text{ood}\)
,作为经过二分类损失优化的
OOD
检测器参与训练:

\[\begin{equation}
\mathcal{L}_\text{ood}=\mathbb{E} _{\textbf{z}\sim\textbf{z}^{\text{id}}}\left[-\log\frac{1}{1 + \exp^{-\mathcal{F}_\text{ood}(\textbf{z})}}\right]+\mathbb{E} _{\textbf{z}\sim\textbf{z}^{\text{ood}}}\left[-\log\frac{\exp^{-\mathcal{F}_\text{ood}(\textbf{z})}}{1+\exp^{-\mathcal{F}_\text{ood}(\textbf{z})}} \right].
\label{eq:optim}
\end{equation}
\]

主要实验




如果本文对你有帮助,麻烦点个赞或在看呗~
更多内容请关注 微信公众号【晓飞的算法工程笔记】

work-life balance.

1、引言

在当今的互联网时代,API(应用程序编程接口)已经成为连接不同软件系统的桥梁。作为一名开发者,掌握API测试技能至关重要。市面上的API测试工具琳琅满目,今天我们要介绍的是一款开源、跨平台的API测试工具——
Insomnia

2、Insomnia介绍

Insomnia
是一款功能丰富、易使用、强大且开源的API测试工具,广泛应用于API的开发、测试与调试。它以其简洁的界面、强大的功能和免费的开源协议赢得了众多开发者和测试人员的青睐。Insomnia不仅支持HTTP、HTTPS、REST等多种请求类型,还扩展了对GraphQL、gRPC、SOAP和WebSockets等协议的支持,使其成为一个多功能的API测试工具。通过一系列强大的功能简化了API的设计和测试流程。

3、Insomnia特点与优势

Insomnia
不仅仅是一个API测试工具,它是一个功能齐全的IDE(集成开发环境),用于设计、测试、调试和管理API。作为一个强大的开源工具,Insomnia拥有众多特点和优势,使其在开发者中获得了极大的认可和流行。

1. 开源与跨平台特性

Insomnia作为一款开源工具,‌坚持开源协议,‌用户可以在任何地方免费使用。‌它支持Windows、‌macOS和Linux等多个操作系统,‌这意味着开发者可以在自己熟悉的平台上进行API测试,‌无需担心平台兼容性问题。‌Insomnia的跨平台特性极大地提升了其适用性和灵活性。‌

2. 直观易用的用户界面

Insomnia提供了简洁直观的用户界面,‌无论是前端开发、‌后端开发还是测试人员,‌都能快速上手。‌界面清晰明了,‌使得用户可以轻松创建和管理多个API请求。‌通过直观的界面,‌用户可以设置请求方法(‌如GET、‌POST、‌PUT、‌DELETE等)‌、‌输入URL、‌添加请求头和参数,‌并发送请求查看响应结果。‌

3. 强大的功能支持

Insomnia不仅支持多种HTTP请求方法和请求头设置,‌还提供了丰富的测试和调试功能。‌例如,‌它支持环境变量和模板标签,‌允许在不同环境之间共享参数和动态生成请求数据。‌这对于在开发、‌测试和生产环境之间切换非常有用。‌此外,‌Insomnia还记录了请求和响应历史,‌方便用户查看以前的交互,‌这对于排查问题和理解API行为非常有帮助。‌

4. 团队协作与版本控制

在团队协作方面,‌Insomnia支持通过Git进行版本控制,‌方便多人共同管理和测试API。‌用户可以导出请求、‌环境变量和设置,‌或从文件导入,‌以便与团队共享或备份。‌这种灵活的协作方式极大地提升了团队的工作效率和协作能力。‌

5. 插件生态系统

Insomnia的一个显著特点是其强大的插件系统。‌通过插件,‌用户可以扩展和定制Insomnia的功能,‌以满足个性化的需求。‌Insomnia官方提供了一个插件市场Plugin Hub,‌发布官方和社区开发的各种插件。‌这些插件可以增加新的功能、‌集成第三方服务或改进用户界面。‌例如,‌通过插件,‌用户可以实现自动同步、‌Swagger导入、‌数据格式转换等高级功能。‌

4、Insomnia适用场景

Insomnia
作为一款强大的开源工具,适用于API的开发、测试与调试领域。其跨平台、直观易用的特性,使得它在多种场景下都能发挥重要作用。以下是Insomnia的主要适用场景:

1. 开发者个人使用

对于独立开发者而言,Insomnia提供了一个轻量级且高效的解决方案来测试和调试他们的RESTful API。无需安装复杂的集成开发环境(IDE)或额外的插件,Insomnia就能满足基本到高级的API测试需求。

2. 开发团队协作

在开发团队中,Insomnia支持导出和导入请求集合,这极大地方便了团队成员之间的共享和协作。团队成员可以轻松地共享API请求、测试案例和测试结果,从而提高整体的开发效率和测试质量。

3. API文档生成与验证

Insomnia不仅限于测试和调试API,它还能与Swagger等API文档工具集成,自动生成API文档。这对于需要频繁更新和维护API文档的项目来说,无疑是一个巨大的便利。同时,Insomnia的测试结果也可以作为API文档的一部分,帮助验证API的准确性和可靠性。

4. 自动化测试

虽然Insomnia本身并不直接提供自动化测试的功能,但它可以与持续集成/持续部署(CI/CD)流程结合使用。通过编写脚本或利用Insomnia提供的插件和扩展,开发者可以自动化地运行API测试,并在每次代码提交时验证API的功能和性能。

5. 学习和教育

对于初学者和教育工作者来说,Insomnia也是一个理想的工具。它提供了直观的用户界面和易于理解的文档,帮助学习者快速上手API开发和测试。同时,Insomnia的开源特性也使得它成为了一个学习和研究API测试技术的绝佳平台。

5、安装

Mac安装:

brew install --cask insomnia

Windows安装:

访问链接:
https://insomnia.rest/download
下载即可
在这里插入图片描述

更多安装方式可见:
https://docs.insomnia.rest/insomnia/install

6、小结

Insomnia是一款功能强大、易用性强的开源API测试工具,适用于各种API测试场景。掌握Insomnia的使用方法,有助于提高开发者工作效率,确保API质量。如果您还在为选择API测试工具而犹豫,不妨试试Insomnia,相信它会成为您开发过程中的得力助手。

参考文献:

  • Insomnia官方文档

    https://docs.insomnia.rest/

  • GitHub insomnia

    https://github.com/Kong/insomnia

前言

.NET 生态中有哪些值得推荐的网络通信框架?今天,给大家推荐一个非常优秀的开源项目——NetCoreServer。

NetCoreServer 是一款 .NET 开源、免费、快速且低延迟的异步套接字服务器和客户端库。无论是需要搭建高性能的服务端应用,还是开发高效的客户端程序,NetCoreServer 都能提供强大的支持。

项目介绍

NetCoreServer 是一个高性能、跨平台的异步套接字服务器和客户端库。

它支持多种传输协议,包括 TCP、SSL、UDP、HTTP、HTTPS 和 WebSocket,提供了丰富的网络通信功能。

该库的设计初衷是解决高并发和低延迟的网络通信需求,采用了异步通信模型,能够高效处理大量连接和数据传输。

提供了丰富的示例包括 TCP 聊天服务器、SSL 聊天服务器和 UDP 回显服务器等多种应用场景。

项目特性

  • 跨平台:支持 Linux、macOS 和 Windows。
  • 异步通信:利用异步编程模式提高性能和响应性。
  • 多协议支持:支持 TCP、SSL、UDP、HTTP、HTTPS 和 WebSocket 协议。
  • 高性能:专为高性能通信设计,通过减少不必要的内存分配和 CPU 占用,以及优化网络 I/O 操作来提高性能。
  • 详细文档和示例:提供详细的文档和丰富的示例代码,帮助大家快速上手。

项目组件

  • TcpServer/TcpClient:用于处理 TCP 连接。
  • SslServer/SslClient:提供 SSL/TLS 加密的 TCP 连接。
  • UdpServer/UdpClient:支持 UDP 数据报传输。
  • WsServer/WsClient:支持 WebSocket 通信。
  • WssServer/WssClient:支持安全的 WebSocket(WebSocket Secure)通信。
  • UdsServer/UdsClient:支持 Unix Domain Socket 通信(仅限 Unix/Linux 系统)。
  • HttpServer/HttpClient:提供 HTTP 和 HTTPS 服务器的实现,支持静态内容服务和自定义请求处理。

项目环境

  • 操作系统:Linux、macOS、Windows
  • 开发环境:.NET 6.0、7-Zip、CMake、Git、Visual Studio

项目示例

  • TCP 聊天服务器、聊天客户端
  • SSL 聊天服务器、聊天客户端
  • UDP 回显服务器、回显客户端
  • UDP 组播服务器、组播客户端
  • Unix Domain Socket 聊天服务器、聊天客户端
  • 简单协议
  • 简单协议服务器、简单协议客户端
  • HTTP/HTTPS服务器、客户端
  • WebSocket 聊天服务器、聊天客户端
  • WebSocket 安全聊天服务器、安全聊天客户端

性能测试

1、往返测试

  • TCP/SSL/UDP 回显服务器
  • Unix Domain Socket 回显服务器
  • 简单协议服务器
  • WebSocket 回显服务器/安全回显服务器

2、组播测试

  • TCP/SSL/UDP 组播服务器
  • Unix Domain Socket 组播服务器
  • WebSocket 组播服务器/安全组播服务器

3、Web 服务器测试

  • HTTP/HTTPS 跟踪服务器

项目使用

1、TCP 聊天服务器

它处理多个 TCP 客户端会话,并将从任何会话接收到的消息广播到所有会话。另外,还可以直接从服务器发送管理员消息。

namespaceTcpChatServer
{
classChatSession : TcpSession
{
public ChatSession(TcpServer server) : base(server) {}protected override voidOnConnected()
{
Console.WriteLine($
"Chat TCP session with Id {Id} connected!");//发送欢迎消息 string message = "Hello from TCP chat! Please send a message or '!' to disconnect the client!";
SendAsync(message);
}
protected override voidOnDisconnected()
{
Console.WriteLine($
"Chat TCP session with Id {Id} disconnected!");
}
protected override void OnReceived(byte[] buffer, long offset, longsize)
{
string message = Encoding.UTF8.GetString(buffer, (int)offset, (int)size);
Console.WriteLine(
"Incoming:" +message);//向所有已连接的会话广播消息 Server.Multicast(message);//如果接收到的消息为 '!',则断开当前会话 if (message == "!")
Disconnect();
}
protected override voidOnError(SocketError error)
{
Console.WriteLine($
"Chat TCP session caught an error with code {error}");
}
}
classChatServer : TcpServer
{
public ChatServer(IPAddress address, int port) : base(address, port) {}protected override TcpSession CreateSession() { return new ChatSession(this); }protected override voidOnError(SocketError error)
{
Console.WriteLine($
"Chat TCP server caught an error with code {error}");
}
}
classProgram
{
static void Main(string[] args)
{
//TCP 服务器端口 int port = 1111;if (args.Length > 0)
port
= int.Parse(args[0]);

Console.WriteLine($
"TCP 服务器端口: {port}");

Console.WriteLine();
//创建一个新的 TCP 聊天服务器 var server = newChatServer(IPAddress.Any, port);//启动服务器 Console.Write("服务器启动中...");
server.Start();
Console.WriteLine(
"完成!");

Console.WriteLine(
"按 Enter 停止服务器或输入 '!' 重启服务器...");//执行文本输入 for(;;)
{
string line =Console.ReadLine();if (string.IsNullOrEmpty(line))break;//重启服务器 if (line == "!")
{
Console.Write(
"服务器重启中...");
server.Restart();
Console.WriteLine(
"完成!");continue;
}
//向所有会话广播管理员消息 line = "(admin)" +line;
server.Multicast(line);
}
//停止服务器 Console.Write("服务器停止中...");
server.Stop();
Console.WriteLine(
"完成!");
}
}
}

2、TCP 聊天客户端

它连接到 TCP 聊天服务器,允许发送消息到服务器并接收新消息。

namespaceTcpChatClient
{
classChatClient : TcpClient
{
public ChatClient(string address, int port) : base(address, port) {}public voidDisconnectAndStop()
{
_stop
= true;
DisconnectAsync();
while(IsConnected)
Thread.Yield();
}
protected override voidOnConnected()
{
Console.WriteLine($
"Chat TCP client connected a new session with Id {Id}");
}
protected override voidOnDisconnected()
{
Console.WriteLine($
"Chat TCP client disconnected a session with Id {Id}");//等待一段时间... Thread.Sleep(1000);//尝试再次连接 if (!_stop)
ConnectAsync();
}
protected override void OnReceived(byte[] buffer, long offset, longsize)
{
Console.WriteLine(Encoding.UTF8.GetString(buffer, (
int)offset, (int)size));
}
protected override voidOnError(SocketError error)
{
Console.WriteLine($
"Chat TCP client caught an error with code {error}");
}
private bool_stop;
}
classProgram
{
static void Main(string[] args)
{
//TCP 服务器地址 string address = "127.0.0.1";if (args.Length > 0)
address
= args[0];//TCP 服务器端口 int port = 1111;if (args.Length > 1)
port
= int.Parse(args[1]);

Console.WriteLine($
"TCP server address: {address}");
Console.WriteLine($
"TCP server port: {port}");

Console.WriteLine();
//创建一个新的 TCP 聊天客户端 var client = newChatClient(address, port);//连接客户端 Console.Write("Client connecting...");
client.ConnectAsync();
Console.WriteLine(
"Done!");

Console.WriteLine(
"Press Enter to stop the client or '!' to reconnect the client...");//执行文本输入 for(;;)
{
string line =Console.ReadLine();if (string.IsNullOrEmpty(line))break;//断开客户端连接 if (line == "!")
{
Console.Write(
"Client disconnecting...");
client.DisconnectAsync();
Console.WriteLine(
"Done!");continue;
}
//将输入的文本发送到聊天服务器 client.SendAsync(line);
}
//断开客户端连接 Console.Write("Client disconnecting...");
client.DisconnectAndStop();
Console.WriteLine(
"Done!");
}
}
}

以上只展示的部分示例,更多示例大家可以访问项目地址获取。

项目地址

GitHub:
https://github.com/chronoxor/NetCoreServer

在线文档:
https://chronoxor.github.io/NetCoreServer

总结

本文只展示部分功能和内容,如果您对项目感兴趣可以访问系统地址获取详细信息和体验。

希望本文能在.NET 网络通信方面为各位提供有益的帮助。期待大家在评论区留言交流,分享您的宝贵经验和建议。

最后

如果你觉得这篇文章对你有帮助,不妨点个赞支持一下!你的支持是我继续分享知识的动力。如果有任何疑问或需要进一步的帮助,欢迎随时留言。

也可以加入微信公众号
[DotNet技术匠]
社区,与其他热爱技术的同行一起交流心得,共同成长!
优秀是一种习惯,欢迎大家留言学习!

大家好,我是汤师爷~

想要深入理解零售企业的组织架构并不容易。大多数人并没有实际经营过零售企业,更不曾参与设计其组织架构。

在调研商家的过程中,我们通常只能了解他们组织架构的现状,却难以直接与企业高层沟通,深入理解组织架构设计背后的逻辑。很多时候,我们只能通过业务场景的表象,去推测商家的组织设计意图。

然而,要为商家提供有竞争力的数字化产品,首先需要确保其组织数字化的合理性。组织管理是一切业务的起点,否则会产生以下问题:商家觉得产品逻辑奇葩、难以理解,运营效率低;而对于业务端来说,许多场景的实现方式别扭,业务操作效率低。

零售企业就像一台精密的机器,可以分为三大要素:组织、流程和资源。

  • 组织
    :企业内部相互协作的团队和部门,为了共同实现企业目标而联系在一起。
  • 流程
    :为达成某个业务目标,由不同角色分工完成的一系列活动,通常具有严格的先后顺序,并明确规定了活动内容、方式及输入输出。例如,门店补货流程、订单履约流程等。
  • 资源
    :包括有形资源(如资金、设备、门店等)和无形资源(如品牌、信息、技术等)。

机器的外部环境也可抽象为几个核心要素:设计者、盈利目标、分钱规则、经营结果。

  • 设计者
    :通常是企业的决策层,即公司的创始人或合伙人。
  • 盈利目标
    :例如,先定个小目标,赚他一个亿。
  • 分钱规则
    :所有零售企业的财务目标都是盈利。盈利之后,根据事先约定的规则,将利润分配给各团队,以保障机器的正常运转。
  • 经营结果
    :财务周期结束后,机器产出经营结果,包括各类经营数据、收入、成本、利润等。

机器运转过程中,决策层不仅会在起点给出输入(盈利目标、分钱规则),还会在事前、事中、事后进行管理,调整组织、流程、资源等关键要素。

经营结果
是一个特别需要关注的要素。决策层会通过观察经营结果,依据分钱规则对各团队进行资金分配或激励,但这一切都需要数据支持,尤其是团队贡献的收入、成本、费用等数据。

此外,决策层还需复盘经营结果,进行根因分析,在新周期前将企业这台“机器”调整到最佳状态,以提升业绩表现。

所有这些分析工作都依赖于大量结构化的数据支撑,而最重要的分析维度正是
管理分类
维度。

零售管理分类法

零售企业是个相当复杂的业务和社会系统,包含了许多要素:组织、地理位置、资源、流程、经营理念,以及把它们有机结合的机制。

一种重要的管理方法是把这些要素划分成多维度的分类视图,然后分别进行管理。

只要每个分类都管理好,叠加起来,大概率就能把企业管理好。通过这些分类方法,零售企业可以更好地组织决策和执行计划,也能抽象或细化需要解决的问题。

1、商品分类法

也就是商品品类管理。长期以来,百货超市的基础经营管理就是品类管理。它是通过给商品设定不同的角色定位,确定不同的品类策略。

大多数企业一般划分五大品类策略:目标性品类、重点品类、补充性品类、季节性品类和便利性品类。不同的企业可能有不同的品类划分和策略。

商品品类管理的核心理念是通过商品来影响顾客,把门店的商品形象准确地传递给消费者。通过商品打动消费者,让他们多买或持续回购,最终提升门店的业绩。

2、责权分类法

前面提到,零售企业是一个高度复杂的业务和社会系统。责任分配是经营企业非常重要的机制,能让零售业务灵活扩展。

从模型上看,责权分类法主张把企业划分为一个个责权明确的组织单元。他们通常具备一定范围的职责和权力,计划、执行、衡量各自的业务活动。

这个概念非常重要,尤其在生成经营报表时。在财务核算中,收入中心、成本中心、利润中心必须关联到某个组织单元,这样才能产出可衡量的经营成果。

3、地理分类法

一些跨地域的零售企业,会按照地理维度来划分经营活动,比如省、市、区县、乡镇,或者华东、华中、华南大区等。

相比责权分类法,地理分类法提供了不同的管理视角。它能帮助企业洞察经营活动背后的一些额外因素,如地域差异、人文差异、地理环境差异等,这些因素可能严重影响企业的业绩。

需要注意的是,有些企业表面上按地理分类划分组织,例如华东区、华中区、华南区,但本质上可能是责权分类法。关键要看是否使用财务衡量指标(收入、成本、费用等)来考核这些组织单元。

4、部门岗位分类法

部门岗位分类法是把组织划分为一系列的部门和岗位。根据部门和岗位的工作性质、责任轻重、难易程度和所需专业资质等,划分出不同的种类和等级。对从事不同工作的人,采用不同的要求和管理方法,是一种以“因事择人”为中心的管理方式。

特别要注意的是,有些企业中,部门岗位分类法划分的组织和责权分类法划分的组织,可能看起来相似,但底层逻辑完全不同。

部门岗位分类法面向人和事,以“因事择人”为中心;而责权分类法面向组织单元,这个组织单元不是具体的人和事,更像是一个可以承载团队、流程、资源等生产要素的容器,以收益和成本为中心。

从顺序上看,先有责权架构,再有部门岗位架构。就像先立王,再招兵买马,立王象征着建立责权,随后才涉及人和事的安排。从粒度上看,责权架构的粒度比部门岗位架构更粗。

组织管理的核心概念模型

在了解了零售管理的各种分类方法后,我们需要深入探讨组织管理的核心概念模型,所有的管理分类方法,最终都会体现在组织架构上,因为组织架构是经营理念的载体。组织管理的核心概念模型如图所示。

1、基础概念

  • 组织单元
    :所有组织都是由组织单元构成的。组织单元是一个抽象的概念,类似一个可以装东西的容器,可以装入团队、业务流程、资源等生产要素。
  • 组织单元的上下级关系
    :组织单元之间有上下级关系,最基本的应用场景包括汇报和数据统计汇总。
  • 组织树
    :当组织单元通过上下级关系连接起来,就形成了一棵组织树。组织树需要明确关联一种组织视图类型。

2、组织视图类型

对于中大型零售企业来说,企业内部分工明确,通常划分为多个业务系统,例如采购系统、供应链系统、销售系统、仓配系统、CRM 系统、HR 系统、财务系统等。这些系统会以不同的视角使用组织数据。

因此,需要引入了
组织视图类型
的概念,通过多组织视图的方式来管理和使用组织数据。以下是一些常见的组织视图类型:

  • 业务组织类型
    :企业按照特定业务模式划分的组织类型。例如,零售企业的运营组织需要制定企业和分店的业绩目标,推动目标实现,管理并指导各个分店的工作。业务组织类型可以根据管理复杂度进一步细分,如运营组织、采购组织、物流组织等。
  • 行政组织类型
    :与前面提到的部门岗位分类法的管理逻辑一致。对应企业中真实存在的组织单元,包括各层级、各部门、各职位等,按照职能目标分工。每个职能岗位有明确的权责分配和工作流程,是当前企业内部的真实结构。
  • 财务组织类型
    :财务组织单元是独立的会计核算主体,主要用于财务会计系统。每个财务组织单元都有一套完整的账套,能够独立生成三大财务报表:资产负债表、损益表、现金流量表。一般情况下,每个法人主体都会对应一个财务组织。
  • 责任中心类型
    :与之前提到的责权分类法的管理逻辑一致。责任中心是管理会计中的概念,指承担一定经济责任并享有一定权利的组织单元。责任中心可以划分为成本中心、利润中心和投资中心。

3、组织单元的核心属性

我们刚才讲了组织单元的基本概念和不同的组织视图类型。现在,让我们来看看组织单元的核心属性,这些属性决定了组织单元的性质和作用。

  • 组织单元的形态
    :也就是组织单元的类型说明,比如集团、公司、分公司、事业部、部门、区域、门店、电商网店等。需要特别注意,这本质上是一种标签,对业务应用没有影响,只是方便团队理解。
  • 组织单元的法人属性
    :明确组织单元的法人性质,包括:
    • 法人企业
      (集团、公司)
    • 法人分支机构
      (分公司、加盟商)
    • 非法人机构
      (事业部、部门、门店等)
  • 组织单元的责任中心模式
    :责任中心模式可分为成本中心、利润中心和投资中心,用于管理会计分析。
  • 组织单元的业务能力
    :明确组织单元执行的业务范围,比如门店销售、加工、库存管理、要货、线上销售等能力。
  • 组织单元的业务终端属性
    :如果组织单元是业务终端,意味着它是组织树的叶子节点,直接从事一线业务活动。典型的业务终端包括门店、电商网店、配送中心。
  • 组织单元的数据共享模式
    :分为全局共享模式、部分共享模式和完全隔离模式。

本文已收录于,我的技术网站:
tangshiye.cn
里面有,算法Leetcode详解,面试八股文、BAT面试真题、简历模版、架构设计,等经验分享。