• 关于

    源程序文件类型是什么

    的搜索结果

回答

第一步: 首先检查一下 web服务器扩展里面 是否开启的asp服务 如果 没有开启 点击允许~ 第二步: IIS6里缺省下是不支持 ../ 路径的~~~ 因为安全考虑吧~ 在网站设置里,右键点出“属性”,在主目录中点击“配置”。在弹出的对话框中“选项”栏中,把“启用父路径”选中,就“噢”了~~ ok asp程序成功运行 如果失败 那没办法了 找微软吧 今天介绍的错误是:http服务器内部500错误,这个错误是很多站长无论是自己写的程序还是下载采用别人的源程序经常遇到的。一按错页面显示是: 网站无法显示该页面 HTTP 500 最可能的原因是: •该网站正在进行维护。 •该网站有程序错误。 您可以尝试以下操作: 刷新该网页。 返回到上一页。 更多信息 此错误(HTTP 500 内部服务器错误)意味着您正在访问的网站出现了服务器问题,此问题阻止了该网页的显示。 有关 HTTP 错误的详细信息,请参阅帮助。 很 多站长看到这个页面便目瞪口呆,有的人到百度搜索答案,网上的答案大同小异,很多都很复杂,根本不知道在说什么。其实服务器内部500错误大概可分为两 种,一种是服务器本身权限问题,另一种是程序上不规范或者错误造成。所以要解决此问题需要先弄清楚其到底是哪种原因,那该如何检测是那种原因呢?请往下 看: 在IE浏览器下点击 工具-internet选项-高级,滚动条拉到最后,将“显示友好HTTP错误信息”前的勾去掉,确定,这时刷新“500内部服务器错误”页面,或者重新启动该页面,页面便会弹出新的报错项目,这是网页报错的信息便会告诉你是原因导致此错误发生。 当 然这时,很多站长会发现即使显示出错误类型了,还是不知道怎么解决,最简单方法就是你吧新的错误类型再次复制到到百度里进行提问查询,便知道如何解决了。 对于程序问题,在这里实在不好说是怎么解决,因为程序错误类型很多,根本不知道各位站长会遇到怎样的错误,如果查出来是权限问题,那么好解决,往下看: 程 序在本地情况下:点击进入到源程序的根目录文件夹,点击最上面的 工具-文件夹选项-查看,将“使用简单文件共享(推荐)”前面的勾去掉,确定。这时要对你要设置权限的文件或者文件夹进行更改权限,选中文件或文件夹右 击,属性-安全-添加-高级-立即查找,在下面的一组用户中选择IWAM_(你的计算机名)和IUSR_(你的计算机名),确定,返回“安全”界面,将 IWAM_(你的计算机名)(为进程账户)权限设置为完全控制,IUSR_(你的计算机名)(来宾账户)设置成读取权限 答案来源于网络
养狐狸的猫 2019-12-02 02:18:16 0 浏览量 回答数 0

回答

第一步:购买域名域名都不陌生,就是地址栏里面输入的那一串字母,域名是需要注册购买的,建议域名自己注册购买,不要找代理商,现在的域名注册平台,自己注册一个账号就可以选购了,域名后缀要选择.com .cn等常用的后缀,买好后要记得上传证件认证,不然无法使用哦!第二步:域名ICP备案域名是否进行ICP备案,与你网站放在哪个地域有关,放在国内的网站就必须备案,没有为什么?这是国家规定,不想备案就要放国外或香港。在哪里备案呢?你的网站空间在哪买的就在哪备案,空间的提供商都有网站自助备案系统注册填写资料就好了。备案准备哪些资料呢?营业执照、法人身份证、公司座机、幕布照(幕布由服务商寄送)、公章(核验单盖章使用),所要的资料系统填写资料的时候都会有明确的提示,按照规定如实填写就好了,备案在你提交资料之后,一般会在20个工作日内通过审核。第三步:购买空间网站空间要在大的运营商购买,购买空间的时候要注意配置,主要是支持什么程序语言和数据库类型,这个是根据你网站源代码编程语言 和 数据库类型来选择,网站编程的语言一般有.net、php、jsp等,数据库一般有sql server、MySQL,根据你购买网站源文件语言和数据库的类型来选择配置,这个不能搞错,搞错了就无法配置了。第四步:网站源码选择之前的都只是准备工作,网站源代码才是网站核心,一般网站源代码获取有两种方式,获取源码其实也就是建站的方式,如果你是找第三方建站公司设计网站,完成后会将源码用ftp工具上传到你空间,一定要求服务商上传调试好网站能正常打开才可以。还有一种建站方式,完全自助式,需要自己在网站现在免费开源的建站程序,比如:织梦、WordPress等等,这一类对于小白用户不建议选择,因为对个人编程和设计能有有一定的要求,后期的问题也很多,很容易半途而废。第五步:域名解析上线最后一步就是解析域名,网站上传到空间了,需要将域名解析指向网站空间地址,前提是你的域名备案已经通过了才可以解析,域名能在浏览器中打开一个网站才能算是真正的完成。
和弦 2019-12-01 23:32:50 0 浏览量 回答数 0

问题

【百问百答】《OSS运维基础实战手册》

1、对象存储 OSS是什么? 2、文件存储NAS是什么? 3、文件存储CPFS是什么? 4、文件存储HDFS是什么? 5、表格存储是什么? 6、云存储网关是什么ÿ...
爱吃鱼的程序员 2021-01-08 15:32:06 12 浏览量 回答数 0

阿里云爆款特惠专场,精选爆款产品低至0.95折!

爆款ECS云服务器8.1元/月起,云数据库低至1.5折,限时抢购!

回答

API(Application Programming Interface,应用程序编程接口)是一套用来控制Windows的各个部件(从桌面的外观到为一个新进程分配的内存)的外观和行为的一套预先定义的Windows函数.用户的每个动作都会引发一个或几个函数的运行以告诉Windows发生了什么. 这在某种程度上很象Windows的天然代码.其他的语言只是提供一种能自动而且更容易的访问API的方法.VB在这方面作了很多工作.它完全隐藏了API并且提供了在Windows环境下编程的一种完全不同的方法. 这也就是说,你用VB写出的每行代码都会被VB转换为API函数传递给Windows.例如,Form1.Print...VB 将会以一定的参数(你的代码中提供的,或是默认参数)调用TextOut 这个API函数. 。同样,当你点击窗体上的一个按钮时,Windows会发送一个消息给窗体(这对于你来说是隐藏的),VB获取这个调用并经过分析后生成一个特定事件(Button_Click). API函数包含在Windows系统目录下的动态连接库文件中(如User32.dll,GDI32.dll,Shell32.dll...). API 声明 正如在"什么是API"中所说,API函数包含在位于系统目录下的DLL文件中.你可以自己输入API函数的声明,但VB提供了一种更简单的方法,即使用API Text Viewer. 要想在你的工程中声明API函数,只需运行API Text Viewer,打开Win32api.txt(或.MDB如果你已经把它转换成了数据库的话,这样可以加快速度.注:微软的这个文件有很多的不足,你可以试一下本站提供下载的api32.txt),选择"声明",找到所需函数,点击"添加(Add)"并"复制(Copy)",然后粘贴(Paste)到你的工程里.使用预定义的常量和类型也是同样的方法. 你将会遇到一些问题: 假设你想在你的窗体模块中声明一个函数.粘贴然后运行,VB会告诉你:编译错误...Declare 语句不允许作为类或对象模块中的 Public 成员...看起来很糟糕,其实你需要做的只是在声明前面添加一个Private(如 Private Declare Function...).--不要忘了,可是这将使该函数只在该窗体模块可用. 在有些情况下,你会得到"不明确的名称"这样的提示,这是因为函数.常量或其他的什么东西共用了一个名称.由于绝大多数的函数(也可能是全部,我没有验证过)都进行了别名化,亦即意味着你可以通过Alias子句使用其它的而不是他们原有的名称,你只需简单地改变一下函数名称而它仍然可以正常运行. API 分为四种类型: 远程过程调用(RPC):通过作用在共享数据缓存器上的过程(或任务)实现程序间的通信。 标准查询语言(SQL):是标准的访问数据的查询语言,通过通用数据库实现应用程序间的数据共享。 文件传输:文件传输通过发送格式化文件实现应用程序间数据共享。 信息交付:指松耦合或紧耦合应用程序间的小型格式化信息,通过程序间的直接通信实现数据共享。 当前应用于 API 的标准包括 ANSI 标准 SQL API。另外还有一些应用于其它类型的标准尚在制定之中。API 可以应用于所有计算机平台和操作系统。这些 API 以不同的格式连接数据(如共享数据缓存器、数据库结构、文件框架)。每种数据格式要求以不同的数据命令和参数实现正确的数据通信,但同时也会产生不同类型的错误。因此,除了具备执行数据共享任务所需的知识以外,这些类型的 API 还必须解决很多网络参数问题和可能的差错条件,即每个应用程序都必须清楚自身是否有强大的性能支持程序间通信。相反由于这种 API 只处理一种信息格式,所以该情形下的信息交付 API 只提供较小的命令、网络参数以及差错条件子集。正因为如此,交付 API 方式大大降低了系统复杂性,所以当应用程序需要通过多个平台实现数据共享时,采用信息交付 API 类型是比较理想的选择。 API 与图形用户接口(GUI)或命令接口有着鲜明的差别: API 接口属于一种操作系统或程序接口,而后两者都属于直接用户接口。 有时公司会将 API 作为其公共开放系统。也就是说,公司制定自己的系统接口标准,当需要执行系统整合、自定义和程序应用等操作时,公司所有成员都可以通过该接口标准调用源代码,该接口标准被称之为开放式 API。 da'an'lai'yu'na'w'n答案来源网络,供您参考
问问小秘 2019-12-02 02:13:03 0 浏览量 回答数 0

问题

Mac OS X上Python的框架版本与非框架版本之间的差异

在Mac OS X上,Python的Framework构建和非Framework构建(即标准UNIX构建)之间有什么区别?另外,每种技术都有哪些优缺点? ...
祖安文状元 2020-02-21 15:57:47 0 浏览量 回答数 1

问题

“/”应用程序中的服务器错误。

网站故障描述 我们的网站刚建好第一年是建站公司帮我放在阿里云的一个虚拟空间里,一年免费服务到期前我自己在阿里云购买了独立服务器才迁移到现在的服务器的。在这之前网站放在阿里云的虚拟空间里时没有出现过这种现象,...
jinyibz 2019-12-01 18:53:48 251 浏览量 回答数 1

回答

此分步示例适用于可能会偶然发现此问题的其他人。本示例使用SSIS 2005并使用SQL Server 2005 64位版本服务器运行作业。 这里的答案仅集中于解决问题中提到的错误消息。该示例将演示重新创建问题的步骤以及引起问题的原因,然后介绍如何解决此问题。 NOTE:我建议使用选项将软件包配置值存储在数据库中,或者在环境变量的帮助下使用间接XML配置。同样,创建Excel文件的步骤将使用模板完成,然后将其移动到其他文件夹中进行存档。这些步骤不在本文中讨论。如前所述,本文的目的是解决错误。 让我们继续该示例。我也已经在博客上写了这个答案,可以在此链接中找到。答案是一样的。 创建一个SSIS包(创建SSIS包的步骤)。本示例使用BIDS2005。我在开始时就以YYYYMMDD_hhmm的格式命名了程序包,其后是SO代表堆栈溢出,然后是SO问题ID,最后是描述。我并不是说您应该这样命名您的包裹。这是我以后可以轻松参考的内容。请注意,我还有一个名为Adventure Works的数据源。我将使用Adventure Works数据源,该数据源指向从此链接下载的AdventureWorks数据库。该示例使用SQL Server 2008 R2数据库。请参阅截图1。 在AdventureWorks数据库中,使用以下给定脚本创建一个名为dbo.GetCurrency的存储过程。 CREATE PROCEDURE [dbo].[GetCurrency] AS BEGIN SET NOCOUNT ON; SELECT TOP 10 CurrencyCode , Name , ModifiedDate FROM Sales.Currency ORDER BY CurrencyCode END GO 在包的“连接管理器”部分,右键单击并选择“从数据源新建连接”。在“ 选择数据源”对话框中,选择“ Adventure Works”,然后单击“确定”。现在,您应该在“ 连接管理器”部分下看到Adventure Works数据源。 在包的“连接管理器”部分,再次右键单击,但是这次选择“ 新建连接…”。这是为了创建Excel连接。在“添加SSIS连接管理器”上,选择“ EXCEL”。在Excel连接管理器上,输入路径C:\ Temp \ Template.xls。将其部署到服务器时,将更改此路径。我选择了Excel版本Microsoft Excel 97-2005,并选择了保留复选框第一行的列名称已选中,以便在创建Excel文件时创建列标题。单击确定。重命名的Excel连接到Excel中,只是为了保持简单。请参阅截图#2 - #7。 在包上,创建以下变量。请参阅截图8。 SQLGetData:此变量的类型为String。这将包含存储过程执行语句。本示例使用值EXEC dbo.GetCurrency 屏幕快照#9显示了存储过程执行语句EXEC dbo.GetCurrency的输出。 在程序包的“控制流”选项卡上,放置一个Data Flow task并将其命名为“导出到Excel”。请参阅屏幕截图#10。 双击“数据流任务”以切换到“数据流”选项卡。 在“数据流”选项卡上,放置一个,OLE DB Source以连接到SQL Server数据以从存储过程中获取数据,并将其命名为SQL。双击OLE DB源,以调出OLE DB源编辑器。在“连接管理器”部分上,从OLE DB连接管理器中选择Adventure Works,从“数据访问”模式的变量中选择SQL命令,然后从“变量名”下拉列表中选择变量User :: SQLGetData。在“列”部分,确保正确映射了列名称。单击“确定”关闭OLE DB源编辑器。请参阅#11和#12屏幕截图。 在“数据流”选项卡上,放置一个,Excel Destination以将数据插入Excel文件并将其命名为Excel。双击Excel目标以打开Excel目标编辑器。在“连接管理器”部分上,从OLE DB连接管理器中选择Excel,然后选择“表”或“数据访问”模式下的视图。此时,我们没有Excel,因为在创建Excel连接管理器时,我们仅指定了路径,但从未创建文件。因此,Excel工作表的下拉名称中将没有任何值。因此,单击“ 新建”。按钮(第二个新按钮)来创建新的Excel工作表。在“创建表”窗口上,BIDS根据传入的数据源自动提供一个创建表。您可以根据自己的喜好更改值。我将通过保留默认值来简单地单击“确定”。工作表的名称将填充在Excel工作表的下拉名称中。工作表的名称取自任务名称,在本例中为Excel Destination,我们将其命名为Excel。在“映射”部分,确保正确映射了列名称。单击“确定”关闭Excel Destination Editor。请参阅截图#13 - #16。 数据流任务配置完成后,其外观应如屏幕截图#17所示。 通过按F5执行包。截图#18 - #21显示了包的两个控制流和数据流任务的成功执行。同样,该文件是在Excel连接中提供的路径C:\ Temp \ Template.xls中生成的,并且存储过程执行输出中显示的数据与写入该文件的数据匹配。 该程序包是在本地计算机上的文件夹路径C:\ Learn \ Learn.VS2005 \ Learn.SSIS中开发的。现在,我们需要将文件部署到承载SQL Server 64位版本的服务器上,以计划作业。因此,服务器上的文件夹将为D:\ SSIS \ Practice。复制包文件(.dtsx),然后将其粘贴到服务器文件夹中。另外,为了使程序包正确运行,我们需要在服务器上显示Excel电子表格。否则,验证将失败。通常,我创建一个Template文件夹,其中将包含与输出匹配的空Excel电子表格文件。稍后,在运行时,我将使用程序包配置将Excel输出路径更改为其他位置。对于此示例,我将使其保持简单。因此,我们将在本地计算机中生成的Excel文件复制到路径C:\ Temp \ Template.xls到服务器位置D:\ SSIS \ Practice中。我希望SQL作业生成名称为Currencies.xls的文件。因此,将文件Template.xls重命名为Currencies.xls。请参阅屏幕截图#22。 为了表明我确实要在64位版本的SQL Server上的服务器上运行该作业,我在SQL Server上执行了SELECT @@ version命令,屏幕快照#23显示了结果。 我们将使用执行包实用程序(dtexec.exe)生成命令行参数。登录到将在SQL作业中运行SSIS包的服务器。双击程序包文件,这将显示“执行程序包实用程序”。在“常规”部分,从“包源”中选择“文件系统”。单击省略号,然后浏览到程序包路径。在“连接管理器”部分,选择“ Excel”并将Excel文件中的路径从C:\ Temp \ Template.xls更改为D:\ SSIS \ Practice \ Currencies.xls。在实用程序中所做的更改将在“命令行”部分相应地生成命令行。在“命令行”部分,复制包含所有必需参数的命令行。我们不会从这里执行该程序包。单击关闭。参考屏幕截图#24 - #26。 接下来,我们需要设置一个作业来运行SSIS包。我们无法选择SQL Server Integration Services包类型,因为它将在64位下运行,并且找不到Excel连接提供程序。因此,我们必须将其作为Operating System (CmdExec)作业类型运行。转到SQL Server Management Studio,然后连接到数据库引擎。展开“ SQL Server代理”,然后右键单击“作业”节点。选择新作业…。在“作业属性”窗口的“常规”部分,提供作业名称为01_SSIS_Export_To_Excel,所有者将是创建作业的用户。我有一个名为SSIS的类别,因此将选择该类别,但默认类别为[未分类(本地)],并提供简短说明。在“步骤”部分,单击“ 新建...”。按钮。这将带来“作业步骤”属性。在“作业步骤”属性的“常规”部分,提供“步骤名称”为“导出到Excel”,选择“类型” Operating system (CmdExec),保留默认的“以帐户身份运行”作为“ SQL Server代理服务帐户”,并提供以下命令。单击确定。在“新建作业”窗口上,单击“确定”。请参阅截图#27 - #31。 C:\Program Files (x86)\Microsoft SQL Server\90\DTS\Binn\DTExec.exe /FILE "D:\SSIS\Practice\20110723_1015_SO_21448_Excel_64_bit_Error.dtsx" /CONNECTION Excel;"\"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=D:\SSIS\Practice\Currencies.xls;Extended Properties=""EXCEL 8.0;HDR=YES"";\"" /MAXCONCURRENT " -1 " /CHECKPOINTING OFF /REPORTING EWCDI 新作业应显示在“ SQL Server代理–>作业”节点下。右键单击新创建的作业01_SSIS_Export_To_Excel,然后选择“ 在步骤…处启动作业”,这将开始执行作业。该作业将按预期失败,因为这是此问题的背景。单击关闭以关闭“启动作业”对话框。请参阅#32和#33屏幕截图。 让我们看看发生了什么。转到“ SQL Server代理和作业”节点。右键单击作业01_SSIS_Export_To_Excel,然后选择查看历史记录。这将打开“日志文件查看器”窗口。您会注意到作业失败。展开红叉附近的节点,然后单击“步骤ID”值为1的行。在底部,您可以看到错误消息。Option “8.0;HDR=YES’;” is not valid.单击“关闭”以关闭“日志文件查看器”窗口。请参阅#34和#35屏幕截图。 现在,右键单击作业,然后选择“属性”以打开“作业属性”。您也可以双击作业以打开“作业属性”窗口。单击左侧的步骤。然后单击编辑。用以下命令替换该命令,然后单击“确定”。在作业属性上单击确定以关闭窗口。右键单击作业01_SSIS_Export_To_Excel,然后选择“在步骤...启动作业”,这将开始执行作业。作业将无法成功执行。单击关闭以关闭“启动作业”对话框。让我们来看看历史。右键单击作业01_SSIS_Export_To_Excel,然后选择查看历史记录。这将打开“日志文件查看器”窗口。您会注意到该作业在第二次运行中成功完成。展开绿色勾号交叉点附近的节点,然后单击“步骤ID”值为1的行。在底部,您会看到消息选项步骤已成功。单击“关闭”关闭“日志文件查看器”窗口。文件D:\ SSIS \ Practice \ Currencies.xls将成功填充数据。如果您多次成功执行作业,则数据将被追加到文件中,并且您将找到更多数据。如前所述,这不是生成文件的正确方法。创建此示例的目的是为了解决此问题。参考屏幕截图 创建此示例的目的是为了解决此问题。参考屏幕截图 创建此示例的目的是为了解决此问题。参考屏幕截图#36 - #38。 屏幕截图#39显示了工作命令行参数和非工作命令行参数之间的差异。右边的是工作命令行,左边的是不正确的命令行。它需要使用反斜杠转义序列的另一个双引号来修复该错误。可能还有其他方法可以很好地解决此问题,但此选项似乎可行。 因此,该示例演示了一种从部署在64位服务器上的SSIS包访问Excel数据源时解决命令行参数问题的方法。 希望能对某人有所帮助。
心有灵_夕 2019-12-25 21:28:07 0 浏览量 回答数 0

