一篇万字长文读懂微软PDB、SourceLink——.net core之nuget 包调试

序言

在大前年,为了说服框架组采用Nuget包的形式分发框架类库,我费了老鼻子的劲也没有取得成功,其中最致命的一个问题是,nuget包不能获得源码调试级的支持,在分发和包的管理形式上其比其他方案都优秀。最后折中的选择是采用源码直接引用项目的方式,这种方案对框架类库的新分支的开发不是很有利,在源码的保护上更是完全没有了保障,不过在当时场景下,也算是可以接受的方案之一了。而经过这几年的发展,微软在这些方面都有了长足的发展,那跟着我,来看看能否解决各位心中的疑惑?

1. 历史悠久的PDB

当看到一个人光鲜亮丽,光彩照人的时候,我们都有着一股探究其老底的冲动。是啊,凭啥他就能行,而我们就不行呢?我们起起底,探究下他的小秘密,说不定从他身上能发掘出不为人知的一面,为我们的崛起提供一些参考的方向,这不香吗?

扯得有点远了,我们回归正题。

1.1 PDB 和符号文件

PDB全称:Program Database,由微软开发的一种调试符号文件存储格式,在windows系统中,为了调试dll或者exe文件,需要有一个符号文件(Symbols file)来支撑调试。符号文件保存多个数据,这些数据在运行二进制文件时实际上并不需要,但在调试过程中可能非常有用。通常,符号文件可能包含:

  • 全局变量

  • 局部变量

  • 函数名称和其入口点的地址

  • 帧指针省略 (FPO) 记录

  • 源行号

调试时,必须确保调试器能够访问与正在调试的目标关联的符号文件。实时调试和调试崩溃转储文件都需要符号。你必须获取要调试的代码的正确符号,并将这些符号加载到调试器中。

而PDB文件就是windows保留符号的文件格式。熟悉C++的朋友,应该对这个文件非常熟悉,它伴随着Visual Studio 和WinDbg而产生,可谓是历史悠久的文件格式之一。

什么,想看看PDB文件保存的是啥玩意?好吧,本尊就满足你的好奇心,在windows的调试工具有个dbh小工具,可以查看pdb的文件内容。

mysymbols [1000000]: symopt -2Symbol Options: 0x14c13
Symbol Options: 0x14c11mysymbols [1000000]: addr 102cb4e_MyFunction1@4name : _InterlockedIncrement@4addr :  102cb4esize : 0flags : 0type : 0
modbase :  1000000value :        0reg : 0scope : SymTagNull (0)tag : SymTagPublicSymbol (a)index : 2ab

当然了,符号文件本身也有很多格式,例如大名鼎鼎的COFF是Unix下常用的调试符号文件格式。

1.2 PDB的变种-便携式PDB

为了能适应跨平台的需求,微软提出了便携式PDB(Portable PDB )标准,以便和长期使用的Windows PDB相区别。其主要支持.NET中的托管代码。从历史上看,Windows PDB用于存储本机代码和托管代码的调试信息,其用于读取和写入这些PDB的工具仅在Windows平台上得到支持。便携式PDB旨在以平台无关的格式有效地存储托管的调试信息,其在多个平台上的有着丰富的支持工具,其以可移植格式存储托管的调试信息,并会生成更小的PDB,这在考虑分发大小时也是重要的优势。

2 使用符号调试

2.1 想要调试三方库或.net 框架

让我们来看一个例子。有时您想进入框架以查看发生了什么,特别是如果发生了意外的事情。假设您如同下面所示设置了断点。那么在按F11想进入框架内部的时候,代码直接往下面执行了,这就是您所看到的。


默认情况下,Visual Studio在调试应用程序时仅逐步执行代码。这是一个非常有用的功能,因为您通常希望理解和研究自己所编写代码的逻辑。

关注自己,是人生在牙牙学语阶段就开始逐渐不断增长的意识,因此始于人性,才是最好的Feature!启用这种体验的功能被恰当地称为仅我的代码(“ Just my Code”)。

在某天,您想调试第三方组件或平台本身的逻辑,在这之前,进行调试非常困难。主要是两个方面的困难:

  1. 缺少第三方组件或平台二进制文件的符号;

  2. 缺少第三方组件或平台二进制文件匹配的符号相关联的源文件。

