欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

淺析getway網(wǎng)關(guān)

 更新時(shí)間:2022年07月08日 14:39:47   作者:china_coding  
這篇文章主要介紹了getway網(wǎng)關(guān)的相關(guān)知識(shí),getway可以實(shí)現(xiàn)nginx的請(qǐng)求轉(zhuǎn)發(fā)和跨域(@CrossOrigin也可以實(shí)現(xiàn)跨域),本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下

一、網(wǎng)關(guān)基本概念

1、API網(wǎng)關(guān)介紹

API網(wǎng)關(guān)出現(xiàn)的原因是微服務(wù)架構(gòu)的出現(xiàn),不同的微服務(wù)一般會(huì)有不同的網(wǎng)絡(luò)地址,而外部客戶端可能需要調(diào)用多個(gè)服務(wù)的接口才能完成一個(gè)業(yè)務(wù)需求,如果讓客戶端直接與各個(gè)微服務(wù)通信,會(huì)有以下的問(wèn)題:

(1)客戶端會(huì)多次請(qǐng)求不同的微服務(wù),增加了客戶端的復(fù)雜性。

(2)存在跨域請(qǐng)求,在一定場(chǎng)景下處理相對(duì)復(fù)雜。

(3)認(rèn)證復(fù)雜,每個(gè)服務(wù)都需要獨(dú)立認(rèn)證。

(4)難以重構(gòu),隨著項(xiàng)目的迭代,可能需要重新劃分微服務(wù)。例如,可能將多個(gè)服務(wù)合并成一個(gè)或者將一個(gè)服務(wù)拆分成多個(gè)。如果客戶端直接與微服務(wù)通信,那么重構(gòu)將會(huì)很難實(shí)施。

(5)某些微服務(wù)可能使用了防火墻/瀏覽器不友好的協(xié)議,直接訪問(wèn)會(huì)有一定的困難。

以上這些問(wèn)題可以借助API網(wǎng)關(guān)解決。API網(wǎng)關(guān)是介于客戶端和服務(wù)器端之間的中間層,所有的外部請(qǐng)求都會(huì)先經(jīng)過(guò)API網(wǎng)關(guān)這一層。也就是說(shuō),API的實(shí)現(xiàn)方面更多的考慮業(yè)務(wù)邏輯,而安全、性能、監(jiān)控可以交由API網(wǎng)關(guān)來(lái)做,這樣既提高業(yè)務(wù)靈活性又不缺安全性

(6)getway可以實(shí)現(xiàn)nginx的請(qǐng)求轉(zhuǎn)發(fā)和跨域(@CrossOrigin也可以實(shí)現(xiàn)跨域)。

負(fù)載均衡:把請(qǐng)求平均分配到多臺(tái)服務(wù)器上。集群部署,部署2臺(tái)service-edu服務(wù),只有端口號(hào)不同,項(xiàng)目都一樣。

2、Spring Cloud Gateway

Spring cloud gateway是spring官方基于Spring 5.0、Spring Boot2.0和Project Reactor等技術(shù)開(kāi)發(fā)的網(wǎng)關(guān),Spring Cloud Gateway旨在為微服務(wù)架構(gòu)提供簡(jiǎn)單、有效和統(tǒng)一的API路由管理方式,Spring Cloud Gateway作為Spring Cloud生態(tài)系統(tǒng)中的網(wǎng)關(guān),目標(biāo)是替代Netflix Zuul,其不僅提供統(tǒng)一的路由方式,并且還基于Filer鏈的方式提供了網(wǎng)關(guān)基本的功能,例如:安全、監(jiān)控/埋點(diǎn)、限流等。

網(wǎng)關(guān)和服務(wù)都在Nacos注冊(cè),注冊(cè)之后通過(guò)Getway網(wǎng)關(guān)在訪問(wèn)相應(yīng)的服務(wù)

3、Spring Cloud Gateway核心概念

網(wǎng)關(guān)提供API全托管服務(wù),豐富的API管理功能,輔助企業(yè)管理大規(guī)模的API,以降低管理成本和安全風(fēng)險(xiǎn),包括協(xié)議適配、協(xié)議轉(zhuǎn)發(fā)、安全策略、防刷、流量、監(jiān)控日志等貢呢。一般來(lái)說(shuō)網(wǎng)關(guān)對(duì)外暴露的URL或者接口信息,我們統(tǒng)稱為路由信息。如果研發(fā)過(guò)網(wǎng)關(guān)中間件或者使用過(guò)Zuul的人,會(huì)知道網(wǎng)關(guān)的核心是Filter以及Filter Chain(Filter責(zé)任鏈)。Sprig Cloud Gateway也具有路由和Filter的概念。下面介紹一下Spring Cloud Gateway中幾個(gè)重要的概念。