问题

【精品问答】Java必备核心知识1000+(附源码)

为了方便Java开发者快速找到相关技术问题和答案,开发者社区策划了Java技术1000问内容,包含最基础的如何学Java、实践中遇到的技术问题、RocketMQ面试、Java容器部署实践等维度内容。 我们会以每...
问问小秘 2019-12-01 22:00:28 870 浏览量 回答数 1

回答

相信对于很多Java开发来说,在刚刚接触Java语言的时候,就听说过Java是一门跨平台的语言,Java是平台无关性的,这也是Java语言可以迅速崛起并风光无限的一个重要原因。那么,到底什么是平台无关性?Java又是如何实现平台无关性的呢?本文就来简单介绍一下。 什么是平台无关性 平台无关性就是一种语言在计算机上的运行不受平台的约束,一次编译,到处执行(Write Once ,Run Anywhere)。 也就是说,用Java创建的可执行二进制程序,能够不加改变的运行于多个平台。 平台无关性好处 作为一门平台无关性语言,无论是在自身发展,还是对开发者的友好度上都是很突出的。 因为其平台无关性,所以Java程序可以运行在各种各样的设备上,尤其是一些嵌入式设备,如打印机、扫描仪、传真机等。随着5G时代的来临,也会有更多的终端接入网络,相信平台无关性的Java也能做出一些贡献。 对于Java开发者来说,Java减少了开发和部署到多个平台的成本和时间。真正的做到一次编译,到处运行。 平台无关性的实现 对于Java的平台无关性的支持,就像对安全性和网络移动性的支持一样,是分布在整个Java体系结构中的。其中扮演者重要的角色的有Java语言规范、Class文件、Java虚拟机(JVM)等。 编译原理基础 讲到Java语言规范、Class文件、Java虚拟机就不得不提Java到底是是如何运行起来的。 我们在Java代码的编译与反编译那些事儿中介绍过,在计算机世界中,计算机只认识0和1,所以,真正被计算机执行的其实是由0和1组成的二进制文件。 但是,我们日常开发使用的C、C++、Java、Python等都属于高级语言,而非二进制语言。所以,想要让计算机认识我们写出来的Java代码,那就需要把他"翻译"成由0和1组成的二进制文件。这个过程就叫做编译。负责这一过程的处理的工具叫做编译器。 在深入分析Java的编译原理中我们介绍过,在Java平台中,想要把Java文件,编译成二进制文件,需要经过两步编译,前端编译和后端编译: 前端编译主要指与源语言有关但与目标机无关的部分。Java中,我们所熟知的javac的编译就是前端编译。除了这种以外,我们使用的很多IDE,如eclipse,idea等,都内置了前端编译器。主要功能就是把.java代码转换成.class代码。 这里提到的.class代码,其实就是Class文件。 后端编译主要是将中间代码再翻译成机器语言。Java中,这一步骤就是Java虚拟机来执行的。 所以,我们说的,Java的平台无关性实现主要作用于以上阶段。如下图所示: 我们从后往前介绍一下这三位主演:Java虚拟机、Class文件、Java语言规范 Java虚拟机 所谓平台无关性,就是说要能够做到可以在多个平台上都能无缝对接。但是,对于不同的平台,硬件和操作系统肯定都是不一样的。 对于不同的硬件和操作系统,最主要的区别就是指令不同。比如同样执行a+b,A操作系统对应的二进制指令可能是10001000,而B操作系统对应的指令可能是11101110。那么,想要做到跨平台,最重要的就是可以根据对应的硬件和操作系统生成对应的二进制指令。 而这一工作,主要由我们的Java虚拟机完成。虽然Java语言是平台无关的,但是JVM确实平台有关的,不同的操作系统上面要安装对应的JVM。 上图是Oracle官网下载JDK的指引,不同的操作系统需要下载对应的Java虚拟机。 有了Java虚拟机,想要执行a+b操作,A操作系统上面的虚拟机就会把指令翻译成10001000,B操作系统上面的虚拟机就会把指令翻译成11101110。 ps:图中的Class文件中内容为mock内容 所以,Java之所以可以做到跨平台,是因为Java虚拟机充当了桥梁。他扮演了运行时Java程序与其下的硬件和操作系统之间的缓冲角色。 字节码 各种不同的平台的虚拟机都使用统一的程序存储格式——字节码(ByteCode)是构成平台无关性的另一个基石。Java虚拟机只与由字节码组成的Class文件进行交互。 我们说Java语言可以Write Once ,Run Anywhere。这里的Write其实指的就是生成Class文件的过程。 因为Java Class文件可以在任何平台创建,也可以被任何平台的Java虚拟机装载并执行,所以才有了Java的平台无关性。 Java语言规范 已经有了统一的Class文件,以及可以在不同平台上将Class文件翻译成对应的二进制文件的Java虚拟机,Java就可以彻底实现跨平台了吗? 其实并不是的,Java语言在跨平台方面也是做了一些努力的,这些努力被定义在Java语言规范中。 比如,Java中基本数据类型的值域和行为都是由其自己定义的。而C/C++中,基本数据类型是由它的占位宽度决定的,占位宽度则是由所在平台决定的。所以,在不同的平台中,对于同一个C++程序的编译结果会出现不同的行为。 举一个简单的例子,对于int类型,在Java中,int占4个字节,这是固定的。 但是在C++中却不是固定的了。在16位计算机上,int类型的长度可能为两字节;在32位计算机上,可能为4字节;当64位计算机流行起来后,int类型的长度可能会达到8字节。(这里说的都是可能哦!) 通过保证基本数据类型在所有平台的一致性,Java语言为平台无关性提供强了有力的支持。 小结 对于Java的平台无关性的支持是分布在整个Java体系结构中的。其中扮演着重要角色的有Java语言规范、Class文件、Java虚拟机等。 Java语言规范 通过规定Java语言中基本数据类型的取值范围和行为 Class文件 所有Java文件要编译成统一的Class文件 Java虚拟机 通过Java虚拟机将Class文件转成对应平台的二进制文件等 Java的平台无关性是建立在Java虚拟机的平台有关性基础之上的,是因为Java虚拟机屏蔽了底层操作系统和硬件的差异。 语言无关性 其实,Java的无关性不仅仅体现在平台无关性上面,向外扩展一下,Java还具有语言无关性。 前面我们提到过。JVM其实并不是和Java文件进行交互的,而是和Class文件,也就是说,其实JVM运行的时候,并不依赖于Java语言。 时至今日,商业机构和开源机构已经在Java语言之外发展出一大批可以在JVM上运行的语言了,如Groovy、Scala、Jython等。之所以可以支持,就是因为这些语言也可以被编译成字节码(Class文件)。而虚拟机并不关心字节码是有哪种语言编译而来的。详见牛逼了,教你用九种语言在JVM上输出HelloWorld 参考资料 《深入理解Java虚拟机(第二版)》 《深入Java虚拟机》 《Java语言规范——基于Java SE 8》 《Java虚拟机规范第8版》
montos 2020-06-01 15:54:00 0 浏览量 回答数 0

问题

【精品问答】Python二级考试题库

1.关于数据的存储结构,以下选项描述正确的是( D ) A: 数据所占的存储空间量 B: 存储在外存中的数据 C: 数据在计算机中的顺序存储方式 D: 数据的逻辑结构在计算机中的表示 2.关于线性...
珍宝珠 2019-12-01 22:03:38 7177 浏览量 回答数 3

回答

在Java中,常量池的概念想必很多人都听说过。这也是面试中比较常考的题目之一。在Java有关的面试题中,一般习惯通过String的有关问题来考察面试者对于常量池的知识的理解,几道简单的String面试题难倒了无数的开发者。所以说,常量池是Java体系中一个非常重要的概念。 谈到常量池,在Java体系中,共用三种常量池。分别是字符串常量池、Class常量池和运行时常量池。 本文先来介绍一下到底什么是Class常量池。 什么是Class文件 在Java代码的编译与反编译那些事儿中我们介绍过Java的编译和反编译的概念。我们知道,计算机只认识0和1,所以程序员写的代码都需要经过编译成0和1构成的二进制格式才能够让计算机运行。 我们在《深入分析Java的编译原理》中提到过,为了让Java语言具有良好的跨平台能力,Java独具匠心的提供了一种可以在所有平台上都能使用的一种中间代码——字节码(ByteCode)。 有了字节码,无论是哪种平台(如Windows、Linux等),只要安装了虚拟机,都可以直接运行字节码。 同样,有了字节码,也解除了Java虚拟机和Java语言之间的耦合。这话可能很多人不理解,Java虚拟机不就是运行Java语言的么?这种解耦指的是什么? 其实,目前Java虚拟机已经可以支持很多除Java语言以外的语言了,如Groovy、JRuby、Jython、Scala等。之所以可以支持,就是因为这些语言也可以被编译成字节码。而虚拟机并不关心字节码是有哪种语言编译而来的。 Java语言中负责编译出字节码的编译器是一个命令是javac。 javac是收录于JDK中的Java语言编译器。该工具可以将后缀名为.java的源文件编译为后缀名为.class的可以运行于Java虚拟机的字节码。 如,我们有以下简单的HelloWorld.java代码: public class HelloWorld { public static void main(String[] args) { String s = "Hollis"; } } 通过javac命令生成class文件: javac HelloWorld.java 生成HelloWorld.class文件:  如何使用16进制打开class文件:使用 vim test.class ,然后在交互模式下,输入:%!xxd 即可。 可以看到,上面的文件就是Class文件,Class文件中包含了Java虚拟机指令集和符号表以及若干其他辅助信息。 要想能够读懂上面的字节码,需要了解Class类文件的结构,由于这不是本文的重点,这里就不展开说明了。 读者可以看到,HelloWorld.class文件中的前八个字母是cafe babe,这就是Class文件的魔数(Java中的”魔数”) 我们需要知道的是,在Class文件的4个字节的魔数后面的分别是4个字节的Class文件的版本号(第5、6个字节是次版本号,第7、8个字节是主版本号,我生成的Class文件的版本号是52,这时Java 8对应的版本。也就是说,这个版本的字节码,在JDK 1.8以下的版本中无法运行)在版本号后面的,就是Class常量池入口了。 Class常量池 Class常量池可以理解为是Class文件中的资源仓库。 Class文件中除了包含类的版本、字段、方法、接口等描述信息外,还有一项信息就是常量池(constant pool table),用于存放编译器生成的各种字面量(Literal)和符号引用(Symbolic References)。 由于不同的Class文件中包含的常量的个数是不固定的,所以在Class文件的常量池入口处会设置两个字节的常量池容量计数器,记录了常量池中常量的个数。  当然,还有一种比较简单的查看Class文件中常量池的方法,那就是通过javap命令。对于以上的HelloWorld.class,可以通过 javap -v HelloWorld.class 查看常量池内容如下:  从上图中可以看到,反编译后的class文件常量池中共有16个常量。而Class文件中常量计数器的数值是0011,将该16进制数字转换成10进制的结果是17。 原因是与Java的语言习惯不同,常量池计数器是从0开始而不是从1开始的,常量池的个数是10进制的17,这就代表了其中有16个常量,索引值范围为1-16。 常量池中有什么 介绍完了什么是Class常量池以及如何查看常量池,那么接下来我们就要深入分析一下,Class常量池中都有哪些内容。 常量池中主要存放两大类常量:字面量(literal)和符号引用(symbolic references)。 字面量 前面说过,运行时常量池中主要保存的是字面量和符号引用,那么到底什么字面量? 在计算机科学中,字面量(literal)是用于表达源代码中一个固定值的表示法(notation)。几乎所有计算机编程语言都具有对基本值的字面量表示,诸如:整数、浮点数以及字符串;而有很多也对布尔类型和字符类型的值也支持字面量表示;还有一些甚至对枚举类型的元素以及像数组、记录和对象等复合类型的值也支持字面量表示法。 以上是关于计算机科学中关于字面量的解释,并不是很容易理解。说简单点,字面量就是指由字母、数字等构成的字符串或者数值。 字面量只可以右值出现,所谓右值是指等号右边的值,如:int a=123这里的a为左值,123为右值。在这个例子中123就是字面量。 int a = 123; String s = "hollis"; 上面的代码事例中,123和hollis都是字面量。 本文开头的HelloWorld代码中,Hollis就是一个字面量。 符号引用 常量池中,除了字面量以外,还有符号引用,那么到底什么是符号引用呢。 符号引用是编译原理中的概念,是相对于直接引用来说的。主要包括了以下三类常量: * 类和接口的全限定名 * 字段的名称和描述符 * 方法的名称和描述符 这也就可以印证前面的常量池中还包含一些com/hollis/HelloWorld、main、([Ljava/lang/String;)V等常量的原因了。 Class常量池有什么用 前面介绍了这么多,关于Class常量池是什么,怎么查看Class常量池以及Class常量池中保存了哪些东西。有一个关键的问题没有讲,那就是Class常量池到底有什么用。 首先,可以明确的是,Class常量池是Class文件中的资源仓库,其中保存了各种常量。而这些常量都是开发者定义出来,需要在程序的运行期使用的。 在《深入理解Java虚拟》中有这样的表述: Java代码在进行Javac编译的时候,并不像C和C++那样有“连接”这一步骤,而是在虚拟机加载Class文件的时候进行动态连接。也就是说,在Class文件中不会保存各个方法、字段的最终内存布局信息,因此这些字段、方法的符号引用不经过运行期转换的话无法得到真正的内存入口地址,也就无法直接被虚拟机使用。当虚拟机运行时,需要从常量池获得对应的符号引用,再在类创建时或运行时解析、翻译到具体的内存地址之中。关于类的创建和动态连接的内容,在虚拟机类加载过程时再进行详细讲解。 前面这段话,看起来很绕,不是很容易理解。其实他的意思就是: Class是用来保存常量的一个媒介场所,并且是一个中间场所。在JVM真的运行时,需要把常量池中的常量加载到内存中。 至于到底哪个阶段会做这件事情,以及Class常量池中的常量会以何种方式被加载到具体什么地方,会在本系列文章的后续内容中继续阐述。欢迎关注我的博客(http://www.hollischuang.com) 和公众号(Hollis),即可第一时间获得最新内容。 另外,关于常量池中常量的存储形式,以及数据类型的表示方法本文中并未涉及,并不是说这部分知识点不重要,只是Class字节码的分析本就枯燥,作者不想在一篇文章中给读者灌输太多的理论上的内容。感兴趣的读者可以自行Google学习,如果真的有必要,我也可以单独写一篇文章再深入介绍。 参考资料 《深入理解java虚拟机》 《Java虚拟机原理图解》 1.2.2、Class文件中的常量池详解(上)
montos 2020-06-02 10:12:18 0 浏览量 回答数 0

问题

【开源项目】Seata问答集锦

当发现必须延迟实例化的bean的目标类时,Seata GlobalTransactionScanner.wrapIfNecessary触发BeanInstantiationExceptionSpringBoot与 Seata ...
一人吃饱,全家不饿 2021-02-02 11:31:44 2 浏览量 回答数 0

回答

Oracle不提供开箱即用的卸载实用程序。 请记住,如果没有有关您的环境的全面信息(Oracle版本?服务器平台?多少数据?什么数据类型?),这里的所有内容都是YMMV,您可能希望在系统上使用它来提高性能和计时。 我的观点1-3只是通用的数据移动思想。第4点是一种将停机时间或中断时间减少到几分钟或几秒钟的方法。 1)有第三方实用程序。我已经使用了其中一些,但最适合您根据自己的意图检查一下。这里列出了一些第三方产品:OraFaq。不幸的是,除非其中的DB服务器在Windows上并且您可以直接在服务器上运行load实用程序,否则它们中的许多都将在Windows上运行,这会减慢数据卸载过程。 2)如果您没有像LOB这样的复杂数据类型,则可以使用SQLPLUS进行滚动。如果您一次创建一个表,则可以轻松对其进行并行化。可能已经多次访问了此主题,这里有一个示例:Linky 3)如果您的年龄在10克以上,则外部表可能是完成此任务的一种有效方法。如果创建具有与当前表相同结构的空白外部表并将数据复制到它们中,则数据将转换为外部表格式(文本文件)。再次,OraFAQ进行救援。 4)如果必须将系统并行运行几天/几周/几月,请使用变更数据捕获/应用工具将停机时间几乎设为零。准备支付$$$。我使用了Golden Gate Software的工具,该工具可以挖掘Oracle重做日志并向MySQL数据库提供插入/更新语句。在上线前一周,您可以在不停机的情况下迁移大量数据。然后在上线期间,关闭源数据库,让Golden Gate赶上最后剩下的事务,然后打开对新目标数据库的访问。我已经使用它进行升级了,追赶期只有几分钟。我们已经有了Golden Gate的站点许可证,因此对于我们而言,这并不是什么便宜的事情。 我将在这里扮演Cranky DBA的角色,并说如果您不能使Oracle表现良好,我很乐意看到有关MySQL如何解决您的特定问题的文章。如果您有一个无法使用SQL的应用程序,那么仍有许多可能的方法来调整Oracle。/肥皂盒来源:stack overflow
保持可爱mmm 2020-05-16 22:28:04 0 浏览量 回答数 0