相比而言,JavaScript具有与.NET几乎相反的问题。JavaScript社区(包括浏览器和node.js变体)都使用SourceMap,其提供了调试第三方精简代码的良好体验。但是,JavaScript编辑器无法提供“仅我的代码”的体验。

对于.NET Core 开发人员,我们希望能够轻松自然地在默认的“ 仅我的代码”体验以及带有第三方组件和平台源调试之间进行自由切换,这一切,并不是梦!

2.2 调试.net core 平台代码

那我们怎么能够调试三方库或.net 框架呢?

Visual Studio 2017版中已经支持了符号调试,在VS 的 工具菜单下,选择选项/调试/常规页签,配置如下参数:

  • 禁用 “启用仅我的代码”

  • 启用源链接


选择选项/调试/符号页签,配置如下参数:

  • 选择 Microsoft符号服务器;

  • 选择 NuGet.org 符号服务器(如果调试的是nuget库);

  • 在缓存符号目录中设定一个目录,避免多次下载符号库。

如果使用的是VS Code,可以为每个项目配置调试器设置:launch.json

"justMyCode": false,
"symbolOptions": {"searchMicrosoftSymbolServer": true,"searchNuGetOrgSymbolServer": true
},
"suppressJITOptimizations": true,
"env": {"COMPlus_ZapDisable": "1","COMPlus_ReadyToRun": "0"
}

注意:

  1. 并非nuget.org上的每个库都会为其.pdb文件建立索引。如果发现调试器找不到正在使用的开源库的PDB文件,请鼓励作者上载其PDB;

  2. 只有Microsoft提供的库才会在Microsoft符号服务器上拥有其.pdb文件,因此,如果您只对三方库感兴趣,可以禁用该选项。

启动调试,发现VS开始下载符号文件,下载完毕后,进入断点。当我们按F11后,弹出如下界面:

3. SourceLink

Source Link是开发人员的一项生产力功能,它允许在编译过程中将有关程序集原始源代码的唯一信息嵌入到PDB中的一组软件包和规范, 通过SourceLink,添加到PDB文件中的元数据,和本地源代码文件、仓库内的代码文件建立了一个映射关系。

因此Visual Studio调试时可以在需要时下载文件, 并为用户提供源代码调试, Microsoft库(例如.NET Core和Roslyn)都已启用Source Link。

3.1 为什么使用SourceLink呢?

大多数调试是针对开发人员计算机上本地构建的源代码完成的。在这种情况下,将二进制文件与源代码匹配并不困难。

但是,在许多调试方案中,原始源代码没法立即就可用。这方面的两个很好的例子是调试崩溃转储或第三方库。在这些情况下,对于开发人员来说,要获取为生成正在调试的二进制文件而构建的确切源代码可能非常困难(可能是特定的版本)。Source Link通过在PDB中嵌入有关源代码的唯一信息(例如git commit hash)来解决此问题。诊断工具(例如调试器)可以使用此独特信息从托管服务(例如GitHub)中检索原始源代码。

sourcelink 最初的版本是 @ctaggart 实现的,目前已归档, 现在已经加入了 .Net 团队,微软人员和ctaggart 一起做了现在的版本。

官网地址: https://github.com/dotnet/sourcelink

3.2 SourceLink的文件规范

SourceLink 是一个Json配置的文件,其内容格式如下:

{"$schema": "http://json-schema.org/draft-04/schema#","title": "SourceLink","description": "A mapping of source file paths to URLs","type": "object","properties": {"documents": {"type": "object","minProperties": 1,"additionalProperties": {"type": "string"},"description": "Each document is defined by a file path and a URL. Original source file paths are compared case-insensitively to documents and the resulting URL is used to download source. The document may contain an asterisk to represent a wildcard in order to match anything in the asterisk's location. The rules for the asterisk are as follows:1. The only acceptable wildcard is one and only one '*', which if present will be replaced by a relative path.2. If the file path does not contain a *, the URL cannot contain a * and if the file path contains a * the URL must contain a *.3. If the file path contains a *, it must be the final character.4. If the URL contains a *, it may be anywhere in the URL."}},"required": ["documents"]
}