(1)路由。路由是網(wǎng)關(guān)最基礎(chǔ)的部分,路由信息有一個(gè)ID、一個(gè)目的URL、一組斷言和一組Filter組成。如果斷言路由為真,則說(shuō)明請(qǐng)求的URL和配置匹配

(2)斷言。Java8中的斷言函數(shù)。Spring Cloud Gateway中的斷言函數(shù)輸入類型是Spring5.0框架中的ServerWebExchange。Spring Cloud Gateway中的斷言函數(shù)允許開(kāi)發(fā)者去定義匹配來(lái)自于http request中的任何信息,比如請(qǐng)求頭和參數(shù)等,簡(jiǎn)單來(lái)講就是一個(gè)匹配規(guī)則,如果匹配到就到Handler去處理。

(3)過(guò)濾器。一個(gè)標(biāo)準(zhǔn)的Spring webFilter。Spring cloud gateway中的filter分為兩種類型的Filter,分別是Gateway Filter和Global Filter。過(guò)濾器Filter將會(huì)對(duì)請(qǐng)求和響應(yīng)進(jìn)行修改處理,統(tǒng)一異常處理,統(tǒng)一跨域處理等。

如上圖所示,Spring cloud Gateway發(fā)出請(qǐng)求。然后再由Gateway Handler Mapping中找到與請(qǐng)求相匹配的路由,將其發(fā)送到Gateway web handler。Handler再通過(guò)指定的過(guò)濾器鏈將請(qǐng)求發(fā)送到我們實(shí)際的服務(wù)執(zhí)行業(yè)務(wù)邏輯,然后返回。

二、getway網(wǎng)關(guān)例子

1、在infrastructure模塊下創(chuàng)建api_gateway模塊

2、在pom.xml引入依賴

<?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">
    <parent>
        <artifactId>infrastructure</artifactId>
        <groupId>com.stu</groupId>
        <version>0.0.1-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>api_gateway</artifactId>
    <dependencies>
        <dependency>
            <groupId>com.stu</groupId>
            <artifactId>common-utils</artifactId>
            <version>0.0.1-SNAPSHOT</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-gateway</artifactId>
        </dependency>

        <!--gson-->
        <dependency>
            <groupId>com.google.code.gson</groupId>
            <artifactId>gson</artifactId>
        </dependency>

        <!--服務(wù)調(diào)用-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>
    </dependencies>

</project>

3、編寫(xiě)application.properties配置文件

# 服務(wù)端口
server.port=8222
# 服務(wù)名
spring.application.name=service-gateway
# nacos服務(wù)地址
spring.cloud.nacos.discovery.server-addr=127.0.0.1:8848
#使用服務(wù)發(fā)現(xiàn)路由,通過(guò)openfeign找到服務(wù)(nginx是通過(guò)配置文件的路徑匹配發(fā)現(xiàn)服務(wù))
spring.cloud.gateway.discovery.locator.enabled=true
#服務(wù)路由名小寫(xiě)
#spring.cloud.gateway.discovery.locator.lower-case-service-id=true
#配置service-edu服務(wù)
#設(shè)置路由id(id可以隨便命名,建議用服務(wù)名稱)
spring.cloud.gateway.routes[0].id=service-edu
#設(shè)置路由的uri
spring.cloud.gateway.routes[0].uri=lb://service-edu
#設(shè)置路由斷言,代理servicerId為auth-service的/auth/路徑
spring.cloud.gateway.routes[0].predicates= Path=/eduservice/**
#配置service-edu服務(wù)
spring.cloud.gateway.routes[1].id=service-msm
## 服務(wù)名
#spring.application.name=service-msm
spring.cloud.gateway.routes[1].uri=lb://service-msm
spring.cloud.gateway.routes[1].predicates= Path=/edumsm/**

yml文件:

server:
  port: 8222
spring:
  application:
  cloud:
    gateway:
      discovery:
        locator:
          enabled: true
      routes:
      - id: SERVICE-ACL
        uri: lb://SERVICE-ACL
        predicates:
        - Path=/*/acl/** # 路徑匹配
      - id: SERVICE-EDU
        uri: lb://SERVICE-EDU
        predicates:
        - Path=/eduservice/** # 路徑匹配
      - id: SERVICE-UCENTER
        uri: lb://SERVICE-UCENTER
        predicates:
        - Path=/ucenter/** # 路徑匹配
    nacos:
      discovery:
        server-addr: 127.0.0.1:8848

4、編寫(xiě)啟動(dòng)類

package com.stu.getway;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
@SpringBootApplication
@EnableDiscoveryClient//Nacos注冊(cè)
public class ApiGetwayApplication {
    public static void main(String[] args) {
        SpringApplication.run(ApiGetwayApplication.class,args);
    }
}

5、測(cè)試

通過(guò)nginx配置訪問(wèn)(8001)

通過(guò)getway配置訪問(wèn)(8222)

三、網(wǎng)關(guān)相關(guān)配置

1、網(wǎng)關(guān)解決跨域問(wèn)題

(1)創(chuàng)建配置類

package com.stu.getway.config;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.cloud.gateway.discovery.DiscoveryClientRouteDefinitionLocator;
import org.springframework.cloud.gateway.discovery.DiscoveryLocatorProperties;
import org.springframework.cloud.gateway.route.RouteDefinitionLocator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.http.codec.ServerCodecConfigurer;
import org.springframework.http.codec.support.DefaultServerCodecConfigurer;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.reactive.CorsUtils;
import org.springframework.web.cors.reactive.CorsWebFilter;
import org.springframework.web.cors.reactive.UrlBasedCorsConfigurationSource;
import org.springframework.web.server.ServerWebExchange;
import org.springframework.web.server.WebFilter;
import org.springframework.web.server.WebFilterChain;
import org.springframework.web.util.pattern.PathPatternParser;
import reactor.core.publisher.Mono;
/**
 * <p>
 * 處理跨域
 * </p>
 *
 * @author qy
 * @since 2019-11-21
 */
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.reactive.CorsWebFilter;
import org.springframework.web.cors.reactive.UrlBasedCorsConfigurationSource;
import org.springframework.web.util.pattern.PathPatternParser;
/**
 * description:
 *
 * @author wangpeng
 * @date 2019/01/02
 */