回答

很多人电脑是不是会出现各种蓝屏故障问题啊,出现问题又不知道怎么样解决。 1.故障检查信息 *STOP 0x0000001E(0xC0000005,0xFDE38AF9,0x0000001,0x7E8B0EB4)KMODE_EXCEPTION_NOT_HANDLED * 其中错误的第一部分是停机码(Stop Code)也就是STOP 0x0000001E, 用于识别已发生错误的类型, 错误第二部分是被括号括起来的四个数字集, 表示随机的开发人员定义的参数(这个参数对于普通用户根本无法理解, 只有驱动程序编写者或者操作系统的开发人员才懂). 第三部分是错误名. 信息第一行通常用来识别生产错误的驱动程序或者设备. 2.推荐操作蓝屏第二部分是推荐用户进行的操作信息. 有时, 推荐的操作仅仅是一般性的建议; 有时, 也就是显示一条与当前问题相关的提示. 一般来说, 惟一的建议就是重启. 3.调试端口告诉用户内存转储映像是否写到磁盘商了, 使用内存转储映像可以确定发生问题的性质, 还会告诉用户调试信息是否被传到另一台电脑商, 以及使用了什么端口完成这次通讯. 蓝屏时的处理办法:1.重启有时只是某个程序或驱动程序一时犯错, 重启后有可能就会正常。 2.新硬件首先, 应该检查新硬件是否插牢, 这个被许多人忽视的问题往往会引发许多莫名其妙的故障. 如果确认没有问题, 将其拔下, 然后换个插槽试试, 并安装最新的驱动程序. 同时还应对照微软网站的硬件兼容类别检查一下硬件是否与操作系统兼容. 3.新驱动和新服务如果刚安装完某个硬件的新驱动, 或安装了某个软件, 而它又在系统服务中添加了相应项目, 在重启或使用中出现了蓝屏故障, 请到安全模式来卸载或禁用它们. 4.检查病毒比如冲击波和振荡波等病毒有时会导致Windows蓝屏死机, 因此查杀病毒必不可少. 同时一些木马间谍软件也会引发蓝屏, 所以最好再用相关工具进行扫描检查. 5.检查BIOS和硬件兼容性对于新装的电脑经常出现蓝屏问题, 应该检查并升级BIOS到最新版本, 同时关闭其中的内存相关项, 比如:缓存和映射. 另外, 还应该对照微软的硬件兼容列表检查自己的硬件. 还有就是, 如果主板BIOS无法支持大容量硬盘也会导致蓝屏, 需要对其进行升级. 6.检查系统曰志在开始-->菜单中输入:EventVwr.msc, 回车出现"事件查看器", 注意检查其中的"系统曰志"和"应用程序曰志"中表明"错误"的项. 7.最后一次正确配置 最后一次正确配置界面 一般情况下, 蓝屏都出现于更新了硬件驱动或新加硬件并安装其驱动后, 这时Windows 2K/XP提供的"最后一次正确配置"就是解决蓝屏的快捷方式. 重启系统, 在出现启动菜单时按下F8键就会出现高级启动选项菜单, 接着选择"最后一次正确配置". 常见的蓝屏代码 0X0000000操作完成 0X0000001不正确的函数 0X0000002系统找不到指定的文件 0X0000003系统找不到指定的路径 0X0000004系统无法打开文件 0X0000005拒绝存取 0X0000006无效的代码 0X0000007内存控制模块已损坏 0X0000008内存空间不足,无法处理这个指令 0X0000009内存控制模块位址无效 0X000000A环境不正确 0X000000B尝试载入一个格式错误的程序 0X000000C存取码错误 0X000000D资料错误 0X000000E内存空间不够,无法完成这项操作 0X000000F系统找不到指定的硬盘 0X0000010无法移除目录 0X0000011系统无法将文件移到其他的硬盘 0X0000012没有任何文件 0X0000019找不到指定扇区或磁道 0X000001A指定的磁盘或磁片无法存取 0X000001B磁盘找不到要求的装置 0X000001C打印机没有纸 0X000001D系统无法将资料写入指定的磁盘 0X000001E系统无法读取指定的装置 0X000001F连接到系统的某个装置没有作用 0X0000021文件的一部分被锁定,现在无法存取 0X0000024开启的分享文件数量太多 0X0000026到达文件结尾 0X0000027磁盘已满 0X0000036网络繁忙 0X000003B网络发生意外的错误 0X0000043网络名称找不到 0X0000050文件已经存在 0X0000052无法建立目录或文件 0X0000053 INT24失败 0X000006B因为代用的磁盘尚未插入,所以程序已经停止 0X000006C磁盘正在使用中或被锁定 0X000006F文件名太长 0X0000070硬盘空间不足 0X000007F找不到指定的程序 0X000045B系统正在关机 0X000045C无法中止系统关机,因为没有关机的动作在进行中 0X000046A可用服务器储存空间不足 0X0000475系统 BIOS无法变更系统电源状态 0X000047E指定的程序需要新的windows版本 0X000047F指定的程序不是windwos或ms-dos程序 0X0000480指定的程序已经启动,无法再启动一次 0X0000481指定的程序是为旧版的windows所写的 0X0000482执行此应用程序所需的程序库文件之一被损 0X0000483没有应用程序与此项操作的指定文件建立关联 0X0000484传送指令到应用程序无效 0X00005A2指定的装置名称无效 0X00005AA系统资源不足,无法完成所要求的服务 0X00005AB系统资源不足,无法完成所要求的服务 0X00005AC系统资源不足,无法完成所要求的服务 110 0x006E系统无法开启指定的装置或档案。 111 0x006F档名太长。 112 0x0070磁碟空间不足。 113 0x0071没有可用的内部档案识别字。 114 0x0072目标内部档案识别字不正确。 117 0x0075由应用程式所执行的IOCTL 呼叫不正确。 118 0x0076写入验证参数值不正确。 119 0x0077系统不支援所要求的指令。 120 0x0078此项功能仅在 Win32 模式有效。 121 0x0079 semaphore超过逾时期间。 122 0x007A传到系统呼叫的资料区域太小。 123 0x007B档名、目录名称或储存体标 124 0x007C系统呼叫层次不正确。 125 0x007D磁碟没有设定标 126 0x007E找不到指定的模组。 127 0x007F找不到指定的程序。 128 0x0080没有子行程可供等待。 129 0x0081 %1这个应用程式无法在 Win32 模式下执行。 130 0x0082 Attempt to use a file handle to an open disk partition for an operation other than raw disk I/O. 131 0x0083尝试将档案指标移至档案开头之前。 132 0x0084无法在指定的装置或档案,设定档案指标。 133 0x0085 JOIN 或 SUBST指令无法用於内含事先结合过的磁碟机。 134 0x0086尝试在已经结合的磁碟机,使用JOIN 或 SUBST 指令。 135 0x0087尝试在已经替换的磁碟机,使用 JOIN 或 SUBST 指令。 136 0x0088系统尝试删除未连结过的磁碟机的连结关系。 137 0x0089系统尝试删除未替换过的磁碟机的替换关系。 138 0x008A系统尝试将磁碟机结合到已经结合过之磁碟机的目录。 139 0x008B系统尝试将磁碟机替换成已经替换过之磁碟机的目录。 140 0x008C系统尝试将磁碟机替换成已经替换过之磁碟机的目录.
独步清客 2019-12-02 00:43:56 0 浏览量 回答数 0

问题

Android5.1.1源码 - zygote fork出的子进程如何权限降级

前言 如果不知道zygote是什么,或者好奇zygote如何启动,可以去看老罗的文章: Android系统进程Zygote启动过程的源代码分析 所有Android应用进程...
移动安全 2019-12-01 21:16:02 4115 浏览量 回答数 0

回答

这个问题想要说清楚还是挺复杂的,题主可以参考 New Options for Managing Character Sets in the Microsoft C/C++ Compiler 这篇文章。具体来说,源代码文件中的字符串常量能否正确的显示在控制台窗口中与以下几个因素有关: •源代码文件(.cpp)保存时所使用的字符集(下文用 C1 代替) •编译器在读取源代码文件时所使用的内部字符集(source character set)(下文用 C2 代替) •编译器在生编译时所使用的字符集(execution character set)(下文用 C3 代替) •运行可执行程序的控制台窗口所使用的字符集(下文用 C4 代替) 第一,“源代码文件保存时所使用的字符集”决定了源代码文件中的抽象字符保存到硬盘中是什么样的字节。这里所说的抽象字符,就是指人所能识别的文字(如“张”)。而字节则是由抽象字符按照字符集的规定映射的,不同的字符集映射的结果不一样(如“张”在 UTF-8 下映射的字节是E5 BC A0三个字节,而在 GBK 下映射的字节是D5 C5两个字节)。比如下面一行代码: char *s = "张三"; 其中的字符串常量"张三"在使用不同的字符集(C1)保存时,映射的字节是不同的。 第二,“编译器在读取源代码文件时所使用的内部字符集”决定了编译器如何把读入的源代码文件字节流进行转换。我所谓的转换就是指把字节流从一种编码转到另一种编码。举例来说,对于抽象字符“张”,如果采用 GBK 编码,映射的字节流就是D5 C5,而转换到 UTF-8 编码,就是把这个字节流转换成E5 BC A0。 这个字符集(C2)是由编译器决定的,标准中并未规定。不同的编译器可能采用不同的内部字符集,同样的编译器不同版本也可能采用不同的内部字符集。在 Visual C++ 的某些版本中,内部字符集是 UTF-8,编译器会尝试判断源文件所使用的字符集(C1),并将其转换成内部字符集(C2),如果编译器不能判断出文件所使用的字符集,则会默认其(C1)为当前操作系统的代码页(default code page)(这里如果判断错误,就会造成乱码或编译出错)。 比如:源文件如果是 UTF-8 with BOM,则能够正确的被 Visual C++ 识别,其中的抽象字符“张”映射的字节流E5 BC A0就会被正确的转换成E5 BC A0(没变)。而源文件如果是 UTF-8 without BOM,则不能正确的被 Visual C++ 识别,编译器会采用当前的代码页来进行转换,其中的抽象字符“张”映射的字节流E5 BC A0就会被当作 GBK 编码,错误的转换成其它字节流E5 AF AE ...(寮)。 第三,“编译器在编译时所使用的字符集”决定了编译器如何把源代码中使用内部字符集(C2)编码的字符/字符串常量转还到编译时所使用的字符集(C3)。这个字符集(C3)也是由编译器决定的,标准中并未规定。C++ 中的字符常量和字符串常量有不同的类型,它们对应于不同的 C3。 在 Visual C++ 中,参考 String and Character Literals 和前文提到的博客,可以推知不同类型的字符/字符串常量对应的 C3: // Character literals auto c0 = 'A'; // char, encoded as default code page auto c1 = u8'A'; // char, encoded as UTF-8 auto c2 = L'A'; // wchar_t, encoded as UTF-16LE auto c3 = u'A'; // char16_t, encoded as UTF-16LE auto c4 = U'A'; // char32_t, encoded as UTF-32LE // String literals auto s0 = "hello"; // const char*, encoded as default code page auto s1 = u8"hello"; // const char*, encoded as UTF-8 auto s2 = L"hello"; // const wchar_t*, encoded as UTF-16LE auto s3 = u"hello"; // const char16_t*, encoded as UTF-16LE auto s4 = U"hello"; // const char32_t*, encoded as UTF-32LE 编译器根据字符串常量的类型把其从 C2 转换到 C3(前面如果判断错误,这里就会继续保留错误)。 比如:auto s1 = "张";,抽象字符“张”在 C2 中(UTF-8)映射的字节流E5 BC A0就会被转换成在 C3 中(CP936,GBK)映射的字节流D5 C5。 auto s2 = u8"张";,抽象字符“张”在 C2 中(UTF-8)映射的字节流E5 BC A0`就会被转换成在 C3 中(UTF-8)映射的字节流E5 BC A0(不变)。 第四,“运行可执行程序的控制台窗口所使用的字符集”决定了如何把编译好的可执行程序中的字节流转换成抽象字符显示在控制台中。比如,在上一步中的s1映射的字节流就会通过 C4(CP 936)映射回抽象字符“张”,在我们看来就是正确的。而上一步中的s2映射的字节流就会通过 C4(CP 936)映射回抽象字符“寮”,在我们看来就是乱码。 以上,就是我理解的 C++ 中字符/字符串的编码处理方式,如果有误还请指出:-) 题主可以尝试在 Visual C++ 中把以下代码分别保存成 CP936、UTF-8 with BOM、UTF-8 without BOM 的格式,看看输出结果是什么。 #include <iostream> #include <fstream> using namespace std; int main() { char *s1 = u8"张"; char *s2 = "张"; cout << "s1 " << sizeof(s1) << " " << strlen(s1) << " -> " << s1 << endl; // Error in console cout << "s2 " << sizeof(s2) << " " << strlen(s2) << " -> " << s2 << endl; // OK in console ofstream os("s1.txt"); if (os.is_open()) { os << "s1 " << sizeof(s1) << " " << strlen(s1) << " -> " << s1 << endl; os.close(); } ofstream os2("s2.txt"); if (os2.is_open()) { os2 << "s2 " << sizeof(s2) << " " << strlen(s2) << " -> " << s2 << endl; os2.close(); } ofstream os3("s3.txt"); if (os3.is_open()) { os3 << "s1 " << sizeof(s1) << " " << strlen(s1) << " -> " << s1 << endl; os3 << "s2 " << sizeof(s2) << " " << strlen(s2) << " -> " << s2 << endl; os3.close(); } cin.get(); return 0; } 输出的三个文件中,前两个文件s1.txt和s2.txt都能够被正常的文本编辑器猜出其编码格式,从而正确显示内容,但是第三个文件s3.txt会显示成部分或全部乱码,因为其中既包含了 UTF-8 编码的字节流又包含了 GBK 编码的字节流,所以文本编辑器就不知道该用什么编码来把字节流映射回抽象文本了。 Character Encoding Model 标准引用和参考文档 From ISO C++11 § 2.3/1 The basic source character set consists of 96 characters: the space character, the control characters representing horizontal tab, vertical tab, form feed, and new-line, plus the following 91 graphical characters: a b c d e f g h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K L M N O P Q R S T U V W X Y Z 0 1 2 3 4 5 6 7 8 9 _ { } [ ] # ( ) < > % : ; . ? * + - / ^ & | ! = , \ " ’ From ISO C++11 § 2.3/2 The universal-character-name construct provides a way to name other characters. hex-quad: hexadecimal-digit hexadecimal-digit hexadecimal-digit hexadecimal-digit universal-character-name: \u hex-quad \U hex-quad hex-quad The character designated by the universal-character-name \UNNNNNNNN is that character whose character short name in ISO/IEC 10646 is NNNNNNNN; the character designated by the universal-character-name \uNNNN is that character whose character short name in ISO/IEC 10646 is 0000NNNN. ... From ISO C++11 § 2.3/3 The basic execution character set and the basic execution wide-character set shall each contain all the members of the basic source character set, plus control characters representing alert, backspace, and carriage return, plus a null character (respectively, null wide character), whose representation has all zero bits. ... The execution character set and the execution wide-character set are implementation-defined supersets of the basic execution character set and the basic execution wide-character set, respectively. The values of the members of the execution character sets and the sets of additional members are locale-specific. From ISO C++11 § 2.2/1 The precedence among the syntax rules of translation is specified by the following phases. 1.Physical source file characters are mapped, in an implementation-defined manner, to the basic source character set (introducing new-line characters for end-of-line indicators) if necessary. The set of physical source file characters accepted is implementation-defined. ... Any source file character not in the basic source character set (2.3) is replaced by the universal-character-name that designates that character. ... 2.... 3.... 4.... 5.Each source character set member in a character literal or a string literal, as well as each escape sequence and universal-character-name in a character literal or a non-raw string literal, is converted to the corresponding member of the execution character set (2.14.3, 2.14.5); if there is no corresponding member, it is converted to an implementation-defined member other than the null (wide) character. 6.... From ISO C++11 § 2.14.3/5A universal-character-name is translated to the encoding, in the appropriate execution character set, of the character named. If there is no such encoding, the universal-character-name is translated to an implementationdefined encoding. [ Note: In translation phase 1, a universal-character-name is introduced whenever an actual extended character is encountered in the source text. Therefore, all extended characters are described in terms of universal-character-names. However, the actual compiler implementation may use its own native character set, so long as the same results are obtained. — end note ] From ISO C++11 § 2.14.5/6 7 156 After translation phase 6, a string literal that does not begin with an encoding-prefix is an ordinary string literal, and is initialized with the given characters.7 A string literal that begins with u8, such as u8"asdf", is a UTF-8 string literal and is initialized with the given characters as encoded in UTF-8....15 Escape sequences and universal-character-names in non-raw string literals have the same meaning as in character literals (2.14.3), except that the single quote ’ is representable either by itself or by the escape sequence ’, and the double quote " shall be preceded by a . In a narrow string literal, a universal-character-name may map to more than one char element due to multibyte encoding. ... ` •Character Sets •String and Character Literals •New Options for Managing Character Sets in the Microsoft C/C++ Compiler `
杨冬芳 2019-12-02 02:25:50 0 浏览量 回答数 0