为了减轻生成该json的工作量,微软提供了一系列的软件包,自动生成Source Link 文件。

3.3 自动生成SourceLink

在.net core项目内,在.csproj文件内增加如下配置

<Project Sdk="Microsoft.NET.Sdk"><PropertyGroup><TargetFramework>netcoreapp2.1</TargetFramework><!-- Optional: Publish the repository URL in the built .nupkg (in the NuSpec <Repository> element) --><PublishRepositoryUrl>true</PublishRepositoryUrl><!-- Optional: Embed source files that are not tracked by the source control manager in the PDB --><EmbedUntrackedSources>true</EmbedUntrackedSources><!-- Optional: Build symbol package (.snupkg) to distribute the PDB containing Source Link --><IncludeSymbols>true</IncludeSymbols><SymbolPackageFormat>snupkg</SymbolPackageFormat></PropertyGroup><ItemGroup><!-- Add PackageReference specific for your source control provider (see below) --> </ItemGroup>
</Project>

按照需要引用下面的软件包,注意,这里设置为 PrivateAssets,以避免发布为nuget包后,引用该包的项目下载sourcelink 包。

  • github.com and GitHub Enterprise

<ItemGroup><PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.0.0" PrivateAssets="All"/>
</ItemGroup>
  • Azure Repos (former Visual Studio Team Services)

<ItemGroup><PackageReference Include="Microsoft.SourceLink.AzureRepos.Git" Version="1.0.0" PrivateAssets="All"/>
</ItemGroup>
  • Azure DevOps Server (former Team Foundation Server)

<ItemGroup><PackageReference Include="Microsoft.SourceLink.AzureDevOpsServer.Git" Version="1.0.0" PrivateAssets="All"/>
</ItemGroup>
  • 如果您的服务器配置有非空的IIS虚拟目录,请在SourceLinkAzureDevOpsServerGitHost项目中指定此目录,如下所示

<ItemGroup><SourceLinkAzureDevOpsServerGitHost Include="server-name" VirtualDirectory="tfs"/>
</ItemGroup>

该Include属性指定域以及服务器的端口(例如server-name或server-name:8080)。

  • GitLab

<ItemGroup><PackageReference Include="Microsoft.SourceLink.GitLab" Version="1.0.0" PrivateAssets="All"/>
</ItemGroup>
  • Bitbucket

<ItemGroup><PackageReference Include="Microsoft.SourceLink.Bitbucket.Git" Version="1.0.0" PrivateAssets="All"/>
</ItemGroup>

如果您的项目是由版本4.7之前的Bitbucket Server或Bitbucket Data Center托管的SourceLinkBitbucketGitHost,则除了软件包参考之外,还必须指定项目组:

<ItemGroup><SourceLinkBitbucketGitHost Include="bitbucket.yourdomain.com" Version="4.5"/>
</ItemGroup>

项目组SourceLinkBitbucketGitHost指定Bitbucket主机的域和Bitbucket的版本。该版本非常重要,因为用于访问文件的URL格式随版本4.7更改。默认情况下,源链接采用新格式(4.7+版)。

  • gitweb (pre-release)

<ItemGroup><PackageReference Include="Microsoft.SourceLink.GitWeb" Version="1.1.0-beta-20204-02" PrivateAssets="All"/>
</ItemGroup>

开发人员必须选择生成源链接文件。这些文件中包含的URL可能指向私有源存储库,这些存储库可能不打算公开给有权访问符号文件的任何人,因此,开发人员应做出明智的选择。

  • 开源开发人员通常选择不参与源链接文件生成,因为他们通常不存在公开问题。

  • 公司开发人员还应选择采用以下方式选择源链接文件生成:

    所有应用程序资产(二进制文件,符号和源代码)都在公司防火墙内使用,因此只有有权访问这些资产的用户才能看到它们。

    二进制资产是从外部运送的,但符号和源仅在公司防火墙内使用过,因此只有有权访问符号和源资产的用户才可以查看它们。

  • 公司开发人员还有另一个选择(可以说是反模式),如下所示:

    二进制和符号资产在外部共享。符号资产包含源链接文件(以及可能生成的文件资产)。
    源链接文件指向需要身份验证的符号源,例如VSTS。
    授权用户(数量可能很少)将可以访问源。
    未经授权的用户(数量可能更多)会从他们不理解的端点接收拒绝访问的消息。

