• 关于

    嵌入式系统如何安装

    的搜索结果

问题

如何编译ARM linux kernel?报错

爱吃鱼的程序员 2020-06-10 10:13:48 0 浏览量 回答数 1

问题

oss c sdk在嵌入式环境下如何编译

yjseu 2019-12-01 21:31:44 13755 浏览量 回答数 6

问题

Media-C-SDK之如何实现安装?

青衫无名 2019-12-01 21:47:32 1227 浏览量 回答数 0

阿里云试用中心,为您提供0门槛上云实践机会!

0元试用32+款产品,最高免费12个月!拨打95187-1,咨询专业上云建议!

问题

一键化安装oss c sdk,轻松搞定第三方库依赖

yjseu 2019-12-01 22:00:03 12749 浏览量 回答数 12

问题

【教程免费下载】深入理解计算机系统(英文版第3版)

玄学酱 2019-12-01 22:08:27 3332 浏览量 回答数 1

问题

【教程免费下载】机器人系统设计与制作:Python语言实现

玄学酱 2019-12-01 22:08:08 4189 浏览量 回答数 11

问题

程序员报错行为大赏-配置报错

问问小秘 2020-06-11 13:18:25 6 浏览量 回答数 1

问题

在 RHEL/CentOS 上安装 OpenJDK 和 Oracle JDK

妙正灰 2019-12-01 21:50:42 2850 浏览量 回答数 0

回答