@Configuration
public class CorsConfig {
    @Bean
    public CorsWebFilter corsFilter() {
        CorsConfiguration config = new CorsConfiguration();
        config.addAllowedMethod("*");
        config.addAllowedOrigin("*");
        config.addAllowedHeader("*");
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(new PathPatternParser());
        source.registerCorsConfiguration("/**", config);
        return new CorsWebFilter(source);
    }
}

2、全局Filter,統(tǒng)一處理會(huì)員登錄與外部不允許訪問(wèn)的服務(wù)

package com.stu.getway.filter;
import com.google.gson.JsonObject;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.util.AntPathMatcher;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;
import java.nio.charset.StandardCharsets;
import java.util.List;
/**
 * <p>
 * 全局Filter,統(tǒng)一處理會(huì)員登錄與外部不允許訪問(wèn)的服務(wù)
 * </p>
 *
 * @author qy
 * @since 2019-11-21
 */
@Component
public class AuthGlobalFilter implements GlobalFilter, Ordered {
    private AntPathMatcher antPathMatcher = new AntPathMatcher();
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        ServerHttpRequest request = exchange.getRequest();
        String path = request.getURI().getPath();
        //校驗(yàn)用戶必須登錄
        if(antPathMatcher.match("/api/**/auth/**", path)) {
            List<String> tokenList = request.getHeaders().get("token");
            if(null == tokenList) {
                ServerHttpResponse response = exchange.getResponse();
                return out(response);
            } else {
//                Boolean isCheck = JwtUtils.checkToken(tokenList.get(0));
//                if(!isCheck) {
                    ServerHttpResponse response = exchange.getResponse();
                    return out(response);
//                }
            }
        }
        //內(nèi)部服務(wù)接口,不允許外部訪問(wèn)
        if(antPathMatcher.match("/**/inner/**", path)) {
            ServerHttpResponse response = exchange.getResponse();
            return out(response);
        }
        return chain.filter(exchange);
    }
    @Override
    public int getOrder() {
        return 0;
    }
    private Mono<Void> out(ServerHttpResponse response) {
        JsonObject message = new JsonObject();
        message.addProperty("success", false);
        message.addProperty("code", 28004);
        message.addProperty("data", "鑒權(quán)失敗");
        byte[] bits = message.toString().getBytes(StandardCharsets.UTF_8);
        DataBuffer buffer = response.bufferFactory().wrap(bits);
        //response.setStatusCode(HttpStatus.UNAUTHORIZED);
        //指定編碼,否則在瀏覽器中會(huì)中文亂碼
        response.getHeaders().add("Content-Type", "application/json;charset=UTF-8");
        return response.writeWith(Mono.just(buffer));
    }
}

3、自定義異常處理

