Hanjst汉吉斯特🙋与龙书编译原理

时间过得时而飞快,时而缓慢。我们人类已经与新冠肺炎疫情奋战了快两年了,好消息是随着疫苗的不断改进和持续的普及防护能力在提升,随着口服特效药面世和不断优化升级人类也不再不堪一击了。

就像不断改进和增强的疫苗和特效药一样,Hanjst汉吉斯特🙋( https://ufqi.com/dev/hanjst/ )也在持续的优化改进升级。回顾上一次更新是在 2021年3月份:Hanjst汉吉斯特🙋优化升级开发者模式( https://ufqi.com/blog/hanjst-updt-with-safari-tel/ ),差不多是年头一次主要升级,年尾一次主要升级。这次针对Hanjst汉吉斯特🙋改进,也是半年多来的累积改进,其中较大的亮点之一是改进针对注释语句的替换的操作。

在Hanjst汉吉斯特🙋的模板语言中,既有HTML的表述语言,也有原生的JavaScript程序代码,相应地会有HTML的注释语句,如
<!– 这是HTML注释内容 –> ,

也会有JavaScript的注释语句,如
//- 这是一个JavaScript注释行, 
/* 注释段落 JavaScript行1
     行2
     注释段落尾部
*/

其中在 JavaScript的单行注释时,这个注释既可以是一个单独的内容行,也可能是紧紧跟随在一段代码之后,如
const aString = “a-string-sample”; //- 声明一个JavaScript字符串变量

为兼容各种情况,程序逻辑事情变得异常的糟糕,经过很多次尝试之后,我们小结所遇到的困境和可能的出路时,目光一下子聚焦到被称之为”龙书(Dragon book)”的计算机程序编译的《编译原理》这本书。这本书的全民是 Compiler: Principles, Techniques and Tools (编译器: 原理,技术和工具), 在线内容收录在 有福经典UfqiLong: https://ufqi.com/news/clscpage.1075.html?tit=编译原理 Compilers: Principles, Techniques, and Tools 。

从本质上说,从模板语言到可执行的生成终端页面呈现HTML的其他程序语言,就是一次编译过程,这个过程与龙书编译原理所描述的过程一个模样。
compiler-fig-02.PNG

侠义的编译是将人类易读通用的程序语言代码“翻译”成为机器可以执行的机器语言代码。比如,将C语言程序代码“翻译”成为机器语言代码,将Java语言程序代码“翻译”成为机器语言代码。
Hanjst汉吉斯特🙋也做了类似的工作。整个翻译逻辑过程如下:

Hanjst模板语言代码 –> (翻译过程) –> JavaScript 语言程序代码 –> (翻译过程) –> 机器语言代码

这其中的“翻译过程”,就是编译器的工作过程,负责读入原语言代码,经过一系列的转换规则过滤与约束和改头换面的操作步骤,最终输出可供执行的目标语言代码程序。
如果所生成的目标代码程序是静态的文件程序代码,称之为静态语言,如果从abc.c 程序原代码到可执行的 abc.out.exe 程序文件。
对应的,如果所生成的目标程序是临时的内存态或者其他过程性临时文件,则称之为解释型语言,或者 动态语言,如直接执行 abc.js 或者 abc.pl 等,其编译后的临时文件只在运行时存在,执行完了或缓存下来或就直接被抛弃了。
整个链条中,Hanjst汉吉斯特只是做了第一个翻译过程,第二个翻译过程通常是有浏览器自带的 JavaScript编译和执行引擎来完成,比如 在 Google Chrome等浏览器中用到的 JavaScript V8 引擎 ( https://v8.dev/ )。

What is V8?

V8 is Google’s open source high-performance JavaScript and WebAssembly engine, written in C++. It is used in Chrome and in Node.js, among others. It implements ECMAScript and WebAssembly, and runs on Windows 7 or later, macOS 10.12+, and Linux systems that use x64, IA-32, ARM, or MIPS processors. V8 can run standalone, or can be embedded into any C++ application.

如果事情再往复杂方向继续发展,我们将不得不面临升级 Hanjst汉吉斯特的编译引擎到通用编译器的逻辑那样:
1)词法分析 Lexical  Analysis ,
2)语法分析 Syntax Anaylsis,
3) 语义分析 Semantic Analysis
编译原理 龙书 Compiler, Dragon Book-4:第一章:引论-2

目前,Hanjst汉吉斯特对模板语言的翻译尚未从最基础的词法分析,而是跳过将程序代码进行“标签化(Tokenized)” 的过程,上来就从语法分析入手,逐行对模板语句进行扫描,使用基于关键词的正则表达式对模板语句进行语义分析。经分析是当前行包括有 Hanjst汉吉斯特定义的语法关键词及相应表达式时,做如下转换:

Hanjst模板语言代码 –> (翻译过程) –> JavaScript 语言程序代码 

如果发现,当前行的内容没有相关关键词及相应的表达式时,直接跳过,将当前行视为一个普通常量字符串数据。

更上一层的语义分析的实现,则是基于语法语句分析的基础上,对包括条件控制语句、循环、退出等情况的处理,需要进行结束条件控制、关闭循环等语义层的操作时,根据一个结构数据表来进行一一对应补全。
这样的结构设计可以应付诸如模板语言这样的简单表达,同时也避免上来就进行Tokenized 的计算开销,可能是因地制宜的平衡之道吧。

然而,如果再复杂一些的情况,比如 Hanjst汉吉斯特这次修改的一个重点就是兼容行如下面的注释行,

const aString = “a-string-sample”; //- 声明一个JavaScript字符串变量

虽然几经周折,结合关键词和正则表达式成功在一些应用场景实现了预期目标,但也是逼仄式的采用了各种“奇技淫巧”——经验上看,约束条件越多,其普适性就会越差,甚至可以遇见,还有我们无法感知到的场景未被覆盖,“黑天鹅”也许就在远方。
这也许就是归纳法范式天然的缺陷。