回答

什么是Kubernetes? Kubernetes是一种轻便的可伸展的开源平台,用来管理容器化的工作或者服务,拥有声明化配置和自动化等优点。它现在拥有一个快速扩大与成长的生态系统,其服务,工具和技术支持可被广泛用于各个方面。 为什么我需要Kubernetes,它用来做些什么? Kubernetes拥有大量的特性,比如: 容器平台 微服务平台 轻量化云服务平台 等等 Kubernetes提供了一个以容器为中心的管理环境,它根据用户的工作负载来协调计算,网络和储存基础架构。它既有PaaS的简化性,又具有IaaS的灵活性,并支持跨基础架构的可移植性 为什么Kubernetes是一个平台? 尽管Kubernetes提供了大量的功能性,总会有新的场景需要新的功能。一些特性的应用程序工作流程可以被简化来加快开发速度。最初的部署通常需要大规模的应用自动化。这就是为什么Kubernetes被设计成一个平台服务,用来创建一个包含工具和其他组成部分的系统环境,来使部署,测量和管理应用更加容易。 Label可以授权用户按照他们的想法来组织他们的资源。Annotation允许用户布置含有自定义信息的资源,来使工作流更加顺畅,并为管理工具提供到checkpoint状态的一种更简单的方式。 此外,Kubernetes控制平面基于开发人员和用户可用的相同API构建。用户可以编写他们自己的 controller,比如schedulers,这些API可以通过通用命令行工具进行定位。 这种设计使得许多其他系统能够在Kubernetes上面构建 Kubernetes不是什么 Kubernetes不是一个传统的,包罗万象的PaaS(平台即服务)系统。由于Kubernetes在容器级而不是在硬件级运行,因此它能提供一些PaaS产品常用的通用功能,比如部署,扩展,负载均衡,日志记录和监控。但是,Kubernetes并不是一个整体,这些默认解决方案都是可选和可插拔的。Kubernetes提供了构建人员平台的构建模块,但是在一些重要的地方保留了用户选择和灵活性。 Kubernetes: 不限制支持的应用程序类型。Kubernetes旨在支持各种各样的工作负载,包括无状态,有状态和数据处理工作负载。 如果一个应用程序可以在一个容器中运行,它应该在Kubernetes上运行得很好。 不部署源代码并且不构建您的应用程序。持续集成,交付和部署(CI / CD)工作流程由组织和偏好以及技术要求决定。 不提供应用程序级服务,例如中间件(例如,消息总线),数据处理框架(例如,Spark),数据库(例如,mysql),高速缓存,也不提供集群存储系统(例如,Ceph)。 在服务中。 这些组件可以在Kubernetes上运行,和/或可以通过便携式机制(例如Open Service Broker)在Kubernetes上运行的应用程序访问。 不指示日志,监视或警报解决方案。 它提供了一些集成作为概念证明,以及收集和导出指标的机制。 不提供或授权配置语言/系统(例如,jsonnet)。 它提供了一个声明性API,可以通过任意形式的声明性规范来实现。 不提供或采用任何全面的机器配置,维护,管理或自我修复系统。 此外,Kubernetes不仅仅是一个编排系统。 实际上,它消除了编排的需要。 业务流程的技术定义是执行定义的工作流程:首先执行A,然后运行B,然后运行C.相反,Kubernetes由一组独立的,可组合的控制流程组成,这些流程将当前状态持续推向所提供的所需状态。 如何从A到C无关紧要。也不需要集中控制。 这使得系统更易于使用且功能更强大,更具弹性且可扩展 为什么使用容器 过去部署应用的方式,是将应用安装在一个使用操作系统软件包管理器的主机上。这样做的缺点是应用程序的可执行文件、配置、库和生命周期互相影响,也会和操作系统纠缠不清。你也可以构建一个不可被修改的虚拟机镜像来实现可预测的部署和回滚,但是这样显然不够轻量化而且不可被移植 新的方式是在虚拟化的操作系统层来部署容器,而不是在虚拟化的硬件层。这些容器之间彼此独立,相对主机也保持独立。它们有自己单独的文件系统,也不能看到其他容器的进程,而且它们对于计算资源的使用量可以被限制。它们比虚拟机更容易被构建,因为它们从底层基础架构和主机文件系统中解耦出来,也可以跨单机与云之间移植。 因为容器小巧且轻快,一个应用程序可以被打包放到每个容器镜像中。这种一对一的应用对镜像的关系可以使容器发挥出最大功效。有了容器,不可变的容器镜像可以在构建时被创建,而不是在部署时,因为每个应用都不需要依赖于程序的其它应用部分,也不依赖于基础生产环境。同样,容器比VM更加透明,这有利于监控和管理。当容器的生命周期由基础架构管理而不是隐藏在流程管理器之后时,尤其如此。最后,当一个应用被部署在每个容器时,管理容器就变得和管理程序部署一样了。 阿里云导入自建K8S集群 更多阿里云帮助文档 https://help.aliyun.com 希望对您有帮助!
阿里朵 2019-12-02 02:19:54 0 浏览量 回答数 0

回答

