阅读更多

0顶
0踩

Web前端

转载新闻 七行JSON代码将你的网站变成移动应用

2018-04-24 13:00 by 副主编 jihong10102006 评论(1) 有46337人浏览
引用
作者|Ethan
译者|大愚若智
编辑|覃云

本文介绍了借助 Jasonette 将 Web 视图和原生组件融合构建真正“混合”应用的做法。

如果我告诉你,只需要 上述 7 行橙色的 JSON 代码 就可以将一个网站变成移动应用,你相信吗?完全不需要使用某种框架 API 重写网站,就可以获得与移动应用相同的行为。如果你已经有一个现成的网站,只需要简单地引用 URL 就可以将其“打包”为原生应用。

而如果在此基础上,只需要略微调整 JSON 代码内容,就可以直接访问所有原生 API、原生 UI 组件以及原生视图切换(View Transition)。

最简化的范例效果如下图所示:

从中可以看出,我嵌入了一个 GitHub.com 的 Web 页面,但界面上其余布局均为原生 UI 组件,例如 导航条 以及 底部的标签栏。而我们并不需要使用任何 API 重写网站,就可以自动获得原生的切换效果。

在介绍具体做法前你可能会问:“看着挺酷,但除了在原生应用框架内展示 Web 页面之外,这种技术还有什么意义?”

问得好!这也是本文要讲的重点。我们只需要创建一个无缝的 Web 视图与应用间双向通信,借此,父应用就可以触发 Web 视图内的任何 JavaScript 函数,随后 Web 视图即可从外部调用原生 API。

例如:

请注意,这个视图包含:
  • 原生导航条,以及内置的切换功能
  • 一个 Web 视图,其中嵌入了一个可以生成二维码的 Web 应用
  • 在底部包含一个原生的文字输入组件
上述所有这一切只需要略微调整 JSON 代码的属性即可实现。

最后请注意,随着在文字输入区输入不同内容,二维码也会产生相应变化。输入的文字可触发二维码生成器 Web 应用内部的 JavaScript 函数重新生成二维码图像。

目前还没有任何一个开发框架曾试图从根本上解决“Web 视图与原生应用无缝集成”的问题,因为这些框架都专注于完全原生,或完全 HTML5 的做法。

无论什么时候当我们听到有人讨论移动应用的未来时,很可能会听到类似“到底是 HTML5 还是原生方法会最终胜出呢?”这样的说法。

似乎没人觉得native和html可以共存,而且二者的协同和最终实现似乎也并不容易。

本文我将要介绍:
  • 为何 Web 引擎与原生组件的融合通常是一种更好的做法。
  • 为何 HTML 与原生的无缝集成那么难,具体又该如何实现。
  • 更重要的是,该如何使用这样的技术快速构建自己的应用。
为何要在原生应用中使用 HTML?

在进一步介绍前,首先一起看看这样做是好是坏,以及什么时候适合使用这种方法。这种做法的一些潜在用例如下:

1. 使用 Web 原生功能

应用中的部分内容使用 Web 引擎来实现也许是一种更适合的做法。例如 WebSocket 是一种原生的 Web 功能,主要面向 Web 环境而设计。这种情况下就更适合使用内建的 Web 引擎(iOS 的 WKWebView 以及 Android 的 WebView),而非安装某些只能“模拟”WebSocket 的第三方库。

无需额外安装任何代码,使用免费工具即可实现目标,这样岂不是更好。同时这也催生了下一个原因。

2. 避免二进制文件体积过大

有些功能也许需要借助庞大的第三方库,而你可能希望能快速用上这样的功能。

例如,为了以原生方式包含二维码图像生成器,可能需要安装某些第三方库,这会导致二进制文件体积增大。但如果使用 Web 视图引擎并通过一个简单的<script src>调用 JavaScript 库,就可以免费实现这一切,并且避免了使用第三方原生库。

3. 缺乏可靠的移动库

对于一些前沿技术,可能暂时并不具备稳定可靠的移动端实现。

好在大部分此类技术都具备 Web 实现,因此最高效的集成方法就是使用 JavaScript 库。