也许,当下一只“黑天鹅”再出现时,就触及我们当前算法背后的极限,不得不使用《编译原理》中的名门正派的功夫来应对更加复杂的场景,以演绎、推理的形式彻底解决无穷尽的应用场景。

1)词法分析 Lexical  Analysis , –> 标签流Tokens Stream
2)语法分析 Syntax Analysis, –> 语法树 Syntax Tree
3) 语义分析 Semantic Analysis –> 语法树 Syntax Tree.

附加1:
来自JavaScript V8 Engine的页面JavaScipt提速优化建议
1) Improve download time, 提高JavaScript的脚步程序下载速度,一般不要超过 50KB , 再大了就拆小点, 对移动端尤其越要再小些。

2) Improve execution time, 提升执行速度,避免在主线程中放入 Long tasks. 这样才能提升页面渲染速度,尽早呈现出来。
Long tasks 是那些执行时间超过 50ms 的任务,Hanjst汉吉斯特完成翻译一个中等复杂程度的页面执行时间通常在 30ms左右。

Long task

Any uninterrupted period where the main UI thread is busy for 50 ms or longer. Common examples include:

  • Long running event handlers.
  • Expensive reflows and other re-renders.
  • Work the browser does between different turns of the event loop that exceeds 50 ms.

3) Avoid large inline scripts, 避免页面内直接书写太长JavaScript程序代码,如果内嵌代码长度超过 1KB,就考虑将其移入某个 .js 程序文件中。

4) JSON parse is faster than Object, 这似乎超出普通认知了…

const data = { foo: 42, bar: 1337 }; // 🐌
const data = JSON.parse('{"foo":42,"bar":1337}'); // 🚀

Hanjst 汉吉斯特 2021年近一年来的主要更新摘要:

* 09:08 2021-03-17, imprvs for debug in mobile browsers, +support for if conditionExpr
* 17:09 2021-04-26, + _enSafeExprAsCondition .
* 21:32 2021-05-19, bugfix for remedyMemoLine .
* 12:31 2021-05-21, bugfix for &amp; .
* 09:04 2021-06-07, add more _enSafeExpr .
* 21:51 2021-06-29, +comment: use Firefox to figure out exact error lineNumber and columnNumber in tpl2code in new Function
* 21:55 2021-11-11, imprvs for remedyMemoLine

更多参考 Hanjst汉吉斯特官网:https://ufqi.com/dev/hanjst/

 


Hanjst
Hanjst 汉吉斯特 Logo

🙋Hanjst汉吉斯特 是一种基于JavaScript的模板语言及模版解析引擎,她运行在客户端或服务器端。

🙋Hanjst汉吉斯特 能够表述逻辑控制,能够实现与服务器端模版语言相同的强大功能。

  • Hanjst当完全在客户端解析时,节省服务器端计算资源;

  • Hanjst模板语言独立,不与服务器端资源做任何绑定;

  • 纯粹的MVC,层间数据用JSON格式传递;

  • 常见模板语言功能全支持,附带复杂而强大的JavaScript编程能力;

  • 无学习成本,直接使用JavaScript书写模板语言;

  • ….

Hanjst is a JavaScript-based templating language and parsing engine that runs on both the client-side and/or server-side.

Hanjst can express logical controls and achieve the same functionalities as the server-side templating languages.

  • Hanjst’s Run-time in client-side, reduce computing render in server-side;

  • Hanjst is Language-independent, not-bound with back-end scripts or languages;

  • Totally-isolated between MVC, data transfer with JSON;

  • Full-support template tags with built-in logic and customized JavaScript functions;

  • No more tags languages to be learned, just JavaScript;

  • ….

Hanjst汉吉斯特🙋与龙书编译原理

 

发表在 -GTAjax, -Hanjst/-汉吉斯特, 编程技术, 计算机技术 | 标签为 , , , , | 2条评论

电热蚊香液套装无味婴儿孕妇家用补充液插电式灭蚊液护发素发膜正品修复干枯免洗家用护发补水顺滑女士发热焗油膏书皮纸自粘透明磨砂加厚包书皮小学生一二三四年级上册上学期书膜全套课本书本保护套16k封面外壳防水a4彩染发剂植物纯自己在家染头发膏女2021流行色显白天然

GWA2吉娃兔🐇Java中的文件上傳表單處理若干問題-2