一 系统介绍 Android 是Google开发的基于Linux平台的、开源的、智能手机操作系统。Android包括操作系统、中间件和应用程序,由于源代码开放,Android可以被移植到不同的硬件平台上。 围绕在Google的Android系统中,形成了移植开发和上层应用程序开发两个不同的开发方面。手机厂商从事移植开发工作,上层的应用程序开发可以由任何单位和个人完成,开发的过程可以基于真实的硬件系统,还可以基于仿真器环境。 作为一个手机平台,Android在技术上的优势主要有以下几点: - 全开放智能手机平台 - 多硬件平台的支持 - 使用众多的标准化技术 - 核心技术完整,统一 - 完善的SDK和文档 - 完善的辅助开发工具 Android的开发者可以在完备的开发环境中进行开发,Android的官方网站也提供了丰富的文档、资料。这样有利于Android系统的开发和运行在一个良好的生态环境中。 https://developer.android.com/about安卓开发者官方网站 从宏观的角度来看,Android是一个开放的软件系统,它包含了众多的源代码。从下至上,Android系统分成4个层次: 第1层次:Linux操作系统及驱动; 第2层次:本地代码(C/C++)框架; 第3层次:Java框架; 第4层次:Java应用程序。 Android系统的架构如图所示: 由于Android系统需要支持Java代码的运行,这部分内容是Android的运行环境(Runtime),由虚拟机和Java基本类组成。 对于Android应用程序的开发,主要关注第3层次和第4层次之间的接口。 二 学习路线 基础学习——JavaSE: 基础学习扩展——JavaEE: 基础学习扩展——Linux基础: Android开发学习——基础理论:系统架构分析: Android系统从底向上一共分了4层,每一层都把底层实现封装,并暴露调用接口给上一层。 Linux内核(Linux Kernel) Android运行在linux kernel 2.6之上,但是把linux内受GNU协议约束的部分做了取代,这样在Android的程序可以用于商业目的。 Linux 内核是硬件和软件层之间的抽象层。 中间件 中间件包括两部分: 核心库和运行时(libraries & Android runtime) 核心库包括,SurfaceManager 显示系统管理库,负责把2D或3D内容显示到屏幕;Media Framework 媒体库,负责支持图像,支持多种视频和音频的录制和回放;SQlite 数据库,一个功能强大的轻量级嵌入式关系数据库;WebKit 浏览器引擎等。 Dalvik虚拟机: 区别于Java虚拟机的是,每一个Android 应用程序都在它自己的进程中运行,都有一个属于自己的Dalvik 虚拟机,这一点可以让系统在运行时可以达到优化,程序间的影响大大降低。Dalvik虚拟机并非运行Java字节码,而是运行自己的字节码。 应用程序框架(Application Framework) 丰富而又可扩展性的视图(Views),可以用来构建应用程序, 它包括列表(lists),网格(grids), 文本框(text boxes),按钮( buttons), 可嵌入的web 浏览器。内容提供者(Content Providers)使得应用程序可以访问另一个应用程序的数据(如联系人数据库), 或者共享它们自己的数据。资源管理器(Resource Manager)提供非代码资源的访问,如本地字符串,图形,和布局文件( layoutfiles )。通知管理器(Notification Manager) 使得应用程序可以在状态栏中显示自定义的提示信息。活动管理器( Activity Manager) 用来管理应用程序生命周期并提供常用的导航回退功能。 三 基础知识 掌握java部分之后,可以使用开发工具进入android世界 您可以使用 Kotlin、Java 和 C++ 语言编写 Android 应用。Android SDK 工具会将您的代码连同任何数据和资源文件编译成一个 APK(Android 软件包),即带有 .apk 后缀的归档文件。一个 APK 文件包含 Android 应用的所有内容,它也是 Android 设备用来安装应用的文件。 每个 Android 应用都处于各自的安全沙盒中,并受以下 Android 安全功能的保护: • Android 操作系统是一种多用户 Linux 系统,其中的每个应用都是一个不同的用户; • 默认情况下,系统会为每个应用分配一个唯一的 Linux 用户 ID(该 ID 仅由系统使用,应用并不知晓)。系统会为应用中的所有文件设置权限,使得只有分配给该应用的用户 ID 才能访问这些文件; • 每个进程都拥有自己的虚拟机 (VM),因此应用代码独立于其他应用而运行。 • 默认情况下,每个应用都在其自己的 Linux 进程内运行。Android 系统会在需要执行任何应用组件时启动该进程,然后当不再需要该进程或系统必须为其他应用恢复内存时,其便会关闭该进程。 Android 系统实现了最小权限原则。换言之,默认情况下,每个应用只能访问执行其工作所需的组件,而不能访问其他组件。这样便能创建非常安全的环境,在此环境中,应用无法访问其未获得权限的系统部分。不过,应用仍可通过一些途径与其他应用共享数据以及访问系统服务: • 可以安排两个应用共享同一 Linux 用户 ID,在此情况下,二者便能访问彼此的文件。为节省系统资源,也可安排拥有相同用户 ID 的应用在同一 Linux 进程中运行,并共享同一 VM。应用还必须使用相同的证书进行签名。 • 应用可以请求访问设备数据(如用户的联系人、短信消息、可装载存储装置(SD 卡)、相机、蓝牙等)的权限。用户必须明确授予这些权限。如需了解详细信息,请参阅使用系统权限。 本文档的其余部分将介绍以下概念: • 用于定义应用的核心框架组件 • 用来声明组件和应用必需设备功能的清单文件。 • 与应用代码分离并允许应用针对各种设备配置适当优化其行为的资源。 应用组件 应用组件是 Android 应用的基本构建块。每个组件都是一个入口点,系统或用户可通过该入口点进入您的应用。有些组件会依赖于其他组件。 共有四种不同的应用组件类型: • Activity • 服务 • 广播接收器 • 内容提供程序 每种类型都有不同的用途和生命周期,后者会定义如何创建和销毁组件。以下部分将介绍应用组件的四种类型。 Activity Activity 是与用户交互的入口点。它表示拥有界面的单个屏幕。例如,电子邮件应用可能有一个显示新电子邮件列表的 Activity、一个用于撰写电子邮件的 Activity 以及一个用于阅读电子邮件的 Activity。尽管这些 Activity 通过协作在电子邮件应用中形成一种紧密结合的用户体验,但每个 Activity 都独立于其他 Activity 而存在。因此,其他应用可以启动其中任何一个 Activity(如果电子邮件应用允许)。例如,相机应用可以启动电子邮件应用内用于撰写新电子邮件的 Activity,以便用户共享图片。Activity 有助于完成系统和应用程序之间的以下重要交互: • 追踪用户当前关心的内容(屏幕上显示的内容),以确保系统继续运行托管 Activity 的进程。 • 了解先前使用的进程包含用户可能返回的内容(已停止的 Activity),从而更优先保留这些进程。 • 帮助应用处理终止其进程的情况,以便用户可以返回已恢复其先前状态的 Activity。 • 提供一种途径,让应用实现彼此之间的用户流,并让系统协调这些用户流。(此处最经典的示例是共享。) 您需将 Activity 作为 Activity 类的子类来实现。如需了解有关 Activity 类的更多信息,请参阅 Activity 开发者指南。 服务 服务是一个通用入口点,用于因各种原因使应用在后台保持运行状态。它是一种在后台运行的组件,用于执行长时间运行的操作或为远程进程执行作业。服务不提供界面。例如,当用户使用其他应用时,服务可能会在后台播放音乐或通过网络获取数据,但这不会阻断用户与 Activity 的交互。诸如 Activity 等其他组件可以启动服务,使该服务运行或绑定到该服务,以便与其进行交互。事实上,有两种截然不同的语义服务可以告知系统如何管理应用:已启动服务会告知系统使其运行至工作完毕。此类工作可以是在后台同步一些数据,或者在用户离开应用后继续播放音乐。在后台同步数据或播放音乐也代表了两种不同类型的已启动服务,而这些服务可以修改系统处理它们的方式: • 音乐播放是用户可直接感知的服务,因此,应用会向用户发送通知,表明其希望成为前台,从而告诉系统此消息;在此情况下,系统明白它应尽全力维持该服务进程运行,因为进程消失会令用户感到不快。 • 通常,用户不会意识到常规后台服务正处于运行状态,因此系统可以更自由地管理其进程。如果系统需要使用 RAM 来处理用户更迫切关注的内容,则其可能允许终止服务(然后在稍后的某个时刻重启服务)。 绑定服务之所以能运行,原因是某些其他应用(或系统)已表示希望使用该服务。从根本上讲,这是为另一个进程提供 API 的服务。因此,系统会知晓这些进程之间存在依赖关系,所以如果进程 A 绑定到进程 B 中的服务,系统便知道自己需使进程 B(及其服务)为进程 A 保持运行状态。此外,如果进程 A 是用户关心的内容,系统随即也知道将进程 B 视为用户关心的内容。由于存在灵活性(无论好坏),服务已成为非常有用的构建块,并且可实现各种高级系统概念。动态壁纸、通知侦听器、屏幕保护程序、输入方法、无障碍功能服务以及众多其他核心系统功能均可构建为在其运行时由应用实现、系统绑定的服务。 您需将服务作为 Service 的子类来实现。如需了解有关 Service 类的更多信息,请参阅服务开发者指南。 注意:如果您的应用面向 Android 5.0(API 级别 21)或更高版本,请使用 JobScheduler 类来调度操作。JobScheduler 的优势在于,它能通过优化作业调度来降低功耗,以及使用 Doze API,从而达到省电目的。如需了解有关使用此类的更多信息,请参阅 JobScheduler 参考文档。 广播接收器 借助广播接收器组件,系统能够在常规用户流之外向应用传递事件,从而允许应用响应系统范围内的广播通知。由于广播接收器是另一个明确定义的应用入口,因此系统甚至可以向当前未运行的应用传递广播。例如,应用可通过调度提醒来发布通知,以告知用户即将发生的事件。而且,通过将该提醒传递给应用的广播接收器,应用在提醒响起之前即无需继续运行。 许多广播均由系统发起,例如,通知屏幕已关闭、电池电量不足或已拍摄照片的广播。应用也可发起广播,例如,通知其他应用某些数据已下载至设备,并且可供其使用。尽管广播接收器不会显示界面,但其可以创建状态栏通知,在发生广播事件时提醒用户。但广播接收器更常见的用途只是作为通向其他组件的通道,旨在执行极少量的工作。例如,它可能会根据带 JobScheduler 的事件调度 JobService 来执行某项工作 广播接收器作为 BroadcastReceiver 的子类实现,并且每条广播都作为 Intent 对象进行传递。如需了解详细信息,请参阅 BroadcastReceiver 类。 内容提供程序 内容提供程序管理一组共享的应用数据,您可以将这些数据存储在文件系统、SQLite 数据库、网络中或者您的应用可访问的任何其他持久化存储位置。其他应用可通过内容提供程序查询或修改数据(如果内容提供程序允许)。例如,Android 系统可提供管理用户联系人信息的内容提供程序。 因此,任何拥有适当权限的应用均可查询内容提供程序(如 ContactsContract.Data),以读取和写入特定人员的相关信息。我们很容易将内容提供程序看作数据库上的抽象,因为其内置的大量 API 和支持时常适用于这一情况。但从系统设计的角度看,二者的核心目的不同。对系统而言,内容提供程序是应用的入口点,用于发布由 URI 架构识别的已命名数据项。因此,应用可以决定如何将其包含的数据映射到 URI 命名空间,进而将这些 URI 分发给其他实体。反之,这些实体也可使用分发的 URI 来访问数据。在管理应用的过程中,系统可以执行以下特殊操作: • 分配 URI 无需应用保持运行状态,因此 URI 可在其所属的应用退出后继续保留。当系统必须从相应的 URI 检索应用数据时,系统只需确保所属应用仍处于运行状态。 • 这些 URI 还会提供重要的细粒度安全模型。例如,应用可将其所拥有图像的 URI 放到剪贴板上,但将其内容提供程序锁定,以便其他应用程序无法随意访问它。当第二个应用尝试访问剪贴板上的 URI 时,系统可允许该应用通过临时的 URI 授权来访问数据,这样便只能访问 URI 后面的数据,而非第二个应用中的其他任何内容。 内容提供程序也适用于读取和写入您的应用不共享的私有数据。 内容提供程序作为 ContentProvider 的子类实现,并且其必须实现一组标准 API,以便其他应用能够执行事务。如需了解详细信息,请参阅内容提供程序开发者指南。 Android 系统设计的独特之处在于,任何应用都可启动其他应用的组件。例如,当您想让用户使用设备相机拍摄照片时,另一个应用可能也可执行该操作,因而您的应用便可使用该应用,而非自行产生一个 Activity 来拍摄照片。您无需加入甚至链接到该相机应用的代码。只需启动拍摄照片的相机应用中的 Activity 即可。完成拍摄时,系统甚至会将照片返回您的应用,以便您使用。对用户而言,这就如同相机是您应用的一部分。 当系统启动某个组件时,它会启动该应用的进程(如果尚未运行),并实例化该组件所需的类。例如,如果您的应用启动相机应用中拍摄照片的 Activity,则该 Activity 会在属于相机应用的进程(而非您的应用进程)中运行。因此,与大多数其他系统上的应用不同,Android 应用并没有单个入口点(即没有 main() 函数)。 由于系统在单独的进程中运行每个应用,且其文件权限会限制对其他应用的访问,因此您的应用无法直接启动其他应用中的组件,但 Android 系统可以。如要启动其他应用中的组件,请向系统传递一条消息,说明启动特定组件的 Intent。系统随后便会为您启动该组件。 启动组件 在四种组件类型中,有三种(Activity、服务和广播接收器)均通过异步消息 Intent 进行启动。Intent 会在运行时对各个组件进行互相绑定。您可以将 Intent 视为从其他组件(无论该组件是属于您的应用还是其他应用)请求操作的信使。 您需使用 Intent 对象创建 Intent,该对象通过定义消息来启动特定组件(显式 Intent)或特定的组件类型(隐式 Intent)。 对于 Activity 和服务,Intent 会定义要执行的操作(例如,查看或发送某内容),并且可指定待操作数据的 URI,以及正在启动的组件可能需要了解的信息。例如,Intent 可能会传达对 Activity 的请求,以便显示图像或打开网页。在某些情况下,您可以通过启动 Activity 来接收结果,这样 Activity 还会返回 Intent 中的结果。例如,您可以发出一个 Intent,让用户选取某位联系人并将其返回给您。返回 Intent 包含指向所选联系人的 URI。 对于广播接收器,Intent 只会定义待广播的通知。例如,指示设备电池电量不足的广播只包含指示“电池电量不足”的已知操作字符串。 与 Activity、服务和广播接收器不同,内容提供程序并非由 Intent 启动。相反,它们会在成为 ContentResolver 的请求目标时启动。内容解析程序会通过内容提供程序处理所有直接事务,因此通过提供程序执行事务的组件便无需执行事务,而是改为在 ContentResolver 对象上调用方法。这会在内容提供程序与请求信息的组件之间留出一个抽象层(以确保安全)。 每种组件都有不同的启动方法: • 如要启动 Activity,您可以向 startActivity() 或 startActivityForResult() 传递 Intent(当您想让 Activity 返回结果时),或者为其安排新任务。 • 在 Android 5.0(API 级别 21)及更高版本中,您可以使用 JobScheduler 类来调度操作。对于早期 Android 版本,您可以通过向 startService() 传递 Intent 来启动服务(或对执行中的服务下达新指令)。您也可通过向将 bindService() 传递 Intent 来绑定到该服务。 • 您可以通过向 sendBroadcast()、sendOrderedBroadcast() 或 sendStickyBroadcast() 等方法传递 Intent 来发起广播。 • 您可以通过在 ContentResolver 上调用 query(),对内容提供程序执行查询。 如需了解有关 Intent 用法的详细信息,请参阅 Intent 和 Intent 过滤器文档。以下文档将为您详细介绍如何启动特定组件:Activity、服务、BroadcastReceiver 和内容提供程序。