1.内存泄漏:基础 对于初学者来说,将内存泄漏视为一种疾病,将Java的OutOfMemoryError(简称OOM)视为一种症状。但与任何疾病一样,并非所有OOM都意味着内存泄漏:由于生成大量局部变量或其他此类事件,OOM可能会发生。另一方面,并非所有内存泄漏都必然表现为OOM,特别是在桌面应用程序或客户端应用程序(没有重新启动时运行很长时间)的情况下。 将内存泄漏视为疾病,将OutOfMemoryError视为症状。但并非所有OutOfMemoryErrors都意味着内存泄漏,并非所有内存泄漏都表现为OutOfMemoryErrors。 为什么这些泄漏如此糟糕?除此之外,程序执行期间泄漏的内存块通常会降低系统性能,因为分配但未使用的内存块必须在系统耗尽空闲物理内存时进行换出。最终,程序甚至可能耗尽其可用的虚拟地址空间,从而导致OOM。 2.解密OutOfMemoryError 如上所述,OOM是内存泄漏的常见指示。实质上,当没有足够的空间来分配新对象时,会抛出错误。当垃圾收集器找不到必要的空间,并且堆不能进一步扩展,会多次尝试。因此,会出现错误以及堆栈跟踪。 诊断OOM的第一步是确定错误的实际含义。这听起来很清除,但答案并不总是那么清晰。例如:OOM是否是因为Java堆已满而出现,还是因为本机堆已满?为了帮助您回答这个问题,让我们分析一些可能的错误消息: java.lang.OutOfMemoryError: Java heap space java.lang.OutOfMemoryError: PermGen space java.lang.OutOfMemoryError: Requested array size exceeds VM limit java.lang.OutOfMemoryError: request bytes for . Out of swap space? java.lang.OutOfMemoryError: (Native method) 2.1.“Java heap space” 此错误消息不一定意味着内存泄漏。实际上,问题可能与配置问题一样简单。 例如,我负责分析一直产生这种类型的OutOfMemoryError的应用程序。经过一番调查后,我发现罪魁祸首是阵列实例化,因为需要太多的内存;在这种情况下,并不是应用程序的错,而是应用程序服务器依赖于默认的堆太小了。我通过调整JVM的内存参数解决了这个问题。 在其他情况下,特别是对于长期存在的应用程序,该消息可能表明我们无意中持有对象的引用,从而阻止垃圾收集器清理它们。这时Java语言等同于内存泄漏。 (注意:应用程序调用的API也可能无意中持有对象引用。) 这些“Java堆空间”OOM的另一个潜在来源是使用finalizers。如果类具有finalize方法,则在垃圾收集时该类型的对象不会被回收。而是在垃圾收集之后,稍后对象将排队等待最终确定。在Sun实现中,finalizers由守护线程执行。如果finalizers线程无法跟上finalization队列,那么Java堆可能会填满并且可能抛出OOM。 2.2.“PermGen space” 此错误消息表明永久代已满。永久代是存储类和方法对象的堆的区域。如果应用程序加载了大量类,则可能需要使用-XX:MaxPermSize选项增加永久代的大小。 Interned java.lang.String对象也存储在永久代中。 java.lang.String类维护一个字符串池。调用实习方法时,该方法检查池以查看是否存在等效字符串。如果是这样,它由实习方法返回;如果没有,则将字符串添加到池中。更准确地说,java.lang.String.intern方法返回一个字符串的规范表示;结果是对该字符串显示为文字时将返回的同一个类实例的引用。如果应用程序实例化大量字符串,则可能需要增加永久代的大小。 注意:您可以使用jmap -permgen命令打印与永久生成相关的统计信息,包括有关内部化String实例的信息。 2.3.“Requested array size exceeds VM limit” 此错误表示应用程序(或该应用程序使用的API)尝试分配大于堆大小的数组。例如,如果应用程序尝试分配512MB的数组但最大堆大小为256MB,则将抛出此错误消息的OOM。在大多数情况下,问题是配置问题或应用程序尝试分配海量数组时导致的错误。 2.4.“Request bytes for . Out of swap space?” 此消息似乎是一个OOM。但是,当本机堆的分配失败并且本机堆可能将被耗尽时,HotSpot VM会抛出此异常。消息中包括失败请求的大小(以字节为单位)以及内存请求的原因。在大多数情况下,是报告分配失败的源模块的名称。 如果抛出此类型的OOM,则可能需要在操作系统上使用故障排除实用程序来进一步诊断问题。在某些情况下,问题甚至可能与应用程序无关。例如,您可能会在以下情况下看到此错误: 操作系统配置的交换空间不足。 系统上的另一个进程是消耗所有可用的内存资源。 由于本机泄漏,应用程序也可能失败(例如,如果某些应用程序或库代码不断分配内存但无法将其释放到操作系统)。 2.5. (Native method) 如果您看到此错误消息并且堆栈跟踪的顶部框架是本机方法,则该本机方法遇到分配失败。此消息与上一个消息之间的区别在于,在JNI或本机方法中检测到Java内存分配失败,而不是在Java VM代码中检测到。 如果抛出此类型的OOM,您可能需要在操作系统上使用实用程序来进一步诊断问题。 2.6.Application Crash Without OOM 有时,应用程序可能会在从本机堆分配失败后很快崩溃。如果您运行的本机代码不检查内存分配函数返回的错误,则会发生这种情况。 例如,如果没有可用内存,malloc系统调用将返回NULL。如果未检查malloc的返回,则应用程序在尝试访问无效的内存位置时可能会崩溃。根据具体情况,可能很难定位此类问题。 在某些情况下,致命错误日志或崩溃转储的信息就足以诊断问题。如果确定崩溃的原因是某些内存分配中缺少错误处理,那么您必须找到所述分配失败的原因。与任何其他本机堆问题一样,系统可能配置了但交换空间不足,另一个进程可能正在消耗所有可用内存资源等。 3.泄漏诊断 在大多数情况下,诊断内存泄漏需要非常详细地了解相关应用程序。警告:该过程可能很长并且是迭代的。 我们寻找内存泄漏的策略将相对简单: 识别症状 启用详细垃圾回收 启用分析 分析踪迹 3.1 识别症状 正如所讨论的,在许多情况下,Java进程最终会抛出一个OOM运行时异常,这是一个明确的指示,表明您的内存资源已经耗尽。在这种情况下,您需要区分正常的内存耗尽和泄漏。分析OOM的消息并尝试根据上面提供的讨论找到罪魁祸首。 通常,如果Java应用程序请求的存储空间超过运行时堆提供的存储空间,则可能是由于设计不佳导致的。例如,如果应用程序创建映像的多个副本或将文件加载到数组中,则当映像或文件非常大时,它将耗尽存储空间。这是正常的资源耗尽。该应用程序按设计工作(虽然这种设计显然是愚蠢的)。 但是,如果应用程序在处理相同类型的数据时稳定地增加其内存利用率,则可能会发生内存泄漏。 3.2 启用详细垃圾收集 断言确实存在内存泄漏的最快方法之一是启用详细垃圾回收。通常可以通过检查verbosegc输出中的模式来识别内存约束问题。 具体来说,-verbosegc参数允许您在每次垃圾收集(GC)过程开始时生成跟踪。也就是说,当内存被垃圾收集时,摘要报告会打印到标准错误,让您了解内存的管理方式。 这是使用-verbosegc选项生成的一些典型输出: image 此GC跟踪文件中的每个块(或节)按递增顺序编号。要理解这种跟踪,您应该查看连续的分配失败节,并查找随着时间的推移而减少的释放内存(字节和百分比),同时总内存(此处,19725304)正在增加。这些是内存耗尽的典型迹象。 3.3 启用分析 不同的JVM提供了生成跟踪文件以反映堆活动的不同方法,这些方法通常包括有关对象类型和大小的详细信息。这称为分析堆。 3.4 分析路径 本文重点介绍Java VisualVM生成的跟踪。跟踪可以有不同的格式,因为它们可以由不同的Java内存泄漏检测工具生成,但它们背后的想法总是相同的:在堆中找到不应该存在的对象块,并确定这些对象是否累积而不是释放。特别感兴趣的是每次在Java应用程序中触发某个事件时已知的临时对象。应该仅存少量,但存在许多对象实例,通常表示应用程序出现错误。 最后,解决内存泄漏需要您彻底检查代码。了解对象泄漏的类型可能对此非常有用,并且可以大大加快调试速度。 4.垃圾收集如何在JVM中运行? 在我们开始分析具有内存泄漏问题的应用程序之前,让我们首先看看垃圾收集在JVM中的工作原理。 JVM使用一种称为跟踪收集器的垃圾收集器,它基本上通过暂停它周围的世界来操作,标记所有根对象(由运行线程直接引用的对象),并遵循它们的引用,标记它沿途看到的每个对象。 Java基于分代假设-实现了一种称为分代垃圾收集器的东西,该假设表明创建的大多数对象被快速丢弃,而未快速收集的对象可能会存在一段时间。 基于此假设,[Java将对象分为多代](www.oracle.com/technetwork…. Generations|outline)。这是一个视觉解释: image Young Generation -这是对象的开始。它有两个子代 Eden Space -对象从这里开始。大多数物体都是在Eden Space中创造和销毁的。在这里,GC执行Minor GCs,这是优化的垃圾收集。执行Minor GC时,对仍然需要的对象的任何引用都将迁移到其中一个survivors空间(S0或S1)。 Survivor Space (S0 and S1)-幸存Eden Space的对象最终来到这里。其中有两个,在任何给定时间只有一个正在使用(除非我们有严重的内存泄漏)。一个被指定为空,另一个被指定为活动,与每个GC循环交替。 Tenured Generation -也被称为老年代(图2中的旧空间),这个空间容纳存活较长的对象,使用寿命更长(如果它们活得足够长,则从Survivor空间移过来)。填充此空间时,GC会执行完整GC,这会在性能方面降低成本。如果此空间无限制地增长,则JVM将抛出OutOfMemoryError - Java堆空间。 Permanent Generation -作为与终身代密切相关的第三代,永久代是特殊的,因为它保存虚拟机所需的数据,以描述在Java语言级别上没有等价的对象。例如,描述类和方法的对象存储在永久代中。 Java足够聪明,可以为每一代应用不同的垃圾收集方法。使用名为Parallel New Collector的跟踪复制收集器处理年轻代。这个收集器阻止了这个世界,但由于年轻一代通常很小,所以暂停很短暂。 有关JVM代及其工作原理的更多信息,请查阅Memory Management in the Java HotSpot™ Virtual Machine 。 5 检测内存泄漏 要查找内存泄漏并消除它们,您需要合适的内存泄漏工具。是时候使用Java VisualVM检测并删除此类泄漏。 5.1 使用Java VisualVM远程分析堆 VisualVM是一种工具,它提供了一个可视化界面,用于查看有关基于Java技术的应用程序运行时的详细信息。 使用VisualVM,您可以查看与本地应用程序和远程主机上运行的应用程序相关的数据。您还可以捕获有关JVM软件实例的数据,并将数据保存到本地系统。 为了从Java VisualVM的所有功能中受益,您应该运行Java平台标准版(Java SE)版本6或更高版本。 Related: Why You Need to Upgrade to Java 8 Already 5.2. 为JVM启用远程连接 在生产环境中,通常很难访问运行代码的实际机器。幸运的是,我们可以远程分析我们的Java应用程序。 首先,我们需要在目标机器上授予自己JVM访问权限。为此,请使用以下内容创建名为jstatd.all.policy的文件: grant codebase "file:${java.home}/../lib/tools.jar" { permission java.security.AllPermission;
游客2q7uranxketok 2021-02-22 19:58:44 0 浏览量 回答数 0

回答

一、软件篇 1、设定虚拟内存 硬盘中有一个很宠大的数据交换文件,它是系统预留给虚拟内存作暂存的地方,很多应用程序都经常会使用到,所以系统需要经常对主存储器作大量的数据存取,因此存取这个档案的速度便构成影响计算机快慢的非常重要因素!一般Windows预设的是由系统自行管理虚拟内存,它会因应不同程序所需而自动调校交换档的大小,但这样的变大缩小会给系统带来额外的负担,令系统运作变慢!有见及此,用户最好自定虚拟内存的最小值和最大值,避免经常变换大小。要设定虚拟内存,在“我的电脑”上按右键选择“属性”,在“高级”选项里的“效能”的对话框中,对“虚拟内存”进行设置。 3、检查应用软件或者驱动程序 有些程序在电脑系统启动会时使系统变慢。如果要是否是这方面的原因,我们可以从“安全模式”启动。因为这是原始启动,“安全模式”运行的要比正常运行时要慢。但是,如果你用“安全模式”启动发现电脑启动速度比正常启动时速度要快,那可能某个程序是导致系统启动速度变慢的原因。 4、桌面图标太多会惹祸 桌面上有太多图标也会降低系统启动速度。Windows每次启动并显示桌面时,都需要逐个查找桌面快捷方式的图标并加载它们,图标越多,所花费的时间当然就越多。同时有些杀毒软件提供了系统启动扫描功能,这将会耗费非常多的时间,其实如果你已经打开了杀毒软件的实时监视功能,那么启动时扫描系统就显得有些多余,还是将这项功能禁止吧! 建议大家将不常用的桌面图标放到一个专门的文件夹中或者干脆删除! 5、ADSL导致的系统启动变慢 默认情况下Windows XP在启动时会对网卡等网络设备进行自检,如果发现网卡的IP地址等未配置好就会对其进行设置,这可能是导致系统启动变慢的真正原因。这时我们可以打开“本地连接”属性菜单,双击“常规”项中的“Internet协议”打开“TCP/IP属性”菜单。将网卡的IP地址配置为一个在公网(默认的网关是192.168.1.1)中尚未使用的数值如192.168.1.X,X取介于2~255之间的值,子网掩码设置为255.255.255.0,默认网关和DNS可取默认设置。 6、字体对速度的影响 虽然 微软 声称Windows操作系统可以安装1000~1500种字体,但实际上当你安装的字体超过500 种时,就会出现问题,比如:字体从应用程序的字体列表中消失以及Windows的启动速度大幅下降。在此建议最好将用不到或者不常用的字体删除,为避免删除后发生意外,可先进行必要的备份。 7、删除随机启动程序 何谓随机启动程序呢?随机启动程序就是在开机时加载的程序。随机启动程序不但拖慢开机时的速度,而且更快地消耗计算机资源以及内存,一般来说,如果想删除随机启动程序,可去“启动”清单中删除,但如果想详细些,例如是QQ、popkiller 之类的软件,是不能在“启动”清单中删除的,要去“附属应用程序”,然后去“系统工具”,再去“系统信息”,进去后,按上方工具列的“工具”,再按“系统组态编辑程序”,进去后,在“启动”的对话框中,就会详细列出在启动电脑时加载的随机启动程序了!XP系统你也可以在“运行”是输入Msconfig调用“系统配置实用程序”才终止系统随机启动程序,2000系统需要从XP中复制msconfig程序。 8、取消背景和关闭activedesktop 不知大家有否留意到,我们平时一直摆放在桌面上漂亮的背景,其实是很浪费计算机资源的!不但如此,而且还拖慢计算机在执行应用程序时的速度!本想美化桌面,但又拖慢计算机的速度,这样我们就需要不在使用背景了,方法是:在桌面上按鼠标右键,再按内容,然后在“背景”的对话框中,选“无”,在“外观”的对话框中,在桌面预设的青绿色,改为黑色......至于关闭activedesktop,即是叫你关闭从桌面上的web画面,例如在桌面上按鼠标右键,再按内容,然后在“背景”的对话框中,有一幅背景,名为Windows XX,那副就是web画面了!所以如何系统配置不高就不要开启。 10、把Windows变得更苗条 与DOS系统相比,Windows过于庞大,而且随着你每天的操作,安装新软件、加载运行库、添加新游戏等等使得它变得更加庞大,而更为重要的是变大的不仅仅是它的目录,还有它的 注册表 和运行库。因为即使删除了某个程序,可是它使用的DLL文件仍然会存在,因而随着使用日久,Windows的启动和退出时需要加载的DLL动态链接库文件越来越大,自然系统运行速度也就越来越慢了。这时我们就需要使用一些彻底删除DLL的程序,它们可以使Windows恢复苗条的身材。建议极品玩家们最好每隔两个月就重新安装一遍Windows,这很有效。 11、更改系统开机时间 虽然你已知道了如何新增和删除一些随机启动程序,但你又知不知道,在开机至到进入Windows的那段时间,计算机在做着什么呢?又或者是,执行着什么程序呢?那些程序,必定要全部载完才开始进入Windows,你有否想过,如果可删除一些不必要的开机时的程序,开机时的速度会否加快呢?答案是会的!想要修改,可按"开始",选"执行",然后键入win.ini,开启后,可以把以下各段落的内容删除,是删内容,千万不要连标题也删除!它们包括:[compatibility]、[compatibility32]、[imecompatibility]、[compatibility95]、[modulecompatibility]和[embedding]。 二、硬件篇 1、Windows系统自行关闭硬盘DMA模式 硬盘的DMA模式大家应该都知道吧,硬盘的PATA模式有DMA33、DMA66、DMA100和DMA133,最新的SATA-150都出来了!一般来说现在大多数人用的还是PATA模式的硬盘,硬盘使用DMA模式相比以前的PIO模式传输的速度要快2~8倍。DMA模式的起用对系统的性能起到了实质的作用。但是你知道吗?Windows 2000、XP、2003系统有时会自行关闭硬盘的DMA模式,自动改用PIO模式运行!这就造成在使用以上系统中硬盘性能突然下降,其中最明显的现象有:系统起动速度明显变慢,一般来说正常Windows XP系统启动时那个由左向右运动的滑条最多走2~4次系统就能启动,但这一问题发生时可能会走5~8次或更多!而且在运行系统时进行硬盘操作时明显感觉变慢,在运行一些大的软件时CPU占用率时常达到100%而产生停顿,玩一些大型3D游戏时画面时有明显停顿,出现以上问题时大家最好看看自己硬盘的DMA模式是不是被Windows 系统自行关闭了。查看自己的系统是否打开DMA模式: a. 双击“管理工具”,然后双击“计算机管理”; b. 单击“系统工具”,然后单击“设备管理器”; c. 展开“IDE ATA/ATAPI 控制器”节点; d. 双击您的“主要IDE控制器”; 2、CPU 和风扇是否正常运转并足够制冷 当CPU风扇转速变慢时,CPU本身的温度就会升高,为了保护CPU的安全,CPU就会自动降低运行频率,从而导致计算机运行速度变慢。有两个方法检测CPU的温度。你可以用“手指测法”用手指试一下处理器的温度是否烫手,但是要注意的是采用这种方法必须先拔掉电源插头,然后接一根接地线来防止身上带的静电击穿CPU以至损坏。另一个比较科学的方法是用带感温器的万用表来检测处理器的温度。 因为处理器的种类和型号不同,合理温度也各不相同。但是总的来说,温度应该低于 110 度。如果你发现处理器的测试高于这处温度,检查一下机箱内的风扇是否正常运转。 3、USB和扫描仪造成的影响 由于Windows 启动时会对各个驱动器(包括光驱)进行检测,因此如果光驱中放置了光盘,也会延长电脑的启动时间。所以如果电脑安装了扫描仪等设备,或在启动时已经连接了USB硬盘,那么不妨试试先将它们断开,看看启动速度是不是有变化。一般来说,由于USB接口速度较慢,因此相应设备会对电脑启动速度有较明显的影响,应该尽量在启动后再连接USB设备。如果没有USB设备,那么建议直接在BIOS设置中将USB功能关闭。 4、是否使用了磁盘压缩 因为“磁盘压缩”可能会使电脑性能急剧下降,造成系统速度的变慢。所以这时你应该检测一下是否使用了“磁盘压缩”,具体操作是在“我的电脑”上点击鼠标右键,从弹出的菜单选择“属性”选项,来检查驱动器的属性。 5、网卡造成的影响 只要设置不当,网卡也会明显影响系统启动速度,你的电脑如果连接在局域网内,安装好网卡驱动程序后,默认情况下系统会自动通过DHCP来获得IP地址,但大多数公司的局域网并没有DHCP服务器,因此如果用户设置成“自动获得IP地址”,系统在启动时就会不断在网络中搜索DHCP 服务器,直到获得IP 地址或超时,自然就影响了启动时间,因此局域网用户最好为自己的电脑指定固定IP地址。 6、文件夹和打印机共享 安装了Windows XP专业版的电脑也会出现启动非常慢的时候,有些时候系统似乎给人死机的感觉,登录系统后,桌面也不出现,电脑就像停止反应,1分钟后才能正常使用。这是由于使用了Bootvis.exe 程序后,其中的Mrxsmb.dll文件为电脑启动添加了67秒的时间! 要解决这个问题,只要停止共享文件夹和打印机即可:选择“开始→设置→网络和拨号连接”,右击“本地连接”,选择“属性”,在打开的窗口中取消“此连接使用下列选定的组件”下的“ Microsoft 网络的文件和打印机共享”前的复选框,重启电脑即可。 7、系统配件配置不当 一些用户在组装机器时往往忽略一些小东西,从而造成计算机整体配件搭配不当,存在着速度上的瓶颈。比如有些朋友选的CPU档次很高,可声卡等却买了普通的便宜货,其实这样做往往是得不偿失。因为这样一来计算机在运行游戏、播放影碟时由于声卡占用CPU资源较高且其数据传输速度较慢,或者其根本无硬件解码而需要采用软件解码方式,常常会引起声音的停顿,甚至导致程序的运行断断续续。又如有些朋友的机器是升了级的,过去老机器上的一些部件如内存条舍不得抛弃,装在新机器上照用,可是由于老内存的速度限制,往往使新机器必须降低速度来迁就它,从而降低了整机的性能,极大地影响了整体的运行速度。 9、断开不用的网络驱动器 为了消除或减少 Windows 必须重新建立的网络连接数目,建议将一些不需要使用的网络驱动器断开,也就是进入“我的电脑”,右击已经建立映射的网络驱动器,选择“断开”即可。 10、缺少足够的内存 Windows操作系统所带来的优点之一就是多线性、多任务,系统可以利用CPU来进行分时操作,以便你同时做许多事情。但事情有利自然有弊,多任务操作也会对你的机器提出更高的要求。朋友们都知道即使是一个最常用的WORD软件也要求最好有16MB左右的内存,而运行如3D MAX等大型软件时,64MB的内存也不够用。所以此时系统就会自动采用硬盘空间来虚拟主内存,用于运行程序和储存交换文件以及各种临时文件。由于硬盘是机械结构,而内存是电子结构,它们两者之间的速度相差好几个数量级,因而使用硬盘来虚拟主内存将导致程序运行的速度大幅度降低。 11、硬盘空间不足 使用Windows系统平台的缺点之一就是对文件的管理不清楚,你有时根本就不知道这个文件对系统是否有用,因而Windows目录下的文件数目越来越多,容量也越来越庞大,加之现在的软件都喜欢越做越大,再加上一些系统产生的临时文件、交换文件,所有这些都会使得硬盘可用空间变小。当硬盘的可用空间小到一定程度时,就会造成系统的交换文件、临时文件缺乏可用空间,降低了系统的运行效率。更为重要的是由于我们平时频繁在硬盘上储存、删除各种软件,使得硬盘的可用空间变得支离破碎,因此系统在存储文件时常常没有按连续的顺序存放,这将导致系统存储和读取文件时频繁移动磁头,极大地降低了系统的运行速度。 12、硬盘分区太多也有错 如果你的Windows 2000没有升级到SP3或SP4,并且定义了太多的分区,那么也会使启动变得很漫长,甚至挂起。所以建议升级最新的SP4,同时最好不要为硬盘分太多的区。因为Windows 在启动时必须装载每个分区,随着分区数量的增多,完成此操作的时间总量也会不断增长。 三、病毒篇 如果你的计算机感染了病毒,那么系统的运行速度会大幅度变慢。病毒入侵后,首先占领内存这个据点,然后便以此为根据地在内存中开始漫无休止地复制自己,随着它越来越庞大,很快就占用了系统大量的内存,导致正常程序运行时因缺少主内存而变慢,甚至不能启动;同时病毒程序会迫使CPU转而执行无用的垃圾程序,使得系统始终处于忙碌状态,从而影响了正常程序的运行,导致计算机速度变慢。下面我们就介绍几种能使系统变慢的病毒。 1、使系统变慢的bride病毒 病毒类型:黑客程序 发作时间:随机 传播方式:网络 感染对象:网络 警惕程度:★★★★ 病毒介绍: 此病毒可以在Windows 2000、Windows XP等操作系统环境下正常运行。运行时会自动连接 www.hotmail.com网站,如果无法连接到此网站,则病毒会休眠几分钟,然后修改注册表将自己加入注册表自启动项,病毒会释放出四个病毒体和一个有漏洞的病毒邮件并通过邮件系统向外乱发邮件,病毒还会释放出FUNLOVE病毒感染局域网计算机,最后病毒还会杀掉已知的几十家反病毒软件,使这些反病毒软件失效。 病毒特征 如果用户发现计算机中有这些特征,则很有可能中了此病毒。 ·病毒运行后会自动连接 www.hotmail.com网站。 ·病毒会释放出Bride.exe,Msconfig.exe,Regedit.exe三个文件到系统目录;释放出:Help.eml, Explorer.exe文件到桌面。 ·病毒会在注册表的HKEY_LOCAL_MACHINESOFTWAREMicrosoftWindowsCurrentVersionRun项中加入病毒Regedit.exe的路径。 ·病毒运行时会释放出一个FUNLOVE病毒并将之执行,而FUNLOVE病毒会在计算机中大量繁殖,造成系统变慢,网络阻塞。 ·病毒会寻找计算机中的邮件地址,然后按照地址向外大量发送标题为:<被感染的计算机机名>(例:如果用户的计算机名为:张冬, 则病毒邮件的标题为:张冬)的病毒邮件。 ·病毒还会杀掉几十家国外著名的反病毒软件。 用户如果在自己的计算机中发现以上全部或部分现象,则很有可能中了Bride(Worm.bride)病毒,请用户立刻用手中的杀毒软件进行清除。 2、使系统变慢的阿芙伦病毒 病毒类型:蠕虫病毒 发作时间:随机 传播方式:网络/文件 感染对象:网络 警惕程度:★★★★ 病毒介绍: 此病毒可以在Windows 9X、Windows NT、Windows 2000、Windows XP等操作系统环境下正常运行。病毒运行时将自己复到到TEMP、SYSTEM、RECYCLED目录下,并随机生成文件名。该病毒运行后,会使消耗大量的系统资源,使系统明显变慢,并且杀掉一些正在运行的反病毒软件,建立四个线程在局域网中疯狂传播。 病毒特征 如果用户发现计算机中有这些特征,则很有可能中了此病毒: ·病毒运行时会将自己复到到TEMP、SYSTEM、RECYCLED目录下,文件名随机 ·病毒运行时会使系统明显变慢 ·病毒会杀掉一些正在运行的反病毒软件 ·病毒会修改注册表的自启动项进行自启动 ·病毒会建立四个线程在局域网中传播 用户如果在自己的计算机中发现以上全部或部分现象,则很有可能中了“阿芙伦(Worm.Avron)”病毒,由于此病毒没有固定的病毒文件名,所以,最好还是选用杀毒软件进行清除。 3、恶性蠕虫 震荡波 病毒名称: Worm.Sasser 中文名称: 震荡波 病毒别名: W32/Sasser.worm [Mcafee] 病毒类型: 蠕虫 受影响系统:WinNT/Win2000/WinXP/Win2003 病毒感染症状: ·莫名其妙地死机或重新启动计算机; ·系统速度极慢,cpu占用100%; ·网络变慢; ·最重要的是,任务管理器里有一个叫"avserve.exe"的进程在运行! 破坏方式: ·利用WINDOWS平台的 Lsass 漏洞进行广泛传播,开启上百个线程不停攻击其它网上其它系统,堵塞网络。病毒的攻击行为可让系统不停的倒计时重启。 ·和最近出现的大部分蠕虫病毒不同,该病毒并不通过邮件传播,而是通过命令易受感染的机器 下载特定文件并运行,来达到感染的目的。 ·文件名为:avserve.exe 解决方案: ·请升级您的操作系统,免受攻击 ·请打开个人防火墙屏蔽端口:445、5554和9996,防止名为avserve.exe的程序访问网络 ·手工解决方案: 首先,若系统为WinMe/WinXP,则请先关闭系统还原功能; 步骤一,使用进程程序管理器结束病毒进程 右键单击任务栏,弹出菜单,选择“任务管理器”,调出“Windows任务管理器”窗口。在任务管理器中,单击“进程”标签,在例表栏内找到病毒进程“avserve.exe”,单击“结束进程按钮”,点击“是”,结束病毒进程,然后关闭“Windows任务管理器”; 步骤二,查找并删除病毒程序 通过“我的电脑”或“资源管理器”进入 系统安装目录(Winnt或windows),找到文件“avser ve.exe”,将它删除;然后进入系统目录(Winntsystem32或windowssystem32),找 到文件"*_up.exe", 将它们删除; 步骤三,清除病毒在注册表里添加的项 打开注册表编辑器: 点击开始——>运行, 输入REGEDIT, 按Enter; 在左边的面板中, 双击(按箭头顺序查找,找到后双击): HKEY_CURRENT_USERSOFTWAREMicrosoftWindowsCurrentVersionRun 在右边的面板中, 找到并删除如下项目:"avserve.exe" = %SystemRoot%avserve.exe 关闭注册表编辑器。 第二部份 系统加速 一、Windows 98 1、不要加载太多随机启动程序 不要在开机时载入太多不必要的随机启动程序。选择“开始→程序→附件→系统工具→系统信息→系统信息对话框”,然后,选择“工具→系统配置实用程序→启动”,只需要internat.exe前打上钩,其他项都可以不需要,选中后确定重起即可。 2、转换系统文件格式 将硬盘由FAT16转为FAT32。 3、不要轻易使用背景 不要使用ActiveDesktop,否则系统运行速度会因此减慢(右击屏幕→寻显示器属性→Web标签→将其中关于“活动桌面”和“频道”的选项全部取消)。 4、设置虚拟内存 自己设定虚拟内存为机器内存的3倍,例如:有32M的内存就设虚拟内存为96M,且最大值和最小值都一样(此设定可通过“控制面板→系统→性能→虚拟内存”来设置)。 5、一些优化设置 a、到控制面板中,选择“系统→性能→ 文件系统”。将硬盘标签的“计算机主要用途”改为网络服务器,“预读式优化"调到全速。 b、将“软盘”标签中“每次启动就搜寻新的软驱”取消。 c、CD-ROM中的“追加高速缓存”调至最大,访问方式选四倍速或更快的CD-ROM。 6、定期对系统进行整理 定期使用下列工具:磁盘扫描、磁盘清理、碎片整理、系统文件检查器(ASD)、Dr?Watson等。 二、Windows 2000 1、升级文件系统 a、如果你所用的操作系统是win 9x与win 2000双重启动的话,建议文件系统格式都用FAT32格式,这样一来可以节省硬盘空间,二来也可以9x与2000之间能实行资源共享。 提醒:要实现这样的双重启动,最好是先在纯DOS环境下安装完9x在C区,再在9x中或者用win 2000启动盘启动在DOS环境下安装2000在另一个区内,并且此区起码要有800M的空间以上 b、如果阁下只使用win 2000的话,建议将文件系统格式转化为NTFS格式,这样一来可节省硬盘空间,二来稳定性和运转速度更高,并且此文件系统格式有很好的纠错性;但这样一来,DOS和win 9x系统就不能在这文件系统格式中运行,这也是上面所说做双启动最好要用FAT32格式才能保证资源共享的原因。而且,某些应用程序也不能在此文件系统格式中运行,大多是DOS下的游戏类。 提醒:在win 2000下将文件系统升级为NTFS格式的方法是,点击“开始-程序-附件”选中“命令提示符”,然后在打开的提示符窗口输入"convert drive_letter:/fs:ntfs",其中的"drive"是你所要升级的硬盘分区符号,如C区;还需要说明的是,升级文件系统,不会破坏所升级硬盘分区里的文件,无需要备份。 · 再运行“添加-删除程序”,就会看见多出了个“添加/删除 Windows 组件”的选项; b、打开“文件夹选项”,在“查看”标签里选中“显示所有文件和文件夹”,此时在你安装win 2000下的区盘根目录下会出现Autoexec.bat和Config.sys两个文件,事实上这两个文件里面根本没有任何内容,可以将它们安全删除。 c、右击“我的电脑”,选中“管理”,在点“服务和应用程序”下的“服务”选项,会看见win 2000上加载的各个程序组见,其中有许多是关于局域网设置或其它一些功能的,你完全可以将你不使用的程序禁用; 如:Alertr,如果你不是处于局域网中,完全可以它设置为禁用;还有Fax Service,不发传真的设置成禁用;Print Spooler,没有打印机的设置成制用;Uninterruptible power Supply,没有UPS的也设置成禁用,这些加载程序你自己可以根据自己实际情况进行设置。 各个加载程序后面都有说明,以及运行状态;选中了要禁用的程序,右击它,选“属性”,然后单击停止,并将“启动类型”设置为“手动”或者“已禁用”就行了 d、关掉调试器Dr. Watson; 运行drwtsn32,把除了“转储全部线程上下文”之外的全都去掉。否则一旦有程序出错,硬盘会响很久,而且会占用很多空间。如果你以前遇到过这种情况,请查找user.dmp文件并删掉,可能会省掉几十兆的空间。这是出错程序的现场,对我们没用。另外蓝屏时出现的memory.dmp也可删掉。可在我的电脑/属性中关掉 “答案来源于网络,供您参考” 希望以上信息可以帮到您!
牧明 2019-12-02 02:15:52 0 浏览量 回答数 0

问题

大型网站选择独立cdn域名(与主站不同根域)的原因

如果有心的访客在访问淘宝,新浪围脖的网站时就会注意到其大量静态文件(诸如css,js,图片等)都是通过非主站的域调入的,这样做有什么好处呢?,下面我们就来分析下他们为什么...
enj0y 2019-12-01 20:22:10 16297 浏览量 回答数 9

问题

使用阿里云服务器进行开发的小结

使用阿里云服务器开发总结(2周工作总结) 1、阿里云暂时只提供C#和Java的sdk,所以需要编写C++代码去调用Dll,以前学习过DLL的显式链接和隐式链接使用两种方...
gameover 2019-12-01 21:06:23 15827 浏览量 回答数 23

问题

【精品问答】100+ Java和JavaSE常用技术点

为大家整理了 Java和JavaSE常用技术点,可以应对面试。供大家学习交流参考: 运行时实现多态需要的三个必要条件? 访问修饰符public、private、protected、以及不写&#x...
游客pklijor6gytpx 2020-03-29 23:26:40 1148 浏览量 回答数 1

问题

2018MySQL技术问答集锦,希望能给喜欢MySQL的同学一些帮助

小编发现问答专区中有很多人在问关于mysql的问题,小编把这些问题汇总一下,希望能给喜欢mysql的大家一些启示和帮助本帖不定期更新,喜欢的可以收藏哦如何搭建MySQL集群?https://yq.aliyun.com/ask/482768m...
技术小能手 2019-12-01 19:31:11 1856 浏览量 回答数 0

回答

我们在《深入分析Java的编译原理》中提到过,为了让Java语言具有良好的跨平台能力,Java独具匠心的提供了一种可以在所有平台上都能使用的一种中间代码——字节码(ByteCode)。 有了字节码,无论是哪种平台(如Windows、Linux等),只要安装了虚拟机,都可以直接运行字节码。 同样,有了字节码,也解除了Java虚拟机和Java语言之间的耦合。这话可能很多人不理解,Java虚拟机不就是运行Java语言的么?这种解耦指的是什么? 其实,目前Java虚拟机已经可以支持很多除Java语言以外的语言了,如Kotlin、Groovy、JRuby、Jython、Scala等。之所以可以支持,就是因为这些语言也可以被编译成字节码。而虚拟机并不关心字节码是有哪种语言编译而来的。 经常使用IDE的开发者可能会发现,当我们在Intelij IDEA中,鼠标右键想要创建Java类的时候,IDE还会提示创建其他类型的文件,这就是IDE默认支持的一些可以运行在JVM上面的语言,没有提示的,可以通过插件来支持。 目前,可以直接在JVM上运行的语言有很多,今天介绍其中比较重要的九种。每种语言通过一段『HelloWorld』代码进行演示,看看不同语言的语法有何不同。 Kotlin Kotlin是一种在Java虚拟机上运行的静态类型编程语言,它也可以被编译成为JavaScript源代码。Kotlin的设计初衷就是用来生产高性能要求的程序的,所以运行起来和Java也是不相上下。Kotlin可以从 JetBrains InteilliJ Idea IDE这个开发工具以插件形式使用。 Hello World In Kotlin fun main(args: Array<String>) { println("Hello, world!") } Groovy Apache的Groovy是Java平台上设计的面向对象编程语言。它的语法风格与Java很像,Java程序员能够很快的熟练使用 Groovy,实际上,Groovy编译器是可以接受完全纯粹的Java语法格式的。 使用Groovy的一个重要特点就是使用类型推断,即能够让编译器能够在程序员没有明确说明的时候推断出变量的类型。Groovy可以使用其他Java语言编写的库。Groovy的语法与Java非常相似,大多数Java代码也匹配Groovy的语法规则,尽管可能语义不同。 Hello World In Groovy static void main(String[] args) { println('Hello, world!'); } Scala Scala是一门多范式的编程语言,设计初衷是要集成面向对象编程和函数式编程的各种特性。 Scala经常被我们描述为多模式的编程语言,因为它混合了来自很多编程语言的元素的特征。但无论如何它本质上还是一个纯粹的面向对象语言。它相比传统编 程语言最大的优势就是提供了很好并行编程基础框架措施了。Scala代码能很好的被优化成字节码,运行起来和原生Java一样快。 Hello World In Scala object HelloWorld { def main(args: Array[String]) { System.out.println("Hello, world!"); } } Jruby JRuby是用来桥接Java与Ruby的,它是使用比Groovy更加简短的语法来编写代码,能够让每行代码执行更多的任务。就和Ruby一样,JRuby不仅仅只提供了高级的语法格式。它同样提供了纯粹的面向对象的实现,闭包等等,而且JRuby跟Ruby自身相比多了很多基于Java类库 可以调用,虽然Ruby也有很多类库,但是在数量以及广泛性上是无法跟Java标准类库相比的。 Hello World In Jruby puts 'Hello, world!' Jython Jython,是一个用Java语言写的Python解释器。Jython能够用Python语言来高效生成动态编译的Java字节码。 Hello World In Jython print "Hello, world!" Fantom Fantom是一种通用的面向对象编程语言,由Brian和Andy Frank创建,运行在Java Runtime Environment,JavaScript和.NET Common Language Runtime上。其主要设计目标是提供标准库API,以抽象出代码是否最终将在JRE或CLR上运行的问题。 Fantom是与Groovy以及JRuby差不多的一样面向对 象的编程语言,但是悲剧的是Fantom无法使用Java类库,而是使用它自己扩展的类库。 Hello World In Fantom class Hello { static Void main() { echo("Hello, world!") } } Clojure Clojure是Lisp编程语言在Java平台上的现代、函数式及动态方言。 与其他Lisp一样,Clojure视代码为数据且拥有一套Lisp宏系统。 虽然Clojure也能被直接编译成Java字节码,但是无法使用动态语言特性以及直 接调用Java类库。与其他的JVM脚本语言不一样,Clojure并不算是面向对象的。 Hello World In Clojure (defn -main [& args] (println "Hello, World!")) Rhino Rhino是一个完全以Java编写的JavaScript引擎,目前由Mozilla基金会所管理。 Rhino的特点是为JavaScript加了个壳,然后嵌入到Java中,这样能够让Java程序员直接使用。其中Rhino的JavaAdapters能够让JavaScript通过调用Java的类来实现特定的功能。 Hello World In Rhino print('Hello, world!') Ceylon Ceylon是一种面向对象,强烈静态类型的编程语言,强调不变性,由Red Hat创建。 Ceylon程序在Java虚拟机上运行,​​可以编译为JavaScript。 语言设计侧重于源代码可读性,可预测性,可扩展性,模块性和元编程性。 Hello World In Ceylon shared void run() { print("Hello, world!"); } 总结 好啦,以上就是目前主流的可以在JVM上面运行的9种语言。加上Java正好10种。如果你是一个Java开发,那么有必要掌握以上9中的一种,这样可以在一些有特殊需求的场景中有更多的选择。推荐在Groovy、Scala、Kotlin中选一个。
montos 2020-06-01 17:04:25 0 浏览量 回答数 0

问题

【Java学习全家桶】1460道Java热门问题,阿里百位技术专家答疑解惑

阿里极客公益活动: 或许你挑灯夜战只为一道难题 或许你百思不解只求一个答案 或许你绞尽脑汁只因一种未知 那么他们来了,阿里系技术专家来云栖问答为你解答技术难题了 他们用户自己手中的技术来帮助用户成长 本次活动特邀百位阿里技术专家对Java常...
管理贝贝 2019-12-01 20:07:15 27612 浏览量 回答数 19

回答

转自:思否 本文作者:Michael van der Gulik 原文链接:《Why WebAssembly is a big deal》 译者:敖小剑 WebAssembly 是每个程序员都应该关注的技术。WebAssembly 会变得更流行。 WebAssembly 将取代 JavaScript。WebAssembly 将取代 HTML 和 CSS。 WebAssembly 将取代手机应用。WebAssembly 将取代桌面应用。在 10 年内,我保证每个程序员至少需要知道如何使用工具来操作 WebAssembly 并理解它是如何工作的。 你可能会说,“太离谱了!” 好吧,请继续阅读。 什么是 WebAssembly 当前形式的 WebAssembly 是 Web 浏览器的新扩展,可以运行预编译代码…快速地。在 C ++ 中编写了一些小代码,然后使用 Emscripten 编译器将该代码编译为 WebAssembly。通过一些 Javascript 粘合,就可以在 Web 浏览器中调用这一小段代码,例如,运行粒子模拟。 WebAssembly 文件,扩展名为.wasm,本身是包含可执行指令的二进制格式。要使用该文件,必须编写一个运行某些 Javascript 的 HTML 文件来获取、编译和执行 WebAssembly 文件。WebAssembly 文件在基于堆栈的虚拟机上执行,并使用共享内存与其 JavaScript 包装器进行通信。 到目前为止,这似乎并不有趣。它看起来只不过是 JavaScript 的加速器。但是,聪明的读者会对 WebAssembly 可能成为什么有所了解。 WebAssembly 将成为什么? 第一个重要发现是 WebAssembly 是一个安全的沙盒虚拟机。可以从 Internet 运行喜欢的 WebAssembly 代码,而确保它不会接管 PC 或服务器。四个主流 Web 浏览器对它的安全性非常有信心,它已经默认实现并启用了。它的真正安全性还有待观察,但安全性是 WebAssembly 的核心设计目标。 第二个重要发现是 WebAssembly 是一个通用的编译目标。它的原始编译器是一个 C 编译器,这个编译器很好地指示了 WebAssembly 虚拟机的低级和可重定向性。许多编程语言都使用 C 语言编写虚拟机,其他一些语言甚至使用 C 本身作为编译目标。 此时,有人整理了一个可以编译为 WebAssembly 的编程语言列表。这份名单将在未来很多年中继续增长。 WebAssembly 允许使用任何编程语言编写代码,然后让其他人在任何平台上安全地运行该代码,无需安装任何内容。朋友们,这是美好梦想的开始。 部署问题 我们来谈谈如何将软件提供给用户。 为新项目选择编程语言的一个重要因素是如何将项目部署到客户。您的程序员喜欢用 Haskell,Python,Visual Basic 或其他语言编写应用程序,具体取决于他们的喜好。要使用喜欢的语言,他们需要编译应用,制作一些可安装的软件包,并以某种方式将其安装在客户端的计算机上。有许多方法可以提供软件 - 包管理器,可执行安装程序或安装服务,如 Steam,Apple App Store,Google Play 或 Microsoft store。 每一个安装机制都意味着痛苦,从应用商店安装时的轻微疼痛,到管理员要求在他的 PC 上运行一些旧的 COBOL 代码时的集群头痛。 部署是一个问题。对于开发人员和系统管理员来说,部署一直是一个痛点。我们使用的编程语言与我们所针对的平台密切相关。如果大量用户在 PC 或移动设备上,我们使用 HTML 和 Javascript。如果用户是 Apple 移动设备用户,我们使用……呃…… Swift?(我实际上不知道)。如果用户在 Android 设备上,我们使用 Java 或 Kotlin。如果用户在真实计算机上并且愿意处理掉他们的部署问题,那么我们开发人员才能在我们使用的编程语言中有更多选择。 WebAssembly 有可能解决部署问题。 有了 WebAssembly,您可以使用任何编程语言编写应用,只要这些编程语言可以支持 WebAssembly,而应用可以在任何设备和任何具有现代 Web 浏览器的操作系统上运行。 硬件垄断 想购买台式机或笔记本电脑。有什么选择?好吧,有英特尔,有 AMD。多年来一直是双寡头垄断。保持这种双寡头垄断的一个原因是 x86 架构只在这两家公司之间交叉许可,而且通常预编译的代码需要 x86 或 x86-64(也就是 AMD-64)架构。还有其他因素,例如设计世界上最快的 CPU 是一件很艰难但也很昂贵的事情。 WebAssembly 是一种可让您在任何平台上运行代码的技术(之一)。如果它成为下一个风口,硬件市场将变得商品化。应用编译为 WebAssembly,就可以在任何东西上运行 - x86,ARM,RISC-V,SPARC。即便是操作系统市场也会商品化;您所需要的只是一个支持 WebAssembly 的浏览器,以便在硬件可以运行时运行最苛刻的应用程序。 编者注:Second State 研发的专为服务端优化的 WebAssembly 引擎 SSVM 已经可以运行在高通骁龙芯片上。Github 链接:https://github.com/second-sta... 云计算 但等等,还有更多。云计算成为IT经理办公室的流行词已有一段时间,WebAssembly 可以直接迎合它。 WebAssembly 在安全沙箱中执行。可以制作一个容器,它可以在服务器上接受和执行 WebAssembly 模块,而资源开销很小。对于提供的每个服务,无需在虚拟机上运行完整的操作系统。托管提供商只提供对可以上传代码的WebAssembly 容器的访问权限。它可以是一个原始容器,接收 socket 并解析自己的 HTTP 连接,也可以是一个完整的 Web 服务容器,其中 WebAssembly 模块只需要处理预解析的HTTP请求。 这还不存在。如果有人想变得富有,那么可以考虑这个想法。 编者注:目前已经有人正在实现这个想法,Byte Alliance 计划将WebAssembly 带到浏览器之外,Second State 已经发布了为服务端设计的WebAssembly 引擎开发者预览版。 不是云计算 WebAssembly 足以取代 PC 上本地安装的大多数应用程序。我们已经使用 WebGL(又名OpenGL ES 2.0)移植了游戏。我预测不久之后,受益于WebAssembly,像 LibreOffice 这样的大型应用可以直接从网站上获得,而无需安装。 在这种情况下,在本地安装应用没什么意义。本地安装的应用和 WebAssembly 应用之间几乎没有区别。WebAssembly 应用已经可以使用屏幕,键盘和鼠标进行交互。它可以在 2D 或 OpenGL 中进行图形处理,并使用硬件对视频流进行解码。可以播放和录制声音。可以访问网络摄像头。可以使用 WebSockets。可以使用 IndexedDB 存储大量数据在本地磁盘上。这些已经是 Web 浏览器中的标准功能,并且都可以使用 JavaScript 向 WebAssembly 暴露。 目前唯一困难的地方是 WebAssembly 无法访问本地文件系统。好吧,可以通过 HTML 使用文件上传对话,但这不算。最终,总会有人为此创建 API,并可能称之为 “WASI”。 “从互联网上运行应用程序!?胡说八道!“,你说。好吧,这是使用 Qt 和 WebAssembly 实现的文本编辑器 (以及更多)。 这是一个简单的例子。复杂的例子是在 WebBrowser 中运行的 Adobe Premier Pro 或 Blender。或者考虑像 Steam 游戏一样可以直接从网络上运行。这听起来像小说,但从技术上说这并非不能发生。 它会来的。 让我们裸奔! 目前,WebAssembly 在包含 HTML 和 Javascript 包装器的环境中执行。为什么不脱掉这些?有了 WebAssembly,为什么还要在浏览器中包含 HTML 渲染器和 JavaScript 引擎? 通过为所有服务提供标准化 API,这些服务通常是 Web 浏览器提供的,可以创建裸 WebAssembly。就是没有 HTML和 Javascript 包装来管理的 WebAssembly。访问的网页是 .wasm 文件,浏览器会抓取并运行该文件。浏览器为WebAssembly 模块提供画布,事件处理程序以及对浏览器提供的所有服务的访问。 这目前还不存在。如果现在使用 Web 浏览器直接访问 .wasm 文件,它会询问是否要下载它。我假设将设计所需的 API 并使其工作。 结果是 Web 可以发展。网站不再局限于 HTML,CSS 和 Javascript。可以创建全新的文档描述语言。可以发明全新的布局引擎。而且,对于像我这样的 polyglots 最相关,我们可以选择任何编程语言来实现在线服务。 可访问性 但我听到了强烈抗议!可访问性怎么样??搜索引擎怎么办? 好吧,我还没有一个好的答案。但我可以想象几种技术解决方案。 一个解决方案是我们保留内容和表现的分离。内容以标准化格式编写,例如 HTML。演示文稿由 WebAssembly 应用管理,该应用可以获取并显示内容。这允许网页设计师使用想要的任何技术进行任意演示 - 不需要 CSS,而搜索引擎和需要不同类型的可访问性的用户仍然可以访问内容。 请记住,许多 WebAssembly 应用并不是可以通过文本访问的,例如游戏和许多应用。盲人不会从图像编辑器中获得太多好处。 另一个解决方案是发明一个 API,它可以作为 WebAssembly 模块,来提供想在屏幕上呈现的 DOM,供屏幕阅读器或搜索引擎使用。基本上会有两种表示形式:一种是在图形画布上,另一种是产生结构化文本输出。 第三种解决方案是使用屏幕阅读器或搜索引擎可以使用的元数据来增强画布。执行 WebAssembly 并在画布上呈现内容,其中包含描述渲染内容的额外元数据。例如,该元数据将包括屏幕上的区域是否是菜单以及存在哪些选项,或者区域是否想要文本输入,以及屏幕上的区域的自然排序(也称为标签顺序)是什么。基本上,曾经在 HTML 中描述的内容现在被描述为具有元数据的画布区域。同样,这只是一个想法,它可能在实践中很糟糕。 可能是什么 1995年,Sun Microsystems 发布了 Java,带有 Java applets 和大量的宣传。有史以来第一次,网页可以做一些比 和 GIF 动画更有趣的事情。开发人员可以使应用完全在用户的 Web 浏览器中运行。它们没有集成到浏览器中,而是实现为繁重的插件,需要安装整个 JVM。1995年,这不是一个小的安装。applets 也需要一段时间来加载并使用大量内存。我们现在凭借大量内存,这不再是一个问题,但在 Java 生命的第一个十年里,它让体验变得令人厌烦。 applets 也不可靠。无法保证它们会运行,尤其是在用户使用 Microsoft 的实现时。他们也不安全,这是棺材里的最后一颗钉子。 以 JVM 为荣,其他语言最终演变为在 JVM 上运行。但现在,那艘船航行了。 FutureSplash / Macromedia / Adobe Flash 也是一个竞争者,但是是专有的,具有专有工具集和专有语言的专有格式。我读到他们确实在2009年开启了文件格式。最终从浏览器中删除了支持,因为它存在安全风险。 这里的结论是,如果希望您的技术存在于每个人的机器上,那么安全性就需要正视。我真诚地希望 WebAssembly 作为标准对安全问题做出很好的反应。 需要什么? WebAssembly 仍处于初期阶段。它目前能很好的运行代码,而规范版本是 1.0,二进制格式定型。目前正在开展SIMD 指令支持。通过 Web Workers 进行多线程处理也正在进行中。 工具可用,并将在未来几年不断改进。浏览器已经让你窥视 WebAssembly 文件。至少 Firefox 允许查看WebAssembly 字节码,设置断点并查看调用堆栈。我听说浏览器也有 profiling 支持。 语言支持包括一套不错的语言集合–C,C++和Rust是一流的公民。C#,Go和Lua显然有稳定的支持。Python,Scala,Ruby,Java和Typescript都有实验性支持。这可能是一个傲慢的陈述,但我真的相信任何想要在21世纪存在的语言都需要能够在 WebAssembly 上编译或运行。 在访问外部设备的 API 支持方面,我所知道的唯一可用于裸 WebAssembly 的 API 是 WASI,它允许文件和流访问等核心功能,允许 WebAssembly 在浏览器外运行。否则,任何访问外部世界的 API 都需要在浏览器中的 Javascript 中实现。除了本地机器上的文件访问,打印机访问和其他新颖的硬件访问(例如非标准蓝牙或USB设备)之外,应用所需的一切几乎都可以满足。“裸WebAssembly”并不是它成功的必要条件; 它只是一个小的优化,不需要浏览器包含对 HTML,CSS 或 Javascript 的支持。 我不确定在桌面环境中让 WebAssembly 成为一等公民需要什么。需要良好的复制和粘贴支持,拖放支持,本地化和国际化,窗口管理事件以及创建通知的功能。也许这些已经可以从网络浏览器中获得; 我经常惊讶与已经可能的事情。 引发爆炸的火花是创建允许现有应用移植的环境。如果创造了“用于 WebAssembly 的 Linux 子系统”,那么可以将大量现有的开源软件移植到 WebAssembly 上。它需要模拟一个文件系统 - 可以通过将文件系统的所有只读部分都缓存为 HTTP 请求来完成,并且所有可写部分都可以在内存中,远程存储或使用浏览器可以提供的任何文件访问。图形支持可以通过移植 X11 或 Wayland 的实现来使用 WebGL(我理解已经作为 AIGLX 存在?)。 一些 SDL 游戏已经被移植到 WebAssembly - 最着名的是官方演示。 一旦 JVM 在 WebAssembly 中运行,就可以在浏览器中运行大量的 Java 软件。同样适用于其他虚拟机和使用它们的语言。 与 Windows 软件的巨大世界一样,我没有答案。WINE 和 ReactOS 都需要底层的 x86 或 x86-64 机器,所以唯一的选择是获取源代码并移植它,或者使用 x86 模拟器。 尾声 WebAssembly 即将到来。 它来得很慢,但现在所有的部分都可以在你正在使用的浏览器上使用。现在我们等待构建用于从各种编程语言中定位 WebAssembly 的基础设施。一旦构建完成,我们将摆脱 HTML,CSS 和 Javascript 的束缚。 加入阿里云钉钉群享福利:每周技术直播,定期群内有奖活动、大咖问答 阿里云开发者社区
茶什i 2020-01-07 10:32:35 0 浏览量 回答数 0

问题

C语言基础 【精品问答合集】

怎样把c语言学好? https://yq.aliyun.com/ask/60638 栈的输出的c语言代码 https://yq.aliyun.com/ask/1507 c语言如何实现事件循环 https://yq...
马铭芳 2019-12-01 20:09:24 25670 浏览量 回答数 14

回答

初识 MyBatis MyBatis 是第一个支持自定义 SQL、存储过程和高级映射的类持久框架。MyBatis 消除了大部分 JDBC 的样板代码、手动设置参数以及检索结果。MyBatis 能够支持简单的 XML 和注解配置规则。使 Map 接口和 POJO 类映射到数据库字段和记录。 MyBatis 的特点 那么 MyBatis 具有什么特点呢?或许我们可以从如下几个方面来描述 MyBatis 中的 SQL 语句和主要业务代码分离,我们一般会把 MyBatis 中的 SQL 语句统一放在 XML 配置文件中,便于统一维护。 解除 SQL 与程序代码的耦合,通过提供 DAO 层,将业务逻辑和数据访问逻辑分离,使系统的设计更清晰,更易维护,更易单元测试。SQL 和代码的分离,提高了可维护性。 MyBatis 比较简单和轻量 本身就很小且简单。没有任何第三方依赖,只要通过配置 jar 包,或者如果你使用 Maven 项目的话只需要配置 Maven 以来就可以。易于使用,通过文档和源代码,可以比较完全的掌握它的设计思路和实现。 屏蔽样板代码 MyBatis 回屏蔽原始的 JDBC 样板代码,让你把更多的精力专注于 SQL 的书写和属性-字段映射上。 编写原生 SQL,支持多表关联 MyBatis 最主要的特点就是你可以手动编写 SQL 语句,能够支持多表关联查询。 提供映射标签,支持对象与数据库的 ORM 字段关系映射 ORM 是什么?对象关系映射(Object Relational Mapping,简称ORM) ,是通过使用描述对象和数据库之间映射的元数据,将面向对象语言程序中的对象自动持久化到关系数据库中。本质上就是将数据从一种形式转换到另外一种形式。 提供 XML 标签,支持编写动态 SQL。 你可以使用 MyBatis XML 标签,起到 SQL 模版的效果,减少繁杂的 SQL 语句,便于维护。 MyBatis 整体架构 MyBatis 最上面是接口层,接口层就是开发人员在 Mapper 或者是 Dao 接口中的接口定义,是查询、新增、更新还是删除操作;中间层是数据处理层,主要是配置 Mapper -> XML 层级之间的参数映射,SQL 解析,SQL 执行,结果映射的过程。上述两种流程都由基础支持层来提供功能支撑,基础支持层包括连接管理,事务管理,配置加载,缓存处理等。 接口层 在不与Spring 集成的情况下,使用 MyBatis 执行数据库的操作主要如下: InputStream is = Resources.getResourceAsStream("myBatis-config.xml"); SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder(); SqlSessionFactory factory = builder.build(is); sqlSession = factory.openSession(); 其中的SqlSessionFactory,SqlSession是 MyBatis 接口的核心类,尤其是 SqlSession,这个接口是MyBatis 中最重要的接口,这个接口能够让你执行命令,获取映射,管理事务。 数据处理层 配置解析 在 Mybatis 初始化过程中,会加载 mybatis-config.xml 配置文件、映射配置文件以及 Mapper 接口中的注解信息,解析后的配置信息会形成相应的对象并保存到 Configration 对象中。之后,根据该对象创建SqlSessionFactory 对象。待 Mybatis 初始化完成后,可以通过 SqlSessionFactory 创建 SqlSession 对象并开始数据库操作。 SQL 解析与 scripting 模块 Mybatis 实现的动态 SQL 语句,几乎可以编写出所有满足需要的 SQL。 Mybatis 中 scripting 模块会根据用户传入的参数,解析映射文件中定义的动态 SQL 节点,形成数据库能执行的SQL 语句。 SQL 执行 SQL 语句的执行涉及多个组件,包括 MyBatis 的四大核心,它们是: Executor、StatementHandler、ParameterHandler、ResultSetHandler。SQL 的执行过程可以用下面这幅图来表示 MyBatis 层级结构各个组件的介绍(这里只是简单介绍,具体介绍在后面): SqlSession: ,它是 MyBatis 核心 API,主要用来执行命令,获取映射,管理事务。接收开发人员提供 Statement Id 和参数。并返回操作结果。Executor :执行器,是 MyBatis 调度的核心,负责 SQL 语句的生成以及查询缓存的维护。StatementHandler : 封装了JDBC Statement 操作,负责对 JDBC Statement 的操作,如设置参数、将Statement 结果集转换成 List 集合。ParameterHandler : 负责对用户传递的参数转换成 JDBC Statement 所需要的参数。ResultSetHandler : 负责将 JDBC 返回的 ResultSet 结果集对象转换成 List 类型的集合。TypeHandler : 用于 Java 类型和 JDBC 类型之间的转换。MappedStatement : 动态 SQL 的封装SqlSource : 表示从 XML 文件或注释读取的映射语句的内容,它创建将从用户接收的输入参数传递给数据库的 SQL。Configuration: MyBatis 所有的配置信息都维持在 Configuration 对象之中。 基础支持层 反射模块 Mybatis 中的反射模块,对 Java 反射进行了很好的封装,提供了简易的 API,方便上层调用,并且对反射操作进行了一系列的优化,比如,缓存了类的 元数据(MetaClass)和对象的元数据(MetaObject),提高了反射操作的性能。 类型转换模块 Mybatis 的别名机制,能够简化配置文件,该机制是类型转换模块的主要功能之一。类型转换模块的另一个功能是实现 JDBC 类型与 Java 类型的转换。在 SQL 语句绑定参数时,会将数据由 Java 类型转换成 JDBC 类型;在映射结果集时,会将数据由 JDBC 类型转换成 Java 类型。 日志模块 在 Java 中,有很多优秀的日志框架,如 Log4j、Log4j2、slf4j 等。Mybatis 除了提供了详细的日志输出信息,还能够集成多种日志框架,其日志模块的主要功能就是集成第三方日志框架。 资源加载模块 该模块主要封装了类加载器,确定了类加载器的使用顺序,并提供了加载类文件和其它资源文件的功能。 解析器模块 该模块有两个主要功能:一个是封装了 XPath,为 Mybatis 初始化时解析 mybatis-config.xml配置文件以及映射配置文件提供支持;另一个为处理动态 SQL 语句中的占位符提供支持。 数据源模块 Mybatis 自身提供了相应的数据源实现,也提供了与第三方数据源集成的接口。数据源是开发中的常用组件之一,很多开源的数据源都提供了丰富的功能,如连接池、检测连接状态等,选择性能优秀的数据源组件,对于提供ORM 框架以及整个应用的性能都是非常重要的。 事务管理模块 一般地,Mybatis 与 Spring 框架集成,由 Spring 框架管理事务。但 Mybatis 自身对数据库事务进行了抽象,提供了相应的事务接口和简单实现。 缓存模块 Mybatis 中有一级缓存和二级缓存,这两级缓存都依赖于缓存模块中的实现。但是需要注意,这两级缓存与Mybatis 以及整个应用是运行在同一个 JVM 中的,共享同一块内存,如果这两级缓存中的数据量较大,则可能影响系统中其它功能,所以需要缓存大量数据时,优先考虑使用 Redis、Memcache 等缓存产品。 Binding 模块 在调用 SqlSession 相应方法执行数据库操作时,需要制定映射文件中定义的 SQL 节点,如果 SQL 中出现了拼写错误,那就只能在运行时才能发现。为了能尽早发现这种错误,Mybatis 通过 Binding 模块将用户自定义的Mapper 接口与映射文件关联起来,系统可以通过调用自定义 Mapper 接口中的方法执行相应的 SQL 语句完成数据库操作,从而避免上述问题。注意,在开发中,我们只是创建了 Mapper 接口,而并没有编写实现类,这是因为 Mybatis 自动为 Mapper 接口创建了动态代理对象。 MyBatis 核心组件 在认识了 MyBatis 并了解其基础架构之后,下面我们来看一下 MyBatis 的核心组件,就是这些组件实现了从 SQL 语句到映射到 JDBC 再到数据库字段之间的转换,执行 SQL 语句并输出结果集。首先来认识 MyBatis 的第一个核心组件 SqlSessionFactory 对于任何框架而言,在使用该框架之前都要经历过一系列的初始化流程,MyBatis 也不例外。MyBatis 的初始化流程如下 String resource = "org/mybatis/example/mybatis-config.xml"; InputStream inputStream = Resources.getResourceAsStream(resource); SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); sqlSessionFactory.openSession(); 上述流程中比较重要的一个对象就是SqlSessionFactory,SqlSessionFactory 是 MyBatis 框架中的一个接口,它主要负责的是 MyBatis 框架初始化操作 为开发人员提供SqlSession 对象 SqlSessionFactory 有两个实现类,一个是 SqlSessionManager 类,一个是 DefaultSqlSessionFactory 类 DefaultSqlSessionFactory : SqlSessionFactory 的默认实现类,是真正生产会话的工厂类,这个类的实例的生命周期是全局的,它只会在首次调用时生成一个实例(单例模式),就一直存在直到服务器关闭。 SqlSessionManager : 已被废弃,原因大概是: SqlSessionManager 中需要维护一个自己的线程池,而使用MyBatis 更多的是要与 Spring 进行集成,并不会单独使用,所以维护自己的 ThreadLocal 并没有什么意义,所以 SqlSessionManager 已经不再使用。 ####SqlSessionFactory 的执行流程 下面来对 SqlSessionFactory 的执行流程来做一个分析 首先第一步是 SqlSessionFactory 的创建 SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); 1 从这行代码入手,首先创建了一个 SqlSessionFactoryBuilder 工厂,这是一个建造者模式的设计思想,由 builder 建造者来创建 SqlSessionFactory 工厂 然后调用 SqlSessionFactoryBuilder 中的 build 方法传递一个InputStream 输入流,Inputstream 输入流中就是你传过来的配置文件 mybatis-config.xml,SqlSessionFactoryBuilder 根据传入的 InputStream 输入流和environment、properties属性创建一个XMLConfigBuilder对象。SqlSessionFactoryBuilder 对象调用XMLConfigBuilder 的parse()方法,流程如下。 XMLConfigBuilder 会解析/configuration标签,configuration 是 MyBatis 中最重要的一个标签,下面流程会介绍 Configuration 标签。 MyBatis 默认使用 XPath 来解析标签,关于 XPath 的使用,参见 https://www.w3school.com.cn/xpath/index.asp 在 parseConfiguration 方法中,会对各个在 /configuration 中的标签进行解析 重要配置 说一下这些标签都是什么意思吧 properties,外部属性,这些属性都是可外部配置且可动态替换的,既可以在典型的 Java 属性文件中配置,亦可通过 properties 元素的子元素来传递。 <properties> <property name="driver" value="com.mysql.jdbc.Driver" /> <property name="url" value="jdbc:mysql://localhost:3306/test" /> <property name="username" value="root" /> <property name="password" value="root" /> </properties> 一般用来给 environment 标签中的 dataSource 赋值 <environment id="development"> <transactionManager type="JDBC" /> <dataSource type="POOLED"> <property name="driver" value="${driver}" /> <property name="url" value="${url}" /> <property name="username" value="${username}" /> <property name="password" value="${password}" /> </dataSource> </environment> 还可以通过外部属性进行配置,但是我们这篇文章以原理为主,不会介绍太多应用层面的操作。 settings ,MyBatis 中极其重要的配置,它们会改变 MyBatis 的运行时行为。 settings 中配置有很多,具体可以参考 https://mybatis.org/mybatis-3/zh/configuration.html#settings 详细了解。这里介绍几个平常使用过程中比较重要的配置 一般使用如下配置 <settings> <setting name="cacheEnabled" value="true"/> <setting name="lazyLoadingEnabled" value="true"/> </settings> typeAliases,类型别名,类型别名是为 Java 类型设置的一个名字。 它只和 XML 配置有关。 <typeAliases> <typeAlias alias="Blog" type="domain.blog.Blog"/> </typeAliases> 当这样配置时,Blog 可以用在任何使用 domain.blog.Blog 的地方。 typeHandlers,类型处理器,无论是 MyBatis 在预处理语句(PreparedStatement)中设置一个参数时,还是从结果集中取出一个值时, 都会用类型处理器将获取的值以合适的方式转换成 Java 类型。 在 org.apache.ibatis.type 包下有很多已经实现好的 TypeHandler,可以参考如下 你可以重写类型处理器或创建你自己的类型处理器来处理不支持的或非标准的类型。 具体做法为:实现 org.apache.ibatis.type.TypeHandler 接口, 或继承一个很方便的类 org.apache.ibatis.type.BaseTypeHandler, 然后可以选择性地将它映射到一个 JDBC 类型。 objectFactory,对象工厂,MyBatis 每次创建结果对象的新实例时,它都会使用一个对象工厂(ObjectFactory)实例来完成。默认的对象工厂需要做的仅仅是实例化目标类,要么通过默认构造方法,要么在参数映射存在的时候通过参数构造方法来实例化。如果想覆盖对象工厂的默认行为,则可以通过创建自己的对象工厂来实现。 public class ExampleObjectFactory extends DefaultObjectFactory { public Object create(Class type) { return super.create(type); } public Object create(Class type, List constructorArgTypes, List constructorArgs) { return super.create(type, constructorArgTypes, constructorArgs); } public void setProperties(Properties properties) { super.setProperties(properties); } public boolean isCollection(Class type) { return Collection.class.isAssignableFrom(type); } } 然后需要在 XML 中配置此对象工厂 <objectFactory type="org.mybatis.example.ExampleObjectFactory"> <property name="someProperty" value="100"/> </objectFactory> plugins,插件开发,插件开发是 MyBatis 设计人员给开发人员留给自行开发的接口,MyBatis 允许你在已映射语句执行过程中的某一点进行拦截调用。MyBatis 允许使用插件来拦截的方法调用包括:Executor、ParameterHandler、ResultSetHandler、StatementHandler 接口,这几个接口也是 MyBatis 中非常重要的接口,我们下面会详细介绍这几个接口。 environments,MyBatis 环境配置,MyBatis 可以配置成适应多种环境,这种机制有助于将 SQL 映射应用于多种数据库之中。例如,开发、测试和生产环境需要有不同的配置;或者想在具有相同 Schema 的多个生产数据库中 使用相同的 SQL 映射。 这里注意一点,虽然 environments 可以指定多个环境,但是 SqlSessionFactory 只能有一个,为了指定创建哪种环境,只要将它作为可选的参数传递给 SqlSessionFactoryBuilder 即可。 SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(reader, environment); SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(reader, environment, properties); databaseIdProvider ,数据库厂商标示,MyBatis 可以根据不同的数据库厂商执行不同的语句,这种多厂商的支持是基于映射语句中的 databaseId 属性。 <databaseIdProvider type="DB_VENDOR"> <property name="SQL Server" value="sqlserver"/> <property name="DB2" value="db2"/> <property name="Oracle" value="oracle" /> </databaseIdProvider> mappers,映射器,这是告诉 MyBatis 去哪里找到这些 SQL 语句,mappers 映射配置有四种方式 上面的一个个属性都对应着一个解析方法,都是使用 XPath 把标签进行解析,解析完成后返回一个 DefaultSqlSessionFactory 对象,它是 SqlSessionFactory 的默认实现类。这就是 SqlSessionFactoryBuilder 的初始化流程,通过流程我们可以看到,初始化流程就是对一个个 /configuration 标签下子标签的解析过程。 SqlSession 在 MyBatis 初始化流程结束,也就是 SqlSessionFactoryBuilder -> SqlSessionFactory 的获取流程后,我们就可以通过 SqlSessionFactory 对象得到 SqlSession 然后执行 SQL 语句了。具体来看一下这个过程‘ 在 SqlSessionFactory.openSession 过程中我们可以看到,会调用到 DefaultSqlSessionFactory 中的 openSessionFromDataSource 方法,这个方法主要创建了两个与我们分析执行流程重要的对象,一个是 Executor 执行器对象,一个是 SqlSession 对象。执行器我们下面会说,现在来说一下 SqlSession 对象 SqlSession 对象是 MyBatis 中最重要的一个对象,这个接口能够让你执行命令,获取映射,管理事务。SqlSession 中定义了一系列模版方法,让你能够执行简单的 CRUD 操作,也可以通过 getMapper 获取 Mapper 层,执行自定义 SQL 语句,因为 SqlSession 在执行 SQL 语句之前是需要先开启一个会话,涉及到事务操作,所以还会有 commit、 rollback、close 等方法。这也是模版设计模式的一种应用。 MapperProxy MapperProxy 是 Mapper 映射 SQL 语句的关键对象,我们写的 Dao 层或者 Mapper 层都是通过 MapperProxy 来和对应的 SQL 语句进行绑定的。下面我们就来解释一下绑定过程 这就是 MyBatis 的核心绑定流程,我们可以看到 SqlSession 首先调用 getMapper 方法,我们刚才说到 SqlSession 是大哥级别的人物,只定义标准(有一句话是怎么说的来着,一流的企业做标准,二流的企业做品牌,三流的企业做产品)。 SqlSession 不愿意做的事情交给 Configuration 这个手下去做,但是 Configuration 也是有小弟的,它不愿意做的事情直接甩给小弟去做,这个小弟是谁呢?它就是 MapperRegistry,马上就到核心部分了。MapperRegistry 相当于项目经理,项目经理只从大面上把握项目进度,不需要知道手下的小弟是如何工作的,把任务完成了就好。最终真正干活的还是 MapperProxyFactory。看到这段代码 Proxy.newProxyInstance ,你是不是有一种恍然大悟的感觉,如果你没有的话,建议查阅一下动态代理的文章,这里推荐一篇 (https://www.jianshu.com/p/95970b089360) 也就是说,MyBatis 中 Mapper 和 SQL 语句的绑定正是通过动态代理来完成的。 通过动态代理,我们就可以方便的在 Dao 层或者 Mapper 层定义接口,实现自定义的增删改查操作了。那么具体的执行过程是怎么样呢?上面只是绑定过程,别着急,下面就来探讨一下 SQL 语句的执行过程。 MapperProxyFactory 会生成代理对象,这个对象就是 MapperProxy,最终会调用到 mapperMethod.execute 方法,execute 方法比较长,其实逻辑比较简单,就是判断是 插入、更新、删除 还是 查询 语句,其中如果是查询的话,还会判断返回值的类型,我们可以点进去看一下都是怎么设计的。 很多代码其实可以忽略,只看我标出来的重点就好了,我们可以看到,不管你前面经过多少道关卡处理,最终都逃不过 SqlSession 这个老大制定的标准。 我们以 selectList 为例,来看一下下面的执行过程。 这是 DefaultSqlSession 中 selectList 的代码,我们可以看到出现了 executor,这是什么呢?我们下面来解释。 Executor 还记得我们之前的流程中提到了 Executor(执行器) 这个概念吗?我们来回顾一下它第一次出现的位置。 由 Configuration 对象创建了一个 Executor 对象,这个 Executor 是干嘛的呢?下面我们就来认识一下 Executor 的继承结构 每一个 SqlSession 都会拥有一个 Executor 对象,这个对象负责增删改查的具体操作,我们可以简单的将它理解为 JDBC 中 Statement 的封装版。 也可以理解为 SQL 的执行引擎,要干活总得有一个发起人吧,可以把 Executor 理解为发起人的角色。 首先先从 Executor 的继承体系来认识一下 如上图所示,位于继承体系最顶层的是 Executor 执行器,它有两个实现类,分别是BaseExecutor和 CachingExecutor。 BaseExecutor 是一个抽象类,这种通过抽象的实现接口的方式是适配器设计模式之接口适配 的体现,是Executor 的默认实现,实现了大部分 Executor 接口定义的功能,降低了接口实现的难度。BaseExecutor 的子类有三个,分别是 SimpleExecutor、ReuseExecutor 和 BatchExecutor。 SimpleExecutor : 简单执行器,是 MyBatis 中默认使用的执行器,每执行一次 update 或 select,就开启一个Statement 对象,用完就直接关闭 Statement 对象(可以是 Statement 或者是 PreparedStatment 对象) ReuseExecutor : 可重用执行器,这里的重用指的是重复使用 Statement,它会在内部使用一个 Map 把创建的Statement 都缓存起来,每次执行 SQL 命令的时候,都会去判断是否存在基于该 SQL 的 Statement 对象,如果存在 Statement 对象并且对应的 connection 还没有关闭的情况下就继续使用之前的 Statement 对象,并将其缓存起来。因为每一个 SqlSession 都有一个新的 Executor 对象,所以我们缓存在 ReuseExecutor 上的 Statement作用域是同一个 SqlSession。 BatchExecutor : 批处理执行器,用于将多个 SQL 一次性输出到数据库 CachingExecutor: 缓存执行器,先从缓存中查询结果,如果存在就返回之前的结果;如果不存在,再委托给Executor delegate 去数据库中取,delegate 可以是上面任何一个执行器。 Executor 的创建和选择 我们上面提到 Executor 是由 Configuration 创建的,Configuration 会根据执行器的类型创建,如下 这一步就是执行器的创建过程,根据传入的 ExecutorType 类型来判断是哪种执行器,如果不指定 ExecutorType ,默认创建的是简单执行器。它的赋值可以通过两个地方进行赋值: 可以通过 标签来设置当前工程中所有的 SqlSession 对象使用默认的 Executor <settings> <!--取值范围 SIMPLE, REUSE, BATCH --> <setting name="defaultExecutorType" value="SIMPLE"/> </settings> 另外一种直接通过Java对方法赋值的方式 session = factory.openSession(ExecutorType.BATCH); Executor 的具体执行过程 Executor 中的大部分方法的调用链其实是差不多的,下面是深入源码分析执行过程,如果你没有时间或者暂时不想深入研究的话,给你下面的执行流程图作为参考。 我们紧跟着上面的 selectList 继续分析,它会调用到 executor.query 方法。 当有一个查询请求访问的时候,首先会经过 Executor 的实现类 CachingExecutor ,先从缓存中查询 SQL 是否是第一次执行,如果是第一次执行的话,那么就直接执行 SQL 语句,并创建缓存,如果第二次访问相同的 SQL 语句的话,那么就会直接从缓存中提取。 上面这段代码是从 selectList -> 从缓存中 query 的具体过程。可能你看到这里有些觉得类都是什么东西,我想鼓励你一下,把握重点,不用每段代码都看,从找到 SQL 的调用链路,其他代码想看的时候在看,看源码就是很容易发蒙,容易烦躁,但是切记一点,把握重点。 上面代码会判断缓存中是否有这条 SQL 语句的执行结果,如果没有的话,就再重新创建 Executor 执行器执行 SQL 语句,注意, list = doQuery 是真正执行 SQL 语句的过程,这个过程中会创建我们上面提到的三种执行器,这里我们使用的是简单执行器。 到这里,执行器所做的工作就完事了,Executor 会把后续的工作交给 StatementHandler 继续执行。下面我们来认识一下 StatementHandler 上面代码会判断缓存中是否有这条 SQL 语句的执行结果,如果没有的话,就再重新创建 Executor 执行器执行 SQL 语句,注意, list = doQuery 是真正执行 SQL 语句的过程,这个过程中会创建我们上面提到的三种执行器,这里我们使用的是简单执行器。 到这里,执行器所做的工作就完事了,Executor 会把后续的工作交给 StatementHandler 继续执行。下面我们来认识一下 StatementHandler StatementHandler 的继承结构 有没有感觉和 Executor 的继承体系很相似呢?最顶级接口是四大组件对象,分别有两个实现类 BaseStatementHandler 和 RoutingStatementHandler,BaseStatementHandler 有三个实现类, 他们分别是 SimpleStatementHandler、PreparedStatementHandler 和 CallableStatementHandler。 RoutingStatementHandler : RoutingStatementHandler 并没有对 Statement 对象进行使用,只是根据StatementType 来创建一个代理,代理的就是对应Handler的三种实现类。在MyBatis工作时,使用的StatementHandler 接口对象实际上就是 RoutingStatementHandler 对象。 BaseStatementHandler : 是 StatementHandler 接口的另一个实现类,它本身是一个抽象类,用于简化StatementHandler 接口实现的难度,属于适配器设计模式体现,它主要有三个实现类 SimpleStatementHandler: 管理 Statement 对象并向数据库中推送不需要预编译的SQL语句。PreparedStatementHandler: 管理 Statement 对象并向数据中推送需要预编译的SQL语句。CallableStatementHandler:管理 Statement 对象并调用数据库中的存储过程。 StatementHandler 的创建和源码分析 我们继续来分析上面 query 的调用链路,StatementHandler 的创建过程如下 MyBatis 会根据 SQL 语句的类型进行对应 StatementHandler 的创建。我们以预处理 StatementHandler 为例来讲解一下 执行器不仅掌管着 StatementHandler 的创建,还掌管着创建 Statement 对象,设置参数等,在创建完 PreparedStatement 之后,我们需要对参数进行处理了。 如 如果用一副图来表示一下这个执行流程的话我想是这样 这里我们先暂停一下,来认识一下第三个核心组件 ParameterHandler ParameterHandler - ParameterHandler 介绍 ParameterHandler 相比于其他的组件就简单很多了,ParameterHandler 译为参数处理器,负责为 PreparedStatement 的 sql 语句参数动态赋值,这个接口很简单只有两个方法 ParameterHandler 只有一个实现类 DefaultParameterHandler , 它实现了这两个方法。 getParameterObject: 用于读取参数setParameters: 用于对 PreparedStatement 的参数赋值ParameterHandler 的解析过程 上面我们讨论过了 ParameterHandler 的创建过程,下面我们继续上面 parameterSize 流程 这就是具体参数的解析过程了,下面我们来描述一下 下面用一个流程图表示一下 ParameterHandler 的解析过程,以简单执行器为例 我们在完成 ParameterHandler 对 SQL 参数的预处理后,回到 SimpleExecutor 中的 doQuery 方法 上面又引出来了一个重要的组件那就是 ResultSetHandler,下面我们来认识一下这个组件 ResultSetHandler - ResultSetHandler 简介 ResultSetHandler 也是一个非常简单的接口 ResultSetHandler 是一个接口,它只有一个默认的实现类,像是 ParameterHandler 一样,它的默认实现类是DefaultResultSetHandler ResultSetHandler 解析过程 MyBatis 只有一个默认的实现类就是 DefaultResultSetHandler,DefaultResultSetHandler 主要负责处理两件事 处理 Statement 执行后产生的结果集,生成结果列表 处理存储过程执行后的输出参数 按照 Mapper 文件中配置的 ResultType 或 ResultMap 来封装成对应的对象,最后将封装的对象返回即可。 其中涉及的主要对象有: ResultSetWrapper : 结果集的包装器,主要针对结果集进行的一层包装,它的主要属性有 ResultSet : Java JDBC ResultSet 接口表示数据库查询的结果。 有关查询的文本显示了如何将查询结果作为java.sql.ResultSet 返回。 然后迭代此ResultSet以检查结果。 TypeHandlerRegistry: 类型注册器,TypeHandlerRegistry 在初始化的时候会把所有的 Java类型和类型转换器进行注册。 ColumnNames: 字段的名称,也就是查询操作需要返回的字段名称 ClassNames: 字段的类型名称,也就是 ColumnNames 每个字段名称的类型 JdbcTypes: JDBC 的类型,也就是 java.sql.Types 类型 ResultMap: 负责处理更复杂的映射关系 在 DefaultResultSetHandler 中处理完结果映射,并把上述结构返回给调用的客户端,从而执行完成一条完整的SQL语句。 内容转载自:CSDN博主:cxuann 原文链接:https://blog.csdn.net/qq_36894974/article/details/104132876?depth_1-utm_source=distribute.pc_feed.none-task&request_id=&utm_source=distribute.pc_feed.none-task
问问小秘 2020-03-05 15:44:27 0 浏览量 回答数 0

问题

数据库百问,教你快速上手数据库

在信息化社会,充分有效地管理和利用各类信息资源,是进行科学研究和决策管理的前提条件。数据库技术是管理信息系统、办公自动化系统、决策支持系统等各类信息系统的核心部分,是进行科学研究和决策管理的重要技术手段。本文为大家整理了云栖问答中有关数据库...
yq传送门 2019-12-01 20:16:46 31116 浏览量 回答数 21

问题

应用 AXIS 开始 Web 服务之旅:报错

一. 介绍 本文并不是想介绍Web服务的原理、系统架构等,我们假设您已经了解了关于Web服务的一些基本的概念、原理等知识。本文主要是针对那些已经了解Web服 务概念,但是还没有亲身体会Web服务...
kun坤 2020-06-08 11:01:46 3 浏览量 回答数 1

云产品推荐

上海奇点人才服务相关的云产品 小程序定制 上海微企信息技术相关的云产品 国内短信套餐包 ECS云服务器安全配置相关的云产品 开发者问答 阿里云建站 自然场景识别相关的云产品 万网 小程序开发制作 视频内容分析 视频集锦 代理记账服务 阿里云AIoT