服務(wù)網(wǎng)關(guān)調(diào)用服務(wù)時(shí)可能會(huì)有一些異?;蚍?wù)不可用,它返回錯(cuò)誤信息不友好,需要我們覆蓋處理

ErrorHandlerConfig

package com.stu.getway.handler;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.boot.autoconfigure.web.ResourceProperties;
import org.springframework.boot.autoconfigure.web.ServerProperties;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.boot.web.reactive.error.ErrorAttributes;
import org.springframework.boot.web.reactive.error.ErrorWebExceptionHandler;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.http.codec.ServerCodecConfigurer;
import org.springframework.web.reactive.result.view.ViewResolver;
import java.util.Collections;
import java.util.List;
/**
 * 覆蓋默認(rèn)的異常處理
 *
 * @author yinjihuan
 *
 */
@Configuration
@EnableConfigurationProperties({ServerProperties.class, ResourceProperties.class})
public class ErrorHandlerConfig {
    private final ServerProperties serverProperties;
    private final ApplicationContext applicationContext;
    private final ResourceProperties resourceProperties;
    private final List<ViewResolver> viewResolvers;
    private final ServerCodecConfigurer serverCodecConfigurer;
    public ErrorHandlerConfig(ServerProperties serverProperties,
                                     ResourceProperties resourceProperties,
                                     ObjectProvider<List<ViewResolver>> viewResolversProvider,
                                        ServerCodecConfigurer serverCodecConfigurer,
                                     ApplicationContext applicationContext) {
        this.serverProperties = serverProperties;
        this.applicationContext = applicationContext;
        this.resourceProperties = resourceProperties;
        this.viewResolvers = viewResolversProvider.getIfAvailable(Collections::emptyList);
        this.serverCodecConfigurer = serverCodecConfigurer;
    }
    @Bean
    @Order(Ordered.HIGHEST_PRECEDENCE)
    public ErrorWebExceptionHandler errorWebExceptionHandler(ErrorAttributes errorAttributes) {
        JsonExceptionHandler exceptionHandler = new JsonExceptionHandler(
                errorAttributes,
                this.resourceProperties,
                this.serverProperties.getError(),
                this.applicationContext);
        exceptionHandler.setViewResolvers(this.viewResolvers);
        exceptionHandler.setMessageWriters(this.serverCodecConfigurer.getWriters());
        exceptionHandler.setMessageReaders(this.serverCodecConfigurer.getReaders());
        return exceptionHandler;
    }
}

JsonExceptionHandler

package com.stu.getway.handler;
import org.springframework.boot.autoconfigure.web.ErrorProperties;
import org.springframework.boot.autoconfigure.web.ResourceProperties;
import org.springframework.boot.autoconfigure.web.reactive.error.DefaultErrorWebExceptionHandler;
import org.springframework.boot.web.reactive.error.ErrorAttributes;
import org.springframework.context.ApplicationContext;
import org.springframework.http.HttpStatus;
import org.springframework.web.reactive.function.server.*;
import java.util.HashMap;
import java.util.Map;
/**
 * 自定義異常處理
 *
 * <p>異常時(shí)用JSON代替HTML異常信息<p>
 *
 * @author yinjihuan
 *
 */
public class JsonExceptionHandler extends DefaultErrorWebExceptionHandler {
    public JsonExceptionHandler(ErrorAttributes errorAttributes, ResourceProperties resourceProperties,
                                ErrorProperties errorProperties, ApplicationContext applicationContext) {
        super(errorAttributes, resourceProperties, errorProperties, applicationContext);
    }
    /**
     * 獲取異常屬性
     */
    @Override
    protected Map<String, Object> getErrorAttributes(ServerRequest request, boolean includeStackTrace) {
        Map<String, Object> map = new HashMap<>();
        map.put("success", false);
        map.put("code", 20005);
        map.put("message", "網(wǎng)關(guān)失敗");
        map.put("data", null);
        return map;
    }
    /**
     * 指定響應(yīng)處理方法為JSON處理的方法
     * @param errorAttributes
     */
    @Override
    protected RouterFunction<ServerResponse> getRoutingFunction(ErrorAttributes errorAttributes) {
        return RouterFunctions.route(RequestPredicates.all(), this::renderErrorResponse);
    }
    /**
     * 根據(jù)code獲取對(duì)應(yīng)的HttpStatus
     * @param errorAttributes
     */
    @Override
    protected int getHttpStatus(Map<String, Object> errorAttributes) {
        return 200;
    }
}