问问小秘 2020-03-03 09:47:38 0 浏览量 回答数 0

问题

搞懂了这几点,你就学会了Web编程

技术小菜鸟 2019-12-01 21:20:38 2373 浏览量 回答数 1

问题

企业运营对DevOps的「傲慢与偏见」

忆远0711 2019-12-01 21:32:29 9823 浏览量 回答数 0

问题

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

问问小秘 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

回答

不依赖微软的库和WindowsAPI,没能试验成功!######问题已解决,谢谢。######看这篇文章,讲的很清楚(:)这是从其他地方拷贝过来的) UNICODE环境设置 在安装Visual Studio时,在选择VC++时需要加入unicode选项,保证相关的库文件可以拷贝到system32下。 UNICODE编译设置: C/C++, Preprocessor difinitions 去除_MBCS,加_UNICODE,UNICODE 在ProjectSetting/link/output 中设置Entry为wWinMainCRTStartup 反之为MBCS(ANSI)编译。 Unicode :宽字节字符集 1. 如何取得一个既包含单字节字符又包含双字节字符的字符串的字符个数? 可以调用Microsoft Visual C++的运行期库包含函数_mbslen来操作多字节(既包括单字节也包括双字节)字符串。 调用strlen函数,无法真正了解字符串中究竟有多少字符,它只能告诉你到达结尾的0之前有多少个字节。 size_t strlen( const char *string ); size_t wcslen( const wchar_t *string ); size_t _mbslen( const unsigned char *string ); size_t _mbstrlen( const char *string ); 2. 如何对DBCS(双字节字符集)字符串进行操作? 函数 描述 PTSTR CharNext ( LPCTSTR ); 返回字符串中下一个字符的地址 PTSTR CharPrev ( LPCTSTR, LPCTSTR ); 返回字符串中上一个字符的地址 BOOL IsDBCSLeadByte( BYTE ); 如果该字节是DBCS字符的第一个字节,则返回非0值 3. 为什幺要使用Unicode? (1) 可以很容易地在不同语言之间进行数据交换。 (2) 使你能够分配支持所有语言的单个二进制.exe文件或DLL文件。 (3) 提高应用程序的运行效率。 Windows 2000是使用Unicode从头进行开发的,如果调用任何一个Windows函数并给它传递一个ANSI字符串,那幺系统首先要将字符串转换成Unicode,然后将Unicode字符串传递给操作系统。如果希望函数返回ANSI字符串,系统就会首先将Unicode字符串转换成ANSI字符串,然后将结果返回给你的应用程序。进行这些字符串的转换需要占用系统的时间和内存。通过从头开始用Unicode来开发应用程序,就能够使你的应用程序更加有效地运行。 Windows CE 本身就是使用Unicode的一种操作系统,完全不支持ANSI Windows函数 Windows 98 只支持ANSI,只能为ANSI开发应用程序。 Microsoft公司将COM从16位Windows转换成Win32时,公司决定需要字符串的所有COM接口方法都只能接受Unicode字符串。 4. 如何编写Unicode源代码?   Microsoft公司为Unicode设计了WindowsAPI,这样,可以尽量减少代码的影响。实际上,可以编写单个源代码文件,以便使用或者不使用Unicode来对它进行编译。只需要定义两个宏(UNICODE和_UNICODE),就可以修改然后重新编译该源文件。   _UNICODE宏用于C运行期头文件,而UNICODE宏则用于Windows头文件。当编译源代码模块时,通常必须同时定义这两个宏。     5. Windows定义的Unicode数据类型有哪些?   数据类型 说明   WCHAR Unicode字符   PWSTR 指向Unicode字符串的指针   PCWSTR 指向一个恒定的Unicode字符串的指针   对应的ANSI数据类型为CHAR,LPSTR和LPCSTR。   ANSI/Unicode通用数据类型为TCHAR,PTSTR,LPCTSTR。     6. 如何对Unicode进行操作?   字符集 特性 实例   ANSI 操作函数以str开头 strcpy   Unicode 操作函数以wcs开头 wcscpy   MBCS 操作函数以_mbs开头 _mbscpy   ANSI/Unicode 操作函数以_tcs开头 _tcscpy(C运行期库)   ANSI/Unicode 操作函数以lstr开头 lstrcpy(Windows函数)   所有新的和未过时的函数在Windows2000中都同时拥有ANSI和Unicode两个版本。ANSI版本函数结尾以A表示;Unicode版本函数结尾以W表示。Windows会如下定义:   #ifdef UNICODE   #define CreateWindowEx CreateWindowExW   #else   #define CreateWindowEx CreateWindowExA   #endif // !UNICODE     7. 如何表示Unicode字符串常量?   字符集 实例   ANSI “string”   Unicode L“string”   ANSI/Unicode T(“string”)或_TEXT(“string”)   if( szError[0] == _TEXT(‘J’) ){ }     8. 为什幺应当尽量使用操作系统函数?   这将有助于稍稍提高应用程序的运行性能,因为操作系统字符串函数常常被大型应用程序比如操作系统的外壳进程Explorer.exe所使用。由于这些函数使用得很多,因此,在应用程序运行时,它们可能已经被装入RAM。   如:StrCat,StrChr,StrCmp和StrCpy等。     9. 如何编写符合ANSI和Unicode的应用程序?   (1) 将文本串视为字符数组,而不是chars数组或字节数组。   (2) 将通用数据类型(如TCHAR和PTSTR)用于文本字符和字符串。   (3) 将显式数据类型(如BYTE和PBYTE)用于字节、字节指针和数据缓存。   (4) 将TEXT宏用于原义字符和字符串。   (5) 执行全局性替换(例如用PTSTR替换PSTR)。   (6) 修改字符串运算问题。例如函数通常希望在字符中传递一个缓存的大小,而不是字节。这意味着不应该传递sizeof(szBuffer),而应该传递(sizeof(szBuffer)/sizeof(TCHAR)。另外,如果需要为字符串分配一个内存块,并且拥有该字符串中的字符数目,那幺请记住要按字节来分配内存。这就是说,应该调用   malloc(nCharacters *sizeof(TCHAR)),而不是调用malloc(nCharacters)。     10. 如何对字符串进行有选择的比较?   通过调用CompareString来实现。   int CompareString(    LCID Locale, // locale identifier DWORD dwCmpFlags, // comparison-style options LPCTSTR lpString1, // pointer to first string int cchCount1, // size, in bytes or characters, of first string LPCTSTR lpString2, // pointer to second string int cchCount2 // size, in bytes or characters, of second string   ); Locale 本地比较的定义    LOCALE_USER_DEFAULT    LOCALE_SYSTEM_DEFAULT     标志 含义   NORM_IGNORECASE 忽略字母的大小写   NORM_IGNOREKANATYPE 不区分平假名与片假名字符   NORM_IGNORENONSPACE 忽略无间隔字符   NORM_IGNORESYMBOLS 忽略符号   NORM_IGNOREWIDTH 不区分单字节字符与作为双字节字符的同一个字符   SORT_STRINGSORT 将标点符号作为普通符号来处理     11. 如何判断一个文本文件是ANSI还是Unicode?   判断如果文本文件的开头两个字节是0xFF和0xFE,那幺就是Unicode,否则是ANSI。     12. 如何判断一段字符串是ANSI还是Unicode?   用IsTextUnicode进行判断。IsTextUnicode使用一系列统计方法和定性方法,以便猜测缓存的内容。由于这不是一种确切的科学方法,因此 IsTextUnicode有可能返回不正确的结果。     13. 如何在Unicode与ANSI之间转换字符串?   Windows函数MultiByteToWideChar用于将多字节字符串转换成宽字符串;函数WideCharToMultiByte将宽字符串转换成等价的多字节字符串。     14. Unicode和DBCS之间的区别    Unicode使用(特别在C程序设计语言环境里)“宽字符集”。「Unicode中的每个字符都是16位宽而不是8位宽。」在Unicode中,没有单单使用8位数值的意义存在。相比之下,在“双位组字符集”中我们仍然处理8位数值。有些位组自身定义字符,而某些位组则显示需要和另一个位组共同定义一个字符。     处理DBCS字符串非常杂乱,但是处理Unicode文字则像处理有秩序的文字。您也许会高兴地知道前128个Unicode字符(16位代码从0x0000到0x007F)就是ASCII字符,而接下来的128个Unicode字符(代码从0x0080到0x00FF)是ISO 8859-1对ASCII的扩展。Unicode中不同部分的字符都同样基于现有的标准。这是为了便于转换。希腊字母表使用从0x0370到0x03FF的代码,斯拉夫语使用从0x0400到0x04FF的代码,美国使用从0x0530到0x058F的代码,希伯来语使用从0x0590到0x05FF的代码。中国、日本和韩国的象形文字(总称为CJK)占用了从0x3000到0x9FFF的代码。Unicode的最大好处是这里只有一个字符集,没有一点含糊。         15.衍生标准     Unicode是一个标准。UTF-8是其概念上的子集,UTF-8是具体的编码标准。而UNICODE是所有想达到世界统一编码标准的标准。UTF-8标准就是Unicode(ISO10646)标准的一种变形方式,      UTF的全称是:Unicode/UCS Transformation Format,其实有两种UTF,一种是UTF-8,一种是UTF-16,      不过UTF-16使用较少,其对应关系如下:      在Unicode中编码为 0000 - 007F 的 UTF-8 中编码形式为: 0xxxxxxx      在Unicode中编码为 0080 - 07FF 的 UTF-8 中编码形式为: 110xxxxx 10xxxxxx      在Unicode中编码为 0000 - 007F 的 UTF-8 中编码形式为: 1110xxxx 10xxxxxx 10xxxxxx           utf-8是unicode的一个新的编码标准,其实unicode有过好几个标准.我们知道一直以来使用的unicode字符内码都是16位,它实际上还不能把全世界的所有字符编在一个平面系统,比如中国的藏文等小语种,所以utf-8扩展到了32位,也就是说理论在utf-8中可容纳二的三十二次方个字符. UNICODE的思想就是想把所有的字符统一编码,实现一个统一的标准.big5、gb都是独立的字符集,这也叫做远东字符集,把它拿到德文版的WINDOWS上可能将会引起字符编码的冲突....早期的WINDOWS默认的字符集是ANSI.notepad中输入的汉字是本地编码,但在NT/2000内部是可以直接支持UNICODE的。notepad.exe在WIN95和98中都是ANSI字符,在NT中则是UNICODE.ANSI和UNICODE可以方便的实现对应映射,也就是转换 ASCII是8位范围内的字符集,对于范围之外的字符如汉字它是无法表达的。unicode是16位范围内的字符集,对于不同地区的字符分区分配,unicode是多个IT巨头共同制定的字符编码标准。如果在unicode环境下比如WINDOWS NT上,一个字符占两字节16位,而在ANSI环境下如WINDOWS98下一个字符占一个字节8位.Unicode字符是16位宽,最多允许65,535字符,数据类型被称为WCHAR。       对于已有的ANSI字符,unicode简单的将其扩展为16位:比如ANSI"A"=0x43,则对应的UNICODE为       "A"= 0x0043        而ASCII用七存放128个字符,ASCII是一个真正的美国标准,所以它不能满足其他国家的需要,例如斯拉夫语的字母和汉字于是出现了Windows ANSI字符集,是一种扩展的ASCII码,用8位存放字符,低128位仍然存放原来的ASCII码,        而高128位加入了希腊字母等        if def UNICODE        TCHAR = wchar        else        TCHAR = char        你需要在Project\Settings\C/C++\Preprocesser definitions中添加UNICODE和_UNICODE        UINCODE,_UNICODE都要定义。不定义_UNICODE的话,用SetText(HWND,LPCTSTR),将被解释为SetTextA(HWND,LPTSTR),这时API将把你给的Unicode字符串看作ANSI字符串,显示乱码。因为windows API是已经编译好存在于dll中的,由于不管UNICODE还是ANSI字符串,都被看作一段buffer,如"0B A3 00 35 24 3C 00 00"如果按ANSI读,因为ANSI字串是以'\0'结束的,所以只能读到两字节"0B A3 \0",如果按UNICODE读,将完整的读到'\0\0'结束。         由于UNICODE没有额外的指示位,所以系统必须知道你提供的字串是哪种格式。此外,UNICODE好象是ANSI C++规定的,_UNICODE是windows SDK提供的。如果不编写windows程序,可以只定义UNICODE。 开发过程:         围绕着文件读写、字符串处理展开。文件主要有两种:.txt和.ini文件        在unicode和非unicode环境下字符串做不同处理的,那么需要参考以上9,10两条,以适应不同环境得字符串处理要求。         对文件读写也一样。只要调用相关接口函数时,参数中的字符串前都加上_TEXT等相关宏。如果写成的那个文件需要是unicode格式保存的,那么在创建文件时需要加入一个字节头。          CFile file;           WCHAR szwBuffer[128];           WCHAR *pszUnicode = L"Unicode string\n"; // unicode string           CHAR pszAnsi = "Ansi string\n"; // ansi string           WORD wSignature = 0xFEFF;           file.Open(TEXT("Test.txt"), CFile::modeCreate|CFile::modeWrite);           file.Write(&wSignature, 2);           file.Write(pszUnicode, lstrlenW(pszUnicode) * sizeof(WCHAR));           // explicitly use lstrlenW function           MultiByteToWideChar(CP_ACP, 0, pszAnsi, -1, szwBuffer, 128);           file.Write(szwBuffer, lstrlenW(szwBuffer) * sizeof(WCHAR));            file.Close();            //以上这段代码在unicode和非unicode环境下都有效。这里显式的指明用Unicode来进行操作。           在非unicode环境下,缺省调用的都是ANSI格式的字符串,此时TCHAR转换为CHAR类型的,除非显式定义WCHAR。所以在这个环境下,如果读取unicode文件,那么首先需要移动2个字节,然后读取得字符串需要用MultiByteToWideChar来转换,转换后字符串信息才代表unicode数据。          在unicode环境下,缺省调用得都是unicode格式得字符串,也就是宽字符,此时TCHAR转换为WCHAR,相关得API函数也都调用宽字符类型的函数。此时读取unicode文件也和上面一样,但是读取得数据是WCHAR的,如果要转换成ANSI格式,需要调用WideCharToMultiByte。如果读取ANSI的,则不用移动两个字节,直接读取然后视需要转换即可。                    某些语言(如韩语)必须在unicode环境下才能显示,这种情况下,在非unicode环境下开发,就算用字符串函数转换也不能达到显示文字的目的,因为此时调用得API函数是用ANSI的(虽然底层都是用UNICODE处理但是处理结果是按照程序员调用的API来显示的)。所以必须用unicode来开发。###### 用WideCharToMultiByte这个API: #include <stdio.h> #include <windows.h> int main() { FILE fp; wchar_t utf[1000], *p = utf; char ansi[2000]; fp = _wfopen(L"C:\1.txt", L"rb"); while(!feof(fp)) fread(p++, 1, 2, fp); *--p = L'\0'; fclose(fp); // utf+1剔除UTf-16标记 WideCharToMultiByte(CP_ACP, 0, utf + 1, -1, ansi, sizeof(ansi), NULL, NULL); puts(ansi); } ###### 楼上的给个链接就好,不用大篇幅复制。 卤煮的意思是说把“\u6C49\u5B57” 这个ASCII字符串转成两个汉字对吧~ ######不用别人的库,查unicode编码表?lz解决了说说方法呀######C++没解决,后来这个模块改用C#写了。###### 按二进制读,先读出0xFF 0xFE,后面数据的两个字节表示一个字,自己想办法读到wstring中 显示,用API的话,一个wcstombs ,一个WideCharToMultiByte 不用API的话自己查表,嵌入式程序可以查表,x86程序完全没那个必要 ###### 干嘛不用std::wstring ###### 用std::wstring吧,自己没有试过……,你可以去尝试下