3.4 源嵌入

在某些情况下,将源代码嵌入符号中是有益的,这样您就可以方便地部署源代码进行调试。但是,这是在便利性和PDB大小之间进行权衡的。尽管将源压缩存储在包含许多源文件的PDB中,但可能会大大增加PDB的大小。

以下嵌入选项(适用于Windows和便携式PDB)均可用:

  • 仅嵌入源代码管理未跟踪的源文件(例如,在生成期间生成的文件)。其余文件由源链接映射。

  • 嵌入手动选择的源文件子集。

  • 嵌入所有源文件

EmbedAllSources具有布尔值的Project属性表示所有传递给编译器的源都应嵌入到PDB中。

自动嵌入未跟踪的源文件

源链接使调试器和其他工具可以查找源控件跟踪的文件的源内容。但是,并非所有参与构建的文件都被跟踪。例如,在构建期间生成的文件通常不检入存储库。尽管可以手动识别此类文件并标记它们以将其嵌入到PDB中,但是这种过程繁琐且容易出错。

该SourceLink.Embed项目已经支持自动识别,而不是由源代码控制跟踪文件的嵌入。这些API将确定源代码控制未跟踪的文件(例如,对于git存储库,匹配.gitignore文件中条目的文件)和设置EmbedUntrackedSources,然后将指示编译器嵌入未跟踪的源代码。

下面是嵌入源代码的例子,在.csproj项目文件内增加如下配置

<PropertyGroup> <EmbedAllSources>True</EmbedAllSources><!--<EmbedUntrackedSources>true</EmbedUntrackedSources>-->
</PropertyGroup>

4.发布符号文件

默认情况下,符号被构建为单独的文件,以最小化二进制文件的大小。这些文件需要由构建它们的系统(例如CI服务器)发布,并由需要它们的系统(例如调试器)发现和检索。

4.1将符号发布到符号服务器

如今,符号服务器主要用于在企业环境中托管符号文件。符号服务器工具可用于此类环境,并且最近也已集成到VSTS中并作为服务公开。

对于在NuGet.org上发布其库的开发人员而言,可公开使用的符号服务器的选项受到限制,并且发布和使用符号的过程比应有的要复杂得多。因此,在NuGet.org上发布的易于调试的软件包数量很少。

符号包(snupkg)

今天,符号包用于分发符号和源。良好的调试体验依赖于调试符号的存在,因为它们提供了一些关键信息,例如已编译的代码与源代码之间的关联、局部变量的名称、堆栈跟踪等。你可以使用符号包 (.snupkg) 来分发这些符号,并改善 NuGet 包的调试体验。

如果使用 dotnet CLI 或 MSBuild,则除 .nupkg 文件外,还需要设置 IncludeSymbols 和 SymbolPackageFormat 属性以创建 .snupkg 文件。

创建 .snupkg 文件有多种方式实现该需求。

  • 将以下属性添加到 .csproj 文件:

<PropertyGroup><IncludeSymbols>true</IncludeSymbols><SymbolPackageFormat>snupkg</SymbolPackageFormat>
</PropertyGroup>
  • 在命令行上指定这些属性:

dotnet pack MyPackage.csproj -p:IncludeSymbols=true -p:SymbolPackageFormat=snupkg
  • 或者使用msbuild

msbuild MyPackage.csproj /t:pack /p:IncludeSymbols=true /p:SymbolPackageFormat=snupkg
  • 使用nuget

nuget pack MyPackage.nuspec -Symbols -SymbolPackageFormat snupkg
nuget pack MyPackage.csproj -Symbols -SymbolPackageFormat snupkg

发布服务包到nuget

# 为方便起见,首先使用 NuGet 保存 API 密钥
nuget SetApiKey Your-API-Key
# 将主包发布到 nuget.org 后,按如下方式推送符号包。
nuget push MyPackage.snupkg
# 还可以使用以下命令同时推送主包和符号包。当前文件夹中必须同时有 .nupkg 和 .snupkg 文件。
nuget push MyPackage.nupkg

4.2 不使用服务器,直接嵌入发布符号包和源文件

