Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537 Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537 欧美综合在线播放,国产精品嫩草影院免费看,日韩精品一区二区三区乱码

          整合營銷服務(wù)商

          電腦端+手機(jī)端+微信端=數(shù)據(jù)同步管理

          免費(fèi)咨詢熱線:

          HTML基礎(chǔ)篇-13文本類表單元素

          HTML基礎(chǔ)篇-13文本類表單元素
          表單是由多個表單元素組合而成的,而表單元素又分很多種類型,文本類的表單元素是使用頻率最高的,但是文本類的表單元素不單是有文本類,還有密碼框,數(shù)字框、電話號碼框等,而這些表單元素各有自己的作用。
          

          標(biāo)

          1. 如何設(shè)置文本類表單元素?

          表單

          表單是用于搜集用戶輸入的信息。而表單是由表單元素組合而成。而根據(jù)表單元素的類型,又分為文本類表單元素、選擇類表單元素、單選類表單元素、多選類表單元素和時間類表單元素等。

          注冊表單

          設(shè)置表單元素

          <input />
          

          文本類表單元素

          概述

          1.1 介紹

          在項(xiàng)目開發(fā)過程中,有很多業(yè)務(wù)模塊的代碼是具有一定規(guī)律性的,例如controller控制器、service接口、service實(shí)現(xiàn)類、mapper接口、model實(shí)體類等等,這部分代碼可以使用代碼生成器生成,我們就可以將更多的時間放在業(yè)務(wù)邏輯上。

          傳統(tǒng)的開發(fā)步驟:

          創(chuàng)建數(shù)據(jù)庫和表 根據(jù)表設(shè)計實(shí)體類 ? 編寫mapper接口 ? 編寫service接口和實(shí)現(xiàn)類 ? 編寫controller控制器 ? 編寫前端頁面 ? 前后端聯(lián)調(diào)

          基于代碼生成器開發(fā)步驟:

          創(chuàng)建數(shù)據(jù)庫和表 ? 使用代碼生成器生成實(shí)體類、mapper、service、controller、前端頁面 ? 將生成好的代碼拷貝到項(xiàng)目中并做調(diào)整 ? 前后端聯(lián)調(diào)

          我們只需要知道數(shù)據(jù)庫和表相關(guān)信息,就可以結(jié)合模版生成各個模塊的代碼,減少了很多重復(fù)工作,也減少出錯概率,提高效率。

          1.2 實(shí)現(xiàn)思路

          (1)需要對數(shù)據(jù)庫表解析獲取到元數(shù)據(jù),包含表字段名稱、字段類型等等

          (2)將通用的代碼編寫成模版文件,部分?jǐn)?shù)據(jù)需使用占位符替換

          (3)將元數(shù)據(jù)和模版文件結(jié)合,使用一些模版引擎工具(例如freemarker)即可生成源代碼文件

          2 Freemarker

          2.1 介紹

          FreeMarker 是一款 模板引擎: 即一種基于模板和要改變的數(shù)據(jù), 并用來生成輸出文本(HTML網(wǎng)頁,電子郵件,配置文件,源代碼等)的通用工具。 它不是面向最終用戶的,而是一個Java類庫,是一款程序員可以嵌入他們所開發(fā)產(chǎn)品的組件。

          模板編寫為FreeMarker Template Language (FTL)。它是簡單的,專用的語言, 在模板中,你可以專注于如何展現(xiàn)數(shù)據(jù), 而在模板之外可以專注于要展示什么數(shù)據(jù)。

          2.2 應(yīng)用場景

          (1)動態(tài)頁面

          freemarker可以作為springmvc一種視圖格式,像jsp一樣被瀏覽器訪問。

          (2)頁面靜態(tài)化

          對于一些內(nèi)容比較多,更新頻率很小,訪問又很頻繁的頁面,可以使用freemarker靜態(tài)化,減少DB的壓力,提高頁面打開速度。

          (3)代碼生成器

          根據(jù)配置生成頁面和代碼,減少重復(fù)工作,提高開發(fā)效率。

          2.3 快速入門

          (1)創(chuàng)建freemarker-demo模塊,并導(dǎo)入相關(guān)依賴

          <?xml version="1.0" encoding="UTF-8"?>
          <project xmlns="http://maven.apache.org/POM/4.0.0"
                   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                   xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
              <modelVersion>4.0.0</modelVersion>
          
              <groupId>com.itheima</groupId>
              <artifactId>freemarker-demo</artifactId>
              <version>1.0-SNAPSHOT</version>
          
              <parent>
                  <groupId>org.springframework.boot</groupId>
                  <artifactId>spring-boot-starter-parent</artifactId>
                  <version>2.3.1.RELEASE</version>
              </parent>
          
              <properties>
                  <maven.compiler.source>8</maven.compiler.source>
                  <maven.compiler.target>8</maven.compiler.target>
              </properties>
          
              <dependencies>
                  <dependency>
                      <groupId>org.springframework.boot</groupId>
                      <artifactId>spring-boot-starter-web</artifactId>
                  </dependency>
                  <dependency>
                      <groupId>org.springframework.boot</groupId>
                      <artifactId>spring-boot-starter-test</artifactId>
                  </dependency>
                  <!-- freemarker -->
                  <dependency>
                      <groupId>org.springframework.boot</groupId>
                      <artifactId>spring-boot-starter-freemarker</artifactId>
                  </dependency>
                  <!-- lombok -->
                  <dependency>
                      <groupId>org.projectlombok</groupId>
                      <artifactId>lombok</artifactId>
                  </dependency>
              </dependencies>
          </project>

          (2)application.yml相關(guān)配置

          server:
            port: 8881 #服務(wù)端口
          spring:
            application:
              name: freemarker-demo #指定服務(wù)名
            freemarker:
              cache: false #關(guān)閉模板緩存,方便測試
              settings:
                template_update_delay: 0 #檢查模板更新延遲時間,設(shè)置為0表示立即檢查,如果時間大于0會有緩存不方便進(jìn)行模板測試
              suffix: .ftl #指定Freemarker模板文件的后綴名

          (3)創(chuàng)建啟動類

          package com.heima.freemarker;
          
          import org.springframework.boot.SpringApplication;
          import org.springframework.boot.autoconfigure.SpringBootApplication;
          
          @SpringBootApplication
          public class FreemarkerDemotApplication {
              public static void main(String[] args) {
                  SpringApplication.run(FreemarkerDemotApplication.class,args);
              }
          }

          (4)創(chuàng)建Student模型類

          package com.itheima.freemarker.entity;
          
          import lombok.AllArgsConstructor;
          import lombok.Data;
          import lombok.NoArgsConstructor;
          
          import java.util.Date;
          
          @Data
          @NoArgsConstructor
          @AllArgsConstructor
          public class Student {
              private Integer id;
              private String name;//姓名
              private Integer age;//年齡
              private Date birthday;//生日
              private Float money;//錢包
          }

          (5)創(chuàng)建StudentController

          package com.itheima.freemarker.controller;
          
          import com.itheima.freemarker.entity.Student;
          import org.springframework.stereotype.Controller;
          import org.springframework.ui.Model;
          import org.springframework.web.bind.annotation.GetMapping;
          import org.springframework.web.bind.annotation.RequestMapping;
          
          import java.util.Date;
          
          @Controller
          @RequestMapping("student")
          public class StudentController {
          
              @GetMapping("index")
              public String index(Model model){
                  //1.純文本形式的參數(shù)
                  model.addAttribute("name", "Freemarker");
          
                  //2.實(shí)體類相關(guān)的參數(shù)
                  Student student=new Student();
                  student.setName("黑馬");
                  student.setAge(18);
                  model.addAttribute("stu", student);
          
                  return "01-index";
              }
          }

          (6)在resources/templates下創(chuàng)建01-index.ftl模版文件

          <!DOCTYPE html>
          <html>
          <head>
              <meta charset="utf-8">
              <title>首頁</title>
          </head>
          <body>
          <b>普通文本 String 展示:</b><br/>
          Hello ${name} <br>
          
          <hr>
          <b>對象Student中的數(shù)據(jù)展示:</b><br/>
          姓名:${stu.name}<br/>
          年齡:${stu.age}
          <hr>
          </body>
          </html>

          (7)測試

          瀏覽器訪問 http://localhost:8881/student/index

          效果如下

          2.4 模版

          2.4.1 基礎(chǔ)語法種類

          (1)注釋,即<#-- -->,介于其之間的內(nèi)容會被freemarker忽略

          <#--我是一個freemarker注釋-->

          (2)插值(Interpolation):即 ${..} 部分,freemarker會用真實(shí)的值代替${..}

          Hello ${name}

          (3)FTL指令:和HTML標(biāo)記類似,名字前加#予以區(qū)分,F(xiàn)reemarker會解析標(biāo)簽中的表達(dá)式或邏輯。

          <# >FTL指令</#> 

          (4)文本,僅文本信息,這些不是freemarker的注釋、插值、FTL指令的內(nèi)容會被freemarker忽略解析,直接輸出內(nèi)容。

          <#--freemarker中的普通文本-->
          我是一個普通的文本

          2.4.2 if指令

          if 指令即判斷指令,是常用的FTL指令,freemarker在解析時遇到if會進(jìn)行判斷,條件為真則輸出if中間的內(nèi)容,否則跳過內(nèi)容不再輸出。

          格式如下

          <#if condition>
            ....
          <#elseif condition2>
            ...
          <#elseif condition3>   
            ...
          <#else>
            ...
          </#if>

          需求:根據(jù)年齡輸出所處的年齡段

          童年:0歲—6歲(周歲,下同) 少年:7歲—17歲 青年:18歲—40歲 中年:41—65歲 老年:66歲以后

          實(shí)例代碼:

          (1)在01-index.ftl添加如下代碼

          <#if stu.age <=6>
          童年
          <#elseif stu.age <=17>
          少年
          <#elseif stu.age <=40>   
          青年
          <#elseif stu.age <=65>   
          中年
          <#else>
          老年
          </#if>

          (2)測試

          瀏覽器訪問http://localhost:8881/student/index

          效果如下

          2.4.3 list指令

          list指令時一個迭代輸出指令,用于迭代輸出數(shù)據(jù)模型中的集合

          格式如下

          <#list items as item>
              ${item_index + 1}------${item}-----<#if item_has_next>,</#if>
          </#list>

          迭代集合對象時,包括兩個特殊的循環(huán)變量: (1)item_index:當(dāng)前變量的索引值。 (2)item_has_next:是否存在下一個對象

          item_index 和 item_has_nex 中的item為<#list items as item> 中as后面的臨時變量

          需求:遍歷學(xué)生集合,輸出序號,學(xué)生id,姓名,所處的年齡段,是否最后一條數(shù)據(jù)

          (1)在StudentController中增加方法

          @GetMapping("list")
          public String list(Model model) throws ParseException {
              List<Student> list=new ArrayList<>();
          
              list.add(new Student(1001,"張飛",15, null, 1000.11F));
              list.add(new Student(1002,"劉備",28, null, 5000.3F));
              list.add(new Student(1003,"關(guān)羽",45, null, 9000.63F));
              list.add(new Student(1004,"諸葛亮",62, null, 10000.99F));
              list.add(new Student(1005,"成吉思汗",75, null, 16000.66F));
              model.addAttribute("stus",list);
          
              return "02-list";
          }

          (2)在resources/templates目錄下創(chuàng)建02-list.ftl模版

          <!DOCTYPE html>
          <html>
          <head>
              <meta charset="utf-8">
              <title>列表頁面</title>
              <style>
                  table{
                      border-spacing: 0;/*把單元格間隙設(shè)置為0*/
                      border-collapse: collapse;/*設(shè)置單元格的邊框合并為1*/
                  }
                  td{
                      border:1px solid #ACBED1;
                      text-align: center;
                  }
              </style>
          </head>
          <body>
          
          <table>
              <tr>
                  <td>序號</td>
                  <td>id</td>
                  <td>姓名</td>
                  <td>所處的年齡段</td>
                  <td>生日</td>
                  <td>錢包</td>
                  <td>是否最后一條數(shù)據(jù)</td>
              </tr>
              <#list stus as stu >
                  <tr>
                      <td>${stu_index + 1}</td>
                      <td>${stu.id}</td>
                      <td>${stu.name}</td>
                      <td>
                          <#if stu.age <=6>
                              童年
                          <#elseif stu.age <=17>
                              少年
                          <#elseif stu.age <=40>   
                              青年
                          <#elseif stu.age <=65>   
                              中年
                          <#else>
                              老年
                          </#if>
                      </td>
                      <td></td>
                      <td>${stu.money}</td>
                      <td>
                          <#if stu_has_next>
                          否
                          <#else>
                          是
                          </#if>
                      </td>
                  </tr>
              </#list>
          </table>
          
          <hr>
          </body>
          </html>

          (2)測試

          瀏覽器訪問http://localhost:8881/student/list

          效果如下

          2.4.4 include指令

          include指令的作用類似于JSP的包含指令,用于包含指定頁,include指令的語法格式如下

          <#include filename [options]></#include>

          (1)filename:該參數(shù)指定被包含的模板文件 (2)options:該參數(shù)可以省略,指定包含時的選項(xiàng),包含encoding和parse兩個選項(xiàng),encoding 指定包含頁面時所使用的解碼集,而parse指定被包含是否作為FTL文件來解析。如果省略了parse選項(xiàng)值,則該選項(xiàng)值默認(rèn)是true

          需求:"早上好,尊敬的 某某 用戶!" 這句話在很多頁面都有用到,請合理設(shè)計!

          (1)在resources/templates目錄下創(chuàng)建00-head.ftl模版,內(nèi)容如下

          早上好,尊敬的 ${name} 用戶!

          (2)在resources/templates目錄下創(chuàng)建03-include.ftl模版,使用include引入00-head.ftl模版,內(nèi)容如下

          <!DOCTYPE html>
          <html>
          <head>
              <meta charset="utf-8">
              <title>詳情頁</title>
          </head>
          <body>
          
          <#include "00-head.ftl" />
          <br>
          歡迎來到黑馬程序員。
          
          </body>
          </html>

          (3)在StudentController中增加方法

          @GetMapping("include")
          public String include(Model model) throws ParseException {
          model.addAttribute("name", "黑馬");
          return "03-include";
          }

          (4)測試

          瀏覽器訪問http://localhost:8881/student/include

          效果如下

          2.4.5 assign指令

          它用于為該模板頁面創(chuàng)建或替換一個頂層變量

          <#assign name="zhangsan" />

          2.4.6 運(yùn)算符

          (1)算數(shù)運(yùn)算符

          FreeMarker表達(dá)式中完全支持算術(shù)運(yùn)算,FreeMarker支持的算術(shù)運(yùn)算符包括:

          • 加法: +
          • 減法: -
          • 乘法: *
          • 除法: /
          • 求模 (求余): %

          (2)比較運(yùn)算符

          • =或者==:判斷兩個值是否相等.
          • !=:判斷兩個值是否不等.
          • >或者gt:判斷左邊值是否大于右邊值
          • >=或者gte:判斷左邊值是否大于等于右邊值
          • <或者lt:判斷左邊值是否小于右邊值
          • <=或者lte:判斷左邊值是否小于等于右邊值

          比較運(yùn)算符注意

          • =!=可以用于字符串、數(shù)值和日期來比較是否相等
          • =!=兩邊必須是相同類型的值,否則會產(chǎn)生錯誤
          • 字符串 "x""x ""X"比較是不等的.因?yàn)镕reeMarker是精確比較
          • 其它的運(yùn)行符可以作用于數(shù)字和日期,但不能作用于字符串
          • 使用gt等字母運(yùn)算符代替>會有更好的效果,因?yàn)?FreeMarker會把>解釋成FTL標(biāo)簽的結(jié)束字符
          • 可以使用括號來避免這種情況,如:<#if (x>y)>

          (3)邏輯運(yùn)算符

          • 邏輯與:&&
          • 邏輯或:||
          • 邏輯非:!

          邏輯運(yùn)算符只能作用于布爾值,否則將產(chǎn)生錯誤 。

          2.4.7 空值處理

          (1)缺失變量默認(rèn)值使用 “!”

          • 使用!要以指定一個默認(rèn)值,當(dāng)變量為空時顯示默認(rèn)值
          • 例: ${name!''}表示如果name為空顯示空字符串。
          • 如果是嵌套對象則建議使用()括起來
          • 例: ${(stu.bestFriend.name)!''}表示,如果stu或bestFriend或name為空默認(rèn)顯示空字符串。

          (2)判斷某變量是否存在使用 “??”

          用法為:variable??,如果該變量存在,返回true,否則返回false

          例:為防止stus為空報錯可以加上判斷如下:

              <#if stus??>
                  <#list stus as stu>
                      ......
                  </#list>
              </#if>

          2.4.8 內(nèi)建函數(shù)

          內(nèi)建函數(shù)語法格式: 變量+?+函數(shù)名稱

          (1)求集合的大小

          ${集合名?size}

          (2)日期格式化

          顯示年月日: ${today?date} 顯示時分秒:${today?time} 顯示日期+時間:${today?datetime} 自定義格式化: ${today?string("yyyy年MM月")}

          (3)內(nèi)建函數(shù)c

          model.addAttribute("point", 102920122);

          point是數(shù)字型,使用${point}會顯示這個數(shù)字的值,每三位使用逗號分隔。

          如果不想顯示為每三位分隔的數(shù)字,可以使用c函數(shù)將數(shù)字型轉(zhuǎn)成字符串輸出

          ${point?c}

          (4)將json字符串轉(zhuǎn)成對象

          一個例子:

          其中用到了 assign標(biāo)簽,assign的作用是定義一個變量。

          <#assign text="{'bank':'工商銀行','account':'10101920201920212'}" />
          <#assign data=text?eval />
          開戶行:${data.bank}  賬號:${data.account}

          (5)常見內(nèi)建函數(shù)匯總

          ?html:html字符轉(zhuǎn)義
          ?cap_first: 字符串的第一個字母變?yōu)榇髮懶问?
          ?lower_case :字符串的小寫形式
          ?upper_case :字符串的大寫形式
          ?trim:去掉字符串首尾的空格
          ?substring(from,to):截字符串  from是第一個字符的開始索引,to最后一個字符之后的位置索引,當(dāng)to為空時,默認(rèn)的是字符串的長度
          ?lenth: 取長度
          ?size: 序列中元素的個數(shù)
          ?int: 數(shù)字的整數(shù)部分(比如 -1.9?int 就是 -1)
          ?replace(param1,param2):字符串替換  param1是匹配的字符串 param2是將匹配的字符替換成指定字符

          內(nèi)建函數(shù)測試demo1

          (1)在StudentController新增方法:

          @GetMapping("innerFunc")
          public String testInnerFunc(Model model) {
              //1.1 小強(qiáng)對象模型數(shù)據(jù)
              Student stu1=new Student();
              stu1.setName("小強(qiáng)");
              stu1.setAge(18);
              stu1.setMoney(1000.86f);
              stu1.setBirthday(new Date());
              //1.2 小紅對象模型數(shù)據(jù)
              Student stu2=new Student();
              stu2.setName("小紅");
              stu2.setMoney(200.1f);
              stu2.setAge(19);
              //1.3 將兩個對象模型數(shù)據(jù)存放到List集合中
              List<Student> stus=new ArrayList<>();
              stus.add(stu1);
              stus.add(stu2);
              model.addAttribute("stus", stus);
              // 2.1 添加日期
              Date date=new Date();
              model.addAttribute("today", date);
              // 3.1 添加數(shù)值
              model.addAttribute("point", 102920122);
              return "04-innerFunc";
          }

          (2)在resources/templates目錄下創(chuàng)建04-innerFunc.ftl模版頁面:

          <!DOCTYPE html>
          <html>
          <head>
              <meta charset="utf-8">
              <title>inner Function</title>
          </head>
          <body>
          
              <b>獲得集合大小</b><br>
          
              集合大小:${stus?size}
              <hr>
          
          
              <b>獲得日期</b><br>
          
              顯示年月日: ${today?date}       <br>
          
              顯示時分秒:${today?time}<br>
          
              顯示日期+時間:${today?datetime}<br>
          
              自定義格式化:  ${today?string("yyyy年MM月")}<br>
          
              <hr>
          
              <b>內(nèi)建函數(shù)C</b><br>
              沒有C函數(shù)顯示的數(shù)值:${point} <br>
          
              有C函數(shù)顯示的數(shù)值:${point?c}
          
              <hr>
          
              <b>聲明變量assign</b><br>
              <#assign text="{'bank':'工商銀行','account':'10101920201920212'}" />
              <#assign data=text?eval />
              開戶行:${data.bank}  賬號:${data.account}
          
          <hr>
          </body>
          </html>

          (3)測試

          瀏覽器訪問http://localhost:8881/student/innerFunc

          效果如下

          內(nèi)建函數(shù)測試demo2

          需求:遍歷學(xué)生集合,顯示集合總條數(shù),id不要逗號隔開,顯示學(xué)生的生日(只顯示年月日),錢包顯示整數(shù)并顯示單位,用戶姓名做脫敏處理(如果是兩個字第二個字顯示為星號,例如張三顯示為張*,如果大于兩個字,中間字顯示為星號,例如成吉思汗顯示為成*汗,諸葛亮顯示為諸*亮

          (1)修改StudentController中的list方法,

          @GetMapping("list")
          public String list(Model model) throws ParseException {
              DateFormat dateFormat=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
              List<Student> list=new ArrayList<>();
          
              list.add(new Student(1001,"張三",15, dateFormat.parse("2007-10-01 10:00:00"), 1000.11F));
              list.add(new Student(1002,"李四",28, dateFormat.parse("1994-10-01 10:00:00"), 5000.3F));
              list.add(new Student(1003,"王五",45, dateFormat.parse("1977-10-01 10:00:00"), 9000.63F));
              list.add(new Student(1004,"趙六",62, dateFormat.parse("1960-10-01 10:00:00"), 10000.99F));
              list.add(new Student(1005,"孫七",75, dateFormat.parse("1947-10-01 10:00:00"), 16000.66F));
              model.addAttribute("stus",list);
          
              return "02-list";
          }

          (2)修改02-list.ftl模版

          共${stus?size}條數(shù)據(jù):輸出總條數(shù)

          stu.id后面加?c:id不需要逗號分割

          stu.birthday后面加?date:生日只輸出年月日

          stu.money后面加?int:金額取整

          姓名需要使用replace和substring函數(shù)處理

          完整內(nèi)容如下

          <!DOCTYPE html>
          <html>
          <head>
              <meta charset="utf-8">
              <title>列表頁面</title>
              <style>
                  table{
                      border-spacing: 0;/*把單元格間隙設(shè)置為0*/
                      border-collapse: collapse;/*設(shè)置單元格的邊框合并為1*/
                  }
                  td{
                      border:1px solid #ACBED1;
                      text-align: center;
                  }
              </style>
          </head>
          <body>
          共${stus?size}條數(shù)據(jù)
          <table>
              <tr>
                  <td>序號</td>
                  <td>id</td>
                  <td>姓名</td>
                  <td>所處的年齡段</td>
                  <td>生日</td>
                  <td>錢包</td>
                  <td>是否最后一條數(shù)據(jù)</td>
              </tr>
              <#list stus as stu >
                  <tr>
                      <td>${stu_index + 1}</td>
                      <td>${stu.id?c}</td>
                      <td>
                          <#if stu.name?length=2>
                              ${stu.name?replace(stu.name?substring(1), "*")}
                          <#else>
                              ${stu.name?replace(stu.name?substring(1, stu.name?length-1), "*")}
                          </#if>
                      </td>
                      <td>
                          <#if stu.age <=6>
                              童年
                          <#elseif stu.age <=17>
                              少年
                          <#elseif stu.age <=40>   
                              青年
                          <#elseif stu.age <=65>   
                              中年
                          <#else>
                              老年
                          </#if>
                      </td>
                      <td>${stu.birthday?date}</td>
                      <td>${stu.money?int}元</td>
                      <td>
                          <#if stu_has_next>
                          否
                          <#else>
                          是
                          </#if>
                      </td>
                  </tr>
              </#list>
          </table>
          
          <hr>
          </body>
          </html>

          (3)測試

          瀏覽器訪問http://localhost:8881/student/list

          效果如下

          2.4.9 靜態(tài)化

          (1)springboot整合freemarker靜態(tài)化文件用法

          編寫springboot測試用例

          package com.itheima.test;
          
          import com.itheima.freemarker.FreemarkerDemoApplication;
          import com.itheima.freemarker.entity.Student;
          import freemarker.template.Configuration;
          import freemarker.template.Template;
          import freemarker.template.TemplateException;
          import org.junit.Test;
          import org.junit.runner.RunWith;
          import org.springframework.beans.factory.annotation.Autowired;
          import org.springframework.boot.test.context.SpringBootTest;
          import org.springframework.test.context.junit4.SpringRunner;
          
          import java.io.FileWriter;
          import java.io.IOException;
          import java.util.*;
          
          @SpringBootTest(classes=FreemarkerDemoApplication.class)
          @RunWith(SpringRunner.class)
          public class FreemarkerTest {
          
              //注入freemarker配置類
              @Autowired
              private Configuration configuration;
          
              @Test
              public void test() throws IOException, TemplateException {
                  Template template=configuration.getTemplate("04-innerFunc.ftl");
                  /**
                   * 靜態(tài)化并輸出到文件中   參數(shù)1:數(shù)據(jù)模型     參數(shù)2:文件輸出流
                   */
                  template.process(getData(), new FileWriter("d:/list.html"));
                  /**
                   * 靜態(tài)化并輸出到字節(jié)輸出流中
                   */
                  //StringWriter out=new StringWriter();
                  //template.process(getData(), out);
                  //System.out.println(out.toString());
              }
          
          
              private Map getData(){
          
                  Map<String,Object> map=new HashMap<>();
          
                  Student stu1=new Student();
                  stu1.setName("小強(qiáng)");
                  stu1.setAge(18);
                  stu1.setMoney(1000.86f);
                  stu1.setBirthday(new Date());
          
                  //小紅對象模型數(shù)據(jù)
                  Student stu2=new Student();
                  stu2.setName("小紅");
                  stu2.setMoney(200.1f);
                  stu2.setAge(19);
          
                  //將兩個對象模型數(shù)據(jù)存放到List集合中
                  List<Student> stus=new ArrayList<>();
                  stus.add(stu1);
                  stus.add(stu2);
          
                  //向model中存放List集合數(shù)據(jù)
                  map.put("stus",stus);
          
          
                  //map數(shù)據(jù)
                  Map<String,Student> stuMap=new HashMap<>();
                  stuMap.put("stu1",stu1);
                  stuMap.put("stu2",stu2);
          
                  map.put("stuMap",stuMap);
                  //日期
                  map.put("today",new Date());
          
                  //長數(shù)值
                  map.put("point",38473897438743L);
          
                  return map;
          
              }
          }

          (2)freemarker原生靜態(tài)化用法

          package com.itheima.freemarker.test;
          
          import com.itheima.freemarker.entity.Student;
          import freemarker.cache.FileTemplateLoader;
          import freemarker.cache.NullCacheStorage;
          import freemarker.template.Configuration;
          import freemarker.template.Template;
          import freemarker.template.TemplateException;
          import freemarker.template.TemplateExceptionHandler;
          
          import java.io.File;
          import java.io.FileWriter;
          import java.io.IOException;
          import java.util.*;
          
          public class FreemarkerTest {
          
              public static void main(String[] args) throws IOException, TemplateException {
                  //創(chuàng)建配置類
                  Configuration CONFIGURATION=new Configuration(Configuration.VERSION_2_3_22);
                  //設(shè)置模版加載路徑
          
                  //ClassTemplateLoader方式:需要將模版放在FreemarkerTest類所在的包,加載模版時會從該包下加載
                  //CONFIGURATION.setTemplateLoader(new ClassTemplateLoader(FreemarkerTest.class,""));
          
                  String path=java.net.URLDecoder.decode(FreemarkerTest.class.getClassLoader().getResource("").getPath(),"utf-8");
                  //FileTemplateLoader方式:需要將模版放置在classpath目錄下 目錄有中文也可以
                  CONFIGURATION.setTemplateLoader(new FileTemplateLoader(new File(path)));
          
                  //設(shè)置編碼
                  CONFIGURATION.setDefaultEncoding("UTF-8");
                  //設(shè)置異常處理器
                  CONFIGURATION.setTemplateExceptionHandler(TemplateExceptionHandler.RETHROW_HANDLER);
                  //設(shè)置緩存方式
                  CONFIGURATION.setCacheStorage(NullCacheStorage.INSTANCE);
                  //加載模版
                  Template template=CONFIGURATION.getTemplate("templates/04-innerFunc.ftl");
                  /**
                   * 靜態(tài)化并輸出到文件中   參數(shù)1:數(shù)據(jù)模型     參數(shù)2:文件輸出流
                   */
                  template.process(getModel(), new FileWriter("d:/list.html"));
                  /**
                   * 靜態(tài)化并輸出到字節(jié)輸出流中
                   */
                  //StringWriter out=new StringWriter();
                  //template.process(getData(), out);
                  //System.out.println(out.toString());
              }
          
          
              public static Map getModel(){
                  Map map=new HashMap();
                  //1.1 小強(qiáng)對象模型數(shù)據(jù)
                  Student stu1=new Student();
                  stu1.setName("小強(qiáng)");
                  stu1.setAge(18);
                  stu1.setMoney(1000.86f);
                  stu1.setBirthday(new Date());
                  //1.2 小紅對象模型數(shù)據(jù)
                  Student stu2=new Student();
                  stu2.setName("小紅");
                  stu2.setMoney(200.1f);
                  stu2.setAge(19);
                  //1.3 將兩個對象模型數(shù)據(jù)存放到List集合中
                  List<Student> stus=new ArrayList<>();
                  stus.add(stu1);
                  stus.add(stu2);
                  map.put("stus", stus);
                  // 2.1 添加日期
                  Date date=new Date();
                  map.put("today", date);
                  // 3.1 添加數(shù)值
                  map.put("point", 102920122);
                  return map;
              }
          }

          3 數(shù)據(jù)庫元數(shù)據(jù)

          3.1 介紹

          元數(shù)據(jù)(Metadata)是描述數(shù)據(jù)的數(shù)據(jù)。

          數(shù)據(jù)庫元數(shù)據(jù)(DatabaseMetaData)就是指定義數(shù)據(jù)庫各類對象結(jié)構(gòu)的數(shù)據(jù)。

          在mysql中可以通過show關(guān)鍵字獲取相關(guān)的元數(shù)據(jù)

          show status; 獲取數(shù)據(jù)庫的狀態(tài)
          show databases; 列出所有數(shù)據(jù)庫
          show tables; 列出所有表
          show create database [數(shù)據(jù)庫名]; 獲取數(shù)據(jù)庫的定義
          show create table [數(shù)據(jù)表名]; 獲取數(shù)據(jù)表的定義
          show columns from <table_name>; 顯示表的結(jié)構(gòu)
          show index from <table_name>; 顯示表中有關(guān)索引和索引列的信息
          show character set; 顯示可用的字符集以及其默認(rèn)整理
          show collation; 顯示每個字符集的整理
          show variables; 列出數(shù)據(jù)庫中的參數(shù)定義值

          也可以從 information_schema庫中獲取元數(shù)據(jù),information_schema數(shù)據(jù)庫是MySQL自帶的信息數(shù)據(jù)庫,它提供了訪問數(shù)據(jù)庫元數(shù)據(jù)的方式。存著其他數(shù)據(jù)庫的信息。

          select schema_name from information_schema.schemata; 列出所有的庫
          select table_name FROM information_schema.tables; 列出所有的表

          在代碼中可以由JDBC的Connection對象通過getMetaData方法獲取而來,主要封裝了是對數(shù)據(jù)庫本身的一些整體綜合信息,例如數(shù)據(jù)庫的產(chǎn)品名稱,數(shù)據(jù)庫的版本號,數(shù)據(jù)庫的URL,是否支持事務(wù)等等。

          DatabaseMetaData的常用方法:

          getDatabaseProductName:獲取數(shù)據(jù)庫的產(chǎn)品名稱
          getDatabaseProductName:獲取數(shù)據(jù)庫的版本號
          getUserName:獲取數(shù)據(jù)庫的用戶名
          getURL:獲取數(shù)據(jù)庫連接的URL
          getDriverName:獲取數(shù)據(jù)庫的驅(qū)動名稱
          driverVersion:獲取數(shù)據(jù)庫的驅(qū)動版本號
          isReadOnly:查看數(shù)據(jù)庫是否只允許讀操作
          supportsTransactions:查看數(shù)據(jù)庫是否支持事務(wù)

          3.2 搭建環(huán)境

          (1)導(dǎo)入mysql依賴

          <dependency>
              <groupId>mysql</groupId>
              <artifactId>mysql-connector-java</artifactId>
              <version>5.1.47</version>
          </dependency>

          (2)創(chuàng)建測試用例

          package com.itheima.test;
          
          import org.junit.Before;
          import org.junit.Test;
          
          import java.sql.*;
          import java.util.Properties;
          
          public class DataBaseMetaDataTest {
              private Connection conn;
          
              @Before
              public void init() throws Exception {
                  Properties pro=new Properties();
                  pro.setProperty("user", "root");
                  pro.setProperty("password", "123456");
                  pro.put("useInformationSchema", "true");//獲取mysql表注釋
                  //pro.setProperty("remarksReporting","true");//獲取oracle表注釋
                  conn=DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/?useUnicode=true&characterEncoding=UTF8", pro);
              }   
          }

          3.3 綜合信息元數(shù)據(jù)

          (1)獲取數(shù)據(jù)庫元信息綜合信息

          @Test
          public void testDatabaseMetaData() throws SQLException {
              //獲取數(shù)據(jù)庫元數(shù)據(jù)
              DatabaseMetaData dbMetaData=conn.getMetaData();
              //獲取數(shù)據(jù)庫產(chǎn)品名稱
              String productName=dbMetaData.getDatabaseProductName();
              System.out.println(productName);
              //獲取數(shù)據(jù)庫版本號
              String productVersion=dbMetaData.getDatabaseProductVersion();
              System.out.println(productVersion);
              //獲取數(shù)據(jù)庫用戶名
              String userName=dbMetaData.getUserName();
              System.out.println(userName);
              //獲取數(shù)據(jù)庫連接URL
              String userUrl=dbMetaData.getURL();
              System.out.println(userUrl);
              //獲取數(shù)據(jù)庫驅(qū)動
              String driverName=dbMetaData.getDriverName();
              System.out.println(driverName);
              //獲取數(shù)據(jù)庫驅(qū)動版本號
              String driverVersion=dbMetaData.getDriverVersion();
              System.out.println(driverVersion);
              //查看數(shù)據(jù)庫是否允許讀操作
              boolean isReadOnly=dbMetaData.isReadOnly();
              System.out.println(isReadOnly);
              //查看數(shù)據(jù)庫是否支持事務(wù)操作
              boolean supportsTransactions=dbMetaData.supportsTransactions();
              System.out.println(supportsTransactions);
          }

          (2)獲取數(shù)據(jù)庫列表

          @Test
          public void testFindAllCatalogs() throws Exception {
              //獲取元數(shù)據(jù)
              DatabaseMetaData metaData=conn.getMetaData();
              //獲取數(shù)據(jù)庫列表
              ResultSet rs=metaData.getCatalogs();
              //遍歷獲取所有數(shù)據(jù)庫表
              while (rs.next()) {
                  //打印數(shù)據(jù)庫名稱
                  System.out.println(rs.getString(1));
              }
              //釋放資源
              rs.close();
              conn.close();
          }

          (3)獲取某數(shù)據(jù)庫中的所有表信息

          @Test
          public void testFindAllTable() throws Exception {
              //獲取元數(shù)據(jù)
              DatabaseMetaData metaData=conn.getMetaData();
              //獲取所有的數(shù)據(jù)庫表信息
              ResultSet rs=metaData.getTables("庫名", "%", "%", new String[]{"TABLE"});
              //拼裝table
              while (rs.next()) {
                  //所屬數(shù)據(jù)庫
                  System.out.println(rs.getString(1));
                  //所屬schema
                  System.out.println(rs.getString(2));
                  //表名
                  System.out.println(rs.getString(3));
                  //數(shù)據(jù)庫表類型
                  System.out.println(rs.getString(4));
                  //數(shù)據(jù)庫表備注
                  System.out.println(rs.getString(5));
                  System.out.println("--------------");
              }
          }

          (4)獲取某張表所有的列信息

          @Test
          public void testFindAllColumns() throws Exception {
              //獲取元數(shù)據(jù)
              DatabaseMetaData metaData=conn.getMetaData();
              //獲取所有的數(shù)據(jù)庫某張表所有列信息
              ResultSet rs=metaData.getColumns("庫名", "%", "表名","%");
          
              while(rs.next()) {
                  //表名
                  System.out.println(rs.getString("TABLE_NAME"));
                  //列名
                  System.out.println(rs.getString("COLUMN_NAME"));
                  //類型碼值
                  System.out.println(rs.getString("DATA_TYPE"));
                  //類型名稱
                  System.out.println(rs.getString("TYPE_NAME"));
                  //列的大小
                  System.out.println(rs.getString("COLUMN_SIZE"));
                  //小數(shù)部分位數(shù),不適用的類型會返回null
                  System.out.println(rs.getString("DECIMAL_DIGITS"));
                  //是否允許使用null
                  System.out.println(rs.getString("NULLABLE"));
                  //列的注釋信息
                  System.out.println(rs.getString("REMARKS"));
                  //默認(rèn)值
                  System.out.println(rs.getString("COLUMN_DEF"));
                  //是否自增
                  System.out.println(rs.getString("IS_AUTOINCREMENT"));
                  //表中的列的索引(從 1 開始
                  System.out.println(rs.getString("ORDINAL_POSITION"));
                  System.out.println("--------------");
              }
          }

          3.4 參數(shù)元數(shù)據(jù)

          參數(shù)元數(shù)據(jù)(ParameterMetaData):是由PreparedStatement對象通過getParameterMetaData方法獲取而 來,主要是針對PreparedStatement對象和其預(yù)編譯的SQL命令語句提供一些信息,ParameterMetaData能提供占位符參數(shù)的個數(shù),獲取指定位置占位符的SQL類型等等 以下有一些關(guān)于ParameterMetaData的常用方法:

          getParameterCount:獲取預(yù)編譯SQL語句中占位符參數(shù)的個數(shù)
          @Test
          public void testParameterMetaData() throws Exception {
              String sql="select * from health.t_checkgroup where id=? and code=?";
              PreparedStatement pstmt=conn.prepareStatement(sql);
              pstmt.setString(1, "7");
              pstmt.setString(2, "0003");
              //獲取ParameterMetaData對象
              ParameterMetaData paramMetaData=pstmt.getParameterMetaData();
              //獲取參數(shù)個數(shù)
              int paramCount=paramMetaData.getParameterCount();
              System.out.println(paramCount);
          }

          3.5 結(jié)果集元數(shù)據(jù)

          結(jié)果集元數(shù)據(jù)(ResultSetMetaData):是由ResultSet對象通過getMetaData方法獲取而來,主要是針對由數(shù)據(jù)庫執(zhí)行的SQL腳本命令獲取的結(jié)果集對象ResultSet中提供的一些信息,比如結(jié)果集中的列數(shù)、指定列的名稱、指 定列的SQL類型等等,可以說這個是對于框架來說非常重要的一個對象。 以下有一些關(guān)于ResultSetMetaData的常用方法:

          getColumnCount:獲取結(jié)果集中列項(xiàng)目的個數(shù)
          getColumnType:獲取指定列的SQL類型對應(yīng)于Java中Types類的字段
          getColumnTypeName:獲取指定列的SQL類型
          getClassName:獲取指定列SQL類型對應(yīng)于Java中的類型(包名加類名
          @Test
          public void testResultSetMetaData() throws Exception {
              String sql="select * from health.t_checkgroup where id=?";
              PreparedStatement pstmt=conn.prepareStatement(sql);
              pstmt.setString(1, "7");
              //執(zhí)行sql語句
              ResultSet rs=pstmt.executeQuery();
              //獲取ResultSetMetaData對象
              ResultSetMetaData metaData=rs.getMetaData();
              //獲取查詢字段數(shù)量
              int columnCount=metaData.getColumnCount();
              System.out.println("字段總數(shù)量:"+ columnCount);
              for (int i=1; i <=columnCount; i++) {
                  //獲取表名稱
                  System.out.println(metaData.getColumnName(i));
                  //獲取java類型
                  System.out.println(metaData.getColumnClassName(i));
                  //獲取sql類型
                  System.out.println(metaData.getColumnTypeName(i));
                  System.out.println("----------");
              }
          }

          4 代碼生成器環(huán)境搭建

          4.1 創(chuàng)建maven工程

          創(chuàng)建maven工程并導(dǎo)入以下依賴

          <properties>
              <java.version>11</java.version>
              <!-- 項(xiàng)目源碼及編譯輸出的編碼 -->
              <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
              <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
              <!-- 項(xiàng)目編譯JDK版本 -->
              <maven.compiler.source>11</maven.compiler.source>
              <maven.compiler.target>11</maven.compiler.target>
          </properties>
          
          <dependencies>
              <dependency>
                  <groupId>org.freemarker</groupId>
                  <artifactId>freemarker</artifactId>
                  <version>2.3.23</version>
              </dependency>
              <dependency>
                  <groupId>mysql</groupId>
                  <artifactId>mysql-connector-java</artifactId>
                  <version>5.1.47</version>
              </dependency>
              <dependency>
                  <groupId>org.projectlombok</groupId>
                  <artifactId>lombok</artifactId>
                  <version>1.18.8</version>
              </dependency>
              <dependency>
                  <groupId>org.apache.commons</groupId>
                  <artifactId>commons-lang3</artifactId>
                  <version>3.10</version>
              </dependency>
          </dependencies>

          目錄結(jié)構(gòu)如下

          譯局是36氪旗下編譯團(tuán)隊(duì),關(guān)注科技、商業(yè)、職場、生活等領(lǐng)域,重點(diǎn)介紹國外的新技術(shù)、新觀點(diǎn)、新風(fēng)向。

          編者按:Marc Andreessen十年前說的“軟件蠶食世界”不僅完全正確,而且似乎不僅如此:軟件正在重塑世界。人類世界的運(yùn)轉(zhuǎn)已經(jīng)無法離開軟件。在浩如煙海的軟件代碼當(dāng)中,哪些對我們起到了關(guān)鍵作用呢?Slate網(wǎng)站邀請了各方人士對那些改變了一切的代碼進(jìn)行評選,這里篩選出36個代碼片段。如果你有更好的選項(xiàng),不妨在評論區(qū)留下你的意見。原文作者是Future Tense,標(biāo)題是:The Lines of Code That Changed Everything。鑒于篇幅太長,我們將分三部分刊出,此為第二部分。

          人類歷史上最重要的36個代碼片段(一)

          13、多人在線交談系統(tǒng)(IRC)

          年代:1988

          在網(wǎng)上閑逛的起源

          /join #cats

          Internet Relay Chat(一般簡稱IRC)的歷史很早,甚至在大部分人不能告訴你互聯(lián)網(wǎng)是什么的時候就有了。這是第一種流行的在群組頻道內(nèi)跟他人實(shí)時聊天的手段。早期用戶會登錄上去分享消息,比方說1991年蘇聯(lián)發(fā)生一起政變期間曾進(jìn)行了媒體管制。聊天本身也需要輸入一些代碼:比方說,要加入頻道,你得輸入“/ join #[ 頻道名稱]。”(對于今天玩Slack上癮的人來說會很熟悉。)如果你想表達(dá)一些關(guān)于自己的信息,可以輸入“/ me太累了”,它就會顯示你的名字加上星號加上“太累了。”功能很基礎(chǔ),但是對于很多人來說,這是他們用計算機(jī)命令畫出的第一筆,并且是加入談話的門票。——April Glaser, Slate

          14、莫里斯蠕蟲

          年代:1988

          讓人意識到互聯(lián)網(wǎng)已經(jīng)變得有多龐大的一盆冷水

          checkother /* 0x57d0 */

          {

          int s, l8, l12, l16, optval;

          struct sockaddr_in sin; /* 16 bytes */

          optval=1;

          if ((random % 7)==3)

          return; /* 612 */

          s=socket(AF_INET, SOCK_STREAM, 0);

          if (s return;

          這是莫里斯蠕蟲代碼關(guān)鍵功能的摘錄。Robert Morris,計算機(jī)歷史博物館和Arialdo Martini提供

          當(dāng)時23歲的康奈爾大學(xué)研究生莫里斯Morris釋放莫里斯蠕蟲(Morris Worm),發(fā)動了所謂的“互聯(lián)網(wǎng)的首次重大攻擊”時,羅伯特·莫里斯和互聯(lián)網(wǎng)本身都還很年輕。當(dāng)時接入互聯(lián)網(wǎng)的6萬臺機(jī)器里面,大概有10%遭到了破壞,造成數(shù)百萬美元的損失,并導(dǎo)致《紐約時報》首次刊出“互聯(lián)網(wǎng)”這一詞。即使是精通技術(shù)的人,對于這個蠕蟲的影響范圍如此之廣也感到瞠目結(jié)舌。莫里斯說,他本意并不想造成如此大的傷害,他也因此成為根據(jù)《計算機(jī)欺詐和濫用法》被起訴的第一人。在被判處三年緩刑之后,他成為了著名的創(chuàng)業(yè)孵化器Y Combinator 的共同創(chuàng)始人以及麻省理工學(xué)院的計算機(jī)科學(xué)助理教授。——Elena Botella

          15、只有一行代碼的病毒

          年代:大約1990年代

          一行代碼的威力,以及計算機(jī)總讓人驚訝的脆弱性

          :{:| :&}; :

          不要在家里跑這行代碼。提供者:Chris Noessel

          你在上面看到的是一種稱為“叉路炸彈(fork bomb)”的病毒——只有一行代碼。當(dāng)然它的發(fā)作需要滿足一些特定的條件(包括Unix 操作系統(tǒng)版本要舊一點(diǎn),易感染的那種)。在條件滿足的情況下,如果你在Bash里面輸入這條命令,它就會一遍又一遍地復(fù)制自身,直到把計算機(jī)中的所有可用內(nèi)存耗盡,導(dǎo)致計算機(jī)崩潰。

          這段代碼的美麗之處不在于代碼之小與危害之大的對比,而在于它用冒號作為函數(shù)名。大多數(shù)函數(shù)(可重復(fù)使用的代碼行)的命名都是描述性的,比方說“Print”或“isThisEmailValid”,但是這并不是嚴(yán)格要求的規(guī)矩。大多數(shù)計算語言都不能用冒號作為函數(shù)名稱,但是Bash就可以。

          我最早見到這行代碼要追溯到2002年,當(dāng)時德國法蘭克福的一家藝術(shù)博物館Angewandte Kunst 博物館正在展覽。博物館展覽代碼可是很罕見的的——Chris Noessel

          16、HTML超鏈接

          年代:1990

          讓我們把所有東西連接上任何東西(甚至是難以想象的東西)的工具

          https://www.slate.com">Slate

          蒂姆·伯納斯·李(Tim Berners-Lee)引入超鏈接,世界從此改變了。超鏈接是一段讓人人皆可遨游WWW的代碼。將信息鏈接起來的概念并不算特別新穎,但超鏈接的新鮮之處在于,它把各種計算機(jī)系統(tǒng)約定的標(biāo)點(diǎn)符號拼湊到了一起,統(tǒng)一成URL冒號雙斜杠的格式,從而對任何現(xiàn)有的條目進(jìn)行命名。盡管伯納斯·李擔(dān)心向后兼容性的問題,但超鏈接任何東西的概念令該想法永不過時。伯納斯·李的超鏈接可以隨意變成“馬上購買”按鈕,點(diǎn)贊拇指、轉(zhuǎn)發(fā)推特等等。這些令人意想不到的用例應(yīng)該能夠提醒我們,當(dāng)我們站在技術(shù)革命的風(fēng)口浪尖時,最難預(yù)料到的就是接下來會發(fā)生的事情。——R Street技術(shù)和創(chuàng)新總監(jiān)Charles Duan

          17、JPEG的引入

          年代:1992

          永遠(yuǎn)改變了我們與攝影的關(guān)系

          double *NaiveDct_transform(double vector[], size_t len) {

          if (SIZE_MAX / sizeof(double) return NULL;

          double *result=malloc(len * sizeof(double));

          if (result==NULL)

          return NULL;

          double factor=M_PI / len;

          for (size_t i=0; i double sum=0;

          for (size_t j=0; j sum +=vector[j] * cos((j + 0.5) * i * factor);

          result[i]=sum;

          }

          return result;

          }

          上述代碼片段是離散余弦變換算法,JPEG背后的基石。

          Nayuki項(xiàng)目

          我們現(xiàn)在已經(jīng)把相機(jī)裝滿照片視為理所當(dāng)然。但是過去表示圖像需要大量的數(shù)據(jù)。1992年,聯(lián)合圖像專家組(Joint Photographic Experts Group)發(fā)布了JPEG的標(biāo)準(zhǔn)規(guī)范,從而讓圖像文件變得更小。盡管當(dāng)時也可以用其他的壓縮格式,但JPEG之所以能成為世界標(biāo)準(zhǔn),部分原因是它不用交版稅。JPEG采用了有損壓縮,在壓縮過程當(dāng)中可以消除圖像里面人眼無法檢測到的部分,比方說顏色的細(xì)微變化。有損壓縮對于1992年引入的另一項(xiàng)發(fā)明MP3也至關(guān)重要.類似地,這種音頻文件格式通過丟棄人耳無法檢測到的數(shù)據(jù)而變得緊湊。——Aaron Mak, Slate

          18、Mosaic瀏覽器

          年代:1993

          現(xiàn)代web的誕生

          MakeImage(dsp, data, width, height, depth, img_info, clip)

          Display *dsp;

          unsigned char *data;

          int width, height;

          int depth;

          ImageInfo *img_info;

          int clip;

          {

          int linepad, shiftnum;

          int shiftstart, shiftstop, shiftinc;

          int bytesperline,bpp;

          int temp;

          int w, h;

          XImage *newimage;

          unsigned char *bit_data, *bitp, *datap;

          Visual *theVisual;

          int bmap_order;

          unsigned long c;

          int rshift, gshift, bshift;

          #ifdef NEW

          switch(bpp=bits_per_pixel(dsp,depth))

          #else

          switch(depth)

          以上是2.7版代碼的一部分。

          美國國家超級計算機(jī)應(yīng)用中心軟件開發(fā)小組,用于X Windows系統(tǒng)的NCSA Mosaic

          以前的瀏覽器渲染處理得很笨拙,雖然文本呈現(xiàn)的效果很好,但是瀏覽圖像卻一定要單獨(dú)打開窗口。Marc Andreessen領(lǐng)導(dǎo)的Mosaic黑客希望做出一個能讓文字和圖像一起呈現(xiàn)的瀏覽器。是他們讓web變得我們熟悉的樣子,就好像在看一本很酷的數(shù)字雜志或報紙一樣。隨著世界各地的網(wǎng)站管理員開始要求更多的標(biāo)簽來讓網(wǎng)站看起來更酷,這也促使HTML標(biāo)準(zhǔn)的發(fā)展走上了快車道。(那時候框架似乎是個超酷的主意。)——Clive Thompson

          19、會跟蹤的像素

          年代:1993

          Facebook的PageView 跟蹤像素。

          Facebook's PageView Tracking Pixel.

          Facebook

          這些小小的HTML片段看起來并沒有多少,但它們卻是數(shù)字廣告的基石,讓它們成為了許多當(dāng)代問題(監(jiān)視,媒體整合甚至虛假信息)的核心。

          早在1990年代的時候,web設(shè)計師就開始用透明的單像素圖像來調(diào)整頁面布局。但是,計算機(jī)必須下載網(wǎng)頁上的每一張圖像,甚至大家察覺不到的像素也得下載。1993年,公司開始利用這一個漏洞:通過跟蹤像素下載,他們就可以了解了你是誰在哪里,還觸發(fā)一個cookie下載到你的瀏覽器。這個cookie使得Cookie使廣告主可以跨多個網(wǎng)站跟蹤你。

          像素跟蹤的成功直接導(dǎo)致了Facebook的“贊”按鈕的誕生,這個按鈕可在嵌入它的每個網(wǎng)站上跟蹤你。這種大規(guī)模的數(shù)據(jù)收集實(shí)現(xiàn)了超級的定向,讓Facebook廣告變得無比成功,其結(jié)果是媒體公司數(shù)十億美元的收入被轉(zhuǎn)移到Facebook。隨著新聞業(yè)的沉淪,定向性的虛假信息大行其道,而基于監(jiān)視的商業(yè)模式開始激增。——Sara Wachter -Boettcher,《技術(shù)錯誤:性別歧視app,帶偏見的算法以及其他的有毒技術(shù)》作者

          20、Robots.txt代碼

          年代:1994

          一個對搜索等應(yīng)用具有重大影響的微型工具

          User-agent: Mediapartners-Google

          Disallow:

          User-agent: TruliaBot

          Disallow: /

          User-agent: *

          Disallow: /search.html

          User-agent: *

          Disallow: /comments/*

          User-agent: Mediapartners-Google*

          Disallow:

          Slate自己的robot.txt

          如果你執(zhí)行過Google搜索的話,你可能會遇到過這樣的結(jié)果:“由于該網(wǎng)站的robots.txt,該搜索結(jié)果的描述不可用。”并不是每個人都希望自己的網(wǎng)站被搜索引擎索引到,這就是robots.txt文件添加到網(wǎng)站的原因之一,讓給網(wǎng)站建檔的bot(有時也叫做蜘蛛或爬蟲)走開而不是訪問該站點(diǎn)。robots.txt在訪問網(wǎng)站內(nèi)容方面起到的非比尋常的調(diào)停作用使得robots.txt成為了法庭上控辯雙方斗爭得最激烈的代碼段之一,其中涉及到了十幾個涉及版權(quán)、黑客、入侵,侵權(quán)行為的案件,甚至2009年的一樁司法不端行為調(diào)查還牽涉到了前第九巡回法院首席法官Alex Kozinski。——喬治敦大學(xué)法學(xué)院知識產(chǎn)權(quán)與信息政策研究室主任Amanda Levendowski

          21、維基(Wiki)

          年代:1994

          為維基百科鋪平了道路

          sub AsLink {

          local($num)=(@_);

          local($ref)=$old{"r$num"};

          defined $ref

          ? ($ref=~ /\.(?:gif|jpg|jpeg|png)$/i

          ? "

          "

          : "[$num]")
          : "[$num]";
          }

          WikiWikiWeb的WikiBase ,最后編輯于2000年6月13日

          Ward Cunningham通過自己的網(wǎng)站W(wǎng)ikiWikiWeb率先發(fā)明了Wiki ,他認(rèn)為這是分享信息最簡單的方法。他用了一種基本的標(biāo)記語言,里面使用方括號將單詞不留空格串在一起,并在文本周圍用省略號標(biāo)記,讓編輯者更新和組織跨頁面鏈接的信息,這套系統(tǒng)至今在各類Wiki網(wǎng)站上仍被廣泛使用,其中就包括2001年推出的Wikipedia(維基百科)。便利的格式使得Wiki成為了某些最重要的活躍在線協(xié)作形式(安全漏洞跟蹤、記筆記等)的工具。但是,跟任何可以在網(wǎng)上進(jìn)行編輯的內(nèi)容一樣,Wiki也很容易受到故意破壞,以及圍繞著應(yīng)該發(fā)布什么不應(yīng)該發(fā)布什么展開的激烈爭吵,所以Wikipedia才會引入討論頁面和規(guī)則來管控編輯添加新信息的方式。——April Glaser

          22、第一個彈出廣告

          年代:90年代中期

          互聯(lián)網(wǎng)的災(zāi)禍

          window.open ('https://www.slate.com/')

          在新窗口打開特定URL的基本代碼。

          20多年前,我寫過一小段JavaScript代碼,它會在打開你請求的頁面的同時打開另一個小的Web瀏覽器窗口。這個新窗口里面有一個廣告——可怕的彈出式廣告。在接下來的幾年中,我震驚地看著彈出廣告在網(wǎng)絡(luò)上泛濫,被web上最糟糕、最具侵?jǐn)_性的廣告主濫用。

          我當(dāng)時做彈出廣告的目的是這個:我的公司Tripod提供免費(fèi)主頁,讓大家把自己想放的任何內(nèi)容放到上面。為了給這項(xiàng)服務(wù)提供補(bǔ)貼,我們得賣廣告。但是廣告主并不總是喜歡他們刊登廣告的頁面的內(nèi)容,因此我們決定將廣告與用戶的內(nèi)容分開。所以就有了彈出廣告。

          我實(shí)現(xiàn)彈出式廣告的時候就知道這并不是個很好的解決方案。看著它在web上傳播就像用膠帶來固定你的汽車,然后看著路上的其他人扯掉幾條銀色的袋子一起湊熱鬧一樣。

          自從我向全世界釋放了這頭邪惡的野獸之后,我出過書,創(chuàng)辦過公司,在大學(xué)教過人,但別人總會把我跟彈出窗口聯(lián)系到一起。當(dāng)本文發(fā)表時,我預(yù)計仍會收到仇恨的郵件——麻省理工學(xué)院公民媒體中心主任Ethan Zuckerman

          23、導(dǎo)致一件T恤不合法的代碼

          年代:大約1995年

          語言:Perl

          以代碼表現(xiàn)激進(jìn)主義的最早例子之一

          #!/bin/perl -s-- -export-a-crypto-system-sig -RSA-3-lines-PERL

          $m=unpack(H.$w,$m.">$m=unpack(H.$w,$m."\0"x$w),$_=`echo "16do$w 2+4Oi0$d*-^1[d2%Sa <"x$w),$_=`echo "16do$w 2+4Oi0$d*-^1[d2%Sa

          2/d0pack('H*',$_)while read(STDIN,$m,($w=2*$d-1+length($n)&~1)/2)

          Munitions T-Shirt主頁

          那件T恤上的文字是這樣寫的:“警告:這件T恤被歸類為軍需品,不得從美國出口或展示給外國人。”曾經(jīng)有一段時間美國政府把強(qiáng)加密看作是地對空導(dǎo)彈:一旦落入美國敵人手中就會變得無比危險。當(dāng)加密是在笨重、昂貴的設(shè)備內(nèi)進(jìn)行時,這種想法還說得過去,但是1990年代,當(dāng)美國國務(wù)院想要阻止密碼學(xué)研究人員把代碼發(fā)布到互聯(lián)網(wǎng)上時,這種想法就不大說得過去了。可是他們沒想到RSA加密算法(現(xiàn)代加密技術(shù)的基本建構(gòu)塊之一)實(shí)在是太優(yōu)雅了,以至于僅用四行寫得密密麻麻的Perl代碼就能表示出來……緊湊到可以印到T恤上面。原先的那件T恤現(xiàn)在已成收藏家的藏品。出口管制雖然還沒有完全取消,但已大大減少。——康奈爾理工學(xué)院、康奈爾法學(xué)院法學(xué)教授James Grimmelmann

          24、Google的PageRank算法

          年代:1996

          革新了我們知識的組織方式

          import numpy as np

          def pagerank(M, num_iterations=100, d=0.85):

          N=M.shape[1]

          v=np.random.rand(N, 1)

          v=v / np.linalg.norm(v, 1)

          iteration=0

          while iteration iteration +=1

          v=d * np.matmul(M, v) + (1 - d) / N

          return v

          Google創(chuàng)建的算法,上述實(shí)現(xiàn)由Wikipedia提供

          在PageRank之前,搜索引擎是通過尋找我們的查詢關(guān)鍵字是否跟文檔里面的單詞匹配來查找信息的。但Larry PageSergey Brin提出了一個絕妙的主意:知識是社會化的,搜索也應(yīng)如此。為此,他們創(chuàng)建了一種算法,PageRank,這個算法會根據(jù)網(wǎng)上有多少其他頁面鏈接到某個網(wǎng)頁來對該網(wǎng)頁的突出程度進(jìn)行排名。Google今天之所以如此強(qiáng)大,就因?yàn)檫@一個洞察。——Clive Thompson

          人類歷史上最重要的36個代碼片段(三)

          譯者:boxi。


          主站蜘蛛池模板: 麻豆一区二区免费播放网站| 亚洲乱码国产一区三区| 国产精品亚洲一区二区麻豆| 无码精品人妻一区二区三区人妻斩| 国产成人综合一区精品| 一区二区三区在线| 国产欧美一区二区精品仙草咪| 成人精品视频一区二区三区| 午夜一区二区在线观看| 激情内射亚洲一区二区三区| 台湾无码AV一区二区三区| jizz免费一区二区三区| 福利国产微拍广场一区视频在线| 国产成人精品日本亚洲专一区| 国产一区二区不卡在线播放| 一区二区三区无码高清视频| 日韩精品一区二区三区中文3d| 一区二区三区精密机械| 曰韩人妻无码一区二区三区综合部 | 痴汉中文字幕视频一区| 五十路熟女人妻一区二区 | av无码精品一区二区三区四区| 国产在线步兵一区二区三区| 成人免费视频一区| 国产伦精品一区二区三区在线观看| 亚洲中文字幕一区精品自拍| 精品人妻AV一区二区三区| 精品少妇人妻AV一区二区三区| 亚洲中文字幕久久久一区| 日韩欧美一区二区三区免费观看| 亚洲av色香蕉一区二区三区蜜桃| 无码人妻啪啪一区二区| 精品国产一区二区三区在线| 精品国产日韩亚洲一区在线| 国产成人无码aa精品一区| 国产福利一区视频| 中文字幕精品无码一区二区三区| 久久se精品一区二区国产| 精品视频一区二区三三区四区| 麻豆一区二区免费播放网站| 精品一区中文字幕|