kun坤 2020-06-07 13:49:51 0 浏览量 回答数 0

问题

Nginx性能为什么如此吊

小柒2012 2019-12-01 21:20:47 15038 浏览量 回答数 3

回答

我们在《深入分析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

回答

简介 如果您听说过 Node,或者阅读过一些文章,宣称 Node 是多么多么的棒,那么您可能会想:“Node 究竟是什么东西?”尽管不是针对所有人的,但 Node 可能是某些人的正确选择。 为试图解释什么是 Node.js,本文探究了它能解决的问题,它如何工作,如何运行一个简单应用程序,最后,Node 何时是和何时不是一个好的解决方案。本文不涉及如何编写一个复杂的 Node 应用程序,也不是一份全面的 Node 教程。阅读本文应该有助于您决定是否应该学习 Node,以便将其用于您的业务。 Node 旨在解决什么问题? Node 公开宣称的目标是 “旨在提供一种简单的构建可伸缩网络程序的方法”。当前的服务器程序有什么问题?我们来做个数学题。在 Java™ 和 PHP 这类语言中,每个连接都会生成一个新线程,每个新线程可能需要 2 MB 配套内存。在一个拥有 8 GB RAM 的系统上,理论上最大的并发连接数量是 4,000 个用户。随着您的客户端基础的增长,您希望您的 web 应用程序支持更多用户,这样,您必须添加更多服务器。当然,这会增加业务成本,尤其是服务器成本、运输成本和人工成本。除这些成本上升外,还有一个技术问题:用户可能针对每个请求使用不同的服务器,因此,任何共享资源都必须在所有服务器之间共享。例如,在 Java 中,静态变量和缓存需要在每个服务器上的 JVMs 之间共享。这就是整个 web 应用程序架构中的瓶颈:一个服务器能够处理的并发连接的最大数量。 Node 解决这个问题的方法是:更改连接连接到服务器的方式。每个连接都创建一个进程,该进程不需要配套内存块,而不是为每个连接生成一个新的 OS 线程(并向其分配一些配套内存)。Node 声称它绝不会死锁,因为它根本不允许使用锁,它不会直接阻塞 I/O 调用。Node 还宣称,运行它的服务器能支持数万个并发连接。事实上,Node 通过将整个系统中的瓶颈从最大连接数量更改到单个系统的流量来改变服务器面貌。 现在您有了一个能处理数万条并发连接的程序,那么您能通过 Node 实际构建什么呢?如果您有一个 web 应用程序需要处理这么多连接,那将是一件很 “恐怖” 的事!那是一种 “如果您有这个问题,那么它根本不是问题” 的问题。在回答上面的问题之前,我们先看看 Node 如何工作以及它被设计的如何运行。 Node 肯定不是什么 没错,Node 是一个服务器程序。但是,它肯定不 像 Apache 或 Tomcat。那些服务器是独立服务器产品,可以立即安装并部署应用程序。通过这些产品,您可以在一分钟内启动并运行一个服务器。Node 肯定不是这种产品。Apache 能添加一个 PHP 模块来允许开发人员创建动态 web 页,使用 Tomcat 的程序员能部署 JSPs 来创建动态 web 页。Node 肯定不是这种类型。 在 Node 的早期阶段(当前是 version 0.4.6),它还不是一个 “运行就绪” 的服务器程序,您还不能安装它,向其中放置文件,拥有一个功能齐全的 web 服务器。即使是要实现 web 服务器在安装完成后启动并运行这个基本功能,也还需要做大量工作。 Node 如何工作 Node 本身运行 V8 JavaScript。等等,服务器上的 JavaScript?没错,您没有看错。服务器端 JavaScript 是一个相对较新的概念,这个概念是大约两年前在 developerWorks 上讨论 Aptana Jaxer 产品时提到的(参见 参考资料)。尽管 Jaxer 一直没有真正流行,但这个理念本身并不是遥不可及的 — 为何不能在服务器上使用客户机上使用的编程语言? 什么使 V8?V8 JavaScript 引擎是 Google 用于他们的 Chrome 浏览器的底层 JavaScript 引擎。很少有人考虑 JavaScript 在客户机上实际做了些什么?实际上,JavaScript 引擎负责解释并执行代码。使用 V8,Google 创建了一个以 C++ 编写的超快解释器,该解释器拥有另一个独特特征;您可以下载该引擎并将其嵌入任何 应用程序。它不仅限于在一个浏览器中运行。因此,Node 实际上使用 Google 编写的 V8 JavaScript 引擎并将其重建为在服务器上使用。太完美了!既然已经有一个不错的解决方案可用,为何还要创建一种新语言呢? 事件驱动编程 许多程序员接受的教育使他们认为,面向对象编程是完美的编程设计,而对其他编程方法不屑一顾。Node 使用一个所谓的事件驱动编程模型。 清单 1. 客户端上使用 jQuery 的事件驱动编程 复制代码 代码如下: // jQuery code on the client-side showing how Event-Driven programming works // When a button is pressed, an Event occurs - deal with it // directly right here in an anonymous function, where all the // necessary variables are present and can be referenced directly $("#myButton").click(function(){ if ($("#myTextField").val() != $(this).val()) alert("Field must match button text"); }); 实际上,服务器端和客户端没有任何区别。没错,这没有按钮点击操作,也没有向文本字段键入的操作,但在一个更高的层面上,事件正在 发生。一个连接被建立 — 事件!数据通过连接接收 — 事件!数据通过连接停止 — 事件! 为什么这种设置类型对 Node 很理想?JavaScript 是一种很棒的事件驱动编程语言,因为它允许匿名函数和闭包,更重要的是,任何写过代码的人都熟悉它的语法。事件发生时调用的回调函数可以在捕获事件处编写。这样,代码容易编写和维护,没有复杂的面向对象框架,没有接口,没有在上面架构任何内容的潜能。只需监听事件,编写一个回调函数,然后,事件驱动编程将照管好一切! 示例 Node 应用程序 最后,我们来看一些代码!让我们将讨论过的所有内容综合起来,创建我们的第一个 Node 应用程序。由于我们已经知道,Node 对于处理高流量应用程序很理想,我们就来创建一个非常简单的 web 应用程序 — 一个为实现最大速度而构建的应用程序。下面是 “老板” 交代的关于我们的样例应用程序的具体要求:创建一个随机数字生成器 RESTful API。这个应用程序应该接受一个输入:一个名为 “number” 的参数。然后,应用程序返回一个介于 0 和该参数之间的随机数字,并将生成的数字返回调用者。由于 “老板” 希望它成为一个广泛流行的应用程序,因此它应该能处理 50,000 个并发用户。我们来看看代码: 清单 2. Node 随机数字生成器 复制代码 代码如下: // these modules need to be imported in order to use them. // Node has several modules. They are like any #include // or import statement in other languages var http = require("http"); var url = require("url"); // The most important line in any Node file. This function // does the actual process of creating the server. Technically, // Node tells the underlying operating system that whenever a // connection is made, this particular callback function should be // executed. Since we're creating a web service with REST API, // we want an HTTP server, which requires the http variable // we created in the lines above. // Finally, you can see that the callback method receives a 'request' // and 'response' object automatically. This should be familiar // to any PHP or Java programmer. http.createServer(function(request, response) { // The response needs to handle all the headers, and the return codes // These types of things are handled automatically in server programs // like Apache and Tomcat, but Node requires everything to be done yourself response.writeHead(200, {"Content-Type": "text/plain"}); // Here is some unique-looking code. This is how Node retrives // parameters passed in from client requests. The url module // handles all these functions. The parse function // deconstructs the URL, and places the query key-values in the // query object. We can find the value for the "number" key // by referencing it directly - the beauty of JavaScript. var params = url.parse(request.url, true).query; var input = params.number; // These are the generic JavaScript methods that will create // our random number that gets passed back to the caller var numInput = new Number(input); var numOutput = new Number(Math.random() * numInput).toFixed(0); // Write the random number to response response.write(numOutput); // Node requires us to explicitly end this connection. This is because // Node allows you to keep a connection open and pass data back and forth, // though that advanced topic isn't discussed in this article. response.end(); // When we create the server, we have to explicitly connect the HTTP server to // a port. Standard HTTP port is 80, so we'll connect it to that one. }).listen(80); // Output a String to the console once the server starts up, letting us know everything // starts up correctly console.log("Random Number Generator Running..."); 将上面的代码放到一个名为 “random.js” 的文件中。现在,要启动这个应用程序并运行它(进而创建 HTTP 服务器并监听端口 80 上的连接),只需在您的命令提示中输入以下命令:% node random.js。下面是服务器已经启动并运行时它看起来的样子: 复制代码 代码如下: root@ubuntu:/home/moila/ws/mike# node random.js Random Number Generator Running... 访问应用程序 应用程序已经启动并运行。Node 正在监听任何连接,我们来测试一下。由于我们创建了一个简单的 RESTful API,我们可以使用我们的 web 浏览器来访问这个应用程序。键入以下地址(确保您完成了上面的步骤):localhost/?number=27。 您的浏览器窗口将更改到一个介于 0 到 27 之间的随机数字。单击浏览器上的 “重新载入” 按钮,将得到另一个随机数字。就是这样,这就是您的第一个 Node 应用程序! Node 对什么有好处? 到此为止,应该能够回答 “Node 是什么” 这个问题了,但您可能还不清楚什么时候应该使用它。这是一个需要提出的重要问题,因为 Node 对有一些东西有好处,但相反,对另一些东西而言,目前 Node 可能不是一个好的解决方案。您需要小心决定何时使用 Node,因为在错误的情况下使用它可能会导致一个多余编码的 LOT。 它对什么有好处? 正如您此前所看到的,Node 非常适合以下情况:您预计可能有很高的流量,而在响应客户端之前服务器端逻辑和处理所需不一定是巨大的。Node 表现出众的典型示例包括: 1.RESTful API 提供 RESTful API 的 web 服务接收几个参数,解析它们,组合一个响应,并返回一个响应(通常是较少的文本)给用户。这是适合 Node 的理想情况,因为您可以构建它来处理数万条连接。它还不需要大量逻辑;它只是从一个数据库查找一些值并组合一个响应。由于响应是少量文本,入站请求时少量文本,因此流量不高,一台机器甚至也可以处理最繁忙的公司的 API 需求。 2.Twitter 队列 想像一下像 Twitter 这样的公司,它必须接收 tweets 并将其写入一个数据库。实际上,每秒几乎有数千条 tweets 达到,数据库不可能及时处理高峰时段需要的写入数量。Node 成为这个问题的解决方案的重要一环。如您所见,Node 能处理数万条入站 tweets。它能迅速轻松地将它们写入一个内存排队机制(例如 memcached),另一个单独进程可以从那里将它们写入数据库。Node 在这里的角色是迅速收集 tweet 并将这个信息传递给另一个负责写入的进程。想象一下另一种设计 — 一个常规 PHP 服务器自己试图处理对数据库的写入 — 每个 tweet 将在写入数据库时导致一个短暂的延迟,这是因为数据库调用正在阻塞通道。由于数据库延迟,一台这样设计的机器每秒可能只能处理 2000 条入站 tweets。每秒 100 万条 tweets 需要 500 个服务器。相反,Node 能处理每个连接而不会阻塞通道,从而能捕获尽可能多的 tweets。一个能处理 50,000 条 tweets 的 Node 机器只需要 20 个服务器。 3.映像文件服务器 一个拥有大型分布式网站的公司(比如 Facebook 或 Flickr)可能会决定将所有机器只用于服务映像。Node 将是这个问题的一个不错的解决方案,因为该公司能使用它编写一个简单的文件检索器,然后处理数万条连接。Node 将查找映像文件,返回文件或一个 404 错误,然后什么也不用做。这种设置将允许这类分布式网站减少它们服务映像、.js 和 .css 文件等静态文件所需的服务器数量。 它对什么有坏处? 当然,在某些情况下,Node 并非理想选择。下面是 Node 不擅长的领域: 1.动态创建的页 目前,Node 没有提供一种默认方法来创建动态页。例如,使用 JavaServer Pages (JSP) 技术时,可以创建一个在这样的 JSP 代码段中包含循环的 index.jsp 页。Node 不支持这类动态的、HTML 驱动的页面。同样,Node 不太适合作为 Apache 和 Tomcat 这样的网页服务器。因此,如果您想在 Node 中提供这样一个服务器端解决方案,必须自己编写整个解决方案。PHP 程序员不想在每次部署 web 应用程序时都编写一个针对 Apache 的 PHP 转换器,当目前为止,这正是 Node 要求您做的。 2. 关系数据库重型应用程序 Node 的目的是快速、异步和非阻塞。数据库并不一定分享这些目标。它们是同步和阻塞的,因为读写时对数据库的调用在结果生成之前将一直阻塞通道。因此,一个每个请求都需要大量数据库调用、大量读取、大量写入的 web 应用程序非常不适合 Node,这是因为关系数据库本身就能抵销 Node 的众多优势。(新的 NoSQL 数据库更适合 Node,不过那完全是另一个主题了。) 结束语 问题是 “什么是 Node.js?” 应该已经得到解答。阅读本文之后,您应该能通过几个清晰简洁的句子回答这个问题。如果这样,那么您已经走到了许多编码员和程序员的前面。我和许多人都谈论过 Node,但它们对 Node 究竟是什么一直很迷惑。可以理解,他们具有的是 Apache 的思维方式 — 服务器是一个应用程序,将 HTML 文件放入其中,一切就会正常运转。而 Node 是目的驱动的。它是一个软件程序,使用 JavaScript 来允许程序员轻松快速地创建快速、可伸缩的 web 服务器。Apache 是运行就绪的,而 Node 是编码就绪的。 Node 完成了它提供高度可伸缩服务器的目标。它并不分配一个 “每个连接一个线程” 模型,而是使用一个 “每个连接一个流程” 模型,只创建每个连接需要的内存。它使用 Google 的一个非常快速的 JavaScript 引擎:V8 引擎。它使用一个事件驱动设计来保持代码最小且易于阅读。所有这些因素促成了 Node 的理想目标 — 编写一个高度可伸缩的解决方案变得比较容易。 与理解 Node 是 什么同样重要的是,理解它不是 什么。Node 并不是 Apache 的一个替代品,后者旨在使 PHP web 应用程序更容易伸缩。事实确实如此。在 Node 的这个初始阶段,大量程序员使用它的可能性不大,但在它能发挥作用的场景中,它的表现非常好。 将来应该期望从 Node 得到什么呢?这也许是本文引出的最重要的问题。既然您知道了它现在的作用,您应该会想知道它下一步将做什么。在接下来的一年中,我期待着 Node 提供与现有的第三方支持库更好地集成。现在,许多第三方程序员已经研发了用于 Node 的插件,包括添加文件服务器支持和 MySQL 支持。希望 Node 开始将它们集成到其核心功能中。最后,我还希望 Node 支持某种动态页面模块,这样,您就可以在 HTML 文件中执行在 PHP 和 JSP(也许是一个 NSP,一个 Node 服务器页)中所做的操作。最后,希望有一天会出现一个 “部署就绪” 的 Node 服务器,可以下载和安装,只需将您的 HTML 文件放到其中,就像使用 Apache 或 Tomcat 那样。Node 现在还处于初始阶段,但它发展得很快,可能不久就会出现在您的视野中。 答案来源于网络