嵌入符号文件和源代码更简单,它不需要网络或互联网连接,也不需要任何配置即可指定源代码存储库和符号服务器的位置。因为配置私有的符号包服务,我暂时并没有找到合适的平台,因此我高度推荐你采用这种方式,非常的便捷,您只需要在csproj内增加如下代码,即可完成嵌入的便携式PDB,以及源文件的发布。

<PropertyGroup><DebugSymbols>True</DebugSymbols><DebugType>Embedded</DebugType><EmbedAllSources>True</EmbedAllSources>
</PropertyGroup>

对于.NET应用程序来说,嵌入PDB文件不会影响编译器的优化,所以也完全不会影响应用的性能。

4.3 使用私有gitlab保护代码

结合第3小节的介绍,我们可以很方便的结合gitlab sourceLink,来制作嵌入符号包,保护源码的发布方式:

<PropertyGroup><TargetFramework>netcoreapp3.1</TargetFramework>    <!-- Optional: Publish the repository URL in the built .nupkg (in the NuSpec <Repository> element) --><PublishRepositoryUrl>true</PublishRepositoryUrl><!-- Optional: Embed source files that are not tracked by the source control manager in the PDB --><EmbedUntrackedSources>true</EmbedUntrackedSources><!-- Optional: Build symbol package (.snupkg) to distribute the PDB containing Source Link --><DebugType>Embedded</DebugType><!--<IncludeSymbols>false</IncludeSymbols><SymbolPackageFormat>snupkg</SymbolPackageFormat>--></PropertyGroup><ItemGroup><PackageReference Include="Microsoft.SourceLink.GitLab" Version="1.0.0" PrivateAssets="All" /></ItemGroup>

如果能早点提供该方式,相信几年前的方案,我应该能胜出,是吧?

5.使用PDB(符号)和SourceLink

在Visual Studio或其他工具中使用符号应该很方便。它需要适用于所有.NET实现,包括.NET Core,.NET Framework,Xamarin,Unity和UWP。

使用符号进行调试的主要场景有以下三种:

  • 在开发阶段调试应用程序。在这种情况下,需要在构建系统外部检索第三方库符号,同时将应用程序符号生成为构建的一部分。

  • 在部署状态下调试应用程序。在这种情况下,需要检索应用程序和库符号。该方案将附加到正在运行的应用程序。

  • 调试应用程序的故障转储。在这种情况下,需要应用程序和库符号。

5.1符号和二进制文件一起分发

此方案适用于开发阶段。如果符号已经嵌入二进制文件中,则不适用。NuGet是二进制分发的一种常见情况,它允许将符号和二进制文件一起部署。

关键特征是符号文件将直接存在于磁盘上已加载的代码文件旁边,从而使调试器可以轻松地找到给定二进制文件的匹配符号文件。根据本文档中的指导,二进制文件和符号通常会以与以下示例类似的结构并置在NuGet包中。

/

/lib

/netstandard2.0

foo.dll

foo.pdb

.NET Core开发是以NuGet为中心的,这有助于解决此问题。在开发过程中(例如使用dotnet run),. NET Core运行时默认情况下从NuGet缓存加载库,从而使调试器可以在同一位置查找匹配的符号文件。

.NET Framework开发使用NuGet,但形式上使用较少。构建项目时,NuGet库将被复制到应用程序bin目录,而不是符号。结果,代码二进制和符号之间的链接丢失了。

构建系统应使用以下逻辑,以更好地启用带符号的调试

如果将代码二进制文件复制到某个位置,则还要将符号文件复制到同一位置。在大多数情况下,这将是应用程序bin目录。

5.2 符号和二进制文件分开分发

此方案适用于调试已部署的应用程序,崩溃转储以及调试NuGet软件包中未附带符号的第三方库。在这些情况下,您需要从符号服务器获取符号。

如上所述,我们建议为上传到NuGet.org的符号提供公共符号服务。您也可以根据需要使用其他符号服务器。

5.3 获取和消耗源文件