4. 构建部分原生,部分基于 Web 的应用

很多新手开发者想要将自己的网站移植为移动应用,但在发现自己现有网站的部分功能过于复杂,无法面向每种移动平台快速重写时,往往会感到沮丧或受挫。

例如你可能有一个非常复杂的 Web 页面无法快速转换为移动应用,但网站的其他内容可以很容易地转换。

面对这种情况,如果通过某种方法将应用的大部分内容以原生方式构建,对于特别复杂的页面直接将其以 HTML 的形式无缝集成到应用中,是不是很棒啊。

这是如何实现的?

A. Jasonette

Jasonette 是一种基于标记语言,构建跨平台原生应用的开源方法。

该技术看似 Web 浏览器,但并不会将 HTML 标记语言解释为 Web 页面,而是会将 JSON 标记解释为 iOS 和 Android 上的原生应用。

正如所有 Web 浏览器都有完全相同的代码,但只要按需解释不同类型的 HTML 标记,即可为用户提供所有不同类型的 Web 应用,所有 Jasonette 应用也有着完全相同的库,可按需解释不同类型的 JSON 标记并创建出你的应用??⒄咄耆扌璐ゼ按氡旧?,只需要编写标记,将代码实时“翻译”为原生应用,即可开发出自己的应用来。

虽然 Jasonette 的核心作用在于构建原生应用,但本文的重点在于介绍如何将 HTML 集成到核心原生引擎中,接下来就一起了解一下吧。

B. Jasonette Web 容器

原生应用很棒,但有时候我们依然需要使用 Web 功能。

但 Web 视图与原生应用的集成是个麻烦的过程。无缝的集成要求:
  • Web 视图应作为原生布局的一部分进行集成:Web 视图应作为原生布局的一部分纳入应用中,并且操作方式应与其他任何原生 UI 组件保持一致。否则会让用户感觉很笨拙,并且感觉上就像自己实际上是在访问网站那样。
  • 父应用可以控制子 Web 容器:父应用应能随意控制子 Web 视图。
  • 子 Web 容器可触发父应用的原生事件:子应用应该能触发父应用的事件以运行原生 API。
这是一个非常繁重的工作,因此先从第一个环节着手介绍:直接将 Web 容器嵌入原生布局?—并将其作为第 1 版发布:

JSON Web 容器,JSON 中的 HTML 将变为原生应用组件。

仅这一点就已经很实用了,但由于无法交互,依然存在一定的局限。

父应用无法控制子 Web 容器,子容器无法向父应用发送任何事件通知,这 导致 Web 容器与外界完全隔离。

C. Jasonette Web 容器 2.0:使其可交互

发布第 1 版之后,我们开始处理第二个问题:为 Web 容器添加交互能力。

下文将介绍如何为之前创建的静态 Web 容器添加交互能力,让它变得更强大。

实现:交互式 Web 容器

1. 通过 URL 加载

问题

之前在第 1 版中,为了使用 Web 容器作为后台视图组件,我们首先需要将$jason.body.background.type设置为"html",随后在$jason.body.background.text属性下添加硬编码的 HTML 文本,例如这样:

一般来说,人们往往更希望直接使用 Web URL 对容器进行实例化,而不希望将整个 HTML 代码以硬编码的方式作为一行代码加入。

解决方案

Web 容器 2.0 增加了url属性,我们可以嵌入file://形式的本地 HTML,例如这样(可以从伴随应用发布的本地 HTML 文件加载):

或者也可以嵌入远程的http[s]:// URL,例如这样(可以从远程 HTML 加载):

2. 父应用与 Web 容器的双向通信

问题

之前,Web 容器只能用于展示内容,无法交互。这意味着 下列做法全部无法实现:

  • Jasonette 到 Web 容器的通信:从 Jasonette 中调用 Web 容器内部的 JavaScript 函数。
  • Web 容器到 Jasonette 的通信:从 Web 容器代码中调用原生 API。
此时我们只能展示 Web 容器的内容。这就像网页中嵌入的 iframe 框架,主页面完全无法访问 iframe 框架中的内容。

