KAPC的前世今生--(下)下RPCRT4!NMP_SyncSendRecv函数分析

第一部分:nt!KiDeliverApc函数调用nt!IopCompleteRequest函数后准备返回
1: kd> kv
 # ChildEBP RetAddr  Args to Child              
00 ba3eec18 80a3c83b 896e4e40 ba3eec64 ba3eec58 nt!IopCompleteRequest+0x3a3 (FPO: [Non-Fpo]) (CONV: stdcall) [d:\srv03rtm\base\ntos\io\iomgr\internal.c @ 1568]
01 ba3eec68 80a44106 00000000 00000000 00000000 nt!KiDeliverApc+0xc5 (FPO: [Non-Fpo]) (CONV: stdcall) [d:\srv03rtm\base\ntos\ke\apcsup.c @ 283]
02 ba3eecac 80a35ea9 00000000 00000000 00000001 nt!KiSwapThread+0x642 (FPO: [Non-Fpo]) (CONV: fastcall) [d:\srv03rtm\base\ntos\ke\thredsup.c @ 2004]
03 ba3eece0 80d1f189 894e9800 00000006 ba3eed01 nt!KeWaitForSingleObject+0x2d7 (FPO: [Non-Fpo]) (CONV: stdcall) [d:\srv03rtm\base\ntos\ke\wait.c @ 1161]
04 ba3eed44 80afbcb2 00000255 00000000 00000000 nt!NtWaitForSingleObject+0xcd (FPO: [Non-Fpo]) (CONV: stdcall) [d:\srv03rtm\base\ntos\ob\obwait.c @ 402]
05 ba3eed44 7ffe0304 00000255 00000000 00000000 nt!_KiSystemService+0x13f (FPO: [0,3] TrapFrame @ ba3eed64) (CONV: cdecl) [d:\srv03rtm\base\ntos\ke\i386\trap.asm @ 1328]
06 0006f5e4 77f2fbc8 77e64045 00000255 00000000 SharedUserData!SystemCallStub+0x4 (FPO: [0,0,0])
07 0006f5e8 77e64045 00000255 00000000 00000000 ntdll!NtWaitForSingleObject+0xc (FPO: [3,0,0]) [d:\srv03rtm\base\ntdll\daytona\obj\i386\usrstubs.asm @ 2371]
08 0006f658 77c6f002 00000255 ffffffff 00000000 kernel32!WaitForSingleObjectEx+0xac (FPO: [Non-Fpo]) (CONV: stdcall) [d:\srv03rtm\base\win32\client\synch.c @ 1237]
09 0006f678 77c6f1bb 006c1a00 00000000 ffffffff RPCRT4!UTIL_WaitForSyncIO+0x1f (FPO: [Non-Fpo]) (CONV: stdcall) [d:\srv03rtm\com\rpc\runtime\trans\common\util.cxx @ 233]
0a 0006f69c 77c727d8 006c19cc 006c1a00 0006f6c4 RPCRT4!UTIL_GetOverlappedResultEx+0xbf (FPO: [Non-Fpo]) (CONV: stdcall) [d:\srv03rtm\com\rpc\runtime\trans\common\util.cxx @ 370]
0b 0006f6c8 77bf4f4b 000003e5 00000050 006c12b8 RPCRT4!NMP_SyncSendRecv+0xd5 (FPO: [Non-Fpo]) (CONV: stdcall) [d:\srv03rtm\com\rpc\runtime\trans\common\nptrans.cxx @ 1995]
0c 0006f6f4 77bf53ce 006dadd0 00000000 00000050 RPCRT4!OSF_CCONNECTION::TransSendReceive+0xb9 (FPO: [Non-Fpo]) (CONV: thiscall) [d:\srv03rtm\com\rpc\runtime\mtrt\osfclnt.cxx @ 3365]
0d 0006f77c 77bf5c76 006c12b8 006c1a90 00000001 RPCRT4!OSF_CCONNECTION::SendFragment+0x32c (FPO: [Non-Fpo]) (CONV: thiscall) [d:\srv03rtm\com\rpc\runtime\mtrt\osfclnt.cxx @ 6012]
0e 0006f7d4 77bfc0ca 00000000 ffffffff 0006f818 RPCRT4!OSF_CCALL::SendNextFragment+0x29b (FPO: [Non-Fpo]) (CONV: thiscall) [d:\srv03rtm\com\rpc\runtime\mtrt\osfclnt.cxx @ 9631]
0f 0006f81c 77bfc397 0006f8b8 0006f860 000006bf RPCRT4!OSF_CCALL::FastSendReceive+0x162 (FPO: [Non-Fpo]) (CONV: thiscall) [d:\srv03rtm\com\rpc\runtime\mtrt\osfclnt.cxx @ 8222]
10 0006f83c 77bfcbac 0006f8b8 0006f860 77e47889 RPCRT4!OSF_CCALL::SendReceiveHelper+0xe1 (FPO: [Non-Fpo]) (CONV: thiscall) [d:\srv03rtm\com\rpc\runtime\mtrt\osfclnt.cxx @ 8539]
11 0006f868 77bf1ca2 006c12d0 0006f8e4 0006f8b8 RPCRT4!OSF_CCALL::SendReceive+0x4c (FPO: [Non-Fpo]) (CONV: thiscall) [d:\srv03rtm\com\rpc\runtime\mtrt\osfclnt.cxx @ 8603]
12 0006f884 77c3f764 0006f8b8 77d80220 0006fc8c RPCRT4!I_RpcSendReceive+0xba (FPO: [Non-Fpo]) (CONV: stdcall) [d:\srv03rtm\com\rpc\runtime\mtrt\msgapi.cxx @ 79]
13 0006f89c 77c7ed10 0006f8e4 006c1308 000b5378 RPCRT4!NdrSendReceive+0x47 (FPO: [Non-Fpo]) (CONV: stdcall) [d:\srv03rtm\com\rpc\ndr20\auxilary.cxx @ 1269]
14 0006fc6c 77dc194a 77d80220 77d7f61c 0006fc8c RPCRT4!NdrClientCall2+0x1f7 (FPO: [Non-Fpo]) (CONV: cdecl) [d:\srv03rtm\com\rpc\ndr20\cltcall.cxx @ 1033]
15 0006fc84 77dbec35 006dab50 0006fd8c 00008000 ADVAPI32!ROpenServiceW+0x17 (FPO: [Non-Fpo]) (CONV: stdcall) [d:\srv03rtm\base\screg\sc\client\svcctl_c.c @ 399]
16 0006fccc 77dc10f1 006dab50 0006fd8c 00008000 ADVAPI32!OpenServiceW+0x26 (FPO: [Non-Fpo]) (CONV: stdcall) [d:\srv03rtm\base\screg\sc\client\scwrap.cxx @ 723]
17 0006fd4c 77dc16c1 00000298 0006fd78 00000216 ADVAPI32!ScDispatcherLoop+0x17e (FPO: [Non-Fpo]) (CONV: stdcall) [d:\srv03rtm\base\screg\sc\client\scapi.cxx @ 910]
18 0006ffac 01003221 00084d00 00000000 00000000 ADVAPI32!StartServiceCtrlDispatcherW+0x121 (FPO: [Non-Fpo]) (CONV: stdcall) [d:\srv03rtm\base\screg\sc\client\scapi.cxx @ 705]
19 0006ffc0 77e62c34 00000000 00000000 7ffdf000 svchost!wmainCRTStartup+0xa2 (FPO: [0,0,3]) (CONV: stdcall) [d:\srv03rtm\base\screg\sc\svchost\svchost.c @ 1369]
1a 0006fff0 00000000 0100317f 00000000 78746341 kernel32!BaseProcessStart+0x23 (FPO: [Non-Fpo]) (CONV: stdcall) [d:\srv03rtm\base\win32\client\support.c @ 580]