到此這篇關(guān)于getway網(wǎng)關(guān)的文章就介紹到這了,更多相關(guān)getway網(wǎng)關(guān)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 遵守這些原則讓你開(kāi)發(fā)效率提高一倍(收藏)

    遵守這些原則讓你開(kāi)發(fā)效率提高一倍(收藏)

    這篇文章主要介紹了遵守這些原則讓你開(kāi)發(fā)效率提高一倍,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-07-07
  • 詳解git reset --hard 和 git reset --soft區(qū)別

    詳解git reset --hard 和 git reset --soft區(qū)別

    這篇文章主要介紹了詳解git reset --hard 和 git reset --soft區(qū)別,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-08-08
  • 一文詳解VSCode安裝配置使用(最新版超詳細(xì)保姆級(jí)含插件)

    一文詳解VSCode安裝配置使用(最新版超詳細(xì)保姆級(jí)含插件)

    安裝VScode就很簡(jiǎn)單了,一路NEXT就可以了,重點(diǎn)是配置使用以及插件推薦,這篇文章主要給大家介紹了關(guān)于VSCode安裝配置使用的相關(guān)資料,本文是最新版超詳細(xì)保姆級(jí)含插件,需要的朋友可以參考下
    2023-05-05
  • 前端開(kāi)發(fā)工具nvim替帶VSCode的安裝配置

    前端開(kāi)發(fā)工具nvim替帶VSCode的安裝配置

    這篇文章主要為大家介紹了一款前端開(kāi)發(fā)工具nvim代替VSCode的配置使用詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-07-07
  • 徹底卸載VSCode的方法步驟(附圖文)

    徹底卸載VSCode的方法步驟(附圖文)

    VSCode卸載后重新安裝,會(huì)發(fā)現(xiàn)好像把之前的設(shè)置和配置也復(fù)原,這樣就達(dá)不到重裝的目的,問(wèn)題就在于卸載時(shí)沒(méi)有卸載干凈,下面這篇文章主要給大家介紹了關(guān)于徹底卸載VSCode的方法步驟,需要的朋友可以參考下
    2023-04-04
  • 解析動(dòng)態(tài)代理jdk的Proxy與spring的CGlib(包括區(qū)別介紹)

    解析動(dòng)態(tài)代理jdk的Proxy與spring的CGlib(包括區(qū)別介紹)

    Spring是Java程序員基本不可能繞開(kāi)的一個(gè)框架,它的核心思想是IoC(控制反轉(zhuǎn))和AOP(面向切面編程)。本文重點(diǎn)給大家介紹動(dòng)態(tài)代理jdk的Proxy與spring的CGlib,感興趣的朋友跟隨小編一起看看吧
    2022-01-01
  • 圖片的色彩空間問(wèn)題

    圖片的色彩空間問(wèn)題

    不知有多少朋友遇到此類問(wèn)題:在PS里處理好的圖,發(fā)到論論壇上以后發(fā)現(xiàn)圖片顏色大變,變得灰蒙蒙,失去了層次,色彩生硬,還有點(diǎn)發(fā)青
    2014-05-05
  • 關(guān)于指令重排現(xiàn)象的兩個(gè)階段詳解

    關(guān)于指令重排現(xiàn)象的兩個(gè)階段詳解

    這個(gè)知識(shí)點(diǎn)也是很多人說(shuō)不清道不明的地方,感覺(jué)都知道,說(shuō)又說(shuō)不出來(lái)。為什么會(huì)這樣呢?因?yàn)檫@幾個(gè)字,很容易被當(dāng)成動(dòng)詞去理解,其實(shí)正確的理解是當(dāng)成名詞,即指令重排現(xiàn)象
    2022-01-01
  • 對(duì)Web開(kāi)發(fā)人員有用的8個(gè)網(wǎng)站小結(jié)

    對(duì)Web開(kāi)發(fā)人員有用的8個(gè)網(wǎng)站小結(jié)

    本文是由比利時(shí)的Web開(kāi)發(fā)人員Jean-Baptiste Jung分享的,Jung還在《Web開(kāi)發(fā)/設(shè)計(jì)人員應(yīng)當(dāng)知道的15個(gè)網(wǎng)站》這篇文章中推薦了15個(gè)相關(guān)網(wǎng)站
    2011-05-05
  • 程序員趣味讀物 談?wù)刄nicode編碼

    程序員趣味讀物 談?wù)刄nicode編碼

    這是一篇程序員寫(xiě)給程序員的趣味讀物。所謂趣味是指可以比較輕松地了解一些原來(lái)不清楚的概念,增進(jìn)知識(shí),類似于打RPG游戲的升級(jí)。整理這篇文章的動(dòng)機(jī)是兩個(gè)問(wèn)題
    2012-08-08

最新評(píng)論