解决方案

Jasonette 最大的目标在于设计一种可以描述跨平台移动应用的标准化标记语言。因此我们需要这个标记语言能够全面地描述父应用和子 Web 容器之间的双向通信。

为此我在父应用和子 Web 容器之间使用了一种基于 JSON-RPC 的通信管道。由于 Jasonette 中的一切都是通过 JSON 对象表达的,因此使用 JSON-RPC 标准格式作为通信协议就成了一种非常自然合理的方式。

为了让 JavaScript 函数能够调用 Web 容器,需要声明一个名为$agent.request的操作:

$agent.request 是一种原生 API,可触发 JSON-RPC 请求并发送给 Web 容器。为了使用该 API,必须将options对象作为参数传递。

options对象实际上是发送给 Web 容器的 JSON-RPC 请求。每个属性的含义如下:
  • id:Web 容器构建在一种名为 Agent 的底层架构基础上,通常来说,我们可以为一个视图使用多个 Agent,每个 Agent 可以有自己的唯一 ID。但 Web 容器是一种特殊类型的 Agent,只能使用 $webcontainer 作为 ID,因此这里需要使用 ID。
  • method:要调用的 JavaScript 函数名称。
  • params:传递给 JavaScript 函数的参数数组。
因此完整来看,所用的标记应该是类似这样的:

这串标记实际上是在说:

当视图加载($jason.head.actions.$load)时,向 Web 容器 Agent 发送一个 JSON-RPC 请求($agent.request),而具体的请求是通过options指定的。

Web 容器在 $jason.body.background 下定义,本例中将会加载一个名为file://index.html的本地文件。

随后会查找一个名为 login 的 JavaScript 函数并传递params下的两个参数("alice"和"1234")。

上文介绍了父应用如何触发子 Web 容器的 JavaScript 函数调用,我们还可以反着来,让 Web 容器触发父应用的原生 API。

详情请参阅 Agent 文档。

Agent 文档: https://docs.jasonette.com/agents/

范 例  

继续回到上文介绍的二维码生成器范例:

  • 其中 底部的文字输入组件是 100% 原生的。
  • 二维码由 作为 Web 应用运行 的 Web 容器生成。
  • 当用户输入内容并按下“生成”,将调用 Web 容器 Agent 中的$agent.request操作,进而调用 JavaScript 函数“qr”。
具体示例可以参阅:
https://github.com/Jasonette/Jasonpedia/blob/gh-pages/webcontainer/agent/fn/index.json

3. 脚本注入

问题

有时候我们可能需要在 Web 容器完成初始 HTML 加载后,动态地将 JavaScript 代码注入 Web 容器。

假设要构建一个自定义的 Web 浏览器应用,我们可能希望将自己的自定义 JavaScript 注入到每个 Web 视图,借此定制 Web 视图的行为,这有点类似于 Web 浏览器的扩展。

就算不需要构建 Web 浏览器,当希望为所包含的内容不由我们控制的 URL 实现自定义行为时,同样需要使用脚本注入的方法。原生应用和 Web 容器只能通过$agent API 通信,但如果无法更改 HTML 内容,只能通过动态注入的方式将$agent接口加入 Web 容器。

解决方案

正如上文所述,$jason.body.background这个 Web 容器也是一个agent,这意味着我们可以使用与普通 Agent 完全相同的 $agent.inject 方法。

4. 对 URL 点击的处理

以往,Web 容器只能通过两种方式处理链接点击操作:
  • 只读:将 Web 容器视作只读的,忽略所有诸如触控或滚动等事件。此时所有 Web 容器都是只读的,除非明确令其表现得像是普通浏览器,具体做法见下文。
  • 普通浏览器行为:像是普通浏览器那样,允许用户与页面交互。为此需要进行声明,将"type": "$default"设置为action属性。
问题

两者均为 “全无或全有(All or nothing)”解决方案。
  • 对于“只读”,Web 容器会忽略用户的所有交互操作。
  • 对于“普通浏览器行为”,Web 容器的表现将与浏览器一致。点击链接后,将像普通网页那样刷新页面展示链接内容,但无法劫持该点击并调用其他原生 API。
