SlideShare a Scribd company logo
1 of 57
Download to read offline
How I make a podcast website
Photo by Michal Czyz on Unsplash
using serverless technology in 2023
Shengyou Fan (范聖佑)
HKOSCon 2023
2023/06/10
Story
Kotlin Advocacy pt.1
—
Kotlin Advocacy pt.2
—
!
Kotlin Advocacy pt.3
—
Kotlin Advocacy pt.4
—
Kotlin Advocacy pt.5
—
18 KUGs in Greater China region
co-host with
Yuang Maggie
Kotlin Fireside Chat
Podcast
—
9Episodes
1Year
3Co-hosts
Kotlin Fireside Chat
Podcast
—
10Platforms
2Locales
An evolution process
of the show
—
• Make a logo, pick a theme music and start!
• Prepare a microphone for better sound quality
• Start being picky with background and lighting
• Put more efforts on post editing and design
• Working on SPECIAL ROADSIDE episode recently
What’s next?
Things we wanna evolve
—
Website Statistics
TL;DR - Website
—
TL;DR - Report
—
Overall structure
—
• Website - a bunch of static webpages
• Data API - provide content to the website
• Crawler - grab number from different platforms
• Report - give an image of the trend
Technology selection
—
• Website - Jamstack approach with Astro + Cloud Storage
• Data API - Cloud Functions with Kotlin
• Crawler - jsoup with Kotlin + Cloud Functions & Scheduler
• Report - Spring Boot with Kotlin + Vaadin Chart
The journey started
Build a website using Astro
Getting started with Astro
—
$ npm create astro@latest
public/
robots.txt
favicon.svg
src/
...
astro.config.mjs
package.json
...
tsconfig.json
# Initialize an Astro project
$ npm run dev
# Live preview Astro project
The src folder
—
src/
Header.astro
components/
layouts/
pages/
scripts/
styles/
MainLayout.astro
index.astro
Reusable units of code for your HTML page
"
A special kind of component that wrap some content in a larger page layout
"
A special kind of component used to create new pages on your site
"
Store your JS or TS files
"
Store your CSS or Sass files
"
Create
MainLayout
—
---
export interface Props {
title: string;
}
const {title} = Astro.props;
---
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>{title}</title>
</head>
<body>
<slot/>
</body>
</html>
pass page-specific values as props
#
Scripts for this component
#
HTML content for a layout
"
"
use a slot element to place page contents within a layout
Use layout
on a page
—
---
import MainLayout from "../layouts/MainLayout.astro";
---
<MainLayout title="⾸⾴">
<main id="content" class="padding-top-bottom">
<div class="container">
</div>
</main>
</MainLayout>
<style>
</style>
#
Import the component
#
Use MainLayout component
#
Apply style only to this page
Make reusable
components
—
---
---
<header id="top" class="navbar navbar-sticky">
// ...
</header>
---
import Header from "../components/Header.astro";
---
<body>
<TopHeader!"
<slot !"
!#body>
#
Header component
#
Any other components " put component in a page
" import
Make a home using
Cloud Storage
—
• Create a Bucket using domain name on Cloud Storage
• Verify domain name ownership via Google Search Console
• Point the domain name to Cloud Storage
• Make Bucket accessible publicly
• Specifies the object name for default page
• Specifies the error page (404) to serve
CI/CD using
Cloud Build
—
steps:
- id: 'Install dependencies'
name: node
entrypoint: npm
args: ['install']
- id: 'Build'
name: node
entrypoint: npm
args: ['run', 'build']
- id: 'Deploy to Cloud Storage'
name: 'gcr.io/google.com/cloudsdktool/cloud-sdk'
args: ['gsutil', '-m', 'rsync', '-R', 'dist', 'gs://...']
#
Install node modules
#
Generate static files
#
Deploy using Cloud SDK
Build & deploy
—
Build an API using Cloud Function
<dependencies>
<dependency>
<groupId>com.google.cloud.functions</groupId>
<artifactId>functions-framework-api</artifactId>
<version>...</version>
<scope>provided</scope>
</dependency>
</dependencies>
<plugins>
<plugin>
<groupId>com.google.cloud.functions</groupId>
<artifactId>function-maven-plugin</artifactId>
<version>...</version>
<configuration>
<functionTarget>...</functionTarget>
</configuration>
</plugin>
</plugins>
Getting started with
Cloud Functions
—
#
Add Functions Framework
#
Plugin for extra tasks
Data Class
—
@Serializable
data class Episode(
val id: Int,
val slug: String,
val title: String,
val abstract: String,
val content: String,
val timeline: String,
val cover: String,
val permalink: String,
val publishedAt: String,
)
class Handler: HttpFunction {
@Throws(IOException::class)
override fun service(req: HttpRequest, res: HttpResponse) {
// ...
}
}
HTTP Function
—
#
Extend from HttpFunction
#
Implement service()
class Handler: HttpFunction {
@Throws(IOException::class)
override fun service(req: HttpRequest, res: HttpResponse) {
// ...
val data = Json.encodeToString(
mapOf("data" to episodes)
)
with(res) {
setStatusCode(HttpURLConnection.HTTP_OK)
setContentType("application/json")
writer.write(data)
}
}
}
JSON response
—
#
Setup response details
#
Serialization collection
CI/CD using
Cloud Build
— steps:
- id: 'Build'
name: 'gcr.io/cloud-builders/mvn'
args:
- 'clean'
- 'verify'
- id: 'Deploy'
name: 'gcr.io/cloud-builders/gcloud'
args:
- 'functions'
- 'deploy'
- '...'
- '--trigger-http'
- '--allow-unauthenticated'
- '--region'
- '...'
- '--gen2'
- '--runtime'
- 'java17'
- '--memory'
- '...MB'
- '--entry-point'
- '...'
#
Build project using maven
#
Deploy using gcloud
Choose memory size
"
Specify the entry class name
"
Choose JVM runtime
"
Use 2nd Gen Functions
"
Choose region
"
Open for HTTP without auth
"
Running serverless
API service
—
Back to frontend
Loading data in
Astro
—
---
let response = await fetch("...")
let episodes = await response.json();
---
<div class="episodes-listing">
{
episodes.map((episode) => (
<Episode slug={`${episode.slug}`}
title={`${episode.title}`}
cover={`${episode.cover}`}
abstract={`${episode.abstract}`}/>
))
}
</div>
#
API call to get data
#
Listing data in a component
Generate pages in
Astro
— // [id].astro
---
const { id } = Astro.params;
let response = await fetch(`.../${id}`)
let episode = await response.json();
export async function getStaticPaths() {
let data = await fetch("...")
let episodes = await data.json();
return episodes.map((episode) => ({
params: { id: episode.id },
props: { episode: episode },
}));
}
---
<header id="..." class="...">
<h1 class="..." set:html={episode.title}/>
</header>
#
Fetch data for single page
#
getStaticPaths()
should return an array
of objects to determine
which paths will be pre-
rendered
#
Display the episode data
uses dynamic params in pages’ filename
"
Build crawlers using jsoup
jsoup:
a HTML Parser
—
https://jsoup.org/
// fetch the webpage
val url = "..."
val doc = Jsoup.connect(url).get()
// use selector-syntax to find elements
val elements = doc.select("div.info div.category .count")
// extract what you need from elements
elements.text()
elements.html()
elements.outerHtml()
elements.attr("...")
Grab text from
喜⻢拉雅
— <!-- webpage html -->
<div class="info kn_">
<div class="category kn_">
<span class="count kn_">
<i class="xuicon xuicon-erji1 kn_"></i>
546
</span>
</div>
</div>
// fetch webpage
val url = "https://www.ximalaya.com/sound/$soundId"
val doc = Jsoup.connect(url).get()
val element = doc.select("div.info div.category .count")[1]
// grab text
element.text().trim().toInt()
Grab text from
YouTube
— <!-- webpage html -->
<!DOCTYPE html>
<html>
<head>
<div>
<meta itemprop="interactionCount" content="128">
</div>
</head>
</html>
// fetch webpage
val url = "https://www.youtube.com/watch?v=$videoId"
val doc = Jsoup.connect(url).get()
val element = doc
.select("meta[itemprop=interactionCount]").first()
// grab text
element?.attr("content")?.toIntOrNull() ?:0
Trigger it hourly via
Cloud Scheduler
—
Display statistic data usingVaadin Chart
Getting started with
Spring Boot + Vaadin
—
Add Vaadin addon
—
// build.gradle.kts
repositories {
// ...
maven(url = “https://maven.vaadin.com/vaadin-addons")
// ...
}
dependencies {
// ...
implementation("com.vaadin:vaadin-charts-flow")
// ...
}
Create chart
—
@Route("...")
@PageTitle("...")
class SingleEpisodeStatisticChartView(
@Autowired val service: StatisticsService,
) : VerticalLayout() {
init {
val chart= Chart(ChartType.COLUMN)
// ...
add(chart)
}
}
#
Prepare data and chart
Chart configuration
—
@Route("...")
@PageTitle("...")
class SingleEpisodeStatisticChartView(
@Autowired val service: StatisticsService,
) : VerticalLayout() {
init {
// ...
val conf = chart.configuration
with(conf) {
title = Title("...")
subTitle = Subtitle("...")
isExporting = true
}
// ...
}
}
Plot options
—
@Route("...")
@PageTitle("...")
class SingleEpisodeStatisticChartView(
@Autowired val service: StatisticsService,
) : VerticalLayout() {
init {
// ...
val column = PlotOptionsColumn()
column.cursor = Cursor.POINTER
column.dataLabels = DataLabels(true)
conf.setPlotOptions(column)
// ...
}
}
Axis configuration
—
@Route("...")
@PageTitle("...")
class SingleEpisodeStatisticChartView(
@Autowired val service: StatisticsService,
) : VerticalLayout() {
init {
// ...
val x = XAxis()
x.type = AxisType.CATEGORY
conf.addxAxis(x)
val y = YAxis()
y.setTitle("!!$")
conf.addyAxis(y)
// ...
}
}
Chart data series
—
@Route("...")
@PageTitle("...")
class SingleEpisodeStatisticChartView(
@Autowired val service: StatisticsService,
) : VerticalLayout() {
init {
// ...
val episodeStatistic = service
.getEpisodeStatisticByPlatform(/* ep. */)
val dataSeries = DataSeries()
episodeStatistic.forEach { (key, value) !"
dataSeries.add(DataSeriesItem(key, value))
}
conf.addSeries(dataSeries)
// ...
}
}
Retrospective
Technologies
—
• Astro for website
• Function Framework with Kotlin for API
• jsoup with Kotlin for crawler
• Spring Boot + Vaadin Chart for Report
GCP services
—
• Cloud Storage
• Cloud Functions
• Cloud Scheduler
• Cloud Build
Moving forward
—
• Paying down technical debt
• Support 2 locales on website
• Download/Import CSV data from Google, Apple, Firstory
• Build cross-platform mobile app
Kotlin Fireside Chat
Podcast
—
https://podcast.kotlin.tips/
Let’s talk at
COSCUP booth
—
29th-30th July
See you in Taipei!
How I make a podcast website
Photo by Michal Czyz on Unsplash
using serverless technology in 2023
Shengyou Fan (范聖佑)
JetBrains Developer Advocate
shengyou.fan@jetbrains.com
Thank you!

More Related Content

What's hot

[JCConf 2023] 從 Kotlin Multiplatform 到 Compose Multiplatform:在多平台間輕鬆共用業務邏輯與 U...
[JCConf 2023] 從 Kotlin Multiplatform 到 Compose Multiplatform:在多平台間輕鬆共用業務邏輯與 U...[JCConf 2023] 從 Kotlin Multiplatform 到 Compose Multiplatform:在多平台間輕鬆共用業務邏輯與 U...
[JCConf 2023] 從 Kotlin Multiplatform 到 Compose Multiplatform:在多平台間輕鬆共用業務邏輯與 U...
Shengyou Fan
 
Windows Kernel Exploitation : This Time Font hunt you down in 4 bytes
Windows Kernel Exploitation : This Time Font hunt you down in 4 bytesWindows Kernel Exploitation : This Time Font hunt you down in 4 bytes
Windows Kernel Exploitation : This Time Font hunt you down in 4 bytes
Peter Hlavaty
 

What's hot (20)

Hibernate
Hibernate Hibernate
Hibernate
 
Linux kernel debugging
Linux kernel debuggingLinux kernel debugging
Linux kernel debugging
 
簡化 JVM 上雲 - 透過 Azure Spring Cloud 提升開發、發佈及服務監控效率
簡化 JVM 上雲 - 透過 Azure Spring Cloud 提升開發、發佈及服務監控效率簡化 JVM 上雲 - 透過 Azure Spring Cloud 提升開發、發佈及服務監控效率
簡化 JVM 上雲 - 透過 Azure Spring Cloud 提升開發、發佈及服務監控效率
 
Linux Porting
Linux PortingLinux Porting
Linux Porting
 
Understanding a kernel oops and a kernel panic
Understanding a kernel oops and a kernel panicUnderstanding a kernel oops and a kernel panic
Understanding a kernel oops and a kernel panic
 
Kernel Recipes 2017 - Understanding the Linux kernel via ftrace - Steven Rostedt
Kernel Recipes 2017 - Understanding the Linux kernel via ftrace - Steven RostedtKernel Recipes 2017 - Understanding the Linux kernel via ftrace - Steven Rostedt
Kernel Recipes 2017 - Understanding the Linux kernel via ftrace - Steven Rostedt
 
[Effective Kotlin 讀書會] 第八章 Efficient collection processing 導讀
[Effective Kotlin 讀書會] 第八章 Efficient collection processing 導讀[Effective Kotlin 讀書會] 第八章 Efficient collection processing 導讀
[Effective Kotlin 讀書會] 第八章 Efficient collection processing 導讀
 
Hunting for Privilege Escalation in Windows Environment
Hunting for Privilege Escalation in Windows EnvironmentHunting for Privilege Escalation in Windows Environment
Hunting for Privilege Escalation in Windows Environment
 
[JCConf 2023] 從 Kotlin Multiplatform 到 Compose Multiplatform:在多平台間輕鬆共用業務邏輯與 U...
[JCConf 2023] 從 Kotlin Multiplatform 到 Compose Multiplatform:在多平台間輕鬆共用業務邏輯與 U...[JCConf 2023] 從 Kotlin Multiplatform 到 Compose Multiplatform:在多平台間輕鬆共用業務邏輯與 U...
[JCConf 2023] 從 Kotlin Multiplatform 到 Compose Multiplatform:在多平台間輕鬆共用業務邏輯與 U...
 
Hunting malware with volatility v2.0
Hunting malware with volatility v2.0Hunting malware with volatility v2.0
Hunting malware with volatility v2.0
 
Init of Android
Init of AndroidInit of Android
Init of Android
 
Page cache in Linux kernel
Page cache in Linux kernelPage cache in Linux kernel
Page cache in Linux kernel
 
Mockito a simple, intuitive mocking framework
Mockito   a simple, intuitive mocking frameworkMockito   a simple, intuitive mocking framework
Mockito a simple, intuitive mocking framework
 
Kernel Debugging & Profiling
Kernel Debugging & ProfilingKernel Debugging & Profiling
Kernel Debugging & Profiling
 
Windows Kernel Exploitation : This Time Font hunt you down in 4 bytes
Windows Kernel Exploitation : This Time Font hunt you down in 4 bytesWindows Kernel Exploitation : This Time Font hunt you down in 4 bytes
Windows Kernel Exploitation : This Time Font hunt you down in 4 bytes
 
iOS Application Penetration Testing for Beginners
iOS Application Penetration Testing for BeginnersiOS Application Penetration Testing for Beginners
iOS Application Penetration Testing for Beginners
 
Launch the First Process in Linux System
Launch the First Process in Linux SystemLaunch the First Process in Linux System
Launch the First Process in Linux System
 
淺談探索 Linux 系統設計之道
淺談探索 Linux 系統設計之道 淺談探索 Linux 系統設計之道
淺談探索 Linux 系統設計之道
 
A look into the sanitizer family (ASAN & UBSAN) by Akul Pillai
A look into the sanitizer family (ASAN & UBSAN) by Akul PillaiA look into the sanitizer family (ASAN & UBSAN) by Akul Pillai
A look into the sanitizer family (ASAN & UBSAN) by Akul Pillai
 
Linux Initialization Process (2)
Linux Initialization Process (2)Linux Initialization Process (2)
Linux Initialization Process (2)
 

Similar to How I make a podcast website using serverless technology in 2023

#NewMeetup Performance
#NewMeetup Performance#NewMeetup Performance
#NewMeetup Performance
Justin Cataldo
 
Developing your first application using FIWARE
Developing your first application using FIWAREDeveloping your first application using FIWARE
Developing your first application using FIWARE
FIWARE
 
125 고성능 web view-deview 2013 발표 자료_공유용
125 고성능 web view-deview 2013 발표 자료_공유용125 고성능 web view-deview 2013 발표 자료_공유용
125 고성능 web view-deview 2013 발표 자료_공유용
NAVER D2
 
JavaScriptIn this project you will create an interactive map for a.pdf
JavaScriptIn this project you will create an interactive map for a.pdfJavaScriptIn this project you will create an interactive map for a.pdf
JavaScriptIn this project you will create an interactive map for a.pdf
sanjeevbansal1970
 
Hdv309 - Real World Sandboxed Solutions
Hdv309 - Real World Sandboxed SolutionsHdv309 - Real World Sandboxed Solutions
Hdv309 - Real World Sandboxed Solutions
woutervugt
 

Similar to How I make a podcast website using serverless technology in 2023 (20)

Presentation Tier optimizations
Presentation Tier optimizationsPresentation Tier optimizations
Presentation Tier optimizations
 
#NewMeetup Performance
#NewMeetup Performance#NewMeetup Performance
#NewMeetup Performance
 
Developing your first application using FIWARE
Developing your first application using FIWAREDeveloping your first application using FIWARE
Developing your first application using FIWARE
 
The Future of CSS with Web components
The Future of CSS with Web componentsThe Future of CSS with Web components
The Future of CSS with Web components
 
The Future of CSS with Web Components
The Future of CSS with Web ComponentsThe Future of CSS with Web Components
The Future of CSS with Web Components
 
DEVICE CHANNELS
DEVICE CHANNELSDEVICE CHANNELS
DEVICE CHANNELS
 
Vue routing tutorial getting started with vue router
Vue routing tutorial getting started with vue routerVue routing tutorial getting started with vue router
Vue routing tutorial getting started with vue router
 
Web Performance Part 4 "Client-side performance"
Web Performance Part 4  "Client-side performance"Web Performance Part 4  "Client-side performance"
Web Performance Part 4 "Client-side performance"
 
125 고성능 web view-deview 2013 발표 자료_공유용
125 고성능 web view-deview 2013 발표 자료_공유용125 고성능 web view-deview 2013 발표 자료_공유용
125 고성능 web view-deview 2013 발표 자료_공유용
 
Web Components With Rails
Web Components With RailsWeb Components With Rails
Web Components With Rails
 
HTML 5 - Overview
HTML 5 - OverviewHTML 5 - Overview
HTML 5 - Overview
 
Familiar HTML5 - 事例とサンプルコードから学ぶ 身近で普通に使わているHTML5
Familiar HTML5 - 事例とサンプルコードから学ぶ 身近で普通に使わているHTML5Familiar HTML5 - 事例とサンプルコードから学ぶ 身近で普通に使わているHTML5
Familiar HTML5 - 事例とサンプルコードから学ぶ 身近で普通に使わているHTML5
 
VMWorld 2017 Hackathon training: Getting Started with Clarity
VMWorld 2017 Hackathon training: Getting Started with ClarityVMWorld 2017 Hackathon training: Getting Started with Clarity
VMWorld 2017 Hackathon training: Getting Started with Clarity
 
Node.js & Twitter Bootstrap Crash Course
Node.js & Twitter Bootstrap Crash CourseNode.js & Twitter Bootstrap Crash Course
Node.js & Twitter Bootstrap Crash Course
 
Night Watch with QA
Night Watch with QANight Watch with QA
Night Watch with QA
 
JavaScriptIn this project you will create an interactive map for a.pdf
JavaScriptIn this project you will create an interactive map for a.pdfJavaScriptIn this project you will create an interactive map for a.pdf
JavaScriptIn this project you will create an interactive map for a.pdf
 
Testing frontends with nightwatch & saucelabs
Testing frontends with nightwatch & saucelabsTesting frontends with nightwatch & saucelabs
Testing frontends with nightwatch & saucelabs
 
Mobile App Development: Primi passi con NativeScript e Angular 2
Mobile App Development: Primi passi con NativeScript e Angular 2Mobile App Development: Primi passi con NativeScript e Angular 2
Mobile App Development: Primi passi con NativeScript e Angular 2
 
Resource Registries: Plone Conference 2014
Resource Registries: Plone Conference 2014Resource Registries: Plone Conference 2014
Resource Registries: Plone Conference 2014
 
Hdv309 - Real World Sandboxed Solutions
Hdv309 - Real World Sandboxed SolutionsHdv309 - Real World Sandboxed Solutions
Hdv309 - Real World Sandboxed Solutions
 

More from Shengyou Fan

More from Shengyou Fan (20)

[Kotlin 讀書會第五梯次] 深入淺出 Kotlin 第一章導讀
[Kotlin 讀書會第五梯次] 深入淺出 Kotlin 第一章導讀[Kotlin 讀書會第五梯次] 深入淺出 Kotlin 第一章導讀
[Kotlin 讀書會第五梯次] 深入淺出 Kotlin 第一章導讀
 
[WebConf Taiwan 2023] 一份 Zend Engine 外帶!透過 Micro 讓一次打包、多處運行變得可能
[WebConf Taiwan 2023] 一份 Zend Engine 外帶!透過 Micro 讓一次打包、多處運行變得可能[WebConf Taiwan 2023] 一份 Zend Engine 外帶!透過 Micro 讓一次打包、多處運行變得可能
[WebConf Taiwan 2023] 一份 Zend Engine 外帶!透過 Micro 讓一次打包、多處運行變得可能
 
[MOPCON 2022] 以 Kotlin Multiplatform 制霸全平台
[MOPCON 2022] 以 Kotlin Multiplatform 制霸全平台[MOPCON 2022] 以 Kotlin Multiplatform 制霸全平台
[MOPCON 2022] 以 Kotlin Multiplatform 制霸全平台
 
Using the Exposed SQL Framework to Manage Your Database
Using the Exposed SQL Framework to Manage Your DatabaseUsing the Exposed SQL Framework to Manage Your Database
Using the Exposed SQL Framework to Manage Your Database
 
[COSCUP 2022] 讓黑畫面再次偉大 - 用 PHP 寫 CLI 工具
[COSCUP 2022] 讓黑畫面再次偉大 - 用 PHP 寫 CLI 工具[COSCUP 2022] 讓黑畫面再次偉大 - 用 PHP 寫 CLI 工具
[COSCUP 2022] 讓黑畫面再次偉大 - 用 PHP 寫 CLI 工具
 
[COSCUP 2022] Kotlin Collection 遊樂園
[COSCUP 2022] Kotlin Collection 遊樂園[COSCUP 2022] Kotlin Collection 遊樂園
[COSCUP 2022] Kotlin Collection 遊樂園
 
[PHP 也有 Day #64] PHP 升級指南
[PHP 也有 Day #64] PHP 升級指南[PHP 也有 Day #64] PHP 升級指南
[PHP 也有 Day #64] PHP 升級指南
 
[Kotlin Serverless 工作坊] 單元 4 - 實作 RSS Aggregator
[Kotlin Serverless 工作坊] 單元 4 - 實作 RSS Aggregator[Kotlin Serverless 工作坊] 單元 4 - 實作 RSS Aggregator
[Kotlin Serverless 工作坊] 單元 4 - 實作 RSS Aggregator
 
[Kotlin Serverless 工作坊] 單元 3 - 實作 JSON API
[Kotlin Serverless 工作坊] 單元 3 - 實作 JSON API[Kotlin Serverless 工作坊] 單元 3 - 實作 JSON API
[Kotlin Serverless 工作坊] 單元 3 - 實作 JSON API
 
[Kotlin Serverless 工作坊] 單元 2 - 簡介 Kotlin Serverless
[Kotlin Serverless 工作坊] 單元 2 - 簡介 Kotlin Serverless[Kotlin Serverless 工作坊] 單元 2 - 簡介 Kotlin Serverless
[Kotlin Serverless 工作坊] 單元 2 - 簡介 Kotlin Serverless
 
[Kotlin Serverless 工作坊] 單元 1 - 開發環境建置
[Kotlin Serverless 工作坊] 單元 1 - 開發環境建置[Kotlin Serverless 工作坊] 單元 1 - 開發環境建置
[Kotlin Serverless 工作坊] 單元 1 - 開發環境建置
 
用 Kotlin 打造讀書會小幫手
用 Kotlin 打造讀書會小幫手用 Kotlin 打造讀書會小幫手
用 Kotlin 打造讀書會小幫手
 
Kotlin 讀書會第三梯次第一章
Kotlin 讀書會第三梯次第一章Kotlin 讀書會第三梯次第一章
Kotlin 讀書會第三梯次第一章
 
用 OPENRNDR 將 Chatbot 訊息視覺化
用 OPENRNDR 將 Chatbot 訊息視覺化用 OPENRNDR 將 Chatbot 訊息視覺化
用 OPENRNDR 將 Chatbot 訊息視覺化
 
[PHP 也有 Day] 垃圾留言守城記 - 用 Laravel 阻擋 SPAM 留言的奮鬥史
[PHP 也有 Day] 垃圾留言守城記 - 用 Laravel 阻擋 SPAM 留言的奮鬥史[PHP 也有 Day] 垃圾留言守城記 - 用 Laravel 阻擋 SPAM 留言的奮鬥史
[PHP 也有 Day] 垃圾留言守城記 - 用 Laravel 阻擋 SPAM 留言的奮鬥史
 
Ktor 部署攻略 - 老派 Fat Jar 大法
Ktor 部署攻略 - 老派 Fat Jar 大法Ktor 部署攻略 - 老派 Fat Jar 大法
Ktor 部署攻略 - 老派 Fat Jar 大法
 
以 Kotlin 快速打造 Mobile Backend
以 Kotlin 快速打造 Mobile Backend以 Kotlin 快速打造 Mobile Backend
以 Kotlin 快速打造 Mobile Backend
 
Kotlin 一條龍 - 打造全平台應用
Kotlin 一條龍 - 打造全平台應用Kotlin 一條龍 - 打造全平台應用
Kotlin 一條龍 - 打造全平台應用
 
[HKOSCon 2020] Build an api service using ktor rapidly
[HKOSCon 2020] Build an api service using ktor rapidly[HKOSCon 2020] Build an api service using ktor rapidly
[HKOSCon 2020] Build an api service using ktor rapidly
 
用 Kotlin 做自動化工具
用 Kotlin 做自動化工具用 Kotlin 做自動化工具
用 Kotlin 做自動化工具
 

Recently uploaded

AI/ML Infra Meetup | Improve Speed and GPU Utilization for Model Training & S...
AI/ML Infra Meetup | Improve Speed and GPU Utilization for Model Training & S...AI/ML Infra Meetup | Improve Speed and GPU Utilization for Model Training & S...
AI/ML Infra Meetup | Improve Speed and GPU Utilization for Model Training & S...
Alluxio, Inc.
 

Recently uploaded (20)

The Impact of PLM Software on Fashion Production
The Impact of PLM Software on Fashion ProductionThe Impact of PLM Software on Fashion Production
The Impact of PLM Software on Fashion Production
 
IT Software Development Resume, Vaibhav jha 2024
IT Software Development Resume, Vaibhav jha 2024IT Software Development Resume, Vaibhav jha 2024
IT Software Development Resume, Vaibhav jha 2024
 
AI/ML Infra Meetup | Reducing Prefill for LLM Serving in RAG
AI/ML Infra Meetup | Reducing Prefill for LLM Serving in RAGAI/ML Infra Meetup | Reducing Prefill for LLM Serving in RAG
AI/ML Infra Meetup | Reducing Prefill for LLM Serving in RAG
 
How to pick right visual testing tool.pdf
How to pick right visual testing tool.pdfHow to pick right visual testing tool.pdf
How to pick right visual testing tool.pdf
 
COMPUTER AND ITS COMPONENTS PPT.by naitik sharma Class 9th A mittal internati...
COMPUTER AND ITS COMPONENTS PPT.by naitik sharma Class 9th A mittal internati...COMPUTER AND ITS COMPONENTS PPT.by naitik sharma Class 9th A mittal internati...
COMPUTER AND ITS COMPONENTS PPT.by naitik sharma Class 9th A mittal internati...
 
AI/ML Infra Meetup | Perspective on Deep Learning Framework
AI/ML Infra Meetup | Perspective on Deep Learning FrameworkAI/ML Infra Meetup | Perspective on Deep Learning Framework
AI/ML Infra Meetup | Perspective on Deep Learning Framework
 
Secure Software Ecosystem Teqnation 2024
Secure Software Ecosystem Teqnation 2024Secure Software Ecosystem Teqnation 2024
Secure Software Ecosystem Teqnation 2024
 
AI/ML Infra Meetup | Improve Speed and GPU Utilization for Model Training & S...
AI/ML Infra Meetup | Improve Speed and GPU Utilization for Model Training & S...AI/ML Infra Meetup | Improve Speed and GPU Utilization for Model Training & S...
AI/ML Infra Meetup | Improve Speed and GPU Utilization for Model Training & S...
 
How to install and activate eGrabber JobGrabber
How to install and activate eGrabber JobGrabberHow to install and activate eGrabber JobGrabber
How to install and activate eGrabber JobGrabber
 
SQL Injection Introduction and Prevention
SQL Injection Introduction and PreventionSQL Injection Introduction and Prevention
SQL Injection Introduction and Prevention
 
GraphSummit Stockholm - Neo4j - Knowledge Graphs and Product Updates
GraphSummit Stockholm - Neo4j - Knowledge Graphs and Product UpdatesGraphSummit Stockholm - Neo4j - Knowledge Graphs and Product Updates
GraphSummit Stockholm - Neo4j - Knowledge Graphs and Product Updates
 
KLARNA - Language Models and Knowledge Graphs: A Systems Approach
KLARNA -  Language Models and Knowledge Graphs: A Systems ApproachKLARNA -  Language Models and Knowledge Graphs: A Systems Approach
KLARNA - Language Models and Knowledge Graphs: A Systems Approach
 
A Comprehensive Appium Guide for Hybrid App Automation Testing.pdf
A Comprehensive Appium Guide for Hybrid App Automation Testing.pdfA Comprehensive Appium Guide for Hybrid App Automation Testing.pdf
A Comprehensive Appium Guide for Hybrid App Automation Testing.pdf
 
Microsoft 365 Copilot; An AI tool changing the world of work _PDF.pdf
Microsoft 365 Copilot; An AI tool changing the world of work _PDF.pdfMicrosoft 365 Copilot; An AI tool changing the world of work _PDF.pdf
Microsoft 365 Copilot; An AI tool changing the world of work _PDF.pdf
 
Entropy, Software Quality, and Innovation (presented at Princeton Plasma Phys...
Entropy, Software Quality, and Innovation (presented at Princeton Plasma Phys...Entropy, Software Quality, and Innovation (presented at Princeton Plasma Phys...
Entropy, Software Quality, and Innovation (presented at Princeton Plasma Phys...
 
how-to-download-files-safely-from-the-internet.pdf
how-to-download-files-safely-from-the-internet.pdfhow-to-download-files-safely-from-the-internet.pdf
how-to-download-files-safely-from-the-internet.pdf
 
A Guideline to Zendesk to Re:amaze Data Migration
A Guideline to Zendesk to Re:amaze Data MigrationA Guideline to Zendesk to Re:amaze Data Migration
A Guideline to Zendesk to Re:amaze Data Migration
 
Facemoji Keyboard released its 2023 State of Emoji report, outlining the most...
Facemoji Keyboard released its 2023 State of Emoji report, outlining the most...Facemoji Keyboard released its 2023 State of Emoji report, outlining the most...
Facemoji Keyboard released its 2023 State of Emoji report, outlining the most...
 
CompTIA Security+ (Study Notes) for cs.pdf
CompTIA Security+ (Study Notes) for cs.pdfCompTIA Security+ (Study Notes) for cs.pdf
CompTIA Security+ (Study Notes) for cs.pdf
 
Implementing KPIs and Right Metrics for Agile Delivery Teams.pdf
Implementing KPIs and Right Metrics for Agile Delivery Teams.pdfImplementing KPIs and Right Metrics for Agile Delivery Teams.pdf
Implementing KPIs and Right Metrics for Agile Delivery Teams.pdf
 

How I make a podcast website using serverless technology in 2023