获取和消耗源文件主要是首先具有获取符号的功能。有了符号后,调试器将发现以下一种或多种情况是正确的:

  • 符号文件包含调试器正在寻找的源文件的嵌入式源,此时调试器将使用该源。

  • 该符号文件是Windows PDB,包含嵌入式源服务器信息。可以使用诸如pdbstr或GitLink之类的构建工具,使用源服务器信息来修改现有的Windows PDB。

  • 该符号文件包含一个嵌入式源链接文件,此时调试器将解释并执行源链接文件中的声明。

  • 否则,将无法通过本文档中讨论的机制获得源

注意:如果调试器无法在符号文件中或通过源链接找到源文件,它仍可以尝试使用**简单符号查询协议**在符号服务器上查找它。这将允许在二进制文件和符号构建完成之后稍后使源可用的情况。

6 小结

弄懂SourceLink和pdb的关系,竟然花费了我一个元旦假期,本来计划在假期内出篇文章简单介绍下,发现在自己都没有搞清楚的情况,写这些是对大家和自己的不负责任,因此,还是静下心来,仔细理清楚各个环节,希望能对大家有所帮助。

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

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

相关文章

放弃winform的窗体吧,改用html作界面,桌面应用程序UI的新的开发方式。

做过很多winform项目&#xff0c;都为winform控件头疼不已。想实现一些漂亮的样子总是很难。我这里列举几个缺点&#xff1a; 1.winform控件大多是 绝对布局 &#xff0c;你需要给出准确的坐标。那么在实现居中效果就会很难。 2.学习成本&#xff0c;也了解各个控件的结构&…

数学建模必备算法模型,全新升级!

转眼间2019年已经过去了四分之一&#xff0c;近日&#xff0c;2019年数学建模国赛的时间也已经出来啦&#xff0c;确定为9月12日&#xff08;周四&#xff09;18时至9月15日&#xff08;周日&#xff09;20时。随着各种各样的数模比赛源源不断地开展&#xff0c;时不时有小伙伴…

boostrap 鼠标滚轮滑动图片_16种基于Bootstrap的css3图片hover效果

bootstrap-image-hover是一款基于Bootstrap的css3图片hover效果。这组图片hover效果共16种特效。同时该特效也支持非Bootstrap版本。使用方法在页面中引入bootstrap相关文件和FontAwesome字体图标文件以及effects.min.css文件。HTML结构该css3图片hover效果的每一种效果都有它们…

从零开始学C++之STL(七):剩下5种算法代码分析与使用示例(remove 、rotate 、sort、lower_bound、accumulate)...

一、移除性算法 &#xff08;remove&#xff09; C Code 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 // TEMPLATE FUNCTION remove_copy template < class _InIt, class _OutIt, cl…

20 种物体破剖面图,真正的让你脑洞大开

全世界只有3.14 % 的人关注了数据与算法之美有很多东西的内部世界十分复杂&#xff0c;单纯的从表面看难以窥其精锐&#xff0c;今天咱们来看那些被劈成两半展示横截面的东西&#xff1a;1.安全气囊2.打火机3.各种枪械消音器4.集装箱船5.路虎车6.曲棍球头盔7.人类心脏8.数码相机…

你的公司内卷化了吗?

大家看上去都很忙&#xff0c;但就是没结果怎么办&#xff1f;忙有结果都是好的&#xff0c;没有结果都是问题。其实可以从三方面来看这个问题&#xff1a;1、没有正确找到方法大家都在教科书学过一只乌鸦喝水的故事。故事告诉人们遇到困难不要放弃&#xff0c;要运用身边可以利…

每日一笑 | 3 X 4 = ?

全世界只有3.14 % 的人关注了数据与算法之美&#xff08;图源网络&#xff0c;侵权删&#xff09;

堵俊平:开放治理是开源社区的终极之路 | DEV. Together 2021 中国开发者生态峰会...

内容来源&#xff1a;2021 年 6 月 5 日&#xff0c;由 SegmentFault 思否主办的 2021 中国开发者生态峰会圆满落幕。会上&#xff0c;开放原子开源基金会 TOC 主席、华为计算开源总经理堵俊平发表了《开放治理&#xff1a;开源社区的终极之路》的主题演讲。分享嘉宾&#xff1…

每日一笑 | 谷歌能严谨到什么地步?

全世界只有3.14 % 的人关注了数据与算法之美&#xff08;图源网络&#xff0c;侵权删&#xff09;