RPC_STATUS
RPC_ENTRY
NMP_SyncSendRecv(
    IN RPC_TRANSPORT_CONNECTION ThisConnection,
    IN UINT InputBufferSize,
    IN BUFFER InputBuffer,
    OUT PUINT pOutputBufferSize,
    OUT BUFFER *pOutputBuffer
    )
{

   b = TransactNamedPipe(p->Conn.Handle,
                          InputBuffer,
                          InputBufferSize,
                          p->pReadBuffer,
                          bytes,
                          &bytes,
                          &p->Read.ol
                          );


    if (!b)
        {
        status = GetLastError();
        if (status == ERROR_IO_PENDING)
            {
            status = UTIL_GetOverlappedResult(p,
                                              &p->Read.ol,
                                              &bytes);
            }
        else
            {
            ASSERT(status != RPC_S_OK);
            }
        }
    else
        {
        status = RPC_S_OK;
        }

    if (status == RPC_S_OK)
        {
        // Success - got the whole reply in the transact

        *pOutputBuffer = p->pReadBuffer;
        p->pReadBuffer = 0;
        *pOutputBufferSize = bytes;

        ASSERT(bytes == MessageLength((PCONN_RPC_HEADER)*pOutputBuffer));

        return(RPC_S_OK);
        }


第二部分:设置事件

1: kd> dv
         Object = 0x894e9800
     WaitReason = UserRequest (0n6)
       WaitMode = 0n1 ''
      Alertable = 0x00 ''
        Timeout = 0x00000000
        DueTime = {-5026319169582360600}
    CurrentPrcb = 0xf7737120
   OriginalTime = 0x00000000
 StackSwappable = 1
        NewTime = {-2207181079913080607}
1: kd> dt KMUTANT 0x894e9800
GDI32!KMUTANT
   +0x000 Header           : _DISPATCHER_HEADER
   +0x010 MutantListEntry  : _LIST_ENTRY [ 0xa060006 - 0x20646156 ]
   +0x018 OwnerThread      : 0x89784b8b _KTHREAD
   +0x01c Abandoned        : 0x90 ''
   +0x01d ApcDisable       : 0xe2 ''
1: kd> dx -id 0,0,89838358 -r1 (*((GDI32!_DISPATCHER_HEADER *)0x894e9800))
(*((GDI32!_DISPATCHER_HEADER *)0x894e9800))                 [Type: _DISPATCHER_HEADER]
    [+0x000] Type             : 0x0 [Type: unsigned char]
    [+0x001] Absolute         : 0x0 [Type: unsigned char]
    [+0x002] Size             : 0x4 [Type: unsigned char]
    [+0x003] Inserted         : 0x0 [Type: unsigned char]
    [+0x003] DebugActive      : 0x0 [Type: unsigned char]
    [+0x000] Lock             : 262144 [Type: long]
    [+0x004] SignalState      : 1 [Type: long]
    [+0x008] WaitListHead     [Type: _LIST_ENTRY]
1: kd> dx -id 0,0,89838358 -r1 (*((GDI32!_LIST_ENTRY *)0x894e9808))
(*((GDI32!_LIST_ENTRY *)0x894e9808))                 [Type: _LIST_ENTRY]
    [+0x000] Flink            : 0x894e9808 [Type: _LIST_ENTRY *]
    [+0x004] Blink            : 0x894e9808 [Type: _LIST_ENTRY *]


typedef enum _KOBJECTS {
    EventNotificationObject = 0,
    EventSynchronizationObject = 1,
    MutantObject = 2,


第三部分:返回到nt!KeWaitForSingleObject函数后


NTSTATUS
KeWaitForSingleObject (
    IN PVOID Object,
    IN KWAIT_REASON WaitReason,
    IN KPROCESSOR_MODE WaitMode,
    IN BOOLEAN Alertable,
    IN PLARGE_INTEGER Timeout OPTIONAL
    )

{
            //
            // If the signal state is greater than zero, then satisfy the wait.
            //

            } else if (Objectx->Header.SignalState > 0) {
                KiWaitSatisfyOther(Objectx);
                WaitStatus = (NTSTATUS)(0);
                goto NoWait;        //等待事件对象有信号了
            }


#define KiWaitSatisfyOther(_Object_) {                                       \
    if (((_Object_)->Header.Type & DISPATCHER_OBJECT_TYPE_MASK) == EventSynchronizationObject) { \
        (_Object_)->Header.SignalState = 0;                                  \
                                                                             \
    } else if ((_Object_)->Header.Type == SemaphoreObject) {                 \
        (_Object_)->Header.SignalState -= 1;                                 \
                                                                             \
    }                                                                        \
}


            InsertTailList(&Objectx->Header.WaitListHead, &WaitBlock->WaitListEntry);


            KiSetContextSwapBusy(Thread);
            KiUnlockDispatcherDatabaseFromSynchLevel();
            WaitStatus = (NTSTATUS)KiSwapThread(Thread, CurrentPrcb);


第四部分:客户端调用nt!KiUnwaitThread函数里面会调用KiUnlinkThread函数脱链


1: kd> kv 4
 # ChildEBP RetAddr  Args to Child              
00 f794abbc 80a3cc41 00000001 896e4e40 896e4e40 nt!KiUnwaitThread+0x7 (FPO: [Non-Fpo]) (CONV: fastcall) [d:\srv03rtm\base\ntos\ke\waitsup.c @ 158]
01 f794abe0 80a3758e 896e4e00 00000000 00000000 nt!KiInsertQueueApc+0x1a9 (FPO: [Non-Fpo]) (CONV: fastcall) [d:\srv03rtm\base\ntos\ke\apcsup.c @ 602]
02 f794abfc 80a26c44 896e4e40 895a7ca8 00000000 nt!KeInsertQueueApc+0x80 (FPO: [Non-Fpo]) (CONV: stdcall) [d:\srv03rtm\base\ntos\ke\apcobj.c @ 302]
03 f794ac30 baaf531e 895a5038 8979ef68 00000000 nt!IopfCompleteRequest+0x244 (FPO: [Non-Fpo]) (CONV: fastcall) [d:\srv03rtm\base\ntos\io\iomgr\iosubs.c @ 3688]

1: kd> dt kTHREAD 89510898
ntdll!KTHREAD
   +0x000 Header           : _DISPATCHER_HEADER
   +0x010 MutantListHead   : _LIST_ENTRY [ 0x895108a8 - 0x895108a8 ]
   +0x018 InitialStack     : 0xba3ef000 Void
   +0x01c StackLimit       : 0xba3eb000 Void
   +0x020 KernelStack      : 0xba3eec5c Void
   +0x024 ThreadLock       : 0
   +0x028 ContextSwitches  : 0xa1
   +0x02c State            : 0x2 ''

   +0x054 WaitBlockList    : 0x89510938 _KWAIT_BLOCK

1: kd> dx -id 0,0,89838358 -r1 ((ntdll!_KWAIT_BLOCK *)0x89510938)
((ntdll!_KWAIT_BLOCK *)0x89510938)                 : 0x89510938 [Type: _KWAIT_BLOCK *]
    [+0x000] WaitListEntry    [Type: _LIST_ENTRY]
    [+0x008] Thread           : 0x89510898 [Type: _KTHREAD *]
    [+0x00c] Object           : 0x894e9800 [Type: void *]
    [+0x010] NextWaitBlock    : 0x89510938 [Type: _KWAIT_BLOCK *]        NextWaitBlock    : 0x89510938
    [+0x014] WaitKey          : 0x0 [Type: unsigned short]
    [+0x016] WaitType         : 0x1 [Type: unsigned short]

VOID
FASTCALL
KiUnwaitThread (
    IN PRKTHREAD Thread,
    IN LONG_PTR WaitStatus,
    IN KPRIORITY Increment
    )
{

    //
    // Unlink thread from the appropriate wait queues and set the wait
    // completion status.
    //

    KiUnlinkThread(Thread, WaitStatus);

    //
    // Set unwait priority adjustment parameters.
    //

    ASSERT(Increment >= 0);

    Thread->AdjustIncrement = (SCHAR)Increment;
    Thread->AdjustReason = (UCHAR)AdjustUnwait;

    //
    // Ready the thread for execution.
    //

    KiReadyThread(Thread);
    return;
}


FORCEINLINE
VOID
FASTCALL
KiUnlinkThread (
    IN PRKTHREAD Thread,
    IN LONG_PTR WaitStatus
    )
{

    PKQUEUE Queue;
    PKTIMER Timer;
    PRKWAIT_BLOCK WaitBlock;

    //
    // Set wait completion status, remove wait blocks from object wait
    // lists, and remove thread from wait list.
    //

    Thread->WaitStatus |= WaitStatus;
    WaitBlock = Thread->WaitBlockList;
    do {
        RemoveEntryList(&WaitBlock->WaitListEntry);


第五部分:什么时候设置事件为有信号状态?

1: kd> dt _irp 0x896e4e40-40
GDI32!_IRP
   +0x000 Type             : 0n6
   +0x002 Size             : 0x94
   +0x004 MdlAddress       : (null)
   +0x008 Flags            : 0x870
   +0x00c AssociatedIrp    : __unnamed
   +0x010 ThreadListEntry  : _LIST_ENTRY [ 0x89510ab0 - 0x89510ab0 ]
   +0x018 IoStatus         : _IO_STATUS_BLOCK
   +0x020 RequestorMode    : 1 ''
   +0x021 PendingReturned  : 0x1 ''
   +0x022 StackCount       : 1 ''
   +0x023 CurrentLocation  : 3 ''
   +0x024 Cancel           : 0 ''
   +0x025 CancelIrql       : 0 ''
   +0x026 ApcEnvironment   : 0 ''
   +0x027 AllocationFlags  : 0xc ''
   +0x028 UserIosb         : 0x006c1a00 _IO_STATUS_BLOCK
   +0x02c UserEvent        : 0x894e9800 _KEVENT            UserEvent        : 0x894e9800

VOID
IopCompleteRequest(
    IN PKAPC Apc,
    IN PKNORMAL_ROUTINE *NormalRoutine,
    IN PVOID *NormalContext,
    IN PVOID *SystemArgument1,
    IN PVOID *SystemArgument2
    )
{

        if (irp->UserEvent) {
            (VOID) KeSetEvent( irp->UserEvent, 0, FALSE );


00 nt!IopCompleteRequest
01 nt!KiDeliverApc
02 nt!KiSwapThread
03 nt!KeWaitForSingleObject
04 nt!NtWaitForSingleObject
05 nt!_KiSystemService
06 SharedUserData!SystemCallStub
07 ntdll!NtWaitForSingleObject
08 kernel32!WaitForSingleObjectEx
09 RPCRT4!UTIL_WaitForSyncIO
0a RPCRT4!UTIL_GetOverlappedResultEx
0b RPCRT4!NMP_SyncSendRecv


1: kd> dt kTHREAD 89510898
ntdll!KTHREAD
   +0x000 Header           : _DISPATCHER_HEADER
   +0x010 MutantListHead   : _LIST_ENTRY [ 0x895108a8 - 0x895108a8 ]
   +0x018 InitialStack     : 0xba3ef000 Void
   +0x01c StackLimit       : 0xba3eb000 Void
   +0x020 KernelStack      : 0xba3eec5c Void
   +0x024 ThreadLock       : 0
   +0x028 ContextSwitches  : 0xa1
   +0x02c State            : 0x2 ''

   +0x054 WaitBlockList    : 0x89510938 _KWAIT_BLOCK
 
1: kd> dx -id 0,0,89838358 -r1 ((ntdll!_KWAIT_BLOCK *)0x89510938)
((ntdll!_KWAIT_BLOCK *)0x89510938)                 : 0x89510938 [Type: _KWAIT_BLOCK *]
    [+0x000] WaitListEntry    [Type: _LIST_ENTRY]
    [+0x008] Thread           : 0x89510898 [Type: _KTHREAD *]
    [+0x00c] Object           : 0x894e9800 [Type: void *]            //Object           : 0x894e9800
    [+0x010] NextWaitBlock    : 0x89510938 [Type: _KWAIT_BLOCK *]
    [+0x014] WaitKey          : 0x0 [Type: unsigned short]
    [+0x016] WaitType         : 0x1 [Type: unsigned short]

第六部分:
    if (status == RPC_S_OK)
        {
        // Success - got the whole reply in the transact

        *pOutputBuffer = p->pReadBuffer;
        p->pReadBuffer = 0;
        *pOutputBufferSize = bytes;

        ASSERT(bytes == MessageLength((PCONN_RPC_HEADER)*pOutputBuffer));

        return(RPC_S_OK);
        }

1: kd> dt NMP_CONNECTION 006c19cc
RPCRT4!NMP_CONNECTION
   +0x000 __VFN_table : 0x77bed498
   +0x004 type             : 0
   +0x008 id               : 0n3
   +0x00c fAborted         : 0n0
   +0x010 ObjectList       : _LIST_ENTRY [ 0xbaadf00d - 0xbaadf00d ]
   +0x018 Conn             : BASE_CONNECTION::__unnamed
   +0x01c StartingWriteIo  : 0n0
   +0x020 StartingReadIo   : 0n0
   +0x024 iPostSize        : 0x400
   +0x028 maxReadBuffer    : 0x400
   +0x02c iLastRead        : 0
   +0x030 Read             : BASE_OVERLAPPED
   +0x04c pReadBuffer      : 0x006c1408  "???"
   +0x050 pAddress         : (null)
1: kd> dd 0x006c1408
006c1408  03020005 00000010 00000030 0000005d
006c1418  00000018 00000000 00000000 e160751f
006c1428  45e3ef7f 690413a0 b8ade145 00000000
006c1438  8a885d04 11c91ceb 0008e89f 6048102b
006c1448  00000002 0054004e 00410020 00540055
006c1458  004f0048 00490052 00590054 00000000
006c1468  00000001 05000000 00000001 000b4ee8
006c1478  00000001 00000001 000e000c 000b4efc

1: kd> dt rpcconn_common 0x006c1408
RPCRT4!rpcconn_common
   +0x000 rpc_vers         : 0x5 ''
   +0x001 rpc_vers_minor   : 0 ''
   +0x002 PTYPE            : 0x2 ''
   +0x003 pfc_flags        : 0x3 ''
   +0x004 drep             : [4]  "???"
   +0x008 frag_length      : 0x30
   +0x00a auth_length      : 0
   +0x00c call_id          : 0x5d

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

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

相关文章

深入理解C++引用:从基础到现代编程实践

一、引用的本质与基本特性 1.1 引用定义 引用是为现有变量创建的别名,通过&符号声明。其核心特点: 必须初始化且不能重新绑定 与被引用变量共享内存地址 无独立存储空间(编译器实现) 类型必须严格匹配 int value 42; in…

嵌入式Linux开发环境搭建,三种方式:虚拟机、物理机、WSL

目录 总结写前面一、Linux虚拟机1 安装VMware、ubuntu18.042 换源3 改中文4 中文输入法5 永不息屏6 设置 root 密码7 安装 terminator8 安装 htop(升级版top)9 安装 Vim10 静态IP-虚拟机ubuntu11 安装 ssh12 安装 MobaXterm (SSH)…

软件工程面试题(二十七)

1、j a v a 对象初始化顺序 1.类的初始化(initialization class & interface) 2.对象的创建(creation of new class instances) 顺序:应为类的加载肯定是第一步的,所以类的初始化在前。大体的初始化顺序是: 类初始化 -> 子类构造函数 -> 父类构造函数 -&g…

《AI大模型开发笔记》MCP快速入门实战(一)

目录 1. MCP入门介绍 2. Function calling技术回顾 3. 大模型Agent开发技术体系回顾 二、 MCP客户端Client开发流程 1. uv工具入门使用指南 1.1 uv入门介绍 1.2 uv安装流程 1.3 uv的基本用法介绍 2.MCP极简客户端搭建流程 2.1 创建 MCP 客户端项目 2.2 创建MCP客户端…

Java中的正则表达式Lambda表达式

正则表达式&&Lambda表达式 正则表达式和Lambda表达式是Java编程中两个非常实用的特性。正则表达式用于字符串匹配与处理,而Lambda表达式则让函数式编程在Java中变得更加简洁。本文将介绍它们的基本用法,并结合示例代码帮助理解。同时要注意&…

Talend API Tester

背景 工作中有时会需要调测http接口,postman无疑是最常用最流行的工具,但是有一个致命问题,必须要登录,而工作经常是私网环境,导致使用非常不方便。因此想找一个Windows系统上的轻量级、无需登录即可使用的http测试工…

leetcode数组-移除元素

题目 题目链接:https://leetcode.cn/problems/remove-element/ 给你一个数组 nums 和一个值 val,你需要 原地 移除所有数值等于 val 的元素。元素的顺序可能发生改变。然后返回 nums 中与 val 不同的元素的数量。 假设 nums 中不等于 val 的元素数量为…

什么是市盈率,通俗解释清楚

市盈率就是“股价和公司盈利能力”的一个比例关系,简单来说,就是你花多少钱买股票,要等多少年才能通过公司赚的钱“回本”。 假设你买了一家公司的股票,花了100块钱,这家公司每年能赚10块钱。那市盈率就是100除以10&am…

突破传统认知:聚类算法的底层逻辑与高阶应用全景解析

一、维度革命:重新定义聚类分析的认知边界 在人工智能的浩瀚星空中,聚类算法犹如一组精密的星际导航仪,帮助我们在无序的数据宇宙中发现隐藏的秩序。这项起源于人类本能分类需求的技术,经历了从简单分组到智能识别的蜕变&#xf…

【愚公系列】《高效使用DeepSeek》051-产品创新研发

🌟【技术大咖愚公搬代码:全栈专家的成长之路,你关注的宝藏博主在这里!】🌟 📣开发者圈持续输出高质量干货的"愚公精神"践行者——全网百万开发者都在追更的顶级技术博主! 👉 江湖人称"愚公搬代码",用七年如一日的精神深耕技术领域,以"…

网络编程—Socket套接字(UDP)

上篇文章: 网络编程—网络概念https://blog.csdn.net/sniper_fandc/article/details/146923380?fromshareblogdetail&sharetypeblogdetail&sharerId146923380&sharereferPC&sharesourcesniper_fandc&sharefromfrom_link 目录 1 概念 2 Soc…

深度学习deeplearn1

import torch # 导入 PyTorch 库,PyTorch 是一个用于深度学习和张量计算的强大库x torch.arange(12) # 创建一个包含从 0 到 11 的整数的一维张量 x # torch.arange 函数用于生成一个指定范围的整数序列print(x) # 打印张量 x 的内容print(x.shape) # 打印张量 x 的…

无线通信技术(三):5G NR通信频带划分与应用场景

目录 一.5G NR频带划分概述 二.全球运营商5G频带分配对比 三.5G频带的应用场景 5G网络的发展离不开频谱资源的合理分配。不同的频段决定了5G的覆盖范围、传输速率和应用场景。本文将系统介绍5G NR频带划分,并结合实际应用场景,理解不同频段的特性及其适用环境。 …

观察者模式在Java单体服务中的运用

观察者模式主要用于当一个对象发生改变时,其关联的所有对象都会收到通知,属于事件驱动类型的设计模式,可以对事件进行监听和响应。下面简单介绍下它的使用: 1 定义事件 import org.springframework.context.ApplicationEvent;pu…

YOLO 获取 COCO 指标终极指南 | 从标签转换到 COCOAPI 评估 (训练/验证) 全覆盖【B 站教程详解】

✅ YOLO 轻松获取论文 COCO 指标:AP(small,medium,large )| 从标签转换到 COCOAPI 评估 (训练/验证) 全覆盖 文章目录 一、摘要二、为什么需要 COCO 指标评估 YOLO 模型?三、核心挑战与解决方案 (视频教程核…

[C/C++]文件输入输出

C style FILE * fileptr filename"C:\\file.txt" fopenfclosefprintfC style //指向std::ostream的指针 #include <iostream> #include <fstream>int main() {std::ostream* output &std::cout; // 默认指向控制台// 输出到控制台*output <&l…

【Android】界面布局-线性布局-例子

线性布局&#xff08;LinearLayout&#xff09;是一种重要的界面布局中&#xff0c;也是经常使用到的一种界面布局 • 在线性布局中&#xff0c;所有的子元素都按照垂直或水平的顺序在界面上排列 ➢如果垂直排列&#xff0c;则每行仅包含一个界面元素 ➢如果水平排列&…

HTML表单属性1

value 属性 value 设置输入字段的初始值&#xff08;默认值&#xff09;,提交表单时&#xff0c;如果用户未做修改&#xff0c;将发送value中的默认值 <form action"#">First name: <br><input type"text" name"firstname" val…

JavaScrip图标工具Chart.js之 气泡图

气泡图用于展示三个变量之间的关系。 气泡的位置由前两个变量决定&#xff0c;对应的是 X 轴和 Y 轴&#xff0c;第三个参数为气泡的大小。 {// X 轴对应值x: number,// Y 轴对应值y: number,// 气泡半径&#xff0c;单位为像素r: number } 泡图的 type 属性为 bubble &#xf…

Git 教程:从 0 到 1 全面指南 教程【全文三万字保姆级详细讲解】

目录 什么是 Git &#xff1f; Git 与 SVN 区别 Git 安装配置 Linux 平台上安装 Centos/RedHat 源码安装 Windows 平台上安装 使用 winget 工具 Mac 平台上安装 Git 配置 用户信息 文本编辑器 差异分析工具 查看配置信息 生成 SSH 密钥&#xff08;可选&#xf…