养狐狸的猫 2019-12-02 02:17:03 0 浏览量 回答数 0

问题

wttr.in 一个 Python 实现的命令行查看天气工具

huc_逆天 2020-05-21 19:12:17 19 浏览量 回答数 1

问题

如何定位Android NDK开发中遇到的错误?报错

爱吃鱼的程序员 2020-06-14 18:55:10 0 浏览量 回答数 1

回答

Go 的优势在于能够将简单的和经过验证的想法结合起来,同时避免了其他语言中出现的许多问题。本文概述了 Go 背后的一些设计原则和工程智慧,作者认为,Go 语言具备的所有这些优点,将共同推动其成为接替 Java 并主导下一代大型软件开发平台的最有力的编程语言候选。很多优秀的编程语言只是在个别领域比较强大,如果将所有因素都纳入考虑,没有其他语言能够像 Go 语言一样“全面开花”,在大型软件工程方面,尤为如此。 基于现实经验 Go 是由经验丰富的软件行业老手一手创建的,长期以来,他们对现有语言的各种缺点有过切身体会的痛苦经历。几十年前,Rob Pike 和 Ken Thompson 在 Unix、C 和 Unicode 的发明中起到了重要作用。Robert Griensemer 在为 JavaScript 和 Java 开发 V8 和 HotSpot 虚拟机之后,在编译器和垃圾收集方面拥有数十年的经验。有太多次,他们不得不等待 Google 规模的 C++/Java 代码库进行编译。于是,他们开始着手创建新的编程语言,将他们半个世纪以来的编写代码所学到的一切经验包含进去。 专注于大型工程 小型工程项目几乎可以用任何编程语言来成功构建。当成千上万的开发人员在数十年的持续时间压力下,在包含数千万行代码的大型代码库上进行协作时,就会发生真正令人痛苦的问题。这样会导致一些问题,如下: 较长的编译时间导致中断开发。代码库由几个人 / 团队 / 部门 / 公司所拥有,混合了不同的编程风格。公司雇佣了数千名工程师、架构师、测试人员、运营专家、审计员、实习生等,他们需要了解代码库,但也具备广泛的编码经验。依赖于许多外部库或运行时,其中一些不再以原始形式存在。在代码库的生命周期中,每行代码平均被重写 10 次,被弄得千疮百痍,而且还会发生技术偏差。文档不完整。 Go 注重减轻这些大型工程的难题,有时会以使小型工程变得更麻烦为代价,例如,代码中到处都需要几行额外的代码行。 注重可维护性 Go 强调尽可能多地将工作转给自动化的代码维护工具中。Go 工具链提供了最常用的功能,如格式化代码和导入、查找符号的定义和用法、简单的重构以及代码异味的识别。由于标准化的代码格式和单一的惯用方式,机器生成的代码更改看起来非常接近 Go 中人为生成的更改并使用类似的模式,从而允许人机之间更加无缝地协作。 保持简单明了 初级程序员为简单的问题创建简单的解决方案。高级程序员为复杂的问题创建复杂的解决方案。伟大的程序员找到复杂问题的简单解决方案。 ——Charles Connell 让很多人惊讶的一点是,Go 居然不包含他们喜欢的其他语言的概念。Go 确实是一种非常小巧而简单的语言,只包含正交和经过验证的概念的最小选择。这鼓励开发人员用最少的认知开销来编写尽可能简单的代码,以便许多其他人可以理解并使用它。 使事情清晰明了 良好的代码总是显而易见的,避免了那些小聪明、难以理解的语言特性、诡异的控制流和兜圈子。 许多语言都致力提高编写代码的效率。然而,在其生命周期中,人们阅读代码的时间却远远超过最初编写代码所需的时间(100 倍)。例如,审查、理解、调试、更改、重构或重用代码。在查看代码时,往往只能看到并理解其中的一小部分,通常不会有完整的代码库概述。为了解释这一点,Go 将所有内容都明确出来。 错误处理就是一个例子。让异常在各个点中断代码并在调用链上冒泡会更容易。Go 需要手动处理和返回每个错误。这使得它可以准确地显示代码可以被中断的位置以及如何处理或包装错误。总的来说,这使得错误处理编写起来更加繁琐,但是也更容易理解。 简单易学 Go 是如此的小巧而简单,以至于人们可以在短短几天内就能研究通整个语言及其基本概念。根据我们的经验,培训用不了一个星期(相比于掌握其他语言需要几个月),初学者就能够理解 Go 专家编写的代码,并为之做出贡献。为了方便吸引更多的用户,Go 网站提供了所有必要的教程和深入研究的文章。这些教程在浏览器中运行,允许人们在将 Go 安装到本地计算机上之前就能够学习和使用 Go。 解决之道 Go 强调的是团队之间的合作,而不是个人的自我表达。 在 Go(和 Python)中,所有的语言特性都是相互正交和互补的,通常有一种方法可以做一些事情。如果你想让 10 个 Python 或 Go 程序员来解决同一个问题,你将会得到 10 个相对类似的解决方案。不同的程序员在彼此的代码库中感觉更自在。在查看其他人的代码时,国骂会更少,而且人们的工作可以更好地融合在一起,从而形成了一致的整体,人人都为之感到自豪,并乐于工作。这还避免了大型工程的问题,如: 开发人员认为良好的工作代码很“混乱”,并要求在开始工作之前进行重写,因为他们的思维方式与原作者不同。 不同的团队成员使用不同的语言子集来编写相同代码库的部分内容。 ![image.png](https://ucc.alicdn.com/pic/developer-ecology/e64418f1455d46aaacfdd03fa949f16d.png) 简单、内置的并发性 Go 专为现代多核硬件设计。 目前使用的大多数编程语言(Java、JavaScript、Python、Ruby、C、C++)都是 20 世纪 80 年代到 21 世纪初设计的,当时大多数 CPU 只有一个计算内核。这就是为什么它们本质上是单线程的,并将并行化视为边缘情况的马后炮。通过现成和同步点之类的附加组件来实现,而这些附加组件既麻烦又难以正确使用。第三方库虽然提供了更简单的并发形式,如 Actor 模型,但是总有多个可用选项,结果导致了语言生态系统的碎片化。今天的硬件拥有越来越多的计算内核,软件必须并行化才能高效运行。Go 是在多核处理器时代编写的,并且在语言中内置了简单、高级的 CSP 风格并发性。 面向计算的语言原语 就深层而言,计算机系统接收数据,对其进行处理(通常要经过几个步骤),然后输出结果数据。例如,Web 服务器从客户端接收 HTTP 请求,并将其转换为一系列数据库或后端调用。一旦这些调用返回,它就将接收到的数据转换成 HTML 或 JSON 并将其输出给调用者。Go 的内置语言原语直接支持这种范例: 结构表示数据 读和写代表流式 IO 函数过程数据 goroutines 提供(几乎无限的)并发性 在并行处理步骤之间传输管道数据 因为所有的计算原语都是由语言以直接形式提供的,因此 Go 源代码更直接地表达了服务器执行的操作。 OO — 好的部分 更改基类中的某些内容的副作用 面向对象非常有用。过去几十年来,面向对象的使用富有成效,并让我们了解了它的哪些部分比其他部分能够更好地扩展。Go 在面向对象方面采用了一种全新的方法,并记住了这些知识。它保留了好的部分,如封装、消息传递等。Go 还避免了继承,因为它现在被认为是有害的,并为组合提供了一流的支持。 现代标准库 目前使用的许多编程语言(Java、JavaScript、Python、Ruby)都是在互联网成为当今无处不在的计算平台之前设计的。因此,这些语言的标准库只提供了相对通用的网络支持,而这些网络并没有针对现代互联网进行优化。Go 是十年前创建的,当时互联网已全面发展。Go 的标准库允许在没有第三方库的情况下创建更复杂的网络服务。这就避免了第三方库的常见问题: 碎片化:总是有多个选项实现相同的功能。 膨胀:库常常实现的不仅仅是它们的用途。 依赖地狱:库通常依赖于特定版本的其他库。 未知质量:第三方代码的质量和安全性可能存在问题。 未知支持:第三方库的开发可能随时停止支持。 意外更改:第三方库通常不像标准库那样严格地进行版本控制。 关于这方面更多的信息请参考 Russ Cox 提供的资料 标准化格式 Gofmt 的风格没有人会去喜欢,但人人都会喜欢 gofmt。 ——Rob Pike Gofmt 是一种以标准化方式来格式化 Go 代码的程序。它不是最漂亮的格式化方式,但却是最简单、最不令人生厌的格式化方式。标准化的源代码格式具有惊人的积极影响: 集中讨论重要主题: 它消除了围绕制表符和空格、缩进深度、行长、空行、花括号的位置等一系列争论。 开发人员在彼此的代码库中感觉很自在, 因为其他代码看起来很像他们编写的代码。每个人都喜欢自由地按照自己喜欢的方式进行格式化代码,但如果其他人按照自己喜欢的方式格式化了代码,这么做很招人烦。 自动代码更改并不会打乱手写代码的格式,例如引入了意外的空白更改。 许多其他语言社区现在正在开发类似 gofmt 的东西。当作为第三方解决方案构建时,通常会有几个相互竞争的格式标准。例如,JavaScript 提供了 Prettier 和 StandardJS。这两者都可以用,也可以只使用其中的一个。但许多 JS 项目并没有采用它们,因为这是一个额外的决策。Go 的格式化程序内置于该语言的标准工具链中,因此只有一个标准,每个人都在使用它。 快速编译 ![image.png](https://ucc.alicdn.com/pic/developer-ecology/8a76f3f07f484266af42781d9e7b8692.png) 对于大型代码库来说,它们长时间的编译是促使 Go 诞生的原因。Google 主要使用的是 C++ 和 Java,与 Haskell、Scala 或 Rust 等更复杂的语言相比,它们的编译速度相对较快。尽管如此,当编译大型代码库时,即使是少量的缓慢也会加剧编译的延迟,从而激怒开发人员,并干扰流程。Go 的设计初衷是为了提高编译效率,因此它的编译器速度非常快,几乎没有编译延迟的现象。这给 Go 开发人员提供了与脚本类语言类似的即时反馈,还有静态类型检查的额外好处。 交叉编译 由于语言运行时非常简单,因此它被移植到许多平台,如 macOS、Linux、Windows、BSD、ARM 等。Go 可以开箱即用地为所有这些平台编译二进制文件。这使得从一台机器进行部署变得很容易。 快速执行 Go 的运行速度接近于 C。与 JITed 语言(Java、JavaScript、Python 等)不同,Go 二进制文件不需要启动或预热的时间,因为它们是作为编译和完全优化的本地代码的形式发布的。Go 的垃圾收集器仅引入微秒量级的可忽略的停顿。除了快速的单核性能外,Go 还可以轻松利用所有的 CPU 内核。 内存占用小 像 JVM、Python 或 Node 这样的运行时不仅仅在运行时加载程序代码,每次运行程序时,它们还会加载大型且高度复杂的基础架构,以进行编译和优化程序。如此一来,它们的启动时间就变慢了,并且还占用了大量内存(数百兆字节)。而 Go 进程的开销更小,因为它们已经完全编译和优化,只需运行即可。Go 还以非常节省内存的方式来存储数据。在内存有限且昂贵的云环境中,以及在开发过程中,这一点非常重要。我们希望在一台机器上能够快速启动整个堆栈,同时将内存留给其他软件。 部署规模小 Go 的二进制文件大小非常简洁。Go 应用程序的 Docker 镜像通常比用 Java 或 Node 编写的等效镜像要小 10 倍,这是因为它无需包含编译器、JIT,以及更少的运行时基础架构的原因。这些特点,在部署大型应用程序时很重要。想象一下,如果要将一个简单的应用程序部署到 100 个生产服务器上会怎么样?如果使用 Node/JVM 时,我们的 Docker 注册表就必须提供 100 个 docker 镜像,每个镜像 200MB,那么一共就需要 20GB。要完成这些部署就需要一些时间。想象一下,如果我们想每天部署 100 次的话,如果使用 Go 服务,那么 Docker 注册表只需提供 10 个 docker 镜像,每个镜像只有 20MB,共只需 2GB 即可。大型 Go 应用程序可以更快、更频繁地部署,从而使得重要更新能够更快地部署到生产环境中。 独立部署 Go 应用程序部署为一个包含所有依赖项的单个可执行文件,并无需安装特定版本的 JVM、Node 或 Python 运行时;也不必将库下载到生产服务器上,更无须对运行 Go 二进制文件的机器进行任何更改。甚至也不需要讲 Go 二进制文件包装到 Docker 来共享他们。你需要做的是,只是将 Go 二进制文件放到服务器上,它就会在那里运行,而不用关心服务器运行的是什么。前面所提到的那些,唯一的例外是使用net和os/user包时针对对glibc的动态链接。 供应依赖关系 Go 有意识避免使用第三方库的中央存储库。Go 应用程序直接链接到相应的 Git 存储库,并将所有相关代码下载(供应)到自己的代码库中。这样做有很多好处: 在使用第三方代码之前,我们可以对其进行审查、分析和测试。该代码就和我们自己的代码一样,是我们应用程序的一部分,应该遵循相同的质量、安全性和可靠性标准。 无需永久访问存储依赖项的各个位置。从任何地方(包括私有 Git repos)获取第三方库,你就能永久拥有它们。 经过验收后,编译代码库无需进一步下载依赖项。 若互联网某处的代码存储库突然提供不同的代码,这也并不足为奇。 即使软件包存储库速度变慢,或托管包不复存在,部署也不会因此中断。 兼容性保证 Go 团队承诺现有的程序将会继续适用于新一代语言。这使得将大型项目升级到最新版本的编译器会非常容易,并且可从它们带来的许多性能和安全性改进中获益。同时,由于 Go 二进制文件包含了它们需要的所有依赖项,因此可以在同一服务器上并行运行使用不同版本的 Go 编译器编译的二进制文件,而无需进行复杂的多个版本的运行时设置或虚拟化。 文档 在大型工程中,文档对于使软件可访问性和可维护性非常重要。与其他特性类似,Go 中的文档简单实用: 由于它是嵌入到源代码中的,因此两者可以同时维护。 它不需要特殊的语法,文档只是普通的源代码注释。 可运行单元测试通常是最好的文档形式。因此 Go 要求将它们嵌入到文档中。 所有的文档实用程序都内置在工具链中,因此每个人都使用它们。 Go linter 需要导出元素的文档,以防止“文档债务”的积累。 商业支持的开源 当商业实体在开放式环境下开发时,那么一些最流行的、经过彻底设计的软件就会出现。这种设置结合了商业软件开发的优势——一致性和精细化,使系统更为健壮、可靠、高效,并具有开放式开发的优势,如来自许多行业的广泛支持,多个大型实体和许多用户的支持,以及即使商业支持停止的长期支持。Go 就是这样发展起来的。 缺点 当然,Go 也并非完美无缺,每种技术选择都是有利有弊。在决定选择 Go 之前,有几个方面需要进行考虑考虑。 未成熟 虽然 Go 的标准库在支持许多新概念(如 HTTP 2 Server push 等)方面处于行业领先地位,但与 JVM 生态系统中的第三方库相比,用于外部 API 的第三方 Go 库可能不那么成熟。 即将到来的改进 由于清楚几乎不可能改变现有的语言元素,Go 团队非常谨慎,只在新特性完全开发出来后才添加新特性。在经历了 10 年的有意稳定阶段之后,Go 团队正在谋划对语言进行一系列更大的改进,作为 Go 2.0 之旅的一部分。 无硬实时 虽然 Go 的垃圾收集器只引入了非常短暂的停顿,但支持硬实时需要没有垃圾收集的技术,例如 Rust。 结语 本文详细介绍了 Go 语言的一些优秀的设计准则,虽然有的准则的好处平常看起来没有那么明显。但当代码库和团队规模增长几个数量级时,这些准则可能会使大型工程项目免于许多痛苦。总的来说,正是这些设计准则让 Go 语言成为了除 Java 之外的编程语言里,用于大型软件开发项目的绝佳选择。

有只黑白猫 2020-01-07 14:11:38 0 浏览量 回答数 0
阿里云大学 云服务器ECS com域名 网站域名whois查询 开发者平台 小程序定制 小程序开发 国内短信套餐包 开发者技术与产品 云数据库 图像识别 开发者问答 阿里云建站 阿里云备案 云市场 万网 阿里云帮助文档 免费套餐 开发者工具 企业信息查询 小程序开发制作 视频内容分析 企业网站制作 视频集锦 代理记账服务 企业建站模板