浏览器的定制与扩展

下载源代码 本文分如下章节&#xff1a; 前言 在MFC中使用浏览器 怎样扩展或定制浏览器 定制鼠标右键弹出出菜单 实现脚本扩展(很重要的external接口) C代码中如何调用网页脚本中的函数 定制消息框的标题 怎样定制、修改浏览器向Web服务器发送的HTTP请求头 怎样修改浏览器标识 …

通过反射实现IOC功能

闲来没事&#xff0c;自己就想着根据反射可以自己写一个简易的IOC组件。IOC组件说白了就是根据反射实例化对应的接口。废话不多说&#xff0c;开始说说我的解决方案。1、项目结构图&#xff1a;IOCTest为web MVC项目。Common 通过配置文件实例化对应的接口IBLL定义的接口BLL实现…

php 分享微博,php微信分享到朋友圈、QQ、朋友、微博

本文实例为大家分享了php微信分享到朋友圈、QQ、朋友、微博的具体代码&#xff0c;供大家参考&#xff0c;具体内容如下前台代码wx.config({debug: false,appId: "{$signPackage[appId]}",timestamp: "{$signPackage[timestamp]}",nonceStr: "{$signP…

如果这个世界都不按套路出牌将会变成怎么样。。。 | 今日最佳

全世界只有3.14 % 的人关注了青少年数学之旅&#xff08;图源网络&#xff0c;侵权删&#xff09;请你有话“直”说↓ ↓ ↓

关于面试,避开这几点,成功几率更大~~~

概述 又是一个大学毕业季&#xff0c;刚好最近几年参与过很多面试&#xff0c;把其中遇到的一些具有“代表性”的面试场景总结出来和小伙伴聊聊&#xff0c;助力小伙伴跳过一些面试大坑(强烈希望)。对于面试&#xff0c;有很多小伙伴认为只是聊技术、聊能力&#xff0c;其实不仅…

脚本语言php是什么意思,php是什么脚本语言

PHP是一种简单的&#xff0c;面向对象的&#xff0c;解释型的&#xff0c;健壮的&#xff0c;安全的&#xff0c;性能非常之高的&#xff0c;独立于架构的&#xff0c;可移植的&#xff0c;动态的脚本语言。PHP具有和JAVA类似的Class关键字。因为不需要虚拟机&#xff0c;以致速…

[IOS地图开发系类]2、位置解码CLGeocoder

2019独角兽企业重金招聘Python工程师标准>>> 接第一步的操作&#xff0c;获取到地址信息经纬度后&#xff0c;我们可以对其进行解码&#xff0c;解码采用的CLGeocoder这个类&#xff0c;使用方式如下&#xff1a; 1、在ViewControlelr.m文件中声明一个CLGeocoder的…

微软相关的开发资源列表(update)

MSDN总站 http://www.msdn.com/MSDN中文站 http://www.microsoft.com/china/msdn/MSDN台湾站http://www.microsoft.com/taiwan/ASP.NET总站 http://www.asp.net/http://www.gotdotnet.com/SQLServerCentral.com is the largest free SQL Server community on the Internet. W…

备战数学建模国赛,快速搞定算法模型!

全世界只有3.14 % 的人关注了青少年数学之旅说到数学建模&#xff0c;大家的第一反应就是国赛、美赛等数学建模比赛&#xff0c;但这只是冰山一角&#xff0c;不过这个反应却也很正常&#xff0c;因为很多小伙伴接触数学建模的契机&#xff0c;大部分还是因为数学建模相关的竞赛…

考虑用Task.WhenAll

异步能在一定场景中带性能的飞跃&#xff0c;同步调用性能&#xff0c;也以带来时间的节省。先看一下被调用的api:using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Logging; using System; using System.Collections.Generic; using System.Linq; using System.Th…

wordpress home.php,WordPress主题通过function.php来加载js和css文件

WordPress主题开发的时候可以直接将需要的js或css写在head标签中&#xff0c;但是现在已经不主张这种加载方式了&#xff0c;现在WordPress主题通过function.php来加载js和css文件。基本架构//加载css及jsfunction wpdie_add_scripts() {wp_enqueue_style(style, get_template_…