去年(2020年)秋天写了上一篇:GWA2吉娃兔🐇Java中的文件上傳表單處理若干問題( https://ufqi.com/blog/gwa2-java-file-upload-issues/ ),随着我们持续不断的研发推进、精益求精,发现在 GWA2Java 中處理文件上傳的HTML表單被稱爲是“客貨混裝”的HTTP請求處理时,还有一些额外的问题需要再补充。兹详述于下,备忘备查。

(问题1-7请参考此前一篇Blog)

8. 数组型数据的接收与处理

在GWA2 Java中,为上传文件当HTML的表单类型被设置成 enctype 屬性為 multipart/form-data , request.getParameter 方法失效,同样地类似方法 request.getParameterValues 也失效了,如此以来,获取类似 多个 checkbox 这样的HTML form的输入,就成了问题。为此,我们需要再扩展一下之前使用 FormItems 来接管 request的相关属性的方法。

ServletFileUpload sfileupld = new ServletFileUpload((new DiskFileItemFactory()));
formItems = sfileupld.parseRequest(request); // can only be parsed once!
if (formItems != null && formItems.size() > 0){
String iname, ivalue; byte[] bytes; Object lastVal;
for (FileItem item : formItems){
// processes only fields that are common form fields
if (item.isFormField()){
bytes = item.getFieldName().getBytes(“ISO-8859-1”); // why 8859?
iname = new String(bytes, “UTF-8”);
bytes = item.getString().getBytes(“ISO-8859-1”);
ivalue = new String(bytes, “UTF-8”);
lastVal = request.getAttribute(iname);
if(lastVal != null){
// checkbox or multiple select
if(lastVal instanceof String[]){
String[] tmpArr = (String[])lastVal;
String[] tmpArr2 = new String[tmpArr.length+1];
for(int si=0; si<tmpArr.length; si++){
tmpArr2[si] = tmpArr[si];
}
tmpArr2[tmpArr.length] = ivalue;
request.setAttribute(iname, tmpArr2);
}
else{
String[] tmpArr = new String[2];
tmpArr[0] = String.valueOf(lastVal); tmpArr[1] = ivalue;
request.setAttribute(iname, tmpArr);
}
}
else{
request.setAttribute(iname, ivalue);
}
//debug(“ctrl/user: iname:”+iname+”, ivalue:”+ivalue+” lastVal:”+lastVal);
}
else{
debug(“ctrl/user: not form field: iname:”+item.getFieldName()+”, ivalue:”+item.getString().length());
}
}

使用 lastVal, 来检测是否同一个key的键值被赋予多个赋值,如果时,就启用一个数列来存储。相关代码在 github/wadelau/GWA2  ( https://github.com/wadelau/GWA2 )上可以获取。
该应用的场景是一个Form中,既有多选框,也有文件上传。

对应地,我们也在相关GWA2 的基础设施组件 comm/Wht 中增加了针对Form 的数列型数据的接收处理,方法名为
Wht.getArray(request, fieldName)
以此来接收和处理类似 multi select和check box类型的输入。

9. 多文件同时上传的优化处理

针对服务器端接收处理文件上传的相关组件,已经非常成熟,拿来用即可。如前所述,我们在GWA2 Java中处理文件的模块主要来自 Apache commons-fileupload-1.4.jar , 一并的也要引入 Apache commons-io-2.7.jar。

在一些细节上,还是有可深究的地方。默认情况下,我们通过 inc/FileSystem 中的一个 upload 方法来处理这些细节。针对 upload这个方法,预期的效果是给定一个上传的 form字段名称,然后返回一个保存后的文件路径,形式如:
formFieldA -> filePathInDisk

如果是多个文件呢?之前的方法是 upload 返回一个数组,包括多个地址,相当于:
[formFieldA, formFieldB] -> [filePathInDisk, filePathInDisk]

此时处理两个以上的文件上传时,它是能够完成预期目标的,可是,如果要更新其中一个文件时,就会出错。由于Form字段名称对应的磁盘文件路径,只有顺序,而没有最终预期的key/value 形式,当修改或更新其中一个文件时,总是返回形式为:
formFieldA -> filePathInDisk

这与只上传一个文件的情形是没法区分的。需要改正、优化。预期的是返回一个key/value形式的 formField/diskFilePath 。

// parses the request’s content to extract file data
@SuppressWarnings(“unchecked”)
List<FileItem> formItems = preFormItems;
if(formItems == null || formItems.size() ==0){
formItems = upload.parseRequest(request);
}
if (formItems != null && formItems.size() > 0){
// iterates over form’s fields
String fieldName, itemName, fileName, suffix, filePath;
File storeFile = null;
String showPath = UPLOAD_DIRECTORY + File.separator + relativePath;
if(!relativePath.endsWith(File.separator)){ showPath += File.separator; }
for (FileItem item : formItems){
// processes only fields that are not common form fields
if (!item.isFormField()){
fileName = “”;
fieldName = item.getFieldName(); itemName = item.getName();
if(itemName != null && !itemName.equals(“”)){
suffix = “”;
if(itemName.lastIndexOf(“.”)>0){
suffix = itemName.substring(itemName.lastIndexOf(“.”), itemName.length());
}
fileName = UUID.randomUUID().toString().replaceAll(“-“,””) + suffix;
filePath = uploadPath + File.separator + fileName;
debug(Log_Tag+” upload: filePath:”+filePath+” itemName:”+itemName);
// saves the file on disk
storeFile = new File(filePath);
item.write(storeFile);
fileName = showPath + fileName;
}
else{
fileName = “”;
debug(Log_Tag+”upload: skip empty itemName.”+itemName);
}
hmResult.put(fieldName, fileName);
}
else{
//debug(Log_Tag+” upload: form field item:”+item);
}
}
}
else{
debug(Log_Tag+” upload: formItems:”+formItems);
}

新增了 fieldName 字段,在返回时,将 Form fieldName 与 diskFilePath 以 key/value 形式严格对应起来,由返回 String 后者 String数组,改为返回 HashMap。如此以来,则可以解决同时上传多个文件,而不依赖顺序来对应所上传的文件,同时,当修改时,也可以避免所跳过的文件产生的顺序异常。完整功能的相关代码在 github/wadelau/GWA2  ( https://github.com/wadelau/GWA2 )上可以获取。

由于方法返回值的修改,不兼容此前版本,建议老版本的用户升级时,使用方法重载后者命名新方法的形式引入新功能。比如,在最近的项目 Boss选址 ( bossxuanzhi.com ) 中,我们就面临要使用命名新方法来兼容前期使用旧方法的 upload 和后期采用新方法的 uploadMultiple 。
如果是在新项目中,建议直接使用即可,没有向前兼容的需求。

 


-GWA2 吉娃兔 是”通用网络应用架构( General Web Application Architeture, https://ufqi.com/dev/gwa2/ )”,基于 -GWA2 可以轻便构建各种网络应用程序,
包括复杂的在线购物商城、在线医疗、在线教育、 旅游交易平台、社群或者社交网站和新闻资讯网站等,
也包括各种企事业单位网上门户,在线交互及服务作业系统等.
还可以包括为NativeApp做服务器端支持, 甚至是WebApp的全部.
-GWA2 是为数不多的支持跨开发语言的应用框架,目前支持 -Java, -PHP, -Perl, -Aspx and -Python .

-GWA2 is a “General Web Application Architecture” and based on -GWA2 developers can easily build a variety of network applications,
including complex online shopping malls, online medical services, online teaching, travel trading platforms, community or social networking sites and news information sites, etc.
Also the applications include various online portals of enterprises and institutions, online interaction and service operations systems.
Moreover it contains server-side support for Native App, or even all of the WebApp.
-GWA2 is one of the web frameworks which provide cross-language support for -Java, -PHP, -Perl, -Aspx and -Python at present.

-GWA2 is E.A.S.Y 
Easy Along, Swift Yield
轻松启动, 快速产出.

 


 

Boss选址( bossxuanzhi.com )是汇成产业服务(汇成产服)提供的在线服务,是服务政府投融资、招商、运营的平台型公司. 汇成产服公司定位:一、专业的政府招商代理服务机构,二、企业选址服务机构,三、企业咨询管理服务平台。

 

( https://ufqi.com/blog/gwa2-java-file-upload-issues-2nd/ )

 

发表在 -GWA2, 编程技术, 计算机技术 | 标签为 , , , , | 留下评论

彩染发剂植物纯自己在家染头发膏女2021流行色显白天然冰糖雪梨膏儿童宝宝砀山慈梨膏山羊绒围巾女冬英伦百搭围脖双面格子加厚保暖披肩显白黑茶色蓝黑色板栗色

理性经济人在边际上做选择

奥地利经济学派的大师米塞斯(Ludwig von Mises / 路德维希·冯·米塞斯)在《人的行为Human Action》论述到:“一个人决不会在「金」与「铁」之间选择,而只是在一定量的金与一定量的铁之间选择。”。( https://ufqi.com/news/ulongpage.1975.html )

我想用新近发生在我们自身的一个案例来试图描绘这种边际选择,而不是非此即彼的是非选择。
2021年10月,我们要为 ufqi.com 举行一些活动,制作若干 ufqi.com 的不干胶贴纸。为此我们先在 某宝网上翻阅,发现不能在网页与店家沟通,需要再安装一个聊天沟通客户端( wwcmd ),隧作罢。
然后尝试在 某东商城上翻阅,找到类似服务店家,直接在网页上进行沟通定制细节,然后按约定下单,隧成交。

针对制作 ufqi.com 不干胶胸贴纸这件需求或任务,所能采取的方法有很多(选择),既可以在楼下街边找一家快印店,也可以网上下单。选择在网上下单制作,还可能面临第二层选项,是在 某宝网上选,还是在某东商城上选?
即便是最终确定了一家某东商城,我们同样还会继续面临第三层选择,是选店家A还是选择店家B、C、D…?

从这个过程看,客户抵达的路径岔口太多异常艰辛,所有商家都不应该辜负客户的每一次光临。都应该殚精竭虑地完成客户的托付,才对得起客户在抵达商家之前的一次次的“临幸”。

我们为何不是那种,打死我也不去街边店下单? 或者打死也不去网上下单?
甚至在网上下单,当我们遇到某宝网上要求我们下载一个客户端才能与店家沟通的障碍时,为何不做出“打死以后也再来某宝网上购物了”的决定呢?

因为我们是理性经济人,我们在做决策时,是从经济的角度考虑,经济的潜台词中,主要内容就是在有限成本支出的前提条件下,获得最大化的产品和服务收益。

在上面这个案例中,表面上再多安装一个沟通客户端对用户来说是负担,是额外的成本开支,深层的是还有其他因素在里面。尽管商家要求用户安装沟通客户端有千万个理由,甚至其决策和设计过程也经过复杂无比的争论,但当遇到有理性思维,懂得做边际选择,有可能替代的产品或服务出现时,其被取代是必然的,剩下的只是时间问题。

我们拒绝再额外多安装一个沟通客户端还由于其行为或者方向与 ufqi.com 所倡导的 互联互通开放包容 的理念相悖,甚至是反向加速。某宝网不提供基于网页的沟通工具,某付宝不提供基于网页版的服务,某多多不提供网页版的服务,尽管是商家的自由,值得尊重,同样地,用户也有选择用或者不用的自由。

这也是为何我们必须旗帜鲜明地反垄断,垄断既是健康经济体的毒瘤,也是社会发展、文明进步的绊脚石。垄断的团体只有一个目的,攫取更多的利益以加固其垄断地位,直到永远,102年是远远不够的。

互联互通开放包容 的先决条件是任何技术或平台必需是多家共同协商制定和维护的。这是互联网络、万维网生存的前提,也是已经发展实践的正确道路。这期间总是有各种软件或(和)硬件公司试图在全局或者某些局部上下通吃左右把控,实施垄断以谋取暴利。

我们都不会忘记,没有万维网以前,所有的软件都是今天流行的App格式(Application 独立二进制程序包,需要独立地安装、运行以满足某种需求),分发途径就是物理磁盘复制拷贝人际传播交换。我们不想回退到史前,所以我们不遗余力地倡导继续保持互联互通、开放包容,基于万维网开发,基于浏览器或者另外一种基于开放技术平台(HTML50?)开发互联网络。
画地为牢的App是旧势力,是垄断、专制的保皇派的利器。
万维网才是打造人类巴别塔的基石。

我们,作为理性经济人,应该在力所能及的情况下,保卫奄奄一息的互联互通开放包容的精神火种,放大视野放长时光,我们的世界基于自由身份平等地位的分工协作才是征程大海。
我们坚信,基于浏览器或者另外某种新的开放技术平台(HTML50?),一定能实现自由地使用搜索引擎、新闻、娱乐、购物和通信等基本互联网服务。我们在一个大公司的垄断平台上忍了很久,可能还要继续再忍一阵子,但这并不代表我们绝望了,毕竟我们是理性的经济人。当我们看到一丝曙光时,代表着未来,引领了方向,就摇旗呐喊助威,表露我们的边际选择倾向。在一个混沌系统中,当我们的选择可以影响整体的发展时,那应该算是幸事。乐观其成。

经济学家张维迎教授在《经济学的十个基本原理》一文中这样解释边际选择:

经济学所要关注的问题,通常不是极端的非此即彼,而是“多一点”还是“少一点”的比较,也就是对“边际成本”和“边际收益”的权衡。
举例来说,我们需要考虑如何在购置食品和购置衣物上分配收入。一般来说,我们不会只买衣服不吃饭,也不会只吃饭不买衣服,而会考虑是多买些食物而少买些衣服,还是多买些衣服而少买些食品,这样的选择就是边际选择。
https://ufqi.com/news/ulongpage.243.html?tit=北大张维迎:你应该知道的10个经济学原理

这里的“衣物”与“食品”的对比,恰如开篇米塞斯举例中的“金”与“铁”一样。在上述制作 ufqi.com 的不干胶胸贴纸的任务描述中,也许我们投赞同和选择票的某东商城以后会基于自身利益考虑也要用户安装一个沟通客户端,也许我们反对和不选择的某宝网也许以后发现用户流失厉害还是改回在浏览器直接允许用户和店家沟通吧。这些都有可能,所幸我们都是理性经济人,当更加经济的方向出现时,我们总是能够用脚投票即可,在经济一边的边际上多买一些,在非经济一边少买一些。

可能的难题是,当信息不能自由流动时,人们因为“无知”而不懂得如何去做边际选择。这恰是所有画地为牢的App努力达成的愿景——“除我之外,再无别的神”。多年前,我们在人民网有个研究就发现,互联网络应用的发展趋势总是服务的排他性和内容的多样性不断集成和加强( 新闻阅读的聚合趋势–传媒–人民网 (people.com.cn),http://yjy.people.com.cn/n/2015/0701/c245081-27239100.html  )。

理性的经济人,我们天生要肩负这种责任,具备一定的抗拒能力,设法保持互联网络生态服务的多样性(每种应用服务两家以上,互联互通)和内容的排他性(文字影音每类内容公推两种默认格式必需支持,其他自选),维护互联互通开放包容的格局。

 

—-这是温习经济学著作的第八篇习作,之前的各篇附列如下。

  1.  写写年度收益率年均收益率和年化收益率-4 | -UFQI-Blog, https://ufqi.com/blog/income-rate-annuals-with-buffett/ 
  2. 写写年度收益率年均收益率和年化收益率-3, 
    https://ufqi.com/blog/income-rate-annuals-with-yale/
  3. 写写年度收益率年均收益率和年化收益率-2 , https://ufqi.com/blog/income-rate-annuals-with-cic/
  4. 写写年度收益率年均收益率和年化收益率, https://ufqi.com/blog/income-rate-annuals/
  5. 治大国若过小家——写写王朝兴衰更替背后的经济账, https://ufqi.com/blog/political-reform-country-vs-home/
  6.  写写🏦存款利率贷款利率和负利率, https://ufqi.com/blog/captial-rate-and-minus-rate/
  7. 写写1929年美国经济大萧条与2020年美国股市大跌, https://ufqi.com/blog/us-1929-economic-crisis-2020-stock-shock/
发表在 社会生活, 计算机技术 | 标签为 , , , | 4条评论

床上电脑桌大学生宿舍上铺懒人可折叠小桌子家用寝室简约学习书桌电热蚊香液套装无味婴儿孕妇家用补充液插电式灭蚊液护发素发膜正品修复干枯免洗家用护发补水顺滑女士发热焗油膏书皮纸自粘透明磨砂加厚包书皮小学生一二三四年级上册上学期书膜全套课本书本保护套16k封面外壳防水a4

有福新闻UfqiNews: 没有富矿我们只提供了一张藏宝图

大约10天前(2021-07-02)我们撰写了 有福新闻UfqiNews 更新日志:《UfqiNews有福新闻更新:提质增效》( https://ufqi.com/blog/ufqinews-imprv-for-quality-experience/ )。这一次我们想写写 有福新闻UfqiNews 初心与使命,简要回顾一下几年来奔波儿灞、灞波儿奔式的改进过程中,核心追求和愿景是什么,以期不忘初心,牢记使命。

在有福新闻UfqiNews的简介页面上,写得多宏观、宏伟而宏大,又有点高远得不接地气。
“有福新闻UfqiNews 带来全新的资讯阅览体验, 不信息过载, 亦不信息茧房.
在寻求最大社会共识和满足千人千面之间保持适度,
在满足广泛涉猎与追求术业专攻之间谋取平衡.”

可能普通读者或者资讯消费者本不懂什么是信息过载,更诳论信息茧房。对于大众传播而言,所热火的流量依然逃不脱人性使然的“(娱乐明)星,(色)性,(血)腥“。诚如大众所言,很黄很暴力…, 这虽不入主流,确实流量的顶流。如同世界上其他一些害人的东西一样,明知有害,却屡禁不止,这三Xing的资讯可算作一类。

图文内容如此,音视频等多媒体内容也概莫能独善其身。一项由Mozilla软件基金会进行的针对Youtube视频站的名为“YouTube Regrets”调查发现:大约70%的观看次数是由推荐算法引导产生的,这其中大约71%被观看视频内容,被标记为”后悔看了”.  ( https://foundation.mozilla.org/en/campaigns/youtube-regrets/ )

世界还在逐渐变好,而不是日渐堕落,说明主流和台面上依然是积极向上、奋发有为的。这是毋庸置疑的,也是必须坚持的操守之一。有福新闻UfqiNews本初的立意是使用计算技术手段对资讯进行聚合整理,让紧要的、精华的内容能够流传得更广泛、更持久、更深入。

有福新闻UfqiNews没有富矿,我们只提供了一张藏宝图。

在这里按图索骥总能找到想要的资讯,虽然只言片语的不完整,却总是画龙点睛的关键之笔。有心挖掘,事情真相或许就在这些碎片式的故纸堆里,通过关键词的穿针引线式的指引,像藏宝图一样,带领用户最终捕捉到关键要点。

我们没有图书馆、资料库,但我们知道哪里有,我们不但知道哪里有,还知道哪些是“好的”,哪些是“不好的”。这个功能有些像传统的搜索引擎,但又不完全相同。如果与搜索引擎类比的话,有福新闻UfqiNews是一种资讯搜索引擎,但这种称呼也不恰当,有福新闻UfqiNews并不索引所有资讯站点,甚至每一个目标中的资讯站点也不是索引全部页面,而只是收录例如首页和栏目频道首页这样的关键部位、关键条目。

如此一路top-down下来,有福新闻UfqiNews将原本庞大、复杂无比的海量资讯减缩到可以计算的范围,取其有限的、有代表性的关键信息再行聚合,从而起到以点带面、窥一斑而知全貌作用。

“有福新闻UfqiNews 寻求最大可能的新闻资讯立场中立、内容客观、真实,数据准确。她是一种新的尝试和探索,第一次让公民社会的“第四权力”在阳光下按自由意志运行。”

借助于互联网络新技术,行业的细分使得单独的广告平台得以独立运行,在此前提下资讯平台可以独立于广告平台而运行,从而形成的以市场为基础的新的资讯传播秩序。资讯平台也许是首次可以不设置广告收入部门而运行。

以上这些理想也好、理论也罢,多只是纸上谈兵。具体实际若何,我们或能从下面一些实例中获得认知或验证。为了标记从有福新闻UfqiNews流出的流量,我们在流出的链接中加入了有福新闻UfqiNews的标记,按通用国际惯例,我们以参数 utm_source=ufqinews 作为标记,告诉下游页面该次访问来自有福新闻UfqiNews。

下面这些页面是我们使用 utm_source=ufqinews 进行检索得到的,这些带有ufqinews标记的页面被登记在内容里,说明作者当初获取内容时使用的场景是从 有福新闻UfqiNews前往目标页面的。

有福新闻UfqiNews 这张藏宝图已经帮助了很多人获得有用的信息,未来也一定会帮助更多的人获取有价值的信息和内容,逐渐掌握使用和驾驭资讯的能力,逐步提高辨识和分析水平。
正确地获取准确的资讯至关重要,因为——信息即权力。


ufqinews logo
有福新闻 UfqiNews

这里呈现热点全局, 尺寸间一览所有令人关注的疑点焦点;
这里表达条分缕析, 视野内一睹各个脉络清晰的故事主线.

有福新闻UfqiNews 带来全新的资讯阅览体验, 不信息过载, 亦不信息茧房.

在寻求最大社会共识和满足千人千面之间谋取平衡,
在满足广泛涉猎与追求术业专攻之间谋取平衡.

媒介插上人工智能的翅膀将如虎添翼, 与资讯比翼双飞.
新闻爱好者的良心之选, 匠心之作.

UfqiNews presents the hot spots globally, with all interesting points at a glance.
Information is organized here and there is a clear storyline within every single detail.

UfqiNews brings a brand new reading experience, no information overload and no information Cocoons,

In seeking a balance of the maximum social consensus and meeting thousands of people for each interest,
In achieving a balance between satisfying a wide range of hunting and pursuing specialization in the industry.

That media is being born with wings of the artificial intelligence will be even more powerful and the information will fly swifter than ever.

Better choices of newsreaders and the art of work from them.

发表在 UfqiNews有福新闻, 社会生活, 计算机技术 | 标签为 , , , , | 一条评论

床上电脑桌大学生宿舍上铺懒人可折叠小桌子家用寝室简约学习书桌电热蚊香液套装无味婴儿孕妇家用补充液插电式灭蚊液护发素发膜正品修复干枯免洗家用护发补水顺滑女士发热焗油膏书皮纸自粘透明磨砂加厚包书皮小学生一二三四年级上册上学期书膜全套课本书本保护套16k封面外壳防水a4

JavaScript未定义变量检测undefined null detection

HTML5自十多年前(2010年前后)被推举以来,逐渐大放异彩,尽管过去十年是属于Native APP的高光时刻,但HTML5的一些新特性和功能还是带来了大量的新网络/网页应用,尤其是在JavaScript的加持下,网页应用有极其令人着迷的便利与强大。

JavaScipt是网页应用默认编程语言,让人又爱又恨。

笔者曾经在《中国计算机学会通讯》上刊发了一篇看法文章《JavaScript或成主导的编程语言》( https://dl.ccf.org.cn/institude/institudeDetail?id=3738875941521408&_ack=1 ),其后两个开源项目 GTAjax ( https://ufqi.com/dev/gtajax )和 Hanjst ( https://ufqi.com/dev/hanjst/Hanjst.demo.html )又分别是使用JavaScript做了实现,甚至 Base62x( https://ufqi.com/dev/base62x/ ) 的编解码方法,都有JavaScript语言版本,可谓是JavaScript的重度用户、开发者。

即便如此“资深”,仍常常觉得JavaScript用起来让人不那么放心,为了写出更可靠的代码,我们甚至在JavaScript中显示地声明用严格检查模式: use strict.

即便如此“谨慎”,我们也会遇到 object/variable is null or undefined 的异常抛出,使得程序异常终止,为用户带来了很不好的体验。随着我们在 UfqiWork/有福工坊( https://ufqi.com/work ) 的开发推进,我们尝试寻找一种检测 JavaScript 变量或者对象是否null 或 undefined方法的努力,有了新收获,兹分享如下。

从JavaScript本身来说,要检测某个对象或变量是否为null/undefined,主要有两个工具可用: typeof 操作符 和 window.hasOwnProperty 方法。我们所创制的方法, 代码1,也是基于这两个基本操作。


//- _isDefined
//- @param: $var, to be tested;
//- @param: global_or_local: ‘global|local’, optional
//- return true | false
//- usage: test whether a global variable($var): _isDefined(“$var”) , _isDefined($var)
//- test a variable($var) declared nearby/locally: _isDefined($var) , _isDefined(“$var”, “local”)
function _isDefined($var, global_or_local){
var isDef = false;
if($var != null){
var myTp = typeof $var;
if(myTp == ‘string’){
if(window.hasOwnProperty($var)){
isDef = true;
}
else if(global_or_local != null && global_or_local == ‘local’){
isDef = true;
}
else{
//- @todo
}
}
else if(myTp != ‘undefined’){
isDef = true;
}
}
return isDef;
}


这些代码已经部署在 Hanjst/汉吉斯特, UfqiWork/有福工坊 相关模块中,经实测,运行良好,符合预期。

在编制这些代码之前,我们也曾经在多个应用中写了大量的检测某个JavaScript是否为null/undefined,无一例外地都是使用 typeof 或者 window.hasOwnProperty方法,甚至再带着对 null和 empty的判断。代码显得异常繁琐和臃肿。相信此后,这些代码将陆续得到简化和修正,新写的代码也将引入该功能 _isDefined .

在编制这些代码之前,我们也在网络上进行了 code review,翻阅了大量针对此问题的解决思路和办法,可能面对不同运行时环境,给出的解决方法也各个不同,实际上并没有一种方法可以通用到“放之四海而皆准”。

比如最接近本方法的一个尝试是定义一个 isDefined2, 代码2,然后在方法体内使用 typeof 操作符判断传入的 $var 是否 null/undefined , 以此来进行判断变量或者对象 $var 是否为 null/undefined .


//- _isDefined2,  WRONG!
//- @param: $var, to be tested
//- return true | false
function _isDefined2($var){
var isDef = false;
if(typeof $var != ‘undefined’){
isDef = true;
}
return isDef;
}


这段代码通常情况下,能够进行运行,并对一些变量实现null/undefined的探测。然而这个情况只局限在本地变量或者当前已经声明的变量,如果待探测的变量 $var 没有在 _isDefined2 调用之前被声明,则调用探测语句 _isDedined2($var) 本身就会报错说 $var is null/undefined .

问题进一步地被延申到 JavaScript的函数方法调用的参数传递是pass-by-value传值,还是 pass-by-reference传引用。通常情况下,JavaScript的方法调用都是 pass-by-value, 所以在执行语句  _isDefined($var) 时,先要对 $var 进行取值操作,而 $var 如果本身 undefined 时,悲剧错误就产生了,检测是否为 null/undefined 之前已经发生了 undefined .

当我们判断了 $var 为String类型的数据对象时,同时引发了另外一个问题,就是当某一个数据变量或对象其本身就是字符串时,如果其本身是一个本地变量,而String类型会被视为检测全局变量,这里就会发生异常错误,把本该返回本地变量为 true的结果,错误地解释为全局变量为 false。因此需要进一步地对方法本身做修正,使之能够兼容本地变量、String类型,改进的做法是针对 _isDefined 引入第二个参数,显示地告诉程序,当前虽然引入了 String类型的变量,但不是默认检测全局变量,而是要检测本地变量。

进一步地修正这个问题,我们创制了样例代码1. 可以兼容全局变量和本地变量,不管$var 是否被什么,都能够进行检测。只是,在调用的时候需要区分,待检测的变量或者对象是全局变量或者是局部变量:
如果是全局变量,调用方式是: _isDefined(“$var”) , _isDefined($var)
如果是局部变量,调用方法是: _isDefined($var, ‘local’) , _isDefined(“$var”, ‘local’) 

变量 $var 在被检测之前,我们能够知道它是全局变量或者局部变量吗?
答案应该是明确的。

测试样例:

var a;
console.log(“UfqiWork/Hanjst: a:”+_isDefined(a));
var b = null;
console.log(“UfqiWork/Hanjst: b:”+_isDefined(b));
var c = 0;
console.log(“UfqiWork/Hanjst: c:”+_isDefined(c));
console.log(“UfqiWork/Hanjst: global-c:”+_isDefined(“c”));
var dd = “d_string”;
console.log(“UfqiWork/Hanjst: local-dd:”+_isDefined(dd, ‘local’));
console.log(“UfqiWork/Hanjst: global-dd:”+_isDefined(dd));
console.log(“UfqiWork/Hanjst: global-dd:”+_isDefined(“dd”));
console.log(“UfqiWork/Hanjst: local-dd:”+_isDefined(“dd”, ‘local’));

预期输出:

UfqiWork/Hanjst: a:false
UfqiWork/Hanjst: b:false
UfqiWork/Hanjst: c:true
UfqiWork/Hanjst: global-c:false
UfqiWork/Hanjst: local-dd:true
UfqiWork/Hanjst: global-dd:false
UfqiWork/Hanjst: global-dd:false
UfqiWork/Hanjst: local-dd:true


Hanjst
Hanjst 汉吉斯特 Logo

🙋Hanjst汉吉斯特 是一种基于JavaScript的模板语言及模版解析引擎,她运行在客户端或服务器端。

🙋Hanjst汉吉斯特 能够表述逻辑控制,能够实现与服务器端模版语言相同的强大功能。

  • Hanjst当完全在客户端解析时,节省服务器端计算资源;

  • Hanjst模板语言独立,不与服务器端资源做任何绑定;

  • 纯粹的MVC,层间数据用JSON格式传递;

  • 常见模板语言功能全支持,附带复杂而强大的JavaScript编程能力;

  • 无学习成本,直接使用JavaScript书写模板语言;

  • ….

Hanjst is a JavaScript-based templating language and parsing engine that runs on both the client-side and/or server-side.

Hanjst can express logical controls and achieve the same functionalities as the server-side templating languages.

  • Hanjst’s Run-time in client-side, reduce computing render in server-side;

  • Hanjst is Language-independent, not-bound with back-end scripts or languages;

  • Totally-isolated between MVC, data transfer with JSON;

  • Full-support template tags with built-in logic and customized JavaScript functions;

  • No more tags languages to be learned, just JavaScript;

  • ….

发表在 -GTAjax, -Hanjst/-汉吉斯特, 编程技术, 计算机技术 | 标签为 , , , , | 4条评论

电热蚊香液套装无味婴儿孕妇家用补充液插电式灭蚊液护发素发膜正品修复干枯免洗家用护发补水顺滑女士发热焗油膏书皮纸自粘透明磨砂加厚包书皮小学生一二三四年级上册上学期书膜全套课本书本保护套16k封面外壳防水a4彩染发剂植物纯自己在家染头发膏女2021流行色显白天然

UfqiNews有福新闻更新:提质增效

上一次成批次地更新 UfqiNews有福新闻, 是在差不多两年前的《UfqiNews有福新闻的第N+1批次更新:清晰,流畅,省电》 ( https://ufqi.com/blog/ufqinews-updt-n-plus-1-fast-and-power-saving/ )。时间过得飞快,实际上 UfqiNews有福新闻 的优化和更新一直在持续,只是短期内大面积的更新,我们才会单独写一篇更新Blog一记录备查,就像接下来这篇改进的描述与说明一样。

1. 延长页面驻留在 UfqiNews有福新闻系统的时间

所面临的问题是,当某些页面依据系统的默认驻留时长到期后被移除,已经被某些外部资源所引用,被移除后的页面仍有访问流量进入。此时就会产生不好的用户体验,用户遭遇 404 页面找不到的情况,极大的浪费多种资源。

有鉴于此,我们通过升级设备运算和存储能力,进一步延长单个资讯页面在系统中的驻留时间,增加了约100%的时长。此举有望减少用户遭遇 404 页面找不到的几率。

2.改进持久永久固定链接的构成部分

如前所述,虽然延长了页面在系统的驻留时间,但仍不可避免的会有少量用户还是会遭遇 404页面找不到的情况。

为进一步解决这个问题,我们同时修改了持久/永久链接的构成部分:在页面固定链接中增加keyWord id。
修改前的页面固定链接: https://ufqi.com/news/page.4343804.html 
修改后的页面固定链接: https://ufqi.com/news/list.1327,187,4419.4343804.html

此举的目的在于,如果因为时间久远,某个页面被系统移除后,根据页面的固定链接,仍能够通过3个左右的关键词来提供几乎相同的内容给用户选择,避免用户打开“答非所问”的页面,或者遭遇 404的情况。

3. 每用户点击额外增加页面驻留时长30天

通过改进程序,增加对被阅览的资讯内容给予更多的驻留时长,让用户的流量来决定某一页资讯内容在系统中的最长寿命。

比如设定算法,某页资讯内容,如果每一个用户的一次点击可以给予30天的时长延续。如此以来,系统中会积淀大量由用户选择的优质内容,久而久之,系统形成正向反馈,越多的用户选择了越多的优质内容,越多的优质内容会吸引更多的用户。

假以时日,UfqiNews有福新闻 将成为中文资讯的一座宝库。那些生生不息的优质内容不断地由用户的一次次点击为其“续命”,直到永久。

4. 增长对资讯摘要的索引内容

根据前端阅读体验,我们适当地增长了对单条资讯的索引内容,大约增长了30%左右。

通过对索引内容的增长,前端用户有望看到更多的资讯细节,有助于用户进一步地的判断是否需要跟进深入阅读全部内容。

5. 通过NLP相关技术改进资讯内容的断句

改进内容分析算法,通过NLP(自然语言处理,Natural Language Processing)相关技术,实现对资讯内容句法分析,优先在整句断开(句号、问号等),其次在半句断开(逗号,分号等)。

结合与 4. 增长摘要的索引内容,用户在前端的浏览体验会更好,不会再看到在半句中间断开的情况。

6. 通过NLP相关改进分词引擎

通过优化升级中文分词引擎,改进分词取词范围(增加对人名、地名和机构名的收录、聚合),增加数组新词汇;

改进对所选择的词汇的权重值的调整,让存储和计算词汇权重值的效率更高。

此外,规划功能增补to-do list:

  1. 浏览历史
  2. 浏览排行榜
  3. 评论排行榜

 


ufqinews logo
有福新闻 UfqiNews

这里呈现热点全局, 尺寸间一览所有令人关注的疑点焦点;
这里表达条分缕析, 视野内一睹各个脉络清晰的故事主线.

有福新闻UfqiNews 带来全新的资讯阅览体验, 不信息过载, 亦不信息茧房.

在寻求最大社会共识和满足千人千面之间谋取平衡,
在满足广泛涉猎与追求术业专攻之间谋取平衡.

媒介插上人工智能的翅膀将如虎添翼, 与资讯比翼双飞.
新闻爱好者的良心之选, 匠心之作.

UfqiNews presents the hot spots globally, with all interesting points at a glance.
Information is organized here and there is a clear storyline within every single detail.

UfqiNews brings a brand new reading experience, no information overload and no information Cocoons,

In seeking a balance of the maximum social consensus and meeting thousands of people for each interest,
In achieving a balance between satisfying a wide range of hunting and pursuing specialization in the industry.

That media is being born with wings of the artificial intelligence will be even more powerful and the information will fly swifter than ever.

Better choices of newsreaders and the art of work from them.

发表在 UfqiNews有福新闻, 服务器运维, 社会生活, 编程技术, 计算机技术 | 标签为 , , , | 3条评论

得力彩色铅笔油性彩铅学生用专业手绘48色水溶性彩铅笔24色画画笔36色小学生安全无毒水溶款绘画素描儿童铅笔医用外科口罩一次性医疗专用口罩防尘透气成人三层防护透气医生插座保护套儿童防触电插孔安全塞防护盖宝宝婴幼儿插头插座孔插板床上电脑桌大学生宿舍上铺懒人可折叠小桌子家用寝室简约学习书桌