解决方案

通过使用新的 Web 容器,可以将任何action附加到$jason.body.background这个 Web 容器,进而处理链接点击之类的事件。

一起看一个例子:

在这里我们为 Web 容器附加了"trigger": "displayBanner",这意味着当用户点击 Web 容器内的任何链接后,将触发displayBanner操作,而非直接交由 Web 视图处理。

此外如果查看displayBanner操作会发现,这里出现了变量$jason。在本例中,点击的链接将通过$jason变量传递。例如,如果点击一个名为"https://google.com"的 URL,$jason将获得下列值:

这意味着我们可以 检查 $jason.url 的值 进而选择性地触发不同操作。

用自定义 Web 浏览器的实现作为另一个例子一起来看看:

我们会检查 URL 是否包含字符串signin,并根据结果执行两个不同操作。
  • 如果包含signin,打开一个新视图并以原生方式完成登录操作。
  • 如果不包含signin,则直接运行"type": "$default"操作,实现类似普通浏览器的行为。
用法示范

构建自定义 Web 浏览器

利用新版 Web 容器的下列特性,可以实现很多有趣的操作:
  • 通过url属性实现自我加载,并充当一个功能齐备的浏览器。
  • 根据 URL 的不同,选择性地处理链接点击操作。
我们甚至可以通过几十行 JSON 代码构建一个自定义的 Web 浏览器。由于现在可以劫持每个链接点击,因此可以检查$jason.url,并根据结果运行我们需要的任何操作。

例如下面的例子:


从上图可以看到,点击链接后的行为与普通浏览器无异("type": "$default")。

从下图可以看到,点击链接后可以用原生方式转换至另一个 JASON 视图。

这一切都可以根据$jason.url的值选择性地触发实现。

第 1 步:向 Web 容器附加一个名为visit的操作:

第 2 步:根据$jason.url的值运行visit内部的相关操作

在下列代码中,我们会检查$jason.url是否与newest、show、ask等内容(均为顶级菜单项链接)相符。如果相符,设置"type": "$default"即可让 Web 容器做出与普通浏览器一样的行为。

如果模式不符,则可通过原生的$href转换打开一个新视图,并将点击的链接作为参数传递过去。

该 Web 浏览器的完整 JSON 标记请参阅(仅 48 行?。?

https://github.com/Jasonette/Jasonpedia/blob/gh-pages/webcontainer/agent/hijack.json
瞬间构建“混合”应用

人们通常在说“混合”应用时,主要是指封装在原生应用框架内部的 HTML Web 应用。

但此处说的并不是这种应用。这里所谓的“混合”是指真正的混合应用,也就是可以同时包含多个原生视图以及多个基于 Web 的视图的应用。在这种应用中,一个视图可以有多个原生 UI 组件,以及一个用相同原生布局渲染的 Web 容器。

Web 视图与原生视图的交织应当尽可能无缝,使得用户完全无法分辨。

在这个例子中,我创建了一个可以在 Web 容器中显示 jasonbase.com 的内容,并将其作为主页视图的应用。

Jasonbase 是我开发的免费 JSON 托管服务,该服务可以很简单地用于托管 Jasonette 应用所用到的 JSON 标记。

当然,这本身是个网站,但我将其嵌入到 Jasonette 中,因此在点击链接后并不会打开网页,而是会通过原生的$href转换展示原生的 JASON 视图。

完全无需触及 Jasonbase.com 的代码就可以构建出这个应用。

只需要将网站作为 Web 容器嵌入 Jasonette,随后劫持链接点击操作的原生处理方式,这样就可以实现原生应用所具备的各类功能,例如触发原生 API 以及进行原生转换。

完整代码可参阅这里:https://github.com/Jasonette/Jasonpedia/blob/gh-pages/webcontainer/agent/hybrid.json

结 论

在我看来,让这一切如此令人赞叹的原因在于,在框架层面上即可妥善处理好一切。所有最困难的工作都是在后台完成的。

应用开发者并不需要自行费时费力从零开始实现下列这一切:
  • 将 Web 视图嵌入原生布局
  • 创建 JavaScript 桥,以便让应用能够调用 Web 视图中的函数
  • 创建原生事件处理架构,以便让 Web 视图能够触发父应用的原生事件
整个解决方案创建了下列内容组成的抽象:
  • 声明式标记语言:用于描述如何将 Web 视图嵌入原生应用。
  • 通信协议(JSON-RPC):用于在应用及其子 Web 视图之间实现极为简单的通信。
我并不觉得这种方法可以解决所有问题,但从自己的用例来看,至少可以说这是个不错的解决方案。

我试着以非常前沿的技术来构建应用,而这些技术已经前沿到在移动端还没有任何稳定可靠的实现(由于协议的一些本质,甚至不清楚最终是否会有移动端的实现)。好在这些技术都有 JavaScript 实现,因此不费什么事就可以轻松地将其与应用相集成。

总的来说,这种技术很棒,我对目前的效果非常满意。最新版文档 已经包含了所有新功能,欢迎大家深入研究并尝试。

声明:能力越大,需要担负的责任也就越大

最后我想说:虽然这种新技术确实很强大,但我觉得大家在开发应用时都应该在用户体验方面进行更全面的权衡。

有些人可能会借助这种技术构建完全由 Web 视图组成的应用,但说到底这样的做法,你的应用实际上就只是一个网站,已经与开发专属应用的本意背道而驰了。

需要强调的是,我并不认为你的每个应用都应同时包含 HTML 和原生组件。我只是认为,这样的做法对很多面临某些具体状况的人会显得较为有用,只不过别过火就好。

相关链接

最新版文档:https://docs.jasonette.com/web/
原文链接:https://medium.freecodecamp.org/how-to-turn-your-website-into-a-mobile-app-with-7-lines-of-json-631c9c9895f5
  • 大小: 79 KB
  • 大小: 1.8 MB
  • 大小: 392.8 KB
  • 大小: 30.6 KB
  • 大小: 22.3 KB
  • 大小: 27.4 KB
  • 大小: 79.1 KB
  • 大小: 21.2 KB
  • 大小: 63.4 KB
  • 大小: 4.4 KB
  • 大小: 392.8 KB
  • 大小: 119 KB
  • 大小: 126.3 KB
  • 大小: 64.3 KB
  • 大小: 6.4 KB
  • 大小: 74.3 KB
  • 大小: 1.6 MB
  • 大小: 964.8 KB
  • 大小: 28.1 KB
  • 大小: 71.1 KB
  • 大小: 1.8 MB
来自: 前端之巅
0
0
评论 共 1 条 请登录后发表评论
1 楼 zhaobo123 2018-05-08 10:14
cool!

发表评论

您还没有登录,请您登录后再发表评论

相关推荐

  • 【译文】用7行JSON代码将你的网页变成移动应用

    在freeCodeCamp社区阅读原文。 原文地址:How to Turn Your Website into a Mobile App with 7 Lines of JSON 原文作者:Ethan 译者:Zhuotao Lian 校对者:Miya 一种将 web 引擎与应用程序融合的新方法 如果我告诉你上面7行橙色的 JSON 代码就能将网站变成移动应用,你怎么看?不需要使用框架 A...

  • 小程序页面跳转,数据传递,json字符串转对象并使用

    小程序页面跳转,数据传递,json字符串转对象并使用 1.新建一个文件夹和page,随便取名,我这里是qrcontent,如下: 2.页面跳转并传递数据 index.js跳转qrcontent.js,在index.js方法中添加代码: success: function (res) { var str = res.data wx.navigateTo({ //保留当前页面,跳转到应...

  • 使用JSON进行数据传输的总结

    一、选择的意义 在异步应用程序中发送和接收信息时,可以选择以纯文本和?XML?作为数据格式。为了更好的使用ajax,?我们将学习一种有用的数据格式?JavaScript Object Notation?(JSON?),以及如何使用它更轻松地在应用程序中移动数据和对象。JSON?是一种简单的数据交换格式,在某些方面,它的作用与XML?非常类似,但比XML?更为简单,JSON?的语法简化了数据交

  • https://blog.csdn.net/matchvs/article/details/80571214

    前言:本Demo原来是Cocos Creator官方的一个Demo,本文章利用了第三方联网插件工具Matchvs将其改造成了一个三人对战的Demo,(在线体验地址)。注意:1.游戏满三人才可以开启,匹配成功后,玩家通过键盘AD键操纵小怪物向左向右移动抢摘星星。2.下载Demo源码后,需用Cocos Creator打开工程(建议使用1.7.0及以上版本)。游戏配置Demo运行之前需要去Matchvs...

  • https://blog.csdn.net/hewei001/article/details/79108587

    1、第一步当然先下载Hbuilder,创建移动app,创建时选择mui登录模板2、项目建成功,直接运行Ctrl+R看看hello word效果。然而最难搞的还是真机调试,我用的小米,折腾了好久,提示联机不上,要安装手机助手。一点默认链接,果不其然,最讨厌的360流氓来了,给我pc端装手机助手,然并卵还是联不上,又让我在手机上安装手机助手,也没用,流氓就是流氓半点用都没,一股脑把360都卸载了。把H

  • https://blog.csdn.net/zwc_csd/article/details/77449119

    今天写API发现PC端可以正常访问,app端请求数据一直为null为了解决问题,我先把API方法的参数全部注释掉,然后,一项一项的取消注释,发现是因为double和int型参数,如果APP不传这些参数,请求数据就会变成null最后,将double 和int 类型的参数全部写为double?和int?类型,即可解决问题在换类型过程中会遇到,double?转换double失败,这是因为用到该参数的方法里

  • App Inventor 初体验。功能强大,真不懂代码的人应该做不好的吧。

    你想过自己写 Android 应用吗?如果你这样做的愿望非常强烈并且又不想学写代码的话,你可以期待下 App Inventor 这个 Google Labs 项目。这个软件将枯燥的代码变成了一块一块的拼图,你需要做的只是把这些零散的拼图按照你自己的意思组合在一起,点击生成,你的第一个 Android 程序就诞生了。 你看到过这样的帖子吗?在网上疯传,然后过了一段时间没了音讯。今天偶然想起来,好歹...

  • 将HTML5封装成android应用APK文件的几种方法

    越来越多的开发者热衷于使用html5+JavaScript开发移动Web App。不过,HTML5 Web APP的出现能否在未来取代移动应用,就目前来说,还是个未知数。一方面,用户在使用习惯上,不喜欢在浏览器上输入复杂的网址;另一方面,Html5 Web App 存放在服务器端,在每次使用时需要进行数据传递,会造成流量浪费。有些开发者不想接触复杂的JAVA代码,那么,有什么办法,既可以使用HTM...

  • javaweb区分PC端和移动

    javaweb:判断当前请求是否为移动设备访问 分类:?【Java】?【好技术要分享】?【javaweb】 ? ? ? ?这段时间都是在做pc端的业务,结果经理找到我说,可能要做移动端的应用,后台逻辑还是用我写的逻辑,但是需要改动一些,看看怎么处理。 ? ? ? ?由于移动端和pc端还是稍微有些区别的,我觉得最好是在一个地儿统一判断,而且不要改动原先的代码,这样可以从

  • https://blog.csdn.net/maninthemirror/article/details/80322091

  • ASP.NET程序通过web.config为网站添加MIME

    网站添加MIME类型,可以在IIS中的“MIME类型”设置中添加,但是这样操作网站每次移动到新的服务器或是重新部署环境都需要再重新添加,这里介绍一个一劳永逸的方法,就是在网站的配置文件web.config中添加MIME类型。 注:Web.config文件是一个XML文本文件,它用来储存ASP.NETWeb 应用程序的配置信息,通过.NET新建一个Web应用程序后,默认情况下会在根目录自动创建一

  • https://blog.csdn.net/zp19860529/article/details/87803391

    1,下载语言切换所需要的js??jquery.localize.js??????//webscripts.softpedia.com/script/Modules/jQuery-Plugins/jQuery-localizationTool-js-83407.html 2,在web.xml中添加代码,拦截json格式数据,配置文件是json文件 &amp;lt;servlet-mapping...

  • https://blog.csdn.net/sqzhao/article/details/48712991

    开始 Chrome Store在上传应用时要求提供源码打包的.zip格式,因此Chrome Store会读取你的源码文件,有一些固定的目录格式,和清单列表。支持多语言化就是其中一个。 这是一个固定的文件夹,在你的应用中创建_locales文件夹,并在下面创建对应你语言代码的文件夹,常用的几个: 中文(简体):zh_CN中文(繁体):zh_TW英文:en 同样还有一个固定的文件格

  • https://blog.csdn.net/bluejoe2000/article/details/79216312

    https://segmentfault.com/a/1190000010675594npmnpm 是javascript 包管理,也是世界上最大的软件记录。使用npm 可以安装,分享和贡献自己的代码,管理项目中的依赖包,package.jsonnpm的包依赖配置json文件,开发时可以在里面记录所有依赖包,也可以配置一些简单的npm 脚本,{ "name": "xxxxxx", "ver

  • 程序员实用工具网站

    目录 1、搜索引擎 2、PPT 3、图片操作 4、文件共享 5、应届生招聘 6、程序员面试题库 7、办公、开发软件 8、高清图片、视频素材网站 9、项目开源 10、在线工具宝典大全 程序员开发需要具备良好的信息检索能力,为了备忘(收藏夹真是满了),将开发过程中常用的网站进行整理。 1、搜索引擎 1.1、秘迹搜索 一款无敌有良心、无敌安全的搜索引擎,不会收集私人信息,保...

  • https://blog.csdn.net/qq_40693171/article/details/100716766

  • https://blog.csdn.net/qq_36903042/article/details/100798101

    写在前边 数据结构与算法: 不知道你有没有这种困惑,虽然刷了很多算法题,当我去面试的时候,面试官让你手写一个算法,可能你对此算法很熟悉,知道实现思路,但是总是不知道该在什么地方写,而且很多边界条件想不全面,一紧张,代码写的乱七八糟。如果遇到没有做过的算法题,思路也不知道从何寻找。面试吃了亏之后,我就慢慢的做出总结,开始分类的把数据结构所有的题型和解题思路每周刷题做出的系统性总结写在了 Github...

  • https://blog.csdn.net/anlian523/article/details/100865538

    对于<? super 类型>,编译器将只允许写操作,不允许读操作。即只可以设值(比如set操作),不可以取值(比如get操作)。 对于<? extends 类型>,编译器将只允许读操作,不允许写操作。即只可以取值,不可以设值。 以上两点都是针对于源码里涉及到了类型参数的函数而言的。比如对于List而言,不允许的写操作有add函数,因为它的函数签名是boolean add(E e);,此时这个形参E就变成了一个涉及了通配符的类型;而不允许的读操作有get函数,因为它的函数签名是E get(int index)

  • 代码整洁 vs 代码肮脏

    写出整洁的代码,是每个程序员的追求?!禼lean code》指出,要想写出好的代码,首先得知道什么是肮脏代码、什么是整洁代码;然后通过大量的刻意练习,才能真正写出整洁的代码。 WTF/min是衡量代码质量的唯一标准,Uncle Bob在书中称糟糕的代码为沼泽(wading),这只突出了我们是糟糕代码的受害者。国内有一个更适合的词汇:屎山,虽然不是很文雅但是更加客观,程序员既是受害者也是加害者。 对...

  • https://blog.csdn.net/ybhuangfugui/article/details/100913641

    今天给大家带来点快乐,程序员才能看懂。 来源:https://zhuanlan.zhihu.com/p/47066521 1. 公司实习生找 Bug 2.在调试时,将断点设置在错误的位置 3.当我有一个很棒的调试想法时 4.偶然间看到自己多年前写的代码 5.当我第一次启动我的单元测试时 ...

Global site tag (gtag.js